F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Serializable.cpp
Go to the documentation of this file.
2 #include <Fw/Types/Assert.hpp>
5 #include <cstdio>
6 #include <cstring> // memcpy
7 #ifdef BUILD_UT
8 #include <Fw/Types/String.hpp>
9 #include <iomanip>
10 #endif
11 
12 // Some macros/functions to optimize for architectures
13 
14 namespace Fw {
15 
17 
19 
20 // ----------------------------------------------------------------------
21 #if FW_SERIALIZABLE_TO_STRING || FW_ENABLE_TEXT_LOGGING || BUILD_UT
22 
23 void Serializable::toString(StringBase& text) const {
24  text = "NOSPEC"; // set to not specified.
25 }
26 
27 #endif
28 
29 #ifdef BUILD_UT
30 std::ostream& operator<<(std::ostream& os, const Serializable& val) {
31  Fw::String out;
32  val.toString(out);
33 
34  os << out;
35 
36  return os;
37 }
38 #endif
39 
40 SerializeBufferBase::SerializeBufferBase() : m_serLoc(0), m_deserLoc(0) {}
41 
43 
44 void SerializeBufferBase::copyFrom(const SerializeBufferBase& src) {
45  this->m_serLoc = src.m_serLoc;
46  this->m_deserLoc = src.m_deserLoc;
47  FW_ASSERT(src.getBuffAddr());
48  FW_ASSERT(this->getBuffAddr());
49  // destination has to be same or bigger
50  FW_ASSERT(src.getBuffLength() <= this->getBuffCapacity(), static_cast<FwAssertArgType>(src.getBuffLength()),
51  static_cast<FwAssertArgType>(this->getBuffLength()));
52  (void)memcpy(this->getBuffAddr(), src.getBuffAddr(), static_cast<size_t>(this->m_serLoc));
53 }
54 
55 // Copy constructor doesn't make sense in this virtual class as there is nothing to copy. Derived classes should
56 // call the empty constructor and then call their own copy function
58  this->copyFrom(src);
59  return *this;
60 }
61 
62 // serialization routines
63 
65  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
67  }
68  FW_ASSERT(this->getBuffAddr());
69  this->getBuffAddr()[this->m_serLoc] = val;
70  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
71  this->m_deserLoc = 0;
72 
73  return FW_SERIALIZE_OK;
74 }
75 
77  return serializeFrom(static_cast<U8>(val), mode);
78 }
79 
80 #if FW_HAS_16_BIT == 1
82  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
84  }
85  FW_ASSERT(this->getBuffAddr());
86  switch (mode) {
87  case Endianness::BIG:
88  // MSB first
89  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 8);
90  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val);
91  break;
92  case Endianness::LITTLE:
93  // LSB first
94  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val);
95  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 8);
96  break;
97  default:
98  FW_ASSERT(false);
99  break;
100  }
101  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
102  this->m_deserLoc = 0;
103  return FW_SERIALIZE_OK;
104 }
105 
107  return serializeFrom(static_cast<U16>(val), mode);
108 }
109 #endif
110 #if FW_HAS_32_BIT == 1
112  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
114  }
115  FW_ASSERT(this->getBuffAddr());
116  switch (mode) {
117  case Endianness::BIG:
118  // MSB first
119  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 24);
120  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 16);
121  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 8);
122  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val);
123  break;
124  case Endianness::LITTLE:
125  // LSB first
126  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val);
127  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 8);
128  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 16);
129  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val >> 24);
130  break;
131  default:
132  FW_ASSERT(false);
133  break;
134  }
135  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
136  this->m_deserLoc = 0;
137  return FW_SERIALIZE_OK;
138 }
139 
141  return serializeFrom(static_cast<U32>(val), mode);
142 }
143 #endif
144 
145 #if FW_HAS_64_BIT == 1
147  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
149  }
150  FW_ASSERT(this->getBuffAddr());
151  switch (mode) {
152  case Endianness::BIG:
153  // MSB first
154  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 56);
155  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 48);
156  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 40);
157  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val >> 32);
158  this->getBuffAddr()[this->m_serLoc + 4] = static_cast<U8>(val >> 24);
159  this->getBuffAddr()[this->m_serLoc + 5] = static_cast<U8>(val >> 16);
160  this->getBuffAddr()[this->m_serLoc + 6] = static_cast<U8>(val >> 8);
161  this->getBuffAddr()[this->m_serLoc + 7] = static_cast<U8>(val);
162  break;
163  case Endianness::LITTLE:
164  // LSB first
165  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val);
166  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 8);
167  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 16);
168  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val >> 24);
169  this->getBuffAddr()[this->m_serLoc + 4] = static_cast<U8>(val >> 32);
170  this->getBuffAddr()[this->m_serLoc + 5] = static_cast<U8>(val >> 40);
171  this->getBuffAddr()[this->m_serLoc + 6] = static_cast<U8>(val >> 48);
172  this->getBuffAddr()[this->m_serLoc + 7] = static_cast<U8>(val >> 56);
173  break;
174  default:
175  FW_ASSERT(false);
176  break;
177  }
178  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
179  this->m_deserLoc = 0;
180  return FW_SERIALIZE_OK;
181 }
182 
184  return serializeFrom(static_cast<U64>(val), mode);
185 }
186 #endif
187 
189  // floating point values need to be byte-swapped as well, so copy to U64 and use that routine
190  U64 u64Val;
191  (void)memcpy(&u64Val, &val, sizeof(val));
192  return this->serializeFrom(u64Val, mode);
193 }
194 
196  // floating point values need to be byte-swapped as well, so copy to U32 and use that routine
197  U32 u32Val;
198  (void)memcpy(&u32Val, &val, sizeof(val));
199  return this->serializeFrom(u32Val, mode);
200 }
201 
203  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(U8)) - 1 >= this->getBuffCapacity()) {
205  }
206 
207  FW_ASSERT(this->getBuffAddr());
208  if (val) {
209  this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_TRUE_VALUE;
210  } else {
211  this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_FALSE_VALUE;
212  }
213 
214  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(U8));
215  this->m_deserLoc = 0;
216  return FW_SERIALIZE_OK;
217 }
218 
220  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(void*)) - 1 >= this->getBuffCapacity()) {
222  }
223 
224  return this->serializeFrom(reinterpret_cast<PlatformPointerCastType>(val), mode);
225 }
226 
228  Serializable::SizeType length,
229  Endianness endianMode) {
230  return this->serializeFrom(buff, static_cast<FwSizeType>(length), Serialization::INCLUDE_LENGTH, endianMode);
231 }
232 
234  FwSizeType length,
235  Serialization::t lengthMode,
236  Endianness endianMode) { // First serialize length
237  SerializeStatus stat;
238  if (lengthMode == Serialization::INCLUDE_LENGTH) {
239  stat = this->serializeFrom(static_cast<FwSizeStoreType>(length), endianMode);
240  if (stat != FW_SERIALIZE_OK) {
241  return stat;
242  }
243  }
244 
245  // make sure we have enough space
246  if (this->m_serLoc + length > this->getBuffCapacity()) {
248  }
249 
250  // copy buffer to our buffer
251  (void)memcpy(&this->getBuffAddr()[this->m_serLoc], buff, static_cast<size_t>(length));
252  this->m_serLoc += static_cast<Serializable::SizeType>(length);
253  this->m_deserLoc = 0;
254 
255  return FW_SERIALIZE_OK;
256 }
257 
259  return val.serializeTo(*this, mode);
260 }
261 
264  if (this->m_serLoc + size + static_cast<Serializable::SizeType>(sizeof(FwSizeStoreType)) >
265  this->getBuffCapacity()) {
267  }
268 
269  // First, serialize size
270  SerializeStatus stat = this->serializeFrom(static_cast<FwSizeStoreType>(size), mode);
271  if (stat != FW_SERIALIZE_OK) {
272  return stat;
273  }
274 
275  FW_ASSERT(this->getBuffAddr());
276  FW_ASSERT(val.getBuffAddr());
277  // serialize buffer
278  (void)memcpy(&this->getBuffAddr()[this->m_serLoc], val.getBuffAddr(), static_cast<size_t>(size));
279  this->m_serLoc += size;
280  this->m_deserLoc = 0;
281 
282  return FW_SERIALIZE_OK;
283 }
284 
287  if ((size < std::numeric_limits<FwSizeStoreType>::min()) || (size > std::numeric_limits<FwSizeStoreType>::max())) {
288  status = FW_SERIALIZE_FORMAT_ERROR;
289  }
290  if (status == FW_SERIALIZE_OK) {
291  status = this->serializeFrom(static_cast<FwSizeStoreType>(size), mode);
292  }
293  return status;
294 }
295 
296 // deserialization routines
297 
299  // check for room
300  if (this->getBuffLength() == this->m_deserLoc) {
302  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
304  }
305  // read from current location
306  FW_ASSERT(this->getBuffAddr());
307  val = this->getBuffAddr()[this->m_deserLoc + 0];
308  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
309  return FW_SERIALIZE_OK;
310 }
311 
313  // check for room
314  if (this->getBuffLength() == this->m_deserLoc) {
316  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
318  }
319  // read from current location
320  FW_ASSERT(this->getBuffAddr());
321  val = static_cast<I8>(this->getBuffAddr()[this->m_deserLoc + 0]);
322  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
323  return FW_SERIALIZE_OK;
324 }
325 
326 #if FW_HAS_16_BIT == 1
328  // check for room
329  if (this->getBuffLength() == this->m_deserLoc) {
331  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
333  }
334  // read from current location
335  FW_ASSERT(this->getBuffAddr());
336  switch (mode) {
337  case Endianness::BIG:
338  // MSB first
339  val = static_cast<U16>(((this->getBuffAddr()[this->m_deserLoc + 1]) << 0) |
340  ((this->getBuffAddr()[this->m_deserLoc + 0]) << 8));
341  break;
342  case Endianness::LITTLE:
343  // LSB first
344  val = static_cast<U16>(((this->getBuffAddr()[this->m_deserLoc + 0]) << 0) |
345  ((this->getBuffAddr()[this->m_deserLoc + 1]) << 8));
346  break;
347  default:
348  FW_ASSERT(false);
349  break;
350  }
351  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
352  return FW_SERIALIZE_OK;
353 }
354 
356  U16 unsignVal;
357  SerializeStatus res = deserializeTo(unsignVal, mode);
359  val = static_cast<I16>(unsignVal);
360  }
361  return res;
362 }
363 #endif
364 #if FW_HAS_32_BIT == 1
366  // check for room
367  if (this->getBuffLength() == this->m_deserLoc) {
369  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
371  }
372  // read from current location
373  FW_ASSERT(this->getBuffAddr());
374  switch (mode) {
375  case Endianness::BIG:
376  // MSB first
377  val = (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 0) |
378  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 8) |
379  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 16) |
380  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 24);
381  break;
382  case Endianness::LITTLE:
383  // LSB first
384  val = (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 0) |
385  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 8) |
386  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 16) |
387  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 24);
388  break;
389  default:
390  FW_ASSERT(false);
391  break;
392  }
393  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
394  return FW_SERIALIZE_OK;
395 }
396 
398  U32 unsignVal;
399  SerializeStatus res = deserializeTo(unsignVal, mode);
401  val = static_cast<I32>(unsignVal);
402  }
403  return res;
404 }
405 #endif
406 
407 #if FW_HAS_64_BIT == 1
408 
410  // check for room
411  if (this->getBuffLength() == this->m_deserLoc) {
413  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
415  }
416  // read from current location
417  FW_ASSERT(this->getBuffAddr());
418  switch (mode) {
419  case Endianness::BIG:
420  // MSB first
421  val = (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 0) |
422  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 8) |
423  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 16) |
424  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 24) |
425  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 32) |
426  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 40) |
427  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 48) |
428  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 56);
429  break;
430  case Endianness::LITTLE:
431  // LSB first
432  val = (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 0) |
433  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 8) |
434  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 16) |
435  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 24) |
436  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 32) |
437  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 40) |
438  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 48) |
439  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 56);
440  break;
441  default:
442  FW_ASSERT(false);
443  break;
444  }
445  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
446  return FW_SERIALIZE_OK;
447 }
448 
450  U64 unsignVal;
451  SerializeStatus res = deserializeTo(unsignVal, mode);
453  val = static_cast<I64>(unsignVal);
454  }
455  return res;
456 }
457 #endif
458 
460  // deserialize as 64-bit int to handle endianness
461  U64 tempVal;
462  SerializeStatus stat = this->deserializeTo(tempVal, mode);
463  if (stat != FW_SERIALIZE_OK) {
464  return stat;
465  }
466  // copy to argument
467  (void)memcpy(&val, &tempVal, sizeof(val));
468 
469  return FW_SERIALIZE_OK;
470 }
471 
473  // check for room
474  if (this->getBuffLength() == this->m_deserLoc) {
476  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(U8))) {
478  }
479  // read from current location
480  FW_ASSERT(this->getBuffAddr());
481  if (FW_SERIALIZE_TRUE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
482  val = true;
483  } else if (FW_SERIALIZE_FALSE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
484  val = false;
485  } else {
487  }
488 
489  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(U8));
490  return FW_SERIALIZE_OK;
491 }
492 
494  // Deserialize as pointer cast, then convert to void*
495  PlatformPointerCastType pointerCastVal = 0;
496  const SerializeStatus stat = this->deserializeTo(pointerCastVal, mode);
497  if (stat == FW_SERIALIZE_OK) {
498  val = reinterpret_cast<void*>(pointerCastVal);
499  }
500  return stat;
501 }
502 
504  // deserialize as 64-bit int to handle endianness
505  U32 tempVal;
506  SerializeStatus stat = this->deserializeTo(tempVal, mode);
507  if (stat != FW_SERIALIZE_OK) {
508  return stat;
509  }
510  (void)memcpy(&val, &tempVal, sizeof(val));
511 
512  return FW_SERIALIZE_OK;
513 }
514 
516  FwSizeType length_in_out = static_cast<FwSizeType>(length);
517  SerializeStatus status = this->deserializeTo(buff, length_in_out, Serialization::INCLUDE_LENGTH, endianMode);
518  length = static_cast<Serializable::SizeType>(length_in_out);
519  return status;
520 }
521 
523  Serializable::SizeType& length,
524  Serialization::t lengthMode,
525  Endianness endianMode) {
526  FW_ASSERT(this->getBuffAddr());
527 
528  if (lengthMode == Serialization::INCLUDE_LENGTH) {
529  FwSizeStoreType storedLength;
530 
531  SerializeStatus stat = this->deserializeTo(storedLength, endianMode);
532 
533  if (stat != FW_SERIALIZE_OK) {
534  return stat;
535  }
536 
537  // make sure it fits
538  if ((storedLength > this->getBuffLeft()) or (storedLength > length)) {
540  }
541 
542  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(storedLength));
543 
544  length = static_cast<FwSizeType>(storedLength);
545 
546  } else {
547  // make sure enough is left
548  if (length > this->getBuffLeft()) {
550  }
551 
552  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(length));
553  }
554 
555  this->m_deserLoc += static_cast<Serializable::SizeType>(length);
556  return FW_SERIALIZE_OK;
557 }
558 
560  return val.deserializeFrom(*this, mode);
561 }
562 
564  FW_ASSERT(val.getBuffAddr());
566 
567  FwSizeStoreType storedLength;
568 
569  stat = this->deserializeTo(storedLength, mode);
570 
571  if (stat != FW_SERIALIZE_OK) {
572  return stat;
573  }
574 
575  // make sure destination has enough room
576 
577  if ((storedLength > val.getBuffCapacity()) or (storedLength > this->getBuffLeft())) {
579  }
580 
581  FW_ASSERT(this->getBuffAddr());
582  (void)memcpy(val.getBuffAddr(), &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(storedLength));
583 
584  stat = val.setBuffLen(storedLength);
585 
586  if (stat != FW_SERIALIZE_OK) {
587  return stat;
588  }
589 
590  this->m_deserLoc += storedLength;
591 
592  return FW_SERIALIZE_OK;
593 }
594 
596  FwSizeStoreType storedSize = 0;
597  Fw::SerializeStatus status = this->deserializeTo(storedSize, mode);
598  if (status == FW_SERIALIZE_OK) {
599  size = static_cast<FwSizeType>(storedSize);
600  }
601  return status;
602 }
603 
605  this->m_deserLoc = 0;
606  this->m_serLoc = 0;
607 }
608 
610  this->m_deserLoc = 0;
611 }
612 
615  // compute new deser loc
616  const FwSizeType newSerLoc = this->m_serLoc + numBytesToSkip;
617  // check for room
618  if (newSerLoc <= this->getBuffCapacity()) {
619  // update deser loc
620  this->m_serLoc = static_cast<Serializable::SizeType>(newSerLoc);
621  } else {
622  status = FW_SERIALIZE_NO_ROOM_LEFT;
623  }
624  return status;
625 }
626 
628  // check for room
629  if (this->getBuffLength() == this->m_deserLoc) {
631  } else if (this->getBuffLength() - this->m_deserLoc < numBytesToSkip) {
633  }
634  // update location in buffer to skip the value
635  this->m_deserLoc += static_cast<Serializable::SizeType>(numBytesToSkip);
636  return FW_SERIALIZE_OK;
637 }
638 
640  // Reset serialization
641  this->resetSer();
642  // Advance to offset
643  return this->serializeSkip(offset);
644 }
646  // Reset deserialization
647  this->resetDeser();
648  // Advance to offset
649  return this->deserializeSkip(offset);
650 }
651 
653  return this->m_serLoc;
654 }
655 
657  if (this->getBuffCapacity() < length) {
659  } else {
660  FW_ASSERT(src);
661  FW_ASSERT(this->getBuffAddr());
662  (void)memcpy(this->getBuffAddr(), src, static_cast<size_t>(length));
663  this->m_serLoc = length;
664  this->m_deserLoc = 0;
665  return FW_SERIALIZE_OK;
666  }
667 }
668 
670  if (this->getBuffCapacity() < length) {
672  } else {
673  this->m_serLoc = length;
674  this->m_deserLoc = 0;
675  return FW_SERIALIZE_OK;
676  }
677 }
678 
680  FW_ASSERT(this->m_serLoc >= this->m_deserLoc, static_cast<FwAssertArgType>(this->m_serLoc),
681  static_cast<FwAssertArgType>(this->m_deserLoc));
682  return this->m_serLoc - this->m_deserLoc;
683 }
684 
686  // make sure there is sufficient size in destination
687  if (dest.getBuffCapacity() < size) {
689  }
690  // otherwise, set destination buffer to data from deserialization pointer plus size
691  SerializeStatus stat = dest.setBuff(&this->getBuffAddr()[this->m_deserLoc], size);
692  if (stat == FW_SERIALIZE_OK) {
693  this->m_deserLoc += size;
694  }
695  return stat;
696 }
697 
699  // make sure there is sufficient size in destination
700  if (dest.getBuffCapacity() < size + dest.getBuffLength()) {
702  }
703  // make sure there is sufficient buffer in source
704  if (this->getBuffLeft() < size) {
706  }
707 
708  // otherwise, serialize bytes to destination without writing length
710  if (stat == FW_SERIALIZE_OK) {
711  this->m_deserLoc += size;
712  }
713  return stat;
714 }
715 
716 // return address of buffer not yet deserialized. This is used
717 // to copy the remainder of a buffer.
719  return &this->getBuffAddr()[this->m_deserLoc];
720 }
721 
724  return &this->getBuffAddr()[this->m_serLoc];
725 }
726 
727 #ifdef BUILD_UT
728 bool SerializeBufferBase::operator==(const SerializeBufferBase& other) const {
729  if (this->getBuffLength() != other.getBuffLength()) {
730  return false;
731  }
732 
733  const U8* us = this->getBuffAddr();
734  const U8* them = other.getBuffAddr();
735 
736  FW_ASSERT(us);
737  FW_ASSERT(them);
738 
739  for (Serializable::SizeType byte = 0; byte < this->getBuffLength(); byte++) {
740  if (us[byte] != them[byte]) {
741  return false;
742  }
743  }
744 
745  return true;
746 }
747 
748 std::ostream& operator<<(std::ostream& os, const SerializeBufferBase& buff) {
749  const U8* us = buff.getBuffAddr();
750 
751  FW_ASSERT(us);
752 
753  for (Serializable::SizeType byte = 0; byte < buff.getBuffLength(); byte++) {
754  os << "[" << std::setw(2) << std::hex << std::setfill('0') << us[byte] << "]" << std::dec;
755  }
756 
757  return os;
758 }
759 #endif
760 
762  this->setExtBuffer(buffPtr, size);
763 }
764 
766  this->clear();
767 }
768 
770  FW_ASSERT(buffPtr != nullptr);
771  this->clear();
772  this->m_buff = buffPtr;
773  this->m_buffSize = size;
774 }
775 
777  this->resetSer();
778  this->resetDeser();
779  this->m_buff = nullptr;
780  this->m_buffSize = 0;
781 }
782 
784  return this->m_buffSize;
785 }
786 
788  return this->m_buff;
789 }
790 
792  return this->m_buff;
793 }
794 
795 // ----------------------------------------------------------------------
796 // Deprecated method implementations for backward compatibility
797 // ----------------------------------------------------------------------
798 
799 SerializeStatus SerializeBufferBase::serialize(U8 val) {
800  return this->serializeFrom(val);
801 }
802 SerializeStatus SerializeBufferBase::serialize(I8 val) {
803  return this->serializeFrom(val);
804 }
805 #if FW_HAS_16_BIT == 1
806 SerializeStatus SerializeBufferBase::serialize(U16 val) {
807  return this->serializeFrom(val);
808 }
809 SerializeStatus SerializeBufferBase::serialize(I16 val) {
810  return this->serializeFrom(val);
811 }
812 #endif
813 #if FW_HAS_32_BIT == 1
814 SerializeStatus SerializeBufferBase::serialize(U32 val) {
815  return this->serializeFrom(val);
816 }
817 SerializeStatus SerializeBufferBase::serialize(I32 val) {
818  return this->serializeFrom(val);
819 }
820 #endif
821 #if FW_HAS_64_BIT == 1
822 SerializeStatus SerializeBufferBase::serialize(U64 val) {
823  return this->serializeFrom(val);
824 }
825 SerializeStatus SerializeBufferBase::serialize(I64 val) {
826  return this->serializeFrom(val);
827 }
828 #endif
829 SerializeStatus SerializeBufferBase::serialize(F32 val) {
830  return this->serializeFrom(val);
831 }
832 SerializeStatus SerializeBufferBase::serialize(F64 val) {
833  return this->serializeFrom(val);
834 }
835 SerializeStatus SerializeBufferBase::serialize(bool val) {
836  return this->serializeFrom(val);
837 }
838 SerializeStatus SerializeBufferBase::serialize(const void* val) {
839  return this->serializeFrom(val);
840 }
841 
842 // Deprecated method for backward compatibility
843 SerializeStatus SerializeBufferBase::serialize(const U8* buff, FwSizeType length, bool noLength) {
845  return this->serializeFrom(buff, length, mode);
846 }
847 
848 SerializeStatus SerializeBufferBase::serialize(const U8* buff, FwSizeType length) {
849  return this->serializeFrom(buff, length);
850 }
851 SerializeStatus SerializeBufferBase::serialize(const U8* buff, FwSizeType length, Serialization::t mode) {
852  return this->serializeFrom(buff, length, mode);
853 }
854 SerializeStatus SerializeBufferBase::serialize(const Serializable& val) {
855  return this->serializeFrom(val);
856 }
857 SerializeStatus SerializeBufferBase::serialize(const SerializeBufferBase& val) {
858  return this->serializeFrom(val);
859 }
860 
861 SerializeStatus SerializeBufferBase::deserialize(U8& val) {
862  return this->deserializeTo(val);
863 }
864 SerializeStatus SerializeBufferBase::deserialize(I8& val) {
865  return this->deserializeTo(val);
866 }
867 #if FW_HAS_16_BIT == 1
868 SerializeStatus SerializeBufferBase::deserialize(U16& val) {
869  return this->deserializeTo(val);
870 }
871 SerializeStatus SerializeBufferBase::deserialize(I16& val) {
872  return this->deserializeTo(val);
873 }
874 #endif
875 #if FW_HAS_32_BIT == 1
876 SerializeStatus SerializeBufferBase::deserialize(U32& val) {
877  return this->deserializeTo(val);
878 }
879 SerializeStatus SerializeBufferBase::deserialize(I32& val) {
880  return this->deserializeTo(val);
881 }
882 #endif
883 #if FW_HAS_64_BIT == 1
884 SerializeStatus SerializeBufferBase::deserialize(U64& val) {
885  return this->deserializeTo(val);
886 }
887 SerializeStatus SerializeBufferBase::deserialize(I64& val) {
888  return this->deserializeTo(val);
889 }
890 #endif
891 SerializeStatus SerializeBufferBase::deserialize(F32& val) {
892  return this->deserializeTo(val);
893 }
894 SerializeStatus SerializeBufferBase::deserialize(F64& val) {
895  return this->deserializeTo(val);
896 }
897 SerializeStatus SerializeBufferBase::deserialize(bool& val) {
898  return this->deserializeTo(val);
899 }
900 SerializeStatus SerializeBufferBase::deserialize(void*& val) {
901  return this->deserializeTo(val);
902 }
903 
904 // Deprecated method for backward compatibility
905 SerializeStatus SerializeBufferBase::deserialize(U8* buff, FwSizeType& length, bool noLength) {
907  return this->deserializeTo(buff, length, mode);
908 }
909 
910 SerializeStatus SerializeBufferBase::deserialize(U8* buff, FwSizeType& length) {
911  return this->deserializeTo(buff, length, Serialization::INCLUDE_LENGTH);
912 }
913 
914 SerializeStatus SerializeBufferBase::deserialize(U8* buff, FwSizeType& length, Serialization::t mode) {
915  return this->deserializeTo(buff, length, mode);
916 }
917 
918 SerializeStatus SerializeBufferBase::deserialize(Serializable& val) {
919  return this->deserializeTo(val);
920 }
921 SerializeStatus SerializeBufferBase::deserialize(SerializeBufferBase& val) {
922  return this->deserializeTo(val);
923 }
924 
925 } // namespace Fw
Serialization/Deserialization operation was successful.
void clear()
clear external buffer
SerializeBufferBase()
default constructor
Deserialization buffer was empty when trying to read more data.
PlatformSizeType FwSizeType
void resetSer()
reset to beginning of buffer to reuse for serialization
SerializeStatus copyRaw(SerializeBufferBase &dest, Serializable::SizeType size)
directly copies buffer without looking for a size in the stream.
int8_t I8
8-bit signed integer
Definition: BasicTypes.h:50
SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG)
deserialize 8-bit unsigned int
No room left in the buffer to serialize data.
#define FW_SERIALIZE_FALSE_VALUE
Value encoded during serialization for boolean false.
Definition: FpConfig.h:35
Serializable::SizeType m_buffSize
size of external buffer
virtual ~SerializeBufferBase()
destructor
Deserialization data had incorrect values (unexpected data types)
Serializable::SizeType m_serLoc
current offset in buffer of serialized data
const U8 * getBuffAddrLeft() const
gets address of remaining non-deserialized data.
ExternalSerializeBuffer()
default constructor
SerializeStatus
forward declaration for string
float F32
32-bit floating point
Definition: BasicTypes.h:83
SerializeStatus deserializeSize(FwSizeType &size, Endianness mode=Endianness::BIG)
deserialize a size value
U16 FwSizeStoreType
The type used to serialize a size value.
Serializable::SizeType getBuffLength() const
returns current buffer size
Serializable::SizeType getBuffLeft() const
returns how much deserialization buffer is left
Data was the wrong format (e.g. wrong packet type)
U8 * m_buff
pointer to external buffer
Omit length from serialization.
#define FW_SERIALIZE_TRUE_VALUE
Value encoded during serialization for boolean true.
Definition: FpConfig.h:31
virtual SerializeStatus deserializeFrom(SerializeBufferBase &buffer, Endianness mode=Endianness::BIG)=0
deserialize contents from buffer
Data was left in the buffer, but not enough to deserialize.
FwSizeType SizeType
Serializable()
Default constructor.
void resetDeser()
reset deserialization to beginning
virtual SerializeStatus serializeTo(SerializeBufferBase &buffer, Endianness mode=Endianness::BIG) const =0
serialize contents to buffer
SerializeStatus copyRawOffset(SerializeBufferBase &dest, Serializable::SizeType size)
directly copies buffer without looking for a size in the stream.
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG)
serialize 8-bit unsigned int
SerializeStatus moveDeserToOffset(FwSizeType offset)
Moves deserialization to the specified offset.
SerializeStatus moveSerToOffset(FwSizeType offset)
Moves serialization to the specified offset.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
virtual Serializable::SizeType getBuffCapacity() const =0
returns capacity, not current size, of buffer
SerializeStatus deserializeSkip(FwSizeType numBytesToSkip)
Skips the number of specified bytes for deserialization.
static U32 min(const U32 a, const U32 b)
Definition: Checksum.cpp:16
void setExtBuffer(U8 *buffPtr, Serializable::SizeType size)
virtual ~Serializable()
destructor
Serializable::SizeType m_deserLoc
current offset for deserialization
double F64
64-bit floating point (double). Required for compiler-supplied double promotion.
Definition: BasicTypes.h:85
SerializeBufferBase & operator=(const SerializeBufferBase &src)
copy assignment operator
SerializeStatus setBuff(const U8 *src, Serializable::SizeType length)
sets buffer contents and size
Include length as first token in serialization.
SerializeStatus serializeSize(const FwSizeType size, Endianness mode=Endianness::BIG)
serialize a size value
Little endian serialization.
Serializable::SizeType getBuffCapacity() const
returns capacity, not current size, of buffer
virtual U8 * getBuffAddr()=0
gets buffer address for data filling
Endianness
#define FW_ASSERT(...)
Definition: Assert.hpp:14
SerializeStatus serializeSkip(FwSizeType numBytesToSkip)
Skips the number of specified bytes for serialization.
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.
Big endian serialization.
U8 * getBuffAddr()
gets buffer address for data filling
SerializeStatus setBuffLen(Serializable::SizeType length)
sets buffer length manually after filling with data
#define U64(C)
Definition: sha.h:181