27 result[0] =
"0123456789ABCDEF"[(uint8_t(
byte) >> 4) & 0x0F];
28 result[1] =
"0123456789ABCDEF"[uint8_t(
byte) & 0x0F];
32 return ToHex(uint8_t(
byte));
44template <
typename... T>
48 return (
"" + ... +
to_string(std::forward<T>(args)));
53 for (
const auto& [key, value] : map) {
54 size += 4 + key.size() + 4 + value.size();
56 return (uint32_t)(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));
150 uint32_t sizeInBytes = 0;
151 if (
auto status =
ParseUint32(data, maxSize, &sizeInBytes); !status.ok()) {
154 if (sizeInBytes > (maxSize - 4)) {
156 StrCat(
"key-value map size ", sizeInBytes,
" exceeds remaining bytes ", (maxSize - 4));
166 while (pos < sizeInBytes) {
168 if (
auto status =
ParseStringView(data + pos, sizeInBytes - pos, &key); !status.ok()) {
169 const auto msg =
StrCat(
"cannot read key-value map key at pos ", pos,
": ", status.message);
172 pos += 4 + key.
size();
174 if (
auto status =
ParseStringView(data + pos, sizeInBytes - pos, &value); !status.ok()) {
175 const auto msg =
StrCat(
"cannot read key-value map value for key \"", key,
"\" at pos ", pos,
176 ": ", status.message);
179 pos += 4 + value.
size();
Status ParseByteArray(const std::byte *data, uint64_t maxSize, ByteArray *output)
uint64_t ParseUint64(const std::byte *data)
constexpr uint64_t FooterLength
std::string MagicToHex(const std::byte *data)
std::string StrCat(T &&... args)
uint32_t KeyValueMapSize(const KeyValueMap &map)
constexpr uint64_t MinHeaderLength
uint32_t ParseUint32(const std::byte *data)
std::string ToHex(uint8_t byte)
Status ParseStringView(const std::byte *data, uint64_t maxSize, std::string_view *output)
const std::string CompressionString(Compression compression)
uint16_t ParseUint16(const std::byte *data)
std::string to_string(const std::string &arg)
Status ParseString(const std::byte *data, uint64_t maxSize, std::string *output)
Status ParseKeyValueMap(const std::byte *data, uint64_t maxSize, KeyValueMap *output)
Compression
Supported MCAP compression algorithms.
constexpr uint8_t Magic[]
Wraps a status code and string message carrying additional context.