1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 /*
12  * This file contains the helper classes for the DataLog APIs. See data_log.h
13  * for the APIs.
14  *
15  * These classes are helper classes used for logging data for offline
16  * processing. Data logged with these classes can conveniently be parsed and
17  * processed with e.g. Matlab.
18  */
19 #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_
20 #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_
21 
22 #include <map>
23 #include <sstream>
24 #include <string>
25 #include <vector>
26 
27 #include "scoped_ptr.h"
28 #include "typedefs.h"
29 
30 namespace webrtc {
31 
32 class CriticalSectionWrapper;
33 class EventWrapper;
34 class LogTable;
35 class RWLockWrapper;
36 class ThreadWrapper;
37 
38 // All container classes need to implement a ToString-function to be
39 // writable to file. Enforce this via the Container interface.
40 class Container {
41  public:
~Container()42   virtual ~Container() {}
43 
44   virtual void ToString(std::string* container_string) const = 0;
45 };
46 
47 template<class T>
48 class ValueContainer : public Container {
49  public:
ValueContainer(T data)50   explicit ValueContainer(T data) : data_(data) {}
51 
ToString(std::string * container_string)52   virtual void ToString(std::string* container_string) const {
53     *container_string = "";
54     std::stringstream ss;
55     ss << data_ << ",";
56     ss >> *container_string;
57   }
58 
59  private:
60   T   data_;
61 };
62 
63 template<class T>
64 class MultiValueContainer : public Container {
65  public:
MultiValueContainer(const T * data,int length)66   MultiValueContainer(const T* data, int length)
67     : data_(data, data + length) {
68   }
69 
ToString(std::string * container_string)70   virtual void ToString(std::string* container_string) const {
71     *container_string = "";
72     std::stringstream ss;
73     for (size_t i = 0; i < data_.size(); ++i)
74       ss << data_[i] << ",";
75     *container_string += ss.str();
76   }
77 
78  private:
79   std::vector<T>  data_;
80 };
81 
82 class DataLogImpl {
83  public:
84   ~DataLogImpl();
85 
86   // The implementation of the CreateLog() method declared in data_log.h.
87   // See data_log.h for a description.
88   static int CreateLog();
89 
90   // The implementation of the StaticInstance() method declared in data_log.h.
91   // See data_log.h for a description.
92   static DataLogImpl* StaticInstance();
93 
94   // The implementation of the ReturnLog() method declared in data_log.h. See
95   // data_log.h for a description.
96   static void ReturnLog();
97 
98   // The implementation of the AddTable() method declared in data_log.h. See
99   // data_log.h for a description.
100   int AddTable(const std::string& table_name);
101 
102   // The implementation of the AddColumn() method declared in data_log.h. See
103   // data_log.h for a description.
104   int AddColumn(const std::string& table_name,
105                 const std::string& column_name,
106                 int multi_value_length);
107 
108   // Inserts a Container into a table with name table_name at the column
109   // with name column_name.
110   // column_name is treated in a case sensitive way.
111   int InsertCell(const std::string& table_name,
112                  const std::string& column_name,
113                  const Container* value_container);
114 
115   // The implementation of the NextRow() method declared in data_log.h. See
116   // data_log.h for a description.
117   int NextRow(const std::string& table_name);
118 
119  private:
120   DataLogImpl();
121 
122   // Initializes the DataLogImpl object, allocates and starts the
123   // thread file_writer_thread_.
124   int Init();
125 
126   // Write all complete rows in every table to file.
127   // This function should only be called by the file_writer_thread_ if that
128   // thread is running to avoid race conditions.
129   void Flush();
130 
131   // Run() is called by the thread file_writer_thread_.
132   static bool Run(void* obj);
133 
134   // This function writes data to file. Note, it blocks if there is no data
135   // that should be written to file availble. Flush is the non-blocking
136   // version of this function.
137   void Process();
138 
139   // Stops the continuous calling of Process().
140   void StopThread();
141 
142   // Collection of tables indexed by the table name as std::string.
143   typedef std::map<std::string, LogTable*> TableMap;
144   typedef webrtc::scoped_ptr<CriticalSectionWrapper> CritSectScopedPtr;
145 
146   static CritSectScopedPtr  crit_sect_;
147   static DataLogImpl*       instance_;
148   int                       counter_;
149   TableMap                  tables_;
150   EventWrapper*             flush_event_;
151   ThreadWrapper*            file_writer_thread_;
152   RWLockWrapper*            tables_lock_;
153 };
154 
155 }  // namespace webrtc
156 
157 #endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_
158