rippled
Loading...
Searching...
No Matches
Serializer.cpp
1#include <xrpl/basics/Buffer.h>
2#include <xrpl/basics/Slice.h>
3#include <xrpl/basics/base_uint.h>
4#include <xrpl/basics/contract.h>
5#include <xrpl/basics/safe_cast.h>
6#include <xrpl/beast/utility/instrumentation.h>
7#include <xrpl/protocol/HashPrefix.h>
8#include <xrpl/protocol/Serializer.h>
9#include <xrpl/protocol/digest.h>
10
11#include <boost/endian/conversion.hpp>
12
13#include <array>
14#include <cstddef>
15#include <cstdint>
16#include <cstring>
17#include <stdexcept>
18#include <string>
19#include <type_traits>
20
21namespace xrpl {
22
23int
25{
26 int ret = mData.size();
27 mData.push_back(static_cast<unsigned char>(i >> 8));
28 mData.push_back(static_cast<unsigned char>(i & 0xff));
29 return ret;
30}
31
32int
34{
35 // This should never trigger; the size & type of a hash prefix are
36 // integral parts of the protocol and unlikely to ever change.
37 static_assert(std::is_same_v<std::uint32_t, std::underlying_type_t<decltype(p)>>);
38
39 return add32(safe_cast<std::uint32_t>(p));
40}
41
42template <>
43int
44Serializer::addInteger(unsigned char i)
45{
46 return add8(i);
47}
48template <>
49int
54template <>
55int
60template <>
61int
66template <>
67int
69{
70 return add32(i);
71}
72
73int
75{
76 int ret = mData.size();
77 mData.insert(mData.end(), vector.begin(), vector.end());
78 return ret;
79}
80
81int
83{
84 int ret = mData.size();
86 return ret;
87}
88
89int
91{
92 int ret = mData.size();
93 mData.insert(mData.end(), s.begin(), s.end());
94 return ret;
95}
96
97int
98Serializer::addRaw(void const* ptr, int len)
99{
100 int ret = mData.size();
101 mData.insert(mData.end(), (char const*)ptr, ((char const*)ptr) + len);
102 return ret;
103}
104
105int
106Serializer::addFieldID(int type, int name)
107{
108 int ret = mData.size();
109 XRPL_ASSERT(
110 (type > 0) && (type < 256) && (name > 0) && (name < 256),
111 "xrpl::Serializer::addFieldID : inputs inside range");
112
113 if (type < 16)
114 {
115 if (name < 16) // common type, common name
116 mData.push_back(static_cast<unsigned char>((type << 4) | name));
117 else
118 {
119 // common type, uncommon name
120 mData.push_back(static_cast<unsigned char>(type << 4));
121 mData.push_back(static_cast<unsigned char>(name));
122 }
123 }
124 else if (name < 16)
125 {
126 // uncommon type, common name
127 mData.push_back(static_cast<unsigned char>(name));
128 mData.push_back(static_cast<unsigned char>(type));
129 }
130 else
131 {
132 // uncommon type, uncommon name
133 mData.push_back(static_cast<unsigned char>(0));
134 mData.push_back(static_cast<unsigned char>(type));
135 mData.push_back(static_cast<unsigned char>(name));
136 }
137
138 return ret;
139}
140
141int
142Serializer::add8(unsigned char byte)
143{
144 int ret = mData.size();
145 mData.push_back(byte);
146 return ret;
147}
148
149bool
150Serializer::get8(int& byte, int offset) const
151{
152 if (offset >= mData.size())
153 return false;
154
155 byte = mData[offset];
156 return true;
157}
158
159bool
161{
162 if (bytes > mData.size())
163 return false;
164
165 mData.resize(mData.size() - bytes);
166 return true;
167}
168
171{
172 return sha512Half(makeSlice(mData));
173}
174
175int
177{
178 int ret = addEncoded(vector.size());
179 addRaw(vector);
180 XRPL_ASSERT(
181 mData.size() == (ret + vector.size() + encodeLengthLength(vector.size())),
182 "xrpl::Serializer::addVL : size matches expected");
183 return ret;
184}
185
186int
188{
189 int ret = addEncoded(slice.size());
190 if (slice.size())
191 addRaw(slice.data(), slice.size());
192 return ret;
193}
194
195int
196Serializer::addVL(void const* ptr, int len)
197{
198 int ret = addEncoded(len);
199
200 if (len)
201 addRaw(ptr, len);
202
203 return ret;
204}
205
206int
208{
210 int numBytes = 0;
211
212 if (length <= 192)
213 {
214 bytes[0] = static_cast<unsigned char>(length);
215 numBytes = 1;
216 }
217 else if (length <= 12480)
218 {
219 length -= 193;
220 bytes[0] = 193 + static_cast<unsigned char>(length >> 8);
221 bytes[1] = static_cast<unsigned char>(length & 0xff);
222 numBytes = 2;
223 }
224 else if (length <= 918744)
225 {
226 length -= 12481;
227 bytes[0] = 241 + static_cast<unsigned char>(length >> 16);
228 bytes[1] = static_cast<unsigned char>((length >> 8) & 0xff);
229 bytes[2] = static_cast<unsigned char>(length & 0xff);
230 numBytes = 3;
231 }
232 else
233 Throw<std::overflow_error>("lenlen");
234
235 return addRaw(&bytes[0], numBytes);
236}
237
238int
240{
241 if (length < 0)
242 Throw<std::overflow_error>("len<0");
243
244 if (length <= 192)
245 return 1;
246
247 if (length <= 12480)
248 return 2;
249
250 if (length <= 918744)
251 return 3;
252
253 Throw<std::overflow_error>("len>918744");
254 return 0; // Silence compiler warning.
255}
256
257int
259{
260 if (b1 < 0)
261 Throw<std::overflow_error>("b1<0");
262
263 if (b1 <= 192)
264 return 1;
265
266 if (b1 <= 240)
267 return 2;
268
269 if (b1 <= 254)
270 return 3;
271
272 Throw<std::overflow_error>("b1>254");
273 return 0; // Silence compiler warning.
274}
275
276int
278{
279 if (b1 < 0)
280 Throw<std::overflow_error>("b1<0");
281
282 if (b1 > 254)
283 Throw<std::overflow_error>("b1>254");
284
285 return b1;
286}
287
288int
290{
291 if (b1 < 193)
292 Throw<std::overflow_error>("b1<193");
293
294 if (b1 > 240)
295 Throw<std::overflow_error>("b1>240");
296
297 return 193 + (b1 - 193) * 256 + b2;
298}
299
300int
301Serializer::decodeVLLength(int b1, int b2, int b3)
302{
303 if (b1 < 241)
304 Throw<std::overflow_error>("b1<241");
305
306 if (b1 > 254)
307 Throw<std::overflow_error>("b1>254");
308
309 return 12481 + (b1 - 241) * 65536 + b2 * 256 + b3;
310}
311
312//------------------------------------------------------------------------------
313
314SerialIter::SerialIter(void const* data, std::size_t size) noexcept
315 : p_(reinterpret_cast<std::uint8_t const*>(data)), remain_(size)
316{
317}
318
319void
321{
322 p_ -= used_;
323 remain_ += used_;
324 used_ = 0;
325}
326
327void
329{
330 if (remain_ < length)
331 Throw<std::runtime_error>("invalid SerialIter skip");
332 p_ += length;
333 used_ += length;
334 remain_ -= length;
335}
336
337unsigned char
339{
340 if (remain_ < 1)
341 Throw<std::runtime_error>("invalid SerialIter get8");
342 unsigned char t = *p_;
343 ++p_;
344 ++used_;
345 --remain_;
346 return t;
347}
348
351{
352 if (remain_ < 2)
353 Throw<std::runtime_error>("invalid SerialIter get16");
354 auto t = p_;
355 p_ += 2;
356 used_ += 2;
357 remain_ -= 2;
358 return (std::uint64_t(t[0]) << 8) + std::uint64_t(t[1]);
359}
360
363{
364 if (remain_ < 4)
365 Throw<std::runtime_error>("invalid SerialIter get32");
366 auto t = p_;
367 p_ += 4;
368 used_ += 4;
369 remain_ -= 4;
370 return (std::uint64_t(t[0]) << 24) + (std::uint64_t(t[1]) << 16) + (std::uint64_t(t[2]) << 8) +
371 std::uint64_t(t[3]);
372}
373
376{
377 if (remain_ < 8)
378 Throw<std::runtime_error>("invalid SerialIter get64");
379 auto t = p_;
380 p_ += 8;
381 used_ += 8;
382 remain_ -= 8;
383 return (std::uint64_t(t[0]) << 56) + (std::uint64_t(t[1]) << 48) + (std::uint64_t(t[2]) << 40) +
384 (std::uint64_t(t[3]) << 32) + (std::uint64_t(t[4]) << 24) + (std::uint64_t(t[5]) << 16) +
385 (std::uint64_t(t[6]) << 8) + std::uint64_t(t[7]);
386}
387
390{
391 if (remain_ < 4)
392 Throw<std::runtime_error>("invalid SerialIter geti32");
393 auto t = p_;
394 p_ += 4;
395 used_ += 4;
396 remain_ -= 4;
397 return boost::endian::load_big_s32(t);
398}
399
402{
403 if (remain_ < 8)
404 Throw<std::runtime_error>("invalid SerialIter geti64");
405 auto t = p_;
406 p_ += 8;
407 used_ += 8;
408 remain_ -= 8;
409 return boost::endian::load_big_s64(t);
410}
411
412void
413SerialIter::getFieldID(int& type, int& name)
414{
415 type = get8();
416 name = type & 15;
417 type >>= 4;
418
419 if (type == 0)
420 {
421 // uncommon type
422 type = get8();
423 if (type < 16)
424 Throw<std::runtime_error>("gFID: uncommon type out of range " + std::to_string(type));
425 }
426
427 if (name == 0)
428 {
429 // uncommon name
430 name = get8();
431 if (name < 16)
432 Throw<std::runtime_error>("gFID: uncommon name out of range " + std::to_string(name));
433 }
434}
435
436// getRaw for blob or buffer
437template <class T>
438T
440{
442 if (remain_ < size)
443 Throw<std::runtime_error>("invalid SerialIter getRaw");
444 T result(size);
445 if (size != 0)
446 {
447 // It's normally safe to call memcpy with size set to 0 (see the
448 // C99 standard 7.21.1/2). However, here this could mean that
449 // result.data would be null, which would trigger undefined behavior.
450 std::memcpy(result.data(), p_, size);
451 p_ += size;
452 used_ += size;
453 remain_ -= size;
454 }
455 return result;
456}
457
458// VFALCO DEPRECATED Returns a copy
459Blob
461{
462 return getRawHelper<Blob>(size);
463}
464
465int
467{
468 int b1 = get8();
469 int datLen;
470 int lenLen = Serializer::decodeLengthLength(b1);
471 if (lenLen == 1)
472 {
473 datLen = Serializer::decodeVLLength(b1);
474 }
475 else if (lenLen == 2)
476 {
477 int b2 = get8();
478 datLen = Serializer::decodeVLLength(b1, b2);
479 }
480 else
481 {
482 XRPL_ASSERT(lenLen == 3, "xrpl::SerialIter::getVLDataLength : lenLen is 3");
483 int b2 = get8();
484 int b3 = get8();
485 datLen = Serializer::decodeVLLength(b1, b2, b3);
486 }
487 return datLen;
488}
489
490Slice
492{
493 if (bytes > remain_)
494 Throw<std::runtime_error>("invalid SerialIter getSlice");
495 Slice s(p_, bytes);
496 p_ += bytes;
497 used_ += bytes;
498 remain_ -= bytes;
499 return s;
500}
501
502// VFALCO DEPRECATED Returns a copy
503Blob
505{
506 return getRaw(getVLDataLength());
507}
508
509Buffer
511{
512 return getRawHelper<Buffer>(getVLDataLength());
513}
514
515} // namespace xrpl
T begin(T... args)
Like std::vector<char> but better.
Definition Buffer.h:16
Blob getRaw(int size)
std::uint16_t get16()
void reset() noexcept
Slice getSlice(std::size_t bytes)
T getRawHelper(int size)
void getFieldID(int &type, int &name)
void skip(int num)
std::size_t remain_
Definition Serializer.h:322
SerialIter(void const *data, std::size_t size) noexcept
std::uint64_t get64()
std::int32_t geti32()
std::int64_t geti64()
unsigned char get8()
std::uint8_t const * p_
Definition Serializer.h:321
std::uint32_t get32()
std::size_t used_
Definition Serializer.h:323
int addFieldID(int type, int name)
static int decodeVLLength(int b1)
int addInteger(Integer)
Blob::iterator begin()
Definition Serializer.h:226
int add16(std::uint16_t i)
uint256 getSHA512Half() const
int addVL(Blob const &vector)
Blob::iterator end()
Definition Serializer.h:231
static int decodeLengthLength(int b1)
bool chop(int num)
int addEncoded(int length)
int addRaw(Blob const &vector)
Slice slice() const noexcept
Definition Serializer.h:44
int add8(unsigned char i)
bool get8(int &, int offset) const
static int encodeLengthLength(int length)
An immutable linear range of bytes.
Definition Slice.h:26
const_iterator begin() const noexcept
Definition Slice.h:127
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Slice.h:78
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition Slice.h:61
const_iterator end() const noexcept
Definition Slice.h:139
T end(T... args)
T insert(T... args)
T is_same_v
T memcpy(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition digest.h:204
HashPrefix
Prefix for hashing functions.
Definition HashPrefix.h:34
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:215
T push_back(T... args)
T resize(T... args)
T size(T... args)
T to_string(T... args)