WPILibC++ 2024.3.2
DataLogReader.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <stdint.h>
8
9#include <iterator>
10#include <memory>
11#include <span>
12#include <utility>
13#include <vector>
14
15#include "wpi/MemoryBuffer.h"
16
17namespace wpi::log {
18
19/**
20 * Data contained in a start control record as created by DataLog::Start() when
21 * writing the log. This can be read by calling DataLogRecord::GetStartData().
22 */
24 /** Entry ID; this will be used for this entry in future records. */
25 int entry;
26
27 /** Entry name. */
29
30 /** Type of the stored data for this entry, as a string, e.g. "double". */
32
33 /** Initial metadata. */
35};
36
37/**
38 * Data contained in a set metadata control record as created by
39 * DataLog::SetMetadata(). This can be read by calling
40 * DataLogRecord::GetSetMetadataData().
41 */
43 /** Entry ID. */
44 int entry;
45
46 /** New metadata for the entry. */
48};
49
50/**
51 * A record in the data log. May represent either a control record (entry == 0)
52 * or a data record. Used only for reading (e.g. with DataLogReader).
53 */
55 public:
56 DataLogRecord() = default;
57 DataLogRecord(int entry, int64_t timestamp, std::span<const uint8_t> data)
58 : m_timestamp{timestamp}, m_data{data}, m_entry{entry} {}
59
60 /**
61 * Gets the entry ID.
62 *
63 * @return entry ID
64 */
65 int GetEntry() const { return m_entry; }
66
67 /**
68 * Gets the record timestamp.
69 *
70 * @return Timestamp, in integer microseconds
71 */
72 int64_t GetTimestamp() const { return m_timestamp; }
73
74 /**
75 * Gets the size of the raw data.
76 *
77 * @return size
78 */
79 size_t GetSize() const { return m_data.size(); }
80
81 /**
82 * Gets the raw data. Use the GetX functions to decode based on the data type
83 * in the entry's start record.
84 */
85 std::span<const uint8_t> GetRaw() const { return m_data; }
86
87 /**
88 * Returns true if the record is a control record.
89 *
90 * @return True if control record, false if normal data record.
91 */
92 bool IsControl() const { return m_entry == 0; }
93
94 /**
95 * Returns true if the record is a start control record. Use GetStartData()
96 * to decode the contents.
97 *
98 * @return True if start control record, false otherwise.
99 */
100 bool IsStart() const;
101
102 /**
103 * Returns true if the record is a finish control record. Use GetFinishEntry()
104 * to decode the contents.
105 *
106 * @return True if finish control record, false otherwise.
107 */
108 bool IsFinish() const;
109
110 /**
111 * Returns true if the record is a set metadata control record. Use
112 * GetSetMetadataData() to decode the contents.
113 *
114 * @return True if set metadata control record, false otherwise.
115 */
116 bool IsSetMetadata() const;
117
118 /**
119 * Decodes a start control record.
120 *
121 * @param[out] out start record decoded data (if successful)
122 * @return True on success, false on error
123 */
125
126 /**
127 * Decodes a finish control record.
128 *
129 * @param[out] out finish record entry ID (if successful)
130 * @return True on success, false on error
131 */
132 bool GetFinishEntry(int* out) const;
133
134 /**
135 * Decodes a set metadata control record.
136 *
137 * @param[out] out set metadata record decoded data (if successful)
138 * @return True on success, false on error
139 */
141
142 /**
143 * Decodes a data record as a boolean. Note if the data type (as indicated in
144 * the corresponding start control record for this entry) is not "boolean",
145 * invalid results may be returned.
146 *
147 * @param[out] value boolean value (if successful)
148 * @return True on success, false on error
149 */
150 bool GetBoolean(bool* value) const;
151
152 /**
153 * Decodes a data record as an integer. Note if the data type (as indicated in
154 * the corresponding start control record for this entry) is not "int64",
155 * invalid results may be returned.
156 *
157 * @param[out] value integer value (if successful)
158 * @return True on success, false on error
159 */
160 bool GetInteger(int64_t* value) const;
161
162 /**
163 * Decodes a data record as a float. Note if the data type (as indicated in
164 * the corresponding start control record for this entry) is not "float",
165 * invalid results may be returned.
166 *
167 * @param[out] value float value (if successful)
168 * @return True on success, false on error
169 */
170 bool GetFloat(float* value) const;
171
172 /**
173 * Decodes a data record as a double. Note if the data type (as indicated in
174 * the corresponding start control record for this entry) is not "double",
175 * invalid results may be returned.
176 *
177 * @param[out] value double value (if successful)
178 * @return True on success, false on error
179 */
180 bool GetDouble(double* value) const;
181
182 /**
183 * Decodes a data record as a string. Note if the data type (as indicated in
184 * the corresponding start control record for this entry) is not "string",
185 * invalid results may be returned.
186 *
187 * @param[out] value string value
188 * @return True (never fails)
189 */
190 bool GetString(std::string_view* value) const;
191
192 /**
193 * Decodes a data record as a boolean array. Note if the data type (as
194 * indicated in the corresponding start control record for this entry) is not
195 * "boolean[]", invalid results may be returned.
196 *
197 * @param[out] arr boolean array
198 * @return True (never fails)
199 */
200 bool GetBooleanArray(std::vector<int>* arr) const;
201
202 /**
203 * Decodes a data record as an integer array. Note if the data type (as
204 * indicated in the corresponding start control record for this entry) is not
205 * "int64[]", invalid results may be returned.
206 *
207 * @param[out] arr integer array (if successful)
208 * @return True on success, false on error
209 */
210 bool GetIntegerArray(std::vector<int64_t>* arr) const;
211
212 /**
213 * Decodes a data record as a float array. Note if the data type (as
214 * indicated in the corresponding start control record for this entry) is not
215 * "float[]", invalid results may be returned.
216 *
217 * @param[out] arr float array (if successful)
218 * @return True on success, false on error
219 */
220 bool GetFloatArray(std::vector<float>* arr) const;
221
222 /**
223 * Decodes a data record as a double array. Note if the data type (as
224 * indicated in the corresponding start control record for this entry) is not
225 * "double[]", invalid results may be returned.
226 *
227 * @param[out] arr double array (if successful)
228 * @return True on success, false on error
229 */
230 bool GetDoubleArray(std::vector<double>* arr) const;
231
232 /**
233 * Decodes a data record as a string array. Note if the data type (as
234 * indicated in the corresponding start control record for this entry) is not
235 * "string[]", invalid results may be returned.
236 *
237 * @param[out] arr string array (if successful)
238 * @return True on success, false on error
239 */
240 bool GetStringArray(std::vector<std::string_view>* arr) const;
241
242 private:
243 int64_t m_timestamp{0};
244 std::span<const uint8_t> m_data;
245 int m_entry{-1};
246};
247
248class DataLogReader;
249
250/** DataLogReader iterator. */
252 public:
253 using iterator_category = std::forward_iterator_tag;
255 using pointer = const value_type*;
256 using reference = const value_type&;
257
258 DataLogIterator(const DataLogReader* reader, size_t pos)
259 : m_reader{reader}, m_pos{pos} {}
260
261 bool operator==(const DataLogIterator& oth) const {
262 return m_reader == oth.m_reader && m_pos == oth.m_pos;
263 }
264 bool operator!=(const DataLogIterator& oth) const {
265 return !this->operator==(oth);
266 }
267
268 bool operator<(const DataLogIterator& oth) const { return m_pos < oth.m_pos; }
269 bool operator>(const DataLogIterator& oth) const {
270 return !this->operator<(oth) && !this->operator==(oth);
271 }
272 bool operator<=(const DataLogIterator& oth) const {
273 return !this->operator>(oth);
274 }
275 bool operator>=(const DataLogIterator& oth) const {
276 return !this->operator<(oth);
277 }
278
280
282 DataLogIterator tmp = *this;
283 ++*this;
284 return tmp;
285 }
286
287 reference operator*() const;
288
289 pointer operator->() const { return &this->operator*(); }
290
291 protected:
293 size_t m_pos;
294 mutable bool m_valid = false;
296};
297
298/** Data log reader (reads logs written by the DataLog class). */
300 friend class DataLogIterator;
301
302 public:
304
305 /** Constructs from a memory buffer. */
306 explicit DataLogReader(std::unique_ptr<MemoryBuffer> buffer);
307
308 /** Returns true if the data log is valid (e.g. has a valid header). */
309 explicit operator bool() const { return IsValid(); }
310
311 /** Returns true if the data log is valid (e.g. has a valid header). */
312 bool IsValid() const;
313
314 /**
315 * Gets the data log version. Returns 0 if data log is invalid.
316 *
317 * @return Version number; most significant byte is major, least significant
318 * is minor (so version 1.0 will be 0x0100)
319 */
320 uint16_t GetVersion() const;
321
322 /**
323 * Gets the extra header data.
324 *
325 * @return Extra header data
326 */
328
329 /**
330 * Gets the buffer identifier, typically the filename.
331 *
332 * @return Identifier string
333 */
335 return m_buf ? m_buf->GetBufferIdentifier() : "Invalid";
336 }
337
338 /** Returns iterator to first record. */
340
341 /** Returns end iterator. */
342 iterator end() const { return DataLogIterator{this, SIZE_MAX}; }
343
344 private:
345 std::unique_ptr<MemoryBuffer> m_buf;
346
347 bool GetRecord(size_t* pos, DataLogRecord* out) const;
348 bool GetNextRecord(size_t* pos) const;
349};
350
352 if (!m_reader->GetNextRecord(&m_pos)) {
353 m_pos = SIZE_MAX;
354 }
355 m_valid = false;
356 return *this;
357}
358
360 if (!m_valid) {
361 size_t pos = m_pos;
362 if (m_reader->GetRecord(&pos, &m_value)) {
363 m_valid = true;
364 }
365 }
366 return m_value;
367}
368
369} // namespace wpi::log
DataLogReader iterator.
Definition: DataLogReader.h:251
DataLogIterator & operator++()
Definition: DataLogReader.h:351
bool m_valid
Definition: DataLogReader.h:294
std::forward_iterator_tag iterator_category
Definition: DataLogReader.h:253
bool operator!=(const DataLogIterator &oth) const
Definition: DataLogReader.h:264
bool operator<(const DataLogIterator &oth) const
Definition: DataLogReader.h:268
const value_type & reference
Definition: DataLogReader.h:256
bool operator>=(const DataLogIterator &oth) const
Definition: DataLogReader.h:275
DataLogIterator operator++(int)
Definition: DataLogReader.h:281
reference operator*() const
Definition: DataLogReader.h:359
DataLogRecord m_value
Definition: DataLogReader.h:295
const DataLogReader * m_reader
Definition: DataLogReader.h:292
DataLogIterator(const DataLogReader *reader, size_t pos)
Definition: DataLogReader.h:258
pointer operator->() const
Definition: DataLogReader.h:289
size_t m_pos
Definition: DataLogReader.h:293
bool operator==(const DataLogIterator &oth) const
Definition: DataLogReader.h:261
bool operator>(const DataLogIterator &oth) const
Definition: DataLogReader.h:269
bool operator<=(const DataLogIterator &oth) const
Definition: DataLogReader.h:272
Data log reader (reads logs written by the DataLog class).
Definition: DataLogReader.h:299
bool IsValid() const
Returns true if the data log is valid (e.g.
iterator begin() const
Returns iterator to first record.
std::string_view GetExtraHeader() const
Gets the extra header data.
std::string_view GetBufferIdentifier() const
Gets the buffer identifier, typically the filename.
Definition: DataLogReader.h:334
DataLogReader(std::unique_ptr< MemoryBuffer > buffer)
Constructs from a memory buffer.
friend class DataLogIterator
Definition: DataLogReader.h:300
uint16_t GetVersion() const
Gets the data log version.
iterator end() const
Returns end iterator.
Definition: DataLogReader.h:342
A record in the data log.
Definition: DataLogReader.h:54
int GetEntry() const
Gets the entry ID.
Definition: DataLogReader.h:65
bool GetInteger(int64_t *value) const
Decodes a data record as an integer.
bool GetFloat(float *value) const
Decodes a data record as a float.
bool GetBooleanArray(std::vector< int > *arr) const
Decodes a data record as a boolean array.
bool GetStartData(StartRecordData *out) const
Decodes a start control record.
bool GetIntegerArray(std::vector< int64_t > *arr) const
Decodes a data record as an integer array.
std::span< const uint8_t > GetRaw() const
Gets the raw data.
Definition: DataLogReader.h:85
bool GetFinishEntry(int *out) const
Decodes a finish control record.
int64_t GetTimestamp() const
Gets the record timestamp.
Definition: DataLogReader.h:72
bool IsStart() const
Returns true if the record is a start control record.
size_t GetSize() const
Gets the size of the raw data.
Definition: DataLogReader.h:79
bool IsFinish() const
Returns true if the record is a finish control record.
bool GetStringArray(std::vector< std::string_view > *arr) const
Decodes a data record as a string array.
bool GetBoolean(bool *value) const
Decodes a data record as a boolean.
bool IsSetMetadata() const
Returns true if the record is a set metadata control record.
bool GetString(std::string_view *value) const
Decodes a data record as a string.
bool GetDoubleArray(std::vector< double > *arr) const
Decodes a data record as a double array.
bool IsControl() const
Returns true if the record is a control record.
Definition: DataLogReader.h:92
bool GetSetMetadataData(MetadataRecordData *out) const
Decodes a set metadata control record.
bool GetDouble(double *value) const
Decodes a data record as a double.
DataLogRecord(int entry, int64_t timestamp, std::span< const uint8_t > data)
Definition: DataLogReader.h:57
bool GetFloatArray(std::vector< float > *arr) const
Decodes a data record as a float array.
basic_string_view< char > string_view
Definition: core.h:501
Definition: ntcore_cpp.h:31
Data contained in a set metadata control record as created by DataLog::SetMetadata().
Definition: DataLogReader.h:42
std::string_view metadata
New metadata for the entry.
Definition: DataLogReader.h:47
int entry
Entry ID.
Definition: DataLogReader.h:44
Data contained in a start control record as created by DataLog::Start() when writing the log.
Definition: DataLogReader.h:23
std::string_view type
Type of the stored data for this entry, as a string, e.g.
Definition: DataLogReader.h:31
int entry
Entry ID; this will be used for this entry in future records.
Definition: DataLogReader.h:25
std::string_view name
Entry name.
Definition: DataLogReader.h:28
std::string_view metadata
Initial metadata.
Definition: DataLogReader.h:34