LogIt++
Header-only, macro-first C++ logging library
Loading...
Searching...
No Matches
MdbxByteIO.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_DETAIL_MDBXBYTEIO_HPP_INCLUDED
3#define LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_DETAIL_MDBXBYTEIO_HPP_INCLUDED
4
7
8#include <cstdint>
9#include <cstring>
10#include <limits>
11#include <stdexcept>
12#include <string>
13#include <vector>
14
15namespace logit {
16namespace detail {
17
19public:
20 void write_u8(uint8_t value) {
21 m_out.push_back(value);
22 }
23
24 void write_u32(uint32_t value) {
25 for (int shift = 24; shift >= 0; shift -= 8) {
26 m_out.push_back(static_cast<uint8_t>((value >> shift) & 0xFFu));
27 }
28 }
29
30 void write_u64(uint64_t value) {
31 for (int shift = 56; shift >= 0; shift -= 8) {
32 m_out.push_back(static_cast<uint8_t>((value >> shift) & 0xFFu));
33 }
34 }
35
36 void write_i64(int64_t value) {
37 uint64_t bits = 0;
38 std::memcpy(&bits, &value, sizeof(bits));
39 write_u64(bits);
40 }
41
42 void write_string(const std::string& value) {
43 if (value.size() > static_cast<size_t>((std::numeric_limits<uint32_t>::max)())) {
44 throw std::length_error("MdbxLogger: string field is too large");
45 }
46 write_u32(static_cast<uint32_t>(value.size()));
47 m_out.insert(m_out.end(), value.begin(), value.end());
48 }
49
50 const std::vector<uint8_t>& bytes() const {
51 return m_out;
52 }
53
54private:
55 std::vector<uint8_t> m_out;
56};
57
59public:
60 MdbxByteReader(const void* data, size_t size)
61 : m_cur(static_cast<const uint8_t*>(data)),
62 m_end(static_cast<const uint8_t*>(data)) {
63 if (m_cur == nullptr && size != 0) {
64 throw std::runtime_error("MdbxLogger: null serialized value");
65 }
66 m_end = m_cur == nullptr ? m_cur : m_cur + size;
67 }
68
69 uint8_t read_u8() {
70 require(1);
71 return *m_cur++;
72 }
73
74 uint32_t read_u32() {
75 require(4);
76 uint32_t value = 0;
77 for (int i = 0; i < 4; ++i) {
78 value = (value << 8) | static_cast<uint32_t>(*m_cur++);
79 }
80 return value;
81 }
82
83 uint64_t read_u64() {
84 require(8);
85 uint64_t value = 0;
86 for (int i = 0; i < 8; ++i) {
87 value = (value << 8) | static_cast<uint64_t>(*m_cur++);
88 }
89 return value;
90 }
91
92 int64_t read_i64() {
93 const uint64_t bits = read_u64();
94 int64_t value = 0;
95 std::memcpy(&value, &bits, sizeof(value));
96 return value;
97 }
98
99 std::string read_string() {
100 const uint32_t size = read_u32();
101 require(size);
102 const char* begin = reinterpret_cast<const char*>(m_cur);
103 m_cur += size;
104 return std::string(begin, size);
105 }
106
107 void finish() const {
108 if (m_cur != m_end) {
109 throw std::runtime_error("MdbxLogger: trailing bytes in serialized value");
110 }
111 }
112
113private:
114 const uint8_t* m_cur;
115 const uint8_t* m_end;
116
117 void require(size_t size) const {
118 if (static_cast<size_t>(m_end - m_cur) < size) {
119 throw std::runtime_error("MdbxLogger: corrupted serialized value");
120 }
121 }
122};
123
124} // namespace detail
125} // namespace logit
126
127#endif // LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_DETAIL_MDBXBYTEIO_HPP_INCLUDED
void require(size_t size) const
MdbxByteReader(const void *data, size_t size)
void write_u64(uint64_t value)
const std::vector< uint8_t > & bytes() const
void write_u32(uint32_t value)
void write_i64(int64_t value)
void write_string(const std::string &value)
void write_u8(uint8_t value)
std::vector< uint8_t > m_out
The primary namespace for the LogIt++ library.