CppLogging  1.0.4.0
C++ Logging Library
record.cpp
Go to the documentation of this file.
1 
9 #include "logging/record.h"
10 
11 namespace {
12 
13 std::string RestoreFormatString(std::string_view pattern, const std::vector<uint8_t>& buffer, size_t& offset, size_t size);
14 
15 size_t ParseArgument(fmt::dynamic_format_arg_store<fmt::format_context>& store, const std::vector<uint8_t>& buffer, size_t& index)
16 {
17  // Parse the argument type
19  std::memcpy(&type, buffer.data() + index, sizeof(uint8_t));
20  index += sizeof(uint8_t);
21 
22  // Parse the named argument name
23  std::string name;
25  {
26  uint32_t length;
27  std::memcpy(&length, buffer.data() + index, sizeof(uint32_t));
28  index += sizeof(uint32_t);
29 
30  name.resize(length);
31  std::memcpy(name.data(), buffer.data() + index, length);
32  index += length;
33 
34  // Parse the named argument type
35  std::memcpy(&type, buffer.data() + index, sizeof(uint8_t));
36  index += sizeof(uint8_t);
37  }
38 
39  // Parse the argument value
40  switch (type)
41  {
43  {
44  uint8_t value;
45  std::memcpy(&value, buffer.data() + index, sizeof(uint8_t));
46  index += sizeof(uint8_t);
47 
48  name.empty() ? store.push_back(value != 0) : store.push_back(fmt::detail::named_arg(name.c_str(), value != 0));
49  break;
50  }
52  {
53  uint8_t value;
54  std::memcpy(&value, buffer.data() + index, sizeof(uint8_t));
55  index += sizeof(uint8_t);
56 
57  name.empty() ? store.push_back((char)value) : store.push_back(fmt::detail::named_arg(name.c_str(), (char)value));
58  break;
59  }
61  {
62  uint32_t value;
63  std::memcpy(&value, buffer.data() + index, sizeof(uint32_t));
64  index += sizeof(uint32_t);
65 
66  name.empty() ? store.push_back((char)value) : store.push_back(fmt::detail::named_arg(name.c_str(), (char)value));
67  break;
68  }
70  {
71  int8_t value;
72  std::memcpy(&value, buffer.data() + index, sizeof(int8_t));
73  index += sizeof(int8_t);
74 
75  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
76  break;
77  }
79  {
80  uint8_t value;
81  std::memcpy(&value, buffer.data() + index, sizeof(uint8_t));
82  index += sizeof(uint8_t);
83 
84  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
85  break;
86  }
88  {
89  int16_t value;
90  std::memcpy(&value, buffer.data() + index, sizeof(int16_t));
91  index += sizeof(int16_t);
92 
93  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
94  break;
95  }
97  {
98  uint16_t value;
99  std::memcpy(&value, buffer.data() + index, sizeof(uint16_t));
100  index += sizeof(uint16_t);
101 
102  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
103  break;
104  }
106  {
107  int32_t value;
108  std::memcpy(&value, buffer.data() + index, sizeof(int32_t));
109  index += sizeof(int32_t);
110 
111  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
112  break;
113  }
115  {
116  uint32_t value;
117  std::memcpy(&value, buffer.data() + index, sizeof(uint32_t));
118  index += sizeof(uint32_t);
119 
120  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
121  break;
122  }
124  {
125  int64_t value;
126  std::memcpy(&value, buffer.data() + index, sizeof(int64_t));
127  index += sizeof(int64_t);
128 
129  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
130  break;
131  }
133  {
134  uint64_t value;
135  std::memcpy(&value, buffer.data() + index, sizeof(uint64_t));
136  index += sizeof(uint64_t);
137 
138  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
139  break;
140  }
142  {
143  float value;
144  std::memcpy(&value, buffer.data() + index, sizeof(float));
145  index += sizeof(float);
146 
147  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
148  break;
149  }
151  {
152  double value;
153  std::memcpy(&value, buffer.data() + index, sizeof(double));
154  index += sizeof(double);
155 
156  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
157  break;
158  }
160  {
161  uint32_t length;
162  std::memcpy(&length, buffer.data() + index, sizeof(uint32_t));
163  index += sizeof(uint32_t);
164 
165  const fmt::string_view value((const char*)buffer.data() + index, length);
166  index += length;
167 
168  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
169  break;
170  }
172  {
173  const void* value;
174  std::memcpy(&value, buffer.data() + index, sizeof(uint64_t));
175  index += sizeof(uint64_t);
176 
177  name.empty() ? store.push_back(value) : store.push_back(fmt::detail::named_arg(name.c_str(), value));
178  break;
179  }
181  {
182  // Parse the custom data type size
183  uint32_t custom_size;
184  std::memcpy(&custom_size, buffer.data() + index, sizeof(uint32_t));
185  index += sizeof(uint32_t);
186  custom_size -= sizeof(uint32_t);
187 
188  // Parse the pattern length
189  uint32_t custom_pattern_length;
190  std::memcpy(&custom_pattern_length, buffer.data() + index, sizeof(uint32_t));
191  index += sizeof(uint32_t);
192  custom_size -= sizeof(uint32_t);
193 
194  // Parse the pattern value
195  std::string custom_pattern;
196  custom_pattern.resize(custom_pattern_length);
197  std::memcpy(custom_pattern.data(), buffer.data() + index, custom_pattern_length);
198  index += custom_pattern_length;
199  custom_size -= custom_pattern_length;
200 
201  const std::string custom = RestoreFormatString(custom_pattern, buffer, index, custom_size);
202 
203  name.empty() ? store.push_back(custom) : store.push_back(fmt::detail::named_arg(name.c_str(), custom));
204  break;
205  }
207  {
208  // Parse the list size
209  uint32_t list_size;
210  std::memcpy(&list_size, buffer.data() + index, sizeof(uint32_t));
211  index += sizeof(uint32_t);
212  list_size -= sizeof(uint32_t);
213 
214  fmt::dynamic_format_arg_store<fmt::format_context> list_store;
215 
216  // Write arguments from the list
217  size_t list_items = 0;
218  size_t list_offset = index;
219  while (index < (list_offset + list_size))
220  {
221  if (ParseArgument(list_store, buffer, index))
222  ++list_items;
223  else
224  return false;
225  }
226 
227  // Prepare list format pattern
228  std::string list_pattern;
229  list_pattern.reserve(2 * list_items);
230  for (size_t i = 0; i < list_items; ++i)
231  list_pattern.append("{}");
232 
233  // Perform list format operation
234  const std::string list_string = fmt::vformat(list_pattern, list_store);
235 
236  name.empty() ? store.push_back(list_string) : store.push_back(fmt::detail::named_arg(name.c_str(), list_string));
237  break;
238  }
239  default:
240  {
241  assert(false && "Unsupported argument type!");
242  return false;
243  }
244  }
245 
246  return true;
247 }
248 
249 std::string RestoreFormatString(std::string_view pattern, const std::vector<uint8_t>& buffer, size_t& offset, size_t size)
250 {
251  fmt::dynamic_format_arg_store<fmt::format_context> store;
252 
253  // Parse format arguments from the buffer and prepare dynamic format storage
254  size_t index = offset;
255  while (index < (offset + size))
256  if (!ParseArgument(store, buffer, index))
257  break;
258  offset = index;
259 
260  // Perform format operation
261  std::string result = fmt::vformat(pattern, store);
262 
263  return result;
264 }
265 
266 } // namespace
267 
268 namespace CppLogging {
269 
270 std::string Record::RestoreFormat(std::string_view pattern, const std::vector<uint8_t>& buffer, size_t offset, size_t size)
271 {
272  size_t index = offset;
273  return RestoreFormatString(pattern, buffer, index, size);
274 }
275 
276 } // namespace CppLogging
std::string RestoreFormat() const
Restore format message and its arguments.
Definition: record.h:89
std::vector< uint8_t > buffer
Buffer of the logging record.
Definition: record.h:50
C++ Logging project definitions.
Definition: appender.h:15
Logging record definition.