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
30namespace webrtc {
31
32class CriticalSectionWrapper;
33class EventWrapper;
34class LogTable;
35class RWLockWrapper;
36class ThreadWrapper;
37
38// All container classes need to implement a ToString-function to be
39// writable to file. Enforce this via the Container interface.
40class Container {
41 public:
42  virtual ~Container() {}
43
44  virtual void ToString(std::string* container_string) const = 0;
45};
46
47template<class T>
48class ValueContainer : public Container {
49 public:
50  explicit ValueContainer(T data) : data_(data) {}
51
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
63template<class T>
64class MultiValueContainer : public Container {
65 public:
66  MultiValueContainer(const T* data, int length)
67    : data_(data, data + length) {
68  }
69
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
82class 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