writer.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "types.hpp"
4 #include "visibility.hpp"
5 #include <cstdio>
6 #include <memory>
7 #include <string>
8 #include <unordered_set>
9 #include <vector>
10 
11 // Forward declaration
12 struct ZSTD_CCtx_s;
13 
14 namespace mcap {
15 
23  bool noChunkCRC = false;
27  bool noAttachmentCRC = false;
31  bool enableDataCRC = false;
35  bool noSummaryCRC = false;
40  bool noChunking = false;
46  bool noMessageIndex = false;
54  bool noSummary = false;
62  uint64_t chunkSize = DefaultChunkSize;
79  bool forceCompression = false;
85  std::string profile;
90  std::string library = "libmcap " MCAP_LIBRARY_VERSION;
91 
92  // The following options are less commonly used, providing more fine-grained
93  // control of index records and the Summary section
94 
95  bool noRepeatedSchemas = false;
96  bool noRepeatedChannels = false;
97  bool noAttachmentIndex = false;
98  bool noMetadataIndex = false;
99  bool noChunkIndex = false;
100  bool noStatistics = false;
101  bool noSummaryOffsets = false;
102 
104  : profile(profile) {}
105 };
106 
111 public:
112  bool crcEnabled = false;
113 
114  IWritable() noexcept;
115  virtual ~IWritable() = default;
116 
124  void write(const std::byte* data, uint64_t size);
129  virtual void end() = 0;
134  virtual uint64_t size() const = 0;
138  uint32_t crc();
142  void resetCrc();
143 
144 protected:
145  virtual void handleWrite(const std::byte* data, uint64_t size) = 0;
146 
147 private:
148  uint32_t crc_;
149 };
150 
155 class MCAP_PUBLIC FileWriter final : public IWritable {
156 public:
157  ~FileWriter() override;
158 
159  Status open(std::string_view filename);
160 
161  void handleWrite(const std::byte* data, uint64_t size) override;
162  void end() override;
163  uint64_t size() const override;
164 
165 private:
166  std::FILE* file_ = nullptr;
167  uint64_t size_ = 0;
168 };
169 
174 class MCAP_PUBLIC StreamWriter final : public IWritable {
175 public:
176  StreamWriter(std::ostream& stream);
177 
178  void handleWrite(const std::byte* data, uint64_t size) override;
179  void end() override;
180  uint64_t size() const override;
181 
182 private:
183  std::ostream& stream_;
184  uint64_t size_ = 0;
185 };
186 
193 public:
194  virtual ~IChunkWriter() override = default;
195 
201  virtual void end() override = 0;
205  virtual uint64_t size() const override = 0;
210  virtual uint64_t compressedSize() const = 0;
215  virtual bool empty() const = 0;
220  void clear();
224  virtual const std::byte* data() const = 0;
229  virtual const std::byte* compressedData() const = 0;
230 
231 protected:
232  virtual void handleClear() = 0;
233 };
234 
239 class MCAP_PUBLIC BufferWriter final : public IChunkWriter {
240 public:
241  void handleWrite(const std::byte* data, uint64_t size) override;
242  void end() override;
243  uint64_t size() const override;
244  uint64_t compressedSize() const override;
245  bool empty() const override;
246  void handleClear() override;
247  const std::byte* data() const override;
248  const std::byte* compressedData() const override;
249 
250 private:
251  std::vector<std::byte> buffer_;
252 };
253 
258 class MCAP_PUBLIC LZ4Writer final : public IChunkWriter {
259 public:
260  LZ4Writer(CompressionLevel compressionLevel, uint64_t chunkSize);
261 
262  void handleWrite(const std::byte* data, uint64_t size) override;
263  void end() override;
264  uint64_t size() const override;
265  uint64_t compressedSize() const override;
266  bool empty() const override;
267  void handleClear() override;
268  const std::byte* data() const override;
269  const std::byte* compressedData() const override;
270 
271 private:
272  std::vector<std::byte> uncompressedBuffer_;
273  std::vector<std::byte> compressedBuffer_;
275 };
276 
281 class MCAP_PUBLIC ZStdWriter final : public IChunkWriter {
282 public:
283  ZStdWriter(CompressionLevel compressionLevel, uint64_t chunkSize);
284  ~ZStdWriter() override;
285 
286  void handleWrite(const std::byte* data, uint64_t size) override;
287  void end() override;
288  uint64_t size() const override;
289  uint64_t compressedSize() const override;
290  bool empty() const override;
291  void handleClear() override;
292  const std::byte* data() const override;
293  const std::byte* compressedData() const override;
294 
295 private:
296  std::vector<std::byte> uncompressedBuffer_;
297  std::vector<std::byte> compressedBuffer_;
298  ZSTD_CCtx_s* zstdContext_ = nullptr;
299 };
300 
304 class MCAP_PUBLIC McapWriter final {
305 public:
306  ~McapWriter();
307 
315  Status open(std::string_view filename, const McapWriterOptions& options);
316 
324  void open(IWritable& writer, const McapWriterOptions& options);
325 
332  void open(std::ostream& stream, const McapWriterOptions& options);
333 
338  void close();
339 
345  void terminate();
346 
354  void addSchema(Schema& schema);
355 
364  void addChannel(Channel& channel);
365 
372  Status write(const Message& message);
373 
381  Status write(Attachment& attachment);
382 
389  Status write(const Metadata& metadata);
390 
395  const Statistics& statistics() const;
396 
401  IWritable* dataSink();
402 
407  void closeLastChunk();
408 
409  // The following static methods are used for serialization of records and
410  // primitives to an output stream. They are not intended to be used directly
411  // unless you are implementing a lower level writer or tests
412 
413  static void writeMagic(IWritable& output);
414 
415  static uint64_t write(IWritable& output, const Header& header);
416  static uint64_t write(IWritable& output, const Footer& footer, bool crcEnabled);
417  static uint64_t write(IWritable& output, const Schema& schema);
418  static uint64_t write(IWritable& output, const Channel& channel);
419  static uint64_t write(IWritable& output, const Message& message);
420  static uint64_t write(IWritable& output, const Attachment& attachment);
421  static uint64_t write(IWritable& output, const Metadata& metadata);
422  static uint64_t write(IWritable& output, const Chunk& chunk);
423  static uint64_t write(IWritable& output, const MessageIndex& index);
424  static uint64_t write(IWritable& output, const ChunkIndex& index);
425  static uint64_t write(IWritable& output, const AttachmentIndex& index);
426  static uint64_t write(IWritable& output, const MetadataIndex& index);
427  static uint64_t write(IWritable& output, const Statistics& stats);
428  static uint64_t write(IWritable& output, const SummaryOffset& summaryOffset);
429  static uint64_t write(IWritable& output, const DataEnd& dataEnd);
430  static uint64_t write(IWritable& output, const Record& record);
431 
432  static void write(IWritable& output, const std::string_view str);
433  static void write(IWritable& output, const ByteArray bytes);
434  static void write(IWritable& output, OpCode value);
435  static void write(IWritable& output, uint16_t value);
436  static void write(IWritable& output, uint32_t value);
437  static void write(IWritable& output, uint64_t value);
438  static void write(IWritable& output, const std::byte* data, uint64_t size);
439  static void write(IWritable& output, const KeyValueMap& map, uint32_t size = 0);
440 
441 private:
442  McapWriterOptions options_{""};
443  uint64_t chunkSize_ = DefaultChunkSize;
444  IWritable* output_ = nullptr;
445  std::unique_ptr<FileWriter> fileOutput_;
446  std::unique_ptr<StreamWriter> streamOutput_;
447  std::unique_ptr<BufferWriter> uncompressedChunk_;
448  std::unique_ptr<LZ4Writer> lz4Chunk_;
449  std::unique_ptr<ZStdWriter> zstdChunk_;
450  std::vector<Schema> schemas_;
451  std::vector<Channel> channels_;
452  std::vector<AttachmentIndex> attachmentIndex_;
453  std::vector<MetadataIndex> metadataIndex_;
454  std::vector<ChunkIndex> chunkIndex_;
455  Statistics statistics_{};
456  std::unordered_set<SchemaId> writtenSchemas_;
457  std::unordered_map<ChannelId, MessageIndex> currentMessageIndex_;
458  Timestamp currentChunkStart_ = MaxTime;
459  Timestamp currentChunkEnd_ = 0;
461  uint64_t uncompressedSize_ = 0;
462  bool opened_ = false;
463 
464  IWritable& getOutput();
465  IChunkWriter* getChunkWriter();
466  void writeChunk(IWritable& output, IChunkWriter& chunkData);
467 };
468 
469 } // namespace mcap
470 
471 #ifdef MCAP_IMPLEMENTATION
472 # include "writer.inl"
473 #endif
mcap::McapWriter::metadataIndex_
std::vector< MetadataIndex > metadataIndex_
Definition: writer.hpp:453
mcap::McapWriter::attachmentIndex_
std::vector< AttachmentIndex > attachmentIndex_
Definition: writer.hpp:452
mcap::McapWriterOptions::profile
std::string profile
The recording profile. See https://mcap.dev/spec/registry#well-known-profiles for more information on...
Definition: writer.hpp:85
mcap::ZStdWriter
An in-memory IChunkWriter implementation that holds data in a temporary buffer before flushing to an ...
Definition: writer.hpp:281
mcap::Compression
Compression
Supported MCAP compression algorithms.
Definition: types.hpp:36
mcap::ByteArray
std::vector< std::byte > ByteArray
Definition: types.hpp:23
bytes
Definition: format.h:4101
mcap::McapWriter::zstdChunk_
std::unique_ptr< ZStdWriter > zstdChunk_
Definition: writer.hpp:449
udp_client.default
default
Definition: udp_client.py:10
mcap::StreamWriter::stream_
std::ostream & stream_
Definition: writer.hpp:183
mcap::McapWriter::fileOutput_
std::unique_ptr< FileWriter > fileOutput_
Definition: writer.hpp:445
mcap::Status
Wraps a status code and string message carrying additional context.
Definition: errors.hpp:35
mcap::McapWriter::schemas_
std::vector< Schema > schemas_
Definition: writer.hpp:450
mcap::Timestamp
uint64_t Timestamp
Definition: types.hpp:20
mcap::McapWriter::lz4Chunk_
std::unique_ptr< LZ4Writer > lz4Chunk_
Definition: writer.hpp:448
mcap::BufferWriter::buffer_
std::vector< std::byte > buffer_
Definition: writer.hpp:251
types.hpp
detail::write
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
Definition: chrono.h:419
mcap::StreamWriter
Implements the IWritable interface used by McapWriter by wrapping a std::ostream stream.
Definition: writer.hpp:174
mcap::ChunkIndex
Chunk Index records are found in the Summary section, providing summary information for a single Chun...
Definition: types.hpp:238
mcap::MaxTime
constexpr Timestamp MaxTime
Definition: types.hpp:31
mcap::Compression::Zstd
@ Zstd
writer
static int writer(lua_State *L, const void *b, size_t size, void *ud)
Definition: lstrlib.c:222
mcap::McapWriter::streamOutput_
std::unique_ptr< StreamWriter > streamOutput_
Definition: writer.hpp:446
mcap::Chunk
An collection of Schemas, Channels, and Messages that supports compression and indexing.
Definition: types.hpp:214
MCAP_PUBLIC
#define MCAP_PUBLIC
Definition: visibility.hpp:22
compressedSize
char int compressedSize
Definition: lz4.h:792
mcap::McapWriter::uncompressedChunk_
std::unique_ptr< BufferWriter > uncompressedChunk_
Definition: writer.hpp:447
mcap::Footer
The final record in an MCAP file (before the trailing magic byte sequence). Contains byte offsets fro...
Definition: types.hpp:114
nonstd::span_lite::size
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1554
sol::stack::clear
void clear(lua_State *L, int table_index)
Definition: sol.hpp:11710
mcap::LZ4Writer
An in-memory IChunkWriter implementation that holds data in a temporary buffer before flushing to an ...
Definition: writer.hpp:258
output
static const char * output
Definition: luac.c:38
mcap::SummaryOffset
Summary Offset records are found in the Summary Offset section. Records in the Summary section are gr...
Definition: types.hpp:339
range_format::map
@ map
mcap::Channel
Describes a Channel that messages are written to. A Channel represents a single connection from a pub...
Definition: types.hpp:158
mcap::IChunkWriter
An abstract interface for writing Chunk data. Chunk data is buffered in memory and written to disk as...
Definition: writer.hpp:192
mcap::McapWriter::writtenSchemas_
std::unordered_set< SchemaId > writtenSchemas_
Definition: writer.hpp:456
MCAP_LIBRARY_VERSION
#define MCAP_LIBRARY_VERSION
Definition: types.hpp:16
mcap::McapWriter::chunkIndex_
std::vector< ChunkIndex > chunkIndex_
Definition: writer.hpp:454
mcap::ZStdWriter::uncompressedBuffer_
std::vector< std::byte > uncompressedBuffer_
Definition: writer.hpp:296
mcap::CompressionLevel::Default
@ Default
mcap::Attachment
An Attachment is an arbitrary file embedded in an MCAP file, including a name, media type,...
Definition: types.hpp:255
visibility.hpp
mcap::McapWriter::channels_
std::vector< Channel > channels_
Definition: writer.hpp:451
mcap::MetadataIndex
Metadata Index records are found in the Summary section, providing summary information for a single M...
Definition: types.hpp:324
mcap
Definition: crc32.hpp:5
mcap::CompressionLevel
CompressionLevel
Compression level to use when compression is enabled. Slower generally produces smaller files,...
Definition: types.hpp:47
mcap::McapWriter::currentMessageIndex_
std::unordered_map< ChannelId, MessageIndex > currentMessageIndex_
Definition: writer.hpp:457
ZSTD_CCtx_s
Definition: zstd.c:14776
string_view
basic_string_view< char > string_view
Definition: core.h:518
compressionLevel
char int int compressionLevel
Definition: lz4hc.h:256
mcap::McapWriterOptions::McapWriterOptions
McapWriterOptions(const std::string_view profile)
Definition: writer.hpp:103
mcap::Metadata
Holds a named map of key/value strings containing arbitrary user data. Metadata records are found in ...
Definition: types.hpp:315
mcap::McapWriter
Provides a write interface to an MCAP file.
Definition: writer.hpp:304
mcap::ZStdWriter::compressedBuffer_
std::vector< std::byte > compressedBuffer_
Definition: writer.hpp:297
mcap::Statistics
The Statistics record is found in the Summary section, providing counts and timestamp ranges for the ...
Definition: types.hpp:299
mcap::Header
Appears at the beginning of every MCAP file (after the magic byte sequence) and contains the recordin...
Definition: types.hpp:102
std
mcap::Message
A single Message published to a Channel.
Definition: types.hpp:181
mcap::DefaultChunkSize
constexpr uint64_t DefaultChunkSize
Definition: types.hpp:29
mcap::Record
A generic Type-Length-Value record using a uint8 type and uint64 length. This is the generic form of ...
Definition: types.hpp:86
mqtt_test.data
dictionary data
Definition: mqtt_test.py:22
mcap::IWritable
An abstract interface for writing MCAP data.
Definition: writer.hpp:110
mcap::LZ4Writer::uncompressedBuffer_
std::vector< std::byte > uncompressedBuffer_
Definition: writer.hpp:272
mcap::OpCode
OpCode
MCAP record types.
Definition: types.hpp:58
mcap::MessageIndex
A list of timestamps to byte offsets for a single Channel. This record appears after each Chunk,...
Definition: types.hpp:228
mcap::DataEnd
The final record in the Data section, signaling the end of Data and beginning of Summary....
Definition: types.hpp:349
mcap::Schema
Describes a schema used for message encoding and decoding and/or describing the shape of messages....
Definition: types.hpp:131
mcap::KeyValueMap
std::unordered_map< std::string, std::string > KeyValueMap
Definition: types.hpp:22
header
const std::string header
mcap::AttachmentIndex
Attachment Index records are found in the Summary section, providing summary information for a single...
Definition: types.hpp:269
mcap::LZ4Writer::compressedBuffer_
std::vector< std::byte > compressedBuffer_
Definition: writer.hpp:273
mcap::Compression::None
@ None
mcap::FileWriter
Implements the IWritable interface used by McapWriter by wrapping a FILE* pointer created by fopen().
Definition: writer.hpp:155
mcap::LZ4Writer::compressionLevel_
CompressionLevel compressionLevel_
Definition: writer.hpp:274
mcap::McapWriterOptions
Configuration options for McapWriter.
Definition: writer.hpp:19
mcap::BufferWriter
An in-memory IChunkWriter implementation backed by a growable buffer.
Definition: writer.hpp:239


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:48