CCF
Loading...
Searching...
No Matches
raw_serialise.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
5#include "ds/serialized.h"
7
8#include <array>
9#include <small_vector/SmallVector.h>
10#include <type_traits>
11
12namespace ccf::kv
13{
15 {
16 private:
17 // Avoid heap allocations for transactions which only touch a limited number
18 // of keys in a few maps
19 using WriterData = llvm_vecsmall::SmallVector<uint8_t, 64>;
20
21 WriterData buf;
22
23 template <typename T>
24 void serialise_entry(const T& t)
25 {
26 size_t size_before = buf.size();
27 buf.resize(buf.size() + sizeof(T));
28
29 auto data_ = buf.data() + size_before;
30 auto size_ = buf.size() - size_before;
31 serialized::write(data_, size_, t);
32 }
33
34 template <typename T>
35 void serialise_vector(const T& entry)
36 {
37 size_t entry_size_bytes = sizeof(typename T::value_type) * entry.size();
38 size_t size_before = buf.size();
39
40 buf.resize(buf.size() + entry_size_bytes);
41
42 auto data_ = buf.data() + size_before;
43 auto size_ = buf.size() - size_before;
45 data_,
46 size_,
47 reinterpret_cast<const uint8_t*>(entry.data()),
48 entry_size_bytes);
49 }
50
51 template <typename T, size_t SIZE>
52 void serialise_array(const std::array<T, SIZE>& array)
53 {
54 constexpr size_t array_size = SIZE * sizeof(T);
55 size_t size_before = buf.size();
56 buf.resize(buf.size() + array_size);
57
58 auto data_ = buf.data() + size_before;
59 auto size_ = buf.size() - size_before;
61 data_,
62 size_,
63 reinterpret_cast<const uint8_t*>(array.data()),
64 array_size);
65 }
66
67 void serialise_string(const std::string& str)
68 {
69 size_t size_before = buf.size();
70 buf.resize(buf.size() + sizeof(size_t) + str.size());
71
72 auto data_ = buf.data() + size_before;
73 auto size_ = buf.size() - size_before;
74 serialized::write(data_, size_, str);
75 }
76
77 public:
78 RawWriter() = default;
79
80 template <typename T>
81 void append(const T& entry)
82 {
83 if constexpr (
85 std::is_same_v<T, ccf::kv::serialisers::SerialisedEntry>)
86 {
87 serialise_entry(entry.size() * sizeof(typename T::value_type));
88 if (entry.size() > 0)
89 {
90 serialise_vector(entry);
91 }
92 }
93 else if constexpr (std::is_same_v<T, ccf::crypto::Sha256Hash>)
94 {
95 serialise_array(entry.h);
96 }
97 else if constexpr (std::is_same_v<T, EntryType>)
98 {
99 serialise_entry(static_cast<uint8_t>(entry));
100 }
101 else if constexpr (std::is_same_v<T, std::string>)
102 {
103 serialise_string(entry);
104 }
105 else if constexpr (std::is_integral_v<T>)
106 {
107 serialise_entry(entry);
108 }
109 else
110 {
111 static_assert(
112 ccf::nonstd::dependent_false<T>::value, "Can't serialise this type");
113 }
114 }
115
116 void clear()
117 {
118 buf.clear();
119 }
120
121 std::vector<uint8_t> get_raw_data()
122 {
123 return {buf.data(), buf.data() + buf.size()};
124 }
125 };
126
128 {
129 public:
130 const uint8_t* data_ptr;
132 size_t data_size;
133
136 template <typename T>
138 {
139 auto remainder = data_size - data_offset;
140 auto data = data_ptr + data_offset;
141 const auto entry = serialized::read<T>(data, remainder);
142 const auto bytes_read = data_size - data_offset - remainder;
143 data_offset += bytes_read;
144 return entry;
145 }
146
149 size_t read_size_prefixed_entry(size_t& start_offset)
150 {
151 auto remainder = data_size - data_offset;
152 auto entry_size = read_entry<size_t>();
153
154 if (remainder < entry_size)
155 {
156 throw std::runtime_error(fmt::format(
157 "Expected {} byte entry, found only {}", entry_size, remainder));
158 }
159
160 start_offset = data_offset;
161 data_offset += entry_size;
162
163 return entry_size;
164 }
165
166 public:
167 RawReader(const RawReader& other) = delete;
168 RawReader& operator=(const RawReader& other) = delete;
169
170 RawReader(const uint8_t* data_in_ptr = nullptr, size_t data_in_size = 0)
171 {
172 init(data_in_ptr, data_in_size);
173 }
174
175 void init(const uint8_t* data_in_ptr, size_t data_in_size)
176 {
177 data_offset = 0;
178 data_ptr = data_in_ptr;
179 data_size = data_in_size;
180 }
181
182 template <typename T>
184 {
185 if constexpr (
187 std::is_same_v<T, ccf::kv::serialisers::SerialisedEntry>)
188 {
189 size_t entry_offset = 0;
190 size_t entry_size = read_size_prefixed_entry(entry_offset);
191
192 T ret(entry_size / sizeof(typename T::value_type));
193 auto data_ = reinterpret_cast<uint8_t*>(ret.data());
194 auto size_ = entry_size;
195 serialized::write(data_, size_, data_ptr + entry_offset, entry_size);
196
197 return ret;
198 }
199 else if constexpr (ccf::nonstd::is_std_array<T>::value)
200 {
201 T ret;
202 auto data_ = reinterpret_cast<uint8_t*>(ret.data());
203 constexpr size_t size = ret.size() * sizeof(typename T::value_type);
204 auto size_ = size;
205 serialized::write(data_, size_, data_ptr + data_offset, size);
206 data_offset += size;
207
208 return ret;
209 }
210 else if constexpr (std::is_same_v<T, ccf::kv::EntryType>)
211 {
212 uint8_t entry_type = read_entry<uint8_t>();
213 if (entry_type > static_cast<uint8_t>(ccf::kv::EntryType::MAX))
214 throw std::logic_error(
215 fmt::format("Invalid EntryType: {}", entry_type));
216
217 return ccf::kv::EntryType(entry_type);
218 }
219 else if constexpr (std::is_same_v<T, std::string>)
220 {
221 size_t entry_offset = 0;
222 read_size_prefixed_entry(entry_offset);
223
224 return {data_ptr + entry_offset, data_ptr + data_offset};
225 }
226 else if constexpr (std::is_integral_v<T>)
227 {
228 return read_entry<T>();
229 }
230 else
231 {
232 static_assert(
234 "Can't deserialise this type");
235 }
236 }
237
238 bool is_eos()
239 {
240 return data_offset >= data_size;
241 }
242 };
243
244}
Definition raw_serialise.h:128
const uint8_t * data_ptr
Definition raw_serialise.h:130
RawReader(const RawReader &other)=delete
size_t read_size_prefixed_entry(size_t &start_offset)
Definition raw_serialise.h:149
bool is_eos()
Definition raw_serialise.h:238
RawReader(const uint8_t *data_in_ptr=nullptr, size_t data_in_size=0)
Definition raw_serialise.h:170
RawReader & operator=(const RawReader &other)=delete
size_t data_size
Definition raw_serialise.h:132
T read_entry()
Definition raw_serialise.h:137
T read_next()
Definition raw_serialise.h:183
void init(const uint8_t *data_in_ptr, size_t data_in_size)
Definition raw_serialise.h:175
size_t data_offset
Definition raw_serialise.h:131
Definition raw_serialise.h:15
void append(const T &entry)
Definition raw_serialise.h:81
std::vector< uint8_t > get_raw_data()
Definition raw_serialise.h:121
void clear()
Definition raw_serialise.h:116
Definition app_interface.h:19
EntryType
Definition kv_types.h:269
void write(uint8_t *&data, size_t &size, const T &v)
Definition serialized.h:106
Definition nonstd.h:63
Definition nonstd.h:40
Definition nonstd.h:50