internal.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "types.hpp"
4 #include <cstring>
5 
6 // Do not compile on systems with non-8-bit bytes
7 static_assert(std::numeric_limits<unsigned char>::digits == 8);
8 
9 namespace mcap {
10 
11 namespace internal {
12 
13 constexpr uint64_t MinHeaderLength = /* magic bytes */ sizeof(Magic) +
14  /* opcode */ 1 +
15  /* record length */ 8 +
16  /* profile length */ 4 +
17  /* library length */ 4;
18 constexpr uint64_t FooterLength = /* opcode */ 1 +
19  /* record length */ 8 +
20  /* summary start */ 8 +
21  /* summary offset start */ 8 +
22  /* summary crc */ 4 +
23  /* magic bytes */ sizeof(Magic);
24 
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];
29  return result;
30 }
31 inline std::string ToHex(std::byte byte) {
32  return ToHex(uint8_t(byte));
33 }
34 
35 inline std::string to_string(const std::string& arg) {
36  return arg;
37 }
38 inline std::string to_string(std::string_view arg) {
39  return std::string(arg);
40 }
41 inline std::string to_string(const char* arg) {
42  return std::string(arg);
43 }
44 template <typename... T>
45 [[nodiscard]] inline std::string StrCat(T&&... args) {
47  using std::to_string;
48  return ("" + ... + to_string(std::forward<T>(args)));
49 }
50 
51 inline uint32_t KeyValueMapSize(const KeyValueMap& map) {
52  size_t size = 0;
53  for (const auto& [key, value] : map) {
54  size += 4 + key.size() + 4 + value.size();
55  }
56  return (uint32_t)(size);
57 }
58 
59 inline const std::string CompressionString(Compression compression) {
60  switch (compression) {
61  case Compression::None:
62  default:
63  return std::string{};
64  case Compression::Lz4:
65  return "lz4";
66  case Compression::Zstd:
67  return "zstd";
68  }
69 }
70 
71 inline uint16_t ParseUint16(const std::byte* data) {
72  return uint16_t(data[0]) | (uint16_t(data[1]) << 8);
73 }
74 
75 inline uint32_t ParseUint32(const std::byte* data) {
76  return uint32_t(data[0]) | (uint32_t(data[1]) << 8) | (uint32_t(data[2]) << 16) |
77  (uint32_t(data[3]) << 24);
78 }
79 
80 inline Status ParseUint32(const std::byte* data, uint64_t maxSize, uint32_t* output) {
81  if (maxSize < 4) {
82  const auto msg = StrCat("cannot read uint32 from ", maxSize, " bytes");
84  }
86  return StatusCode::Success;
87 }
88 
89 inline uint64_t ParseUint64(const std::byte* data) {
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);
93 }
94 
95 inline Status ParseUint64(const std::byte* data, uint64_t maxSize, uint64_t* output) {
96  if (maxSize < 8) {
97  const auto msg = StrCat("cannot read uint64 from ", maxSize, " bytes");
99  }
100  *output = ParseUint64(data);
101  return StatusCode::Success;
102 }
103 
104 inline Status ParseStringView(const std::byte* data, uint64_t maxSize, std::string_view* output) {
105  uint32_t size = 0;
106  if (auto status = ParseUint32(data, maxSize, &size); !status.ok()) {
107  const auto msg = StrCat("cannot read string size: ", status.message);
109  }
110  if (uint64_t(size) > (maxSize - 4)) {
111  const auto msg = StrCat("string size ", size, " exceeds remaining bytes ", (maxSize - 4));
113  }
114  *output = std::string_view(reinterpret_cast<const char*>(data + 4), size);
115  return StatusCode::Success;
116 }
117 
118 inline Status ParseString(const std::byte* data, uint64_t maxSize, std::string* output) {
119  uint32_t size = 0;
120  if (auto status = ParseUint32(data, maxSize, &size); !status.ok()) {
121  return status;
122  }
123  if (uint64_t(size) > (maxSize - 4)) {
124  const auto msg = StrCat("string size ", size, " exceeds remaining bytes ", (maxSize - 4));
126  }
127  *output = std::string(reinterpret_cast<const char*>(data + 4), size);
128  return StatusCode::Success;
129 }
130 
131 inline Status ParseByteArray(const std::byte* data, uint64_t maxSize, ByteArray* output) {
132  uint32_t size = 0;
133  if (auto status = ParseUint32(data, maxSize, &size); !status.ok()) {
134  return status;
135  }
136  if (uint64_t(size) > (maxSize - 4)) {
137  const auto msg = StrCat("byte array size ", size, " exceeds remaining bytes ", (maxSize - 4));
139  }
140  output->resize(size);
141  std::memcpy(output->data(), data + 4, size);
142  return StatusCode::Success;
143 }
144 
145 inline Status ParseKeyValueMap(const std::byte* data, uint64_t maxSize, KeyValueMap* output) {
146  uint32_t sizeInBytes = 0;
147  if (auto status = ParseUint32(data, maxSize, &sizeInBytes); !status.ok()) {
148  return status;
149  }
150  if (sizeInBytes > (maxSize - 4)) {
151  const auto msg =
152  StrCat("key-value map size ", sizeInBytes, " exceeds remaining bytes ", (maxSize - 4));
154  }
155 
156  // Account for the byte size prefix in sizeInBytes to make the bounds checking
157  // below simpler
158  sizeInBytes += 4;
159 
160  output->clear();
161  uint64_t pos = 4;
162  while (pos < sizeInBytes) {
163  std::string_view key;
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);
167  }
168  pos += 4 + key.size();
169  std::string_view value;
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);
174  }
175  pos += 4 + value.size();
176  output->emplace(key, value);
177  }
178  return StatusCode::Success;
179 }
180 
181 inline std::string MagicToHex(const std::byte* data) {
185 }
186 
187 } // namespace internal
188 
189 } // namespace mcap
mcap::Compression
Compression
Supported MCAP compression algorithms.
Definition: types.hpp:36
mcap::ByteArray
std::vector< std::byte > ByteArray
Definition: types.hpp:23
mcap::internal::ParseUint32
uint32_t ParseUint32(const std::byte *data)
Definition: internal.hpp:75
mcap::internal::ParseByteArray
Status ParseByteArray(const std::byte *data, uint64_t maxSize, ByteArray *output)
Definition: internal.hpp:131
mcap::internal::ParseStringView
Status ParseStringView(const std::byte *data, uint64_t maxSize, std::string_view *output)
Definition: internal.hpp:104
mcap::Status
Wraps a status code and string message carrying additional context.
Definition: errors.hpp:35
mcap::internal::FooterLength
constexpr uint64_t FooterLength
Definition: internal.hpp:18
types.hpp
arg
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1875
mcap::Compression::Zstd
@ Zstd
mqtt_test_proto.msg
msg
Definition: mqtt_test_proto.py:43
nonstd::span_lite::size
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1554
mcap::internal::MagicToHex
std::string MagicToHex(const std::byte *data)
Definition: internal.hpp:181
output
static const char * output
Definition: luac.c:38
range_format::map
@ map
mcap::internal::CompressionString
const std::string CompressionString(Compression compression)
Definition: internal.hpp:59
mcap::internal::ToHex
std::string ToHex(uint8_t byte)
Definition: internal.hpp:25
mcap::internal::ParseKeyValueMap
Status ParseKeyValueMap(const std::byte *data, uint64_t maxSize, KeyValueMap *output)
Definition: internal.hpp:145
mcap::Magic
constexpr uint8_t Magic[]
Definition: types.hpp:28
mcap::internal::KeyValueMapSize
uint32_t KeyValueMapSize(const KeyValueMap &map)
Definition: internal.hpp:51
mcap::Status::ok
bool ok() const
Definition: errors.hpp:111
mcap
Definition: crc32.hpp:5
mcap::StatusCode::Success
@ Success
string_view
basic_string_view< char > string_view
Definition: core.h:518
mcap::internal::ParseString
Status ParseString(const std::byte *data, uint64_t maxSize, std::string *output)
Definition: internal.hpp:118
mcap::Compression::Lz4
@ Lz4
mcap::internal::StrCat
std::string StrCat(T &&... args)
Definition: internal.hpp:45
mcap::internal::ParseUint64
uint64_t ParseUint64(const std::byte *data)
Definition: internal.hpp:89
mcap::StatusCode::InvalidRecord
@ InvalidRecord
mcap::internal::to_string
std::string to_string(const std::string &arg)
Definition: internal.hpp:35
mqtt_test.data
dictionary data
Definition: mqtt_test.py:22
mcap::internal::ParseUint16
uint16_t ParseUint16(const std::byte *data)
Definition: internal.hpp:71
mcap::internal::MinHeaderLength
constexpr uint64_t MinHeaderLength
Definition: internal.hpp:13
mcap::KeyValueMap
std::unordered_map< std::string, std::string > KeyValueMap
Definition: types.hpp:22
mcap::Compression::None
@ None
udp_client.args
args
Definition: udp_client.py:12


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