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_INCLUDE_DATA_LOG_IMPL_H_ 18 #define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_DATA_LOG_IMPL_H_ 19 20 #include <map> 21 #include <sstream> 22 #include <string> 23 #include <vector> 24 25 #include "webrtc/base/platform_thread.h" 26 #include "webrtc/base/scoped_ptr.h" 27 #include "webrtc/typedefs.h" 28 29 namespace webrtc { 30 31 class CriticalSectionWrapper; 32 class EventWrapper; 33 class LogTable; 34 class RWLockWrapper; 35 36 // All container classes need to implement a ToString-function to be 37 // writable to file. Enforce this via the Container interface. 38 class Container { 39 public: ~Container()40 virtual ~Container() {} 41 42 virtual void ToString(std::string* container_string) const = 0; 43 }; 44 45 template<class T> 46 class ValueContainer : public Container { 47 public: ValueContainer(T data)48 explicit ValueContainer(T data) : data_(data) {} 49 ToString(std::string * container_string)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 61 template<class T> 62 class MultiValueContainer : public Container { 63 public: MultiValueContainer(const T * data,int length)64 MultiValueContainer(const T* data, int length) 65 : data_(data, data + length) { 66 } 67 ToString(std::string * container_string)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 80 class 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 rtc::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 // This is a scoped_ptr so that we don't have to create threads in the no-op 150 // impl. 151 rtc::scoped_ptr<rtc::PlatformThread> file_writer_thread_; 152 RWLockWrapper* tables_lock_; 153 }; 154 155 } // namespace webrtc 156 157 #endif // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_DATA_LOG_IMPL_H_ 158