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), "xrpl::Serializer::addFieldID : inputs inside range");
111
112 if (type < 16)
113 {
114 if (name < 16) // common type, common name
115 mData.push_back(static_cast<unsigned char>((type << 4) | name));
116 else
117 {
118 // common type, uncommon name
119 mData.push_back(static_cast<unsigned char>(type << 4));
120 mData.push_back(static_cast<unsigned char>(name));
121 }
122 }
123 else if (name < 16)
124 {
125 // uncommon type, common name
126 mData.push_back(static_cast<unsigned char>(name));
127 mData.push_back(static_cast<unsigned char>(type));
128 }
129 else
130 {
131 // uncommon type, uncommon name
132 mData.push_back(static_cast<unsigned char>(0));
133 mData.push_back(static_cast<unsigned char>(type));
134 mData.push_back(static_cast<unsigned char>(name));
135 }
136
137 return ret;
138}
139
140int
141Serializer::add8(unsigned char byte)
142{
143 int ret = mData.size();
144 mData.push_back(byte);
145 return ret;
146}
147
148bool
149Serializer::get8(int& byte, int offset) const
150{
151 if (offset >= mData.size())
152 return false;
153
154 byte = mData[offset];
155 return true;
156}
157
158bool
160{
161 if (bytes > mData.size())
162 return false;
163
164 mData.resize(mData.size() - bytes);
165 return true;
166}
167
170{
171 return sha512Half(makeSlice(mData));
172}
173
174int
176{
177 int ret = addEncoded(vector.size());
178 addRaw(vector);
179 XRPL_ASSERT(
180 mData.size() == (ret + vector.size() + encodeLengthLength(vector.size())),
181 "xrpl::Serializer::addVL : size matches expected");
182 return ret;
183}
184
185int
187{
188 int ret = addEncoded(slice.size());
189 if (slice.size())
190 addRaw(slice.data(), slice.size());
191 return ret;
192}
193
194int
195Serializer::addVL(void const* ptr, int len)
196{
197 int ret = addEncoded(len);
198
199 if (len)
200 addRaw(ptr, len);
201
202 return ret;
203}
204
205int
207{
209 int numBytes = 0;
210
211 if (length <= 192)
212 {
213 bytes[0] = static_cast<unsigned char>(length);
214 numBytes = 1;
215 }
216 else if (length <= 12480)
217 {
218 length -= 193;
219 bytes[0] = 193 + static_cast<unsigned char>(length >> 8);
220 bytes[1] = static_cast<unsigned char>(length & 0xff);
221 numBytes = 2;
222 }
223 else if (length <= 918744)
224 {
225 length -= 12481;
226 bytes[0] = 241 + static_cast<unsigned char>(length >> 16);
227 bytes[1] = static_cast<unsigned char>((length >> 8) & 0xff);
228 bytes[2] = static_cast<unsigned char>(length & 0xff);
229 numBytes = 3;
230 }
231 else
232 Throw<std::overflow_error>("lenlen");
233
234 return addRaw(&bytes[0], numBytes);
235}
236
237int
239{
240 if (length < 0)
241 Throw<std::overflow_error>("len<0");
242
243 if (length <= 192)
244 return 1;
245
246 if (length <= 12480)
247 return 2;
248
249 if (length <= 918744)
250 return 3;
251
252 Throw<std::overflow_error>("len>918744");
253 return 0; // Silence compiler warning.
254}
255
256int
258{
259 if (b1 < 0)
260 Throw<std::overflow_error>("b1<0");
261
262 if (b1 <= 192)
263 return 1;
264
265 if (b1 <= 240)
266 return 2;
267
268 if (b1 <= 254)
269 return 3;
270
271 Throw<std::overflow_error>("b1>254");
272 return 0; // Silence compiler warning.
273}
274
275int
277{
278 if (b1 < 0)
279 Throw<std::overflow_error>("b1<0");
280
281 if (b1 > 254)
282 Throw<std::overflow_error>("b1>254");
283
284 return b1;
285}
286
287int
289{
290 if (b1 < 193)
291 Throw<std::overflow_error>("b1<193");
292
293 if (b1 > 240)
294 Throw<std::overflow_error>("b1>240");
295
296 return 193 + (b1 - 193) * 256 + b2;
297}
298
299int
300Serializer::decodeVLLength(int b1, int b2, int b3)
301{
302 if (b1 < 241)
303 Throw<std::overflow_error>("b1<241");
304
305 if (b1 > 254)
306 Throw<std::overflow_error>("b1>254");
307
308 return 12481 + (b1 - 241) * 65536 + b2 * 256 + b3;
309}
310
311//------------------------------------------------------------------------------
312
313SerialIter::SerialIter(void const* data, std::size_t size) noexcept
314 : p_(reinterpret_cast<std::uint8_t const*>(data)), remain_(size)
315{
316}
317
318void
320{
321 p_ -= used_;
322 remain_ += used_;
323 used_ = 0;
324}
325
326void
328{
329 if (remain_ < length)
330 Throw<std::runtime_error>("invalid SerialIter skip");
331 p_ += length;
332 used_ += length;
333 remain_ -= length;
334}
335
336unsigned char
338{
339 if (remain_ < 1)
340 Throw<std::runtime_error>("invalid SerialIter get8");
341 unsigned char t = *p_;
342 ++p_;
343 ++used_;
344 --remain_;
345 return t;
346}
347
350{
351 if (remain_ < 2)
352 Throw<std::runtime_error>("invalid SerialIter get16");
353 auto t = p_;
354 p_ += 2;
355 used_ += 2;
356 remain_ -= 2;
357 return (std::uint64_t(t[0]) << 8) + std::uint64_t(t[1]);
358}
359
362{
363 if (remain_ < 4)
364 Throw<std::runtime_error>("invalid SerialIter get32");
365 auto t = p_;
366 p_ += 4;
367 used_ += 4;
368 remain_ -= 4;
369 return (std::uint64_t(t[0]) << 24) + (std::uint64_t(t[1]) << 16) + (std::uint64_t(t[2]) << 8) + std::uint64_t(t[3]);
370}
371
374{
375 if (remain_ < 8)
376 Throw<std::runtime_error>("invalid SerialIter get64");
377 auto t = p_;
378 p_ += 8;
379 used_ += 8;
380 remain_ -= 8;
381 return (std::uint64_t(t[0]) << 56) + (std::uint64_t(t[1]) << 48) + (std::uint64_t(t[2]) << 40) +
382 (std::uint64_t(t[3]) << 32) + (std::uint64_t(t[4]) << 24) + (std::uint64_t(t[5]) << 16) +
383 (std::uint64_t(t[6]) << 8) + std::uint64_t(t[7]);
384}
385
388{
389 if (remain_ < 4)
390 Throw<std::runtime_error>("invalid SerialIter geti32");
391 auto t = p_;
392 p_ += 4;
393 used_ += 4;
394 remain_ -= 4;
395 return boost::endian::load_big_s32(t);
396}
397
400{
401 if (remain_ < 8)
402 Throw<std::runtime_error>("invalid SerialIter geti64");
403 auto t = p_;
404 p_ += 8;
405 used_ += 8;
406 remain_ -= 8;
407 return boost::endian::load_big_s64(t);
408}
409
410void
411SerialIter::getFieldID(int& type, int& name)
412{
413 type = get8();
414 name = type & 15;
415 type >>= 4;
416
417 if (type == 0)
418 {
419 // uncommon type
420 type = get8();
421 if (type < 16)
422 Throw<std::runtime_error>("gFID: uncommon type out of range " + std::to_string(type));
423 }
424
425 if (name == 0)
426 {
427 // uncommon name
428 name = get8();
429 if (name < 16)
430 Throw<std::runtime_error>("gFID: uncommon name out of range " + std::to_string(name));
431 }
432}
433
434// getRaw for blob or buffer
435template <class T>
436T
438{
440 if (remain_ < size)
441 Throw<std::runtime_error>("invalid SerialIter getRaw");
442 T result(size);
443 if (size != 0)
444 {
445 // It's normally safe to call memcpy with size set to 0 (see the
446 // C99 standard 7.21.1/2). However, here this could mean that
447 // result.data would be null, which would trigger undefined behavior.
448 std::memcpy(result.data(), p_, size);
449 p_ += size;
450 used_ += size;
451 remain_ -= size;
452 }
453 return result;
454}
455
456// VFALCO DEPRECATED Returns a copy
457Blob
459{
460 return getRawHelper<Blob>(size);
461}
462
463int
465{
466 int b1 = get8();
467 int datLen;
468 int lenLen = Serializer::decodeLengthLength(b1);
469 if (lenLen == 1)
470 {
471 datLen = Serializer::decodeVLLength(b1);
472 }
473 else if (lenLen == 2)
474 {
475 int b2 = get8();
476 datLen = Serializer::decodeVLLength(b1, b2);
477 }
478 else
479 {
480 XRPL_ASSERT(lenLen == 3, "xrpl::SerialIter::getVLDataLength : lenLen is 3");
481 int b2 = get8();
482 int b3 = get8();
483 datLen = Serializer::decodeVLLength(b1, b2, b3);
484 }
485 return datLen;
486}
487
488Slice
490{
491 if (bytes > remain_)
492 Throw<std::runtime_error>("invalid SerialIter getSlice");
493 Slice s(p_, bytes);
494 p_ += bytes;
495 used_ += bytes;
496 remain_ -= bytes;
497 return s;
498}
499
500// VFALCO DEPRECATED Returns a copy
501Blob
503{
504 return getRaw(getVLDataLength());
505}
506
507Buffer
509{
510 return getRawHelper<Buffer>(getVLDataLength());
511}
512
513} // 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:126
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Slice.h:77
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition Slice.h:60
const_iterator end() const noexcept
Definition Slice.h:138
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:213
T push_back(T... args)
T resize(T... args)
T size(T... args)
T to_string(T... args)