writer.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "types.hpp"
4 #include <cstdio>
5 #include <memory>
6 #include <string>
7 #include <unordered_set>
8 #include <vector>
9 
10 // Forward declaration
11 struct ZSTD_CCtx_s;
12 
13 namespace mcap {
14 
23  bool noCRC = false;
28  bool noChunking = false;
34  bool noMessageIndex = false;
42  bool noSummary = false;
67  bool forceCompression = false;
73  std::string profile;
78  std::string library = "libmcap " MCAP_LIBRARY_VERSION;
79 
80  // The following options are less commonly used, providing more fine-grained
81  // control of index records and the Summary section
82 
83  bool noRepeatedSchemas = false;
84  bool noRepeatedChannels = false;
85  bool noAttachmentIndex = false;
86  bool noMetadataIndex = false;
87  bool noChunkIndex = false;
88  bool noStatistics = false;
89  bool noSummaryOffsets = false;
90 
92  : profile(profile) {}
93 };
94 
98 class IWritable {
99 public:
100  bool crcEnabled = false;
101 
102  IWritable() noexcept;
103  virtual ~IWritable() = default;
104 
112  void write(const std::byte* data, uint64_t size);
117  virtual void end() = 0;
122  virtual uint64_t size() const = 0;
126  uint32_t crc();
130  void resetCrc();
131 
132 protected:
133  virtual void handleWrite(const std::byte* data, uint64_t size) = 0;
134 
135 private:
136  uint32_t crc_;
137 };
138 
143 class FileWriter final : public IWritable {
144 public:
145  ~FileWriter() override;
146 
147  Status open(std::string_view filename, size_t bufferCapacity = 1024);
148 
149  void handleWrite(const std::byte* data, uint64_t size) override;
150  void end() override;
151  uint64_t size() const override;
152 
153 private:
154  std::vector<std::byte> buffer_;
156  std::FILE* file_ = nullptr;
157  uint64_t size_ = 0;
158 };
159 
164 class StreamWriter final : public IWritable {
165 public:
166  StreamWriter(std::ostream& stream);
167 
168  void handleWrite(const std::byte* data, uint64_t size) override;
169  void end() override;
170  uint64_t size() const override;
171 
172 private:
173  std::ostream& stream_;
174  uint64_t size_ = 0;
175 };
176 
182 class IChunkWriter : public IWritable {
183 public:
184  virtual ~IChunkWriter() = default;
185 
191  virtual void end() = 0;
195  virtual uint64_t size() const = 0;
200  virtual uint64_t compressedSize() const = 0;
205  virtual bool empty() const = 0;
210  void clear();
214  virtual const std::byte* data() const = 0;
219  virtual const std::byte* compressedData() const = 0;
220 
221 protected:
222  virtual void handleClear() = 0;
223 };
224 
229 class BufferWriter final : public IChunkWriter {
230 public:
231  void handleWrite(const std::byte* data, uint64_t size) override;
232  void end() override;
233  uint64_t size() const override;
234  uint64_t compressedSize() const override;
235  bool empty() const override;
236  void handleClear() override;
237  const std::byte* data() const override;
238  const std::byte* compressedData() const override;
239 
240 private:
241  std::vector<std::byte> buffer_;
242 };
243 
248 class LZ4Writer final : public IChunkWriter {
249 public:
251 
252  void handleWrite(const std::byte* data, uint64_t size) override;
253  void end() override;
254  uint64_t size() const override;
255  uint64_t compressedSize() const override;
256  bool empty() const override;
257  void handleClear() override;
258  const std::byte* data() const override;
259  const std::byte* compressedData() const override;
260 
261 private:
262  std::vector<std::byte> uncompressedBuffer_;
263  std::vector<std::byte> compressedBuffer_;
265 };
266 
271 class ZStdWriter final : public IChunkWriter {
272 public:
274  ~ZStdWriter() override;
275 
276  void handleWrite(const std::byte* data, uint64_t size) override;
277  void end() override;
278  uint64_t size() const override;
279  uint64_t compressedSize() const override;
280  bool empty() const override;
281  void handleClear() override;
282  const std::byte* data() const override;
283  const std::byte* compressedData() const override;
284 
285 private:
286  std::vector<std::byte> uncompressedBuffer_;
287  std::vector<std::byte> compressedBuffer_;
288  ZSTD_CCtx_s* zstdContext_ = nullptr;
289 };
290 
294 class McapWriter final {
295 public:
296  ~McapWriter();
297 
305  Status open(std::string_view filename, const McapWriterOptions& options);
306 
314  void open(IWritable& writer, const McapWriterOptions& options);
315 
322  void open(std::ostream& stream, const McapWriterOptions& options);
323 
328  void close();
329 
335  void terminate();
336 
344  void addSchema(Schema& schema);
345 
354  void addChannel(Channel& channel);
355 
362  Status write(const Message& message);
363 
371  Status write(Attachment& attachment);
372 
379  Status write(const Metadata& metdata);
380 
385  const Statistics& statistics() const;
386 
391  IWritable* dataSink();
392 
393  // The following static methods are used for serialization of records and
394  // primitives to an output stream. They are not intended to be used directly
395  // unless you are implementing a lower level writer or tests
396 
397  static void writeMagic(IWritable& output);
398 
399  static uint64_t write(IWritable& output, const Header& header);
400  static uint64_t write(IWritable& output, const Footer& footer, bool crcEnabled);
401  static uint64_t write(IWritable& output, const Schema& schema);
402  static uint64_t write(IWritable& output, const Channel& channel);
403  static uint64_t write(IWritable& output, const Message& message);
404  static uint64_t write(IWritable& output, const Attachment& attachment);
405  static uint64_t write(IWritable& output, const Metadata& metadata);
406  static uint64_t write(IWritable& output, const Chunk& chunk);
407  static uint64_t write(IWritable& output, const MessageIndex& index);
408  static uint64_t write(IWritable& output, const ChunkIndex& index);
409  static uint64_t write(IWritable& output, const AttachmentIndex& index);
410  static uint64_t write(IWritable& output, const MetadataIndex& index);
411  static uint64_t write(IWritable& output, const Statistics& stats);
412  static uint64_t write(IWritable& output, const SummaryOffset& summaryOffset);
413  static uint64_t write(IWritable& output, const DataEnd& dataEnd);
414  static uint64_t write(IWritable& output, const Record& record);
415 
416  static void write(IWritable& output, const std::string_view str);
417  static void write(IWritable& output, const ByteArray bytes);
418  static void write(IWritable& output, OpCode value);
419  static void write(IWritable& output, uint16_t value);
420  static void write(IWritable& output, uint32_t value);
421  static void write(IWritable& output, uint64_t value);
422  static void write(IWritable& output, const std::byte* data, uint64_t size);
423  static void write(IWritable& output, const KeyValueMap& map, uint32_t size = 0);
424 
425 private:
426  McapWriterOptions options_{""};
427  uint64_t chunkSize_ = DefaultChunkSize;
428  IWritable* output_ = nullptr;
429  std::unique_ptr<FileWriter> fileOutput_;
430  std::unique_ptr<StreamWriter> streamOutput_;
431  std::unique_ptr<BufferWriter> uncompressedChunk_;
432  std::unique_ptr<LZ4Writer> lz4Chunk_;
433  std::unique_ptr<ZStdWriter> zstdChunk_;
434  std::vector<Schema> schemas_;
435  std::vector<Channel> channels_;
436  std::vector<AttachmentIndex> attachmentIndex_;
437  std::vector<MetadataIndex> metadataIndex_;
438  std::vector<ChunkIndex> chunkIndex_;
439  Statistics statistics_{};
440  std::unordered_set<SchemaId> writtenSchemas_;
441  std::unordered_map<ChannelId, MessageIndex> currentMessageIndex_;
442  Timestamp currentChunkStart_ = MaxTime;
443  Timestamp currentChunkEnd_ = 0;
445  uint64_t uncompressedSize_ = 0;
446  bool opened_ = false;
447 
448  IWritable& getOutput();
449  IChunkWriter* getChunkWriter();
450  void writeChunk(IWritable& output, IChunkWriter& chunkData);
451 };
452 
453 } // namespace mcap
454 
455 #ifdef MCAP_IMPLEMENTATION
456 #include "writer.inl"
457 #endif
Implements the IWritable interface used by McapWriter by wrapping a FILE* pointer created by fopen() ...
Definition: writer.hpp:143
Compression
Supported MCAP compression algorithms.
Definition: types.hpp:34
An abstract interface for writing MCAP data.
Definition: writer.hpp:98
McapWriterOptions(const std::string_view profile)
Definition: writer.hpp:91
An Attachment is an arbitrary file embedded in an MCAP file, including a name, content-type, timestamps, and optional CRC. Attachment records are written in the Data section, outside of Chunks.
Definition: types.hpp:252
The Statistics record is found in the Summary section, providing counts and timestamp ranges for the ...
Definition: types.hpp:296
Wraps a status code and string message carrying additional context.
Definition: errors.hpp:33
std::unordered_map< ChannelId, MessageIndex > currentMessageIndex_
Definition: writer.hpp:441
Describes a Channel that messages are written to. A Channel represents a single connection from a pub...
Definition: types.hpp:155
std::unique_ptr< StreamWriter > streamOutput_
Definition: writer.hpp:430
std::vector< std::byte > buffer_
Definition: writer.hpp:154
CompressionLevel compressionLevel_
Definition: writer.hpp:264
static int writer(lua_State *L, const void *b, size_t size, void *ud)
Definition: lstrlib.c:222
constexpr Timestamp MaxTime
Definition: types.hpp:29
An in-memory IChunkWriter implementation that holds data in a temporary buffer before flushing to an ...
Definition: writer.hpp:271
uint64_t Timestamp
Definition: types.hpp:18
CompressionLevel compressionLevel
Compression level to use when writing Chunks. Slower generally produces smaller files, at the expense of more CPU time. These levels map to different internal settings for each compression algorithm.
Definition: writer.hpp:61
std::unique_ptr< LZ4Writer > lz4Chunk_
Definition: writer.hpp:432
An collection of Schemas, Channels, and Messages that supports compression and indexing.
Definition: types.hpp:211
basic_string_view< char > string_view
Definition: core.h:522
char int compressedSize
Definition: lz4.h:724
Chunk Index records are found in the Summary section, providing summary information for a single Chun...
Definition: types.hpp:235
Metdata Index records are found in the Summary section, providing summary information for a single Me...
Definition: types.hpp:321
std::vector< std::byte > buffer_
Definition: writer.hpp:241
Attachment Index records are found in the Summary section, providing summary information for a single...
Definition: types.hpp:266
uint64_t chunkSize
Target uncompressed Chunk payload size in bytes. Once a Chunk&#39;s uncompressed data meets or exceeds th...
Definition: writer.hpp:50
The final record in an MCAP file (before the trailing magic byte sequence). Contains byte offsets fro...
Definition: types.hpp:111
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
Definition: chrono.h:354
#define MCAP_LIBRARY_VERSION
Definition: types.hpp:14
std::vector< std::byte > uncompressedBuffer_
Definition: writer.hpp:262
bool noChunking
Do not write Chunks to the file, instead writing Schema, Channel, and Message records directly into t...
Definition: writer.hpp:28
An in-memory IChunkWriter implementation backed by a growable buffer.
Definition: writer.hpp:229
bool forceCompression
By default, Chunks that do not benefit from compression will be written uncompressed. This option can be used to force compression on all Chunks. This option is ignored if noChunking=true.
Definition: writer.hpp:67
Summary Offset records are found in the Summary Offset section. Records in the Summary section are gr...
Definition: types.hpp:336
std::unique_ptr< FileWriter > fileOutput_
Definition: writer.hpp:429
size_t bufferCapacity_
Definition: writer.hpp:155
std::vector< std::byte > compressedBuffer_
Definition: writer.hpp:287
The final record in the Data section, signaling the end of Data and beginning of Summary. Optionally contains a CRC of the entire Data section.
Definition: types.hpp:346
Provides a write interface to an MCAP file.
Definition: writer.hpp:294
constexpr uint64_t DefaultChunkSize
Definition: types.hpp:27
Holds a named map of key/value strings containing arbitrary user data. Metadata records are found in ...
Definition: types.hpp:312
Implements the IWritable interface used by McapWriter by wrapping a std::ostream stream.
Definition: writer.hpp:164
OpCode
MCAP record types.
Definition: types.hpp:56
std::unique_ptr< ZStdWriter > zstdChunk_
Definition: writer.hpp:433
An abstract interface for writing Chunk data. Chunk data is buffered in memory and written to disk as...
Definition: writer.hpp:182
std::unordered_set< SchemaId > writtenSchemas_
Definition: writer.hpp:440
A single Message published to a Channel.
Definition: types.hpp:178
std::vector< Schema > schemas_
Definition: writer.hpp:434
std::vector< std::byte > uncompressedBuffer_
Definition: writer.hpp:286
An in-memory IChunkWriter implementation that holds data in a temporary buffer before flushing to an ...
Definition: writer.hpp:248
std::vector< std::byte > compressedBuffer_
Definition: writer.hpp:263
bool noSummary
Do not write Summary or Summary Offset sections to the file, placing the Footer record immediately af...
Definition: writer.hpp:42
std::vector< MetadataIndex > metadataIndex_
Definition: writer.hpp:437
Appears at the beginning of every MCAP file (after the magic byte sequence) and contains the recordin...
Definition: types.hpp:99
std::vector< Channel > channels_
Definition: writer.hpp:435
std::vector< ChunkIndex > chunkIndex_
Definition: writer.hpp:438
Compression compression
Compression algorithm to use when writing Chunks. This option is ignored if noChunking=true.
Definition: writer.hpp:55
bool noCRC
Disable CRC calculations for Chunks, Attachments, and the Data and Summary sections.
Definition: writer.hpp:23
std::ostream & stream_
Definition: writer.hpp:173
std::vector< AttachmentIndex > attachmentIndex_
Definition: writer.hpp:436
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1485
const std::string header
void clear(lua_State *L, int table_index)
Definition: sol.hpp:11710
Definition: core.h:1131
CompressionLevel
Compression level to use when compression is enabled. Slower generally produces smaller files...
Definition: types.hpp:45
static const char * output
Definition: luac.c:38
bool noMessageIndex
Do not write Message Index records to the file. If noSummary=true and noChunkIndex=false, Chunk Index records will still be written to the Summary section, providing a coarse message index.
Definition: writer.hpp:34
dictionary data
Definition: mqtt_test.py:22
std::unordered_map< std::string, std::string > KeyValueMap
Definition: types.hpp:20
Describes a schema used for message encoding and decoding and/or describing the shape of messages...
Definition: types.hpp:128
A list of timestamps to byte offsets for a single Channel. This record appears after each Chunk...
Definition: types.hpp:225
std::unique_ptr< BufferWriter > uncompressedChunk_
Definition: writer.hpp:431
std::vector< std::byte > ByteArray
Definition: types.hpp:21
std::string library
A freeform string written by recording libraries. For this library, the default is "libmcap {Major}...
Definition: writer.hpp:78
std::string profile
The recording profile. See https://github.com/foxglove/mcap/tree/main/docs/specification/profiles for...
Definition: writer.hpp:73
Definition: format.h:895
Definition: format.h:2459
A generic Type-Length-Value record using a uint8 type and uint64 length. This is the generic form of ...
Definition: types.hpp:83
Configuration options for McapWriter.
Definition: writer.hpp:18


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Jun 19 2023 03:12:53