rippled
Loading...
Searching...
No Matches
Serializer.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/Log.h>
21#include <xrpl/basics/contract.h>
22#include <xrpl/protocol/Serializer.h>
23#include <xrpl/protocol/digest.h>
24#include <cstdint>
25#include <type_traits>
26
27namespace ripple {
28
29int
31{
32 int ret = mData.size();
33 mData.push_back(static_cast<unsigned char>(i >> 8));
34 mData.push_back(static_cast<unsigned char>(i & 0xff));
35 return ret;
36}
37
38int
40{
41 // This should never trigger; the size & type of a hash prefix are
42 // integral parts of the protocol and unlikely to ever change.
43 static_assert(
45
46 return add32(safe_cast<std::uint32_t>(p));
47}
48
49template <>
50int
51Serializer::addInteger(unsigned char i)
52{
53 return add8(i);
54}
55template <>
56int
58{
59 return add16(i);
60}
61template <>
62int
64{
65 return add32(i);
66}
67template <>
68int
70{
71 return add64(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(const void* ptr, int len)
100{
101 int ret = mData.size();
102 mData.insert(mData.end(), (const char*)ptr, ((const char*)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(const void* 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:36
std::size_t remain_
Definition: Serializer.h:349
SerialIter(void const *data, std::size_t size) noexcept
Definition: Serializer.cpp:316
Slice getSlice(std::size_t bytes)
Definition: Serializer.cpp:498
void skip(int num)
Definition: Serializer.cpp:330
std::int64_t geti64()
Definition: Serializer.cpp:404
std::uint8_t const * p_
Definition: Serializer.h:348
std::int32_t geti32()
Definition: Serializer.cpp:392
void getFieldID(int &type, int &name)
Definition: Serializer.cpp:416
T getRawHelper(int size)
Definition: Serializer.cpp:444
Blob getRaw(int size)
Definition: Serializer.cpp:466
void reset() noexcept
Definition: Serializer.cpp:322
std::size_t used_
Definition: Serializer.h:350
std::uint16_t get16()
Definition: Serializer.cpp:352
std::uint32_t get32()
Definition: Serializer.cpp:364
unsigned char get8()
Definition: Serializer.cpp:340
std::uint64_t get64()
Definition: Serializer.cpp:377
Blob::iterator begin()
Definition: Serializer.h:252
int addFieldID(int type, int name)
Definition: Serializer.cpp:107
Slice slice() const noexcept
Definition: Serializer.h:66
bool get8(int &, int offset) const
Definition: Serializer.cpp:151
uint256 getSHA512Half() const
Definition: Serializer.cpp:171
static int encodeLengthLength(int length)
Definition: Serializer.cpp:241
int addEncoded(int length)
Definition: Serializer.cpp:209
int addInteger(Integer)
int addRaw(Blob const &vector)
Definition: Serializer.cpp:75
int addVL(Blob const &vector)
Definition: Serializer.cpp:177
bool chop(int num)
Definition: Serializer.cpp:161
static int decodeLengthLength(int b1)
Definition: Serializer.cpp:260
int add16(std::uint16_t i)
Definition: Serializer.cpp:30
int add8(unsigned char i)
Definition: Serializer.cpp:143
Blob::iterator end()
Definition: Serializer.h:257
static int decodeVLLength(int b1)
Definition: Serializer.cpp:279
An immutable linear range of bytes.
Definition: Slice.h:45
const_iterator begin() const noexcept
Definition: Slice.h:148
const_iterator end() const noexcept
Definition: Slice.h:160
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Slice.h:97
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:80
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:26
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:243
HashPrefix
Prefix for hashing functions.
Definition: HashPrefix.h:54
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:223
T push_back(T... args)
T resize(T... args)
T size(T... args)
T to_string(T... args)