7 static_assert(std::numeric_limits<unsigned char>::digits == 8);
25 inline std::string
ToHex(uint8_t byte) {
26 std::string
result{2,
'\0'};
27 result[0] =
"0123456789ABCDEF"[(uint8_t(byte) >> 4) & 0x0F];
28 result[1] =
"0123456789ABCDEF"[uint8_t(byte) & 0x0F];
31 inline std::string
ToHex(std::byte byte) {
32 return ToHex(uint8_t(byte));
39 return std::string(arg);
42 return std::string(arg);
44 template <
typename... T>
53 for (
const auto& [key,
value] : map) {
54 size += 4 + key.size() + 4 +
value.size();
60 switch (compression) {
72 return uint16_t(data[0]) | (uint16_t(data[1]) << 8);
76 return uint32_t(data[0]) | (uint32_t(data[1]) << 8) | (uint32_t(data[2]) << 16) |
77 (uint32_t(data[3]) << 24);
82 const auto msg =
StrCat(
"cannot read uint32 from ", maxSize,
" bytes");
90 return uint64_t(data[0]) | (uint64_t(data[1]) << 8) | (uint64_t(data[2]) << 16) |
91 (uint64_t(data[3]) << 24) | (uint64_t(data[4]) << 32) | (uint64_t(data[5]) << 40) |
92 (uint64_t(data[6]) << 48) | (uint64_t(data[7]) << 56);
97 const auto msg =
StrCat(
"cannot read uint64 from ", maxSize,
" bytes");
106 if (
auto status =
ParseUint32(data, maxSize, &size); !status.ok()) {
107 const auto msg =
StrCat(
"cannot read string size: ", status.message);
110 if (uint64_t(size) > (maxSize - 4)) {
111 const auto msg =
StrCat(
"string size ", size,
" exceeds remaining bytes ", (maxSize - 4));
120 if (
auto status =
ParseUint32(data, maxSize, &size); !status.ok()) {
123 if (uint64_t(size) > (maxSize - 4)) {
124 const auto msg =
StrCat(
"string size ", size,
" exceeds remaining bytes ", (maxSize - 4));
127 *output = std::string(reinterpret_cast<const char*>(data + 4), size);
133 if (
auto status =
ParseUint32(data, maxSize, &size); !status.ok()) {
136 if (uint64_t(size) > (maxSize - 4)) {
137 const auto msg =
StrCat(
"byte array size ", size,
" exceeds remaining bytes ", (maxSize - 4));
140 output->resize(size);
141 std::memcpy(output->data(), data + 4,
size);
146 uint32_t sizeInBytes = 0;
147 if (
auto status =
ParseUint32(data, maxSize, &sizeInBytes); !status.ok()) {
150 if (sizeInBytes > (maxSize - 4)) {
152 StrCat(
"key-value map size ", sizeInBytes,
" exceeds remaining bytes ", (maxSize - 4));
162 while (pos < sizeInBytes) {
164 if (
auto status =
ParseStringView(data + pos, sizeInBytes - pos, &key); !status.
ok()) {
165 const auto msg =
StrCat(
"cannot read key-value map key at pos ", pos,
": ", status.message);
168 pos += 4 + key.size();
170 if (
auto status =
ParseStringView(data + pos, sizeInBytes - pos, &value); !status.
ok()) {
171 const auto msg =
StrCat(
"cannot read key-value map value for key \"", key,
"\" at pos ", pos,
172 ": ", status.message);
175 pos += 4 + value.size();
176 output->emplace(key, value);
Compression
Supported MCAP compression algorithms.
Status ParseStringView(const std::byte *data, uint64_t maxSize, std::string_view *output)
uint16_t ParseUint16(const std::byte *data)
Wraps a status code and string message carrying additional context.
std::string MagicToHex(const std::byte *data)
const std::string CompressionString(Compression compression)
Status ParseByteArray(const std::byte *data, uint64_t maxSize, ByteArray *output)
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
uint32_t ParseUint32(const std::byte *data)
basic_string_view< char > string_view
constexpr uint64_t FooterLength
constexpr uint8_t Magic[]
std::string to_string(const std::string &arg)
std::string ToHex(uint8_t byte)
Status ParseKeyValueMap(const std::byte *data, uint64_t maxSize, KeyValueMap *output)
uint32_t KeyValueMapSize(const KeyValueMap &map)
Status ParseString(const std::byte *data, uint64_t maxSize, std::string *output)
span_constexpr std::size_t size(span< T, Extent > const &spn)
static const char * output
std::unordered_map< std::string, std::string > KeyValueMap
std::vector< std::byte > ByteArray
constexpr uint64_t MinHeaderLength
std::string StrCat(T &&... args)
uint64_t ParseUint64(const std::byte *data)