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