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