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 
41 
42 LinearBufferBase::LinearBufferBase() : m_serLoc(0), m_deserLoc(0) {}
43 
45 
47  this->m_serLoc = src.m_serLoc;
48  this->m_deserLoc = src.m_deserLoc;
49  FW_ASSERT(src.getBuffAddr());
50  FW_ASSERT(this->getBuffAddr());
51  // destination has to be same or bigger
52  FW_ASSERT(src.getSize() <= this->getCapacity(), static_cast<FwAssertArgType>(src.getSize()),
53  static_cast<FwAssertArgType>(this->getSize()));
54  (void)memcpy(this->getBuffAddr(), src.getBuffAddr(), static_cast<size_t>(this->m_serLoc));
55 }
56 
57 // Copy constructor doesn't make sense in this virtual class as there is nothing to copy. Derived classes should
58 // call the empty constructor and then call their own copy function
59 LinearBufferBase& LinearBufferBase::operator=(const LinearBufferBase& src) { // lgtm[cpp/rule-of-two]
60  this->copyFrom(src);
61  return *this;
62 }
63 
64 // serialization routines
65 
67  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getCapacity()) {
69  }
70  FW_ASSERT(this->getBuffAddr());
71  this->getBuffAddr()[this->m_serLoc] = val;
72  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
73  this->m_deserLoc = 0;
74 
75  return FW_SERIALIZE_OK;
76 }
77 
79  return serializeFrom(static_cast<U8>(val), mode);
80 }
81 
82 #if FW_HAS_16_BIT == 1
84  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getCapacity()) {
86  }
87  FW_ASSERT(this->getBuffAddr());
88  switch (mode) {
89  case Endianness::BIG:
90  // MSB first
91  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 8);
92  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val);
93  break;
94  case Endianness::LITTLE:
95  // LSB first
96  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val);
97  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 8);
98  break;
99  default:
100  FW_ASSERT(false);
101  break;
102  }
103  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
104  this->m_deserLoc = 0;
105  return FW_SERIALIZE_OK;
106 }
107 
109  return serializeFrom(static_cast<U16>(val), mode);
110 }
111 #endif
112 #if FW_HAS_32_BIT == 1
114  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getCapacity()) {
116  }
117  FW_ASSERT(this->getBuffAddr());
118  switch (mode) {
119  case Endianness::BIG:
120  // MSB first
121  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 24);
122  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 16);
123  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 8);
124  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val);
125  break;
126  case Endianness::LITTLE:
127  // LSB first
128  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val);
129  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 8);
130  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 16);
131  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val >> 24);
132  break;
133  default:
134  FW_ASSERT(false);
135  break;
136  }
137  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
138  this->m_deserLoc = 0;
139  return FW_SERIALIZE_OK;
140 }
141 
143  return serializeFrom(static_cast<U32>(val), mode);
144 }
145 #endif
146 
147 #if FW_HAS_64_BIT == 1
149  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getCapacity()) {
151  }
152  FW_ASSERT(this->getBuffAddr());
153  switch (mode) {
154  case Endianness::BIG:
155  // MSB first
156  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 56);
157  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 48);
158  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 40);
159  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val >> 32);
160  this->getBuffAddr()[this->m_serLoc + 4] = static_cast<U8>(val >> 24);
161  this->getBuffAddr()[this->m_serLoc + 5] = static_cast<U8>(val >> 16);
162  this->getBuffAddr()[this->m_serLoc + 6] = static_cast<U8>(val >> 8);
163  this->getBuffAddr()[this->m_serLoc + 7] = static_cast<U8>(val);
164  break;
165  case Endianness::LITTLE:
166  // LSB first
167  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val);
168  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 8);
169  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 16);
170  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val >> 24);
171  this->getBuffAddr()[this->m_serLoc + 4] = static_cast<U8>(val >> 32);
172  this->getBuffAddr()[this->m_serLoc + 5] = static_cast<U8>(val >> 40);
173  this->getBuffAddr()[this->m_serLoc + 6] = static_cast<U8>(val >> 48);
174  this->getBuffAddr()[this->m_serLoc + 7] = static_cast<U8>(val >> 56);
175  break;
176  default:
177  FW_ASSERT(false);
178  break;
179  }
180  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
181  this->m_deserLoc = 0;
182  return FW_SERIALIZE_OK;
183 }
184 
186  return serializeFrom(static_cast<U64>(val), mode);
187 }
188 #endif
189 
191  // floating point values need to be byte-swapped as well, so copy to U64 and use that routine
192  U64 u64Val;
193  (void)memcpy(&u64Val, &val, sizeof(val));
194  return this->serializeFrom(u64Val, mode);
195 }
196 
198  // floating point values need to be byte-swapped as well, so copy to U32 and use that routine
199  U32 u32Val;
200  (void)memcpy(&u32Val, &val, sizeof(val));
201  return this->serializeFrom(u32Val, mode);
202 }
203 
205  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(U8)) - 1 >= this->getCapacity()) {
207  }
208 
209  FW_ASSERT(this->getBuffAddr());
210  if (val) {
211  this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_TRUE_VALUE;
212  } else {
213  this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_FALSE_VALUE;
214  }
215 
216  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(U8));
217  this->m_deserLoc = 0;
218  return FW_SERIALIZE_OK;
219 }
220 
222  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(void*)) - 1 >= this->getCapacity()) {
224  }
225 
226  return this->serializeFrom(reinterpret_cast<PlatformPointerCastType>(val), mode);
227 }
228 
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->getCapacity()) {
248  }
249 
250  if (length > 0) {
251  FW_ASSERT(buff);
252  }
253  FW_ASSERT(this->getBuffAddr());
254  // copy buffer to our buffer
255  (void)memcpy(&this->getBuffAddr()[this->m_serLoc], buff, static_cast<size_t>(length));
256  this->m_serLoc += static_cast<Serializable::SizeType>(length);
257  this->m_deserLoc = 0;
258 
259  return FW_SERIALIZE_OK;
260 }
261 
263  return val.serializeTo(*this, mode);
264 }
265 
267  Serializable::SizeType size = val.getSize();
268  if (this->m_serLoc + size + static_cast<Serializable::SizeType>(sizeof(FwSizeStoreType)) > this->getCapacity()) {
270  }
271 
272  // First, serialize size
273  SerializeStatus stat = this->serializeFrom(static_cast<FwSizeStoreType>(size), mode);
274  if (stat != FW_SERIALIZE_OK) {
275  return stat;
276  }
277 
278  FW_ASSERT(this->getBuffAddr());
279  FW_ASSERT(val.getBuffAddr());
280  // serialize buffer
281  (void)memcpy(&this->getBuffAddr()[this->m_serLoc], val.getBuffAddr(), static_cast<size_t>(size));
282  this->m_serLoc += size;
283  this->m_deserLoc = 0;
284 
285  return FW_SERIALIZE_OK;
286 }
287 
290  if ((size < std::numeric_limits<FwSizeStoreType>::min()) || (size > std::numeric_limits<FwSizeStoreType>::max())) {
291  status = FW_SERIALIZE_FORMAT_ERROR;
292  }
293  if (status == FW_SERIALIZE_OK) {
294  status = this->serializeFrom(static_cast<FwSizeStoreType>(size), mode);
295  }
296  return status;
297 }
298 
299 // deserialization routines
300 
302  // check for room
303  if (this->getSize() == this->m_deserLoc) {
305  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
307  }
308  // read from current location
309  FW_ASSERT(this->getBuffAddr());
310  val = this->getBuffAddr()[this->m_deserLoc + 0];
311  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
312  return FW_SERIALIZE_OK;
313 }
314 
316  // check for room
317  if (this->getSize() == this->m_deserLoc) {
319  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
321  }
322  // read from current location
323  FW_ASSERT(this->getBuffAddr());
324  val = static_cast<I8>(this->getBuffAddr()[this->m_deserLoc + 0]);
325  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
326  return FW_SERIALIZE_OK;
327 }
328 
329 #if FW_HAS_16_BIT == 1
331  // check for room
332  if (this->getSize() == this->m_deserLoc) {
334  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
336  }
337  // read from current location
338  FW_ASSERT(this->getBuffAddr());
339  switch (mode) {
340  case Endianness::BIG:
341  // MSB first
342  val = static_cast<U16>(((this->getBuffAddr()[this->m_deserLoc + 1]) << 0) |
343  ((this->getBuffAddr()[this->m_deserLoc + 0]) << 8));
344  break;
345  case Endianness::LITTLE:
346  // LSB first
347  val = static_cast<U16>(((this->getBuffAddr()[this->m_deserLoc + 0]) << 0) |
348  ((this->getBuffAddr()[this->m_deserLoc + 1]) << 8));
349  break;
350  default:
351  FW_ASSERT(false);
352  break;
353  }
354  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
355  return FW_SERIALIZE_OK;
356 }
357 
359  U16 unsignVal = 0;
360  SerializeStatus res = deserializeTo(unsignVal, mode);
362  val = static_cast<I16>(unsignVal);
363  }
364  return res;
365 }
366 #endif
367 #if FW_HAS_32_BIT == 1
369  // check for room
370  if (this->getSize() == this->m_deserLoc) {
372  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
374  }
375  // read from current location
376  FW_ASSERT(this->getBuffAddr());
377  switch (mode) {
378  case Endianness::BIG:
379  // MSB first
380  val = (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 0) |
381  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 8) |
382  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 16) |
383  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 24);
384  break;
385  case Endianness::LITTLE:
386  // LSB first
387  val = (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 0) |
388  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 8) |
389  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 16) |
390  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 24);
391  break;
392  default:
393  FW_ASSERT(false);
394  break;
395  }
396  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
397  return FW_SERIALIZE_OK;
398 }
399 
401  U32 unsignVal = 0;
402  SerializeStatus res = deserializeTo(unsignVal, mode);
404  val = static_cast<I32>(unsignVal);
405  }
406  return res;
407 }
408 #endif
409 
410 #if FW_HAS_64_BIT == 1
411 
413  // check for room
414  if (this->getSize() == this->m_deserLoc) {
416  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
418  }
419  // read from current location
420  FW_ASSERT(this->getBuffAddr());
421  switch (mode) {
422  case Endianness::BIG:
423  // MSB first
424  val = (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 0) |
425  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 8) |
426  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 16) |
427  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 24) |
428  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 32) |
429  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 40) |
430  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 48) |
431  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 56);
432  break;
433  case Endianness::LITTLE:
434  // LSB first
435  val = (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 0) |
436  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 8) |
437  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 16) |
438  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 24) |
439  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 32) |
440  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 40) |
441  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 48) |
442  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 56);
443  break;
444  default:
445  FW_ASSERT(false);
446  break;
447  }
448  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
449  return FW_SERIALIZE_OK;
450 }
451 
453  U64 unsignVal;
454  SerializeStatus res = deserializeTo(unsignVal, mode);
456  val = static_cast<I64>(unsignVal);
457  }
458  return res;
459 }
460 #endif
461 
463  // deserialize as 64-bit int to handle endianness
464  U64 tempVal;
465  SerializeStatus stat = this->deserializeTo(tempVal, mode);
466  if (stat != FW_SERIALIZE_OK) {
467  return stat;
468  }
469  // copy to argument
470  (void)memcpy(&val, &tempVal, sizeof(val));
471 
472  return FW_SERIALIZE_OK;
473 }
474 
476  // check for room
477  if (this->getSize() == this->m_deserLoc) {
479  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(U8))) {
481  }
482  // read from current location
483  FW_ASSERT(this->getBuffAddr());
484  if (FW_SERIALIZE_TRUE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
485  val = true;
486  } else if (FW_SERIALIZE_FALSE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
487  val = false;
488  } else {
490  }
491 
492  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(U8));
493  return FW_SERIALIZE_OK;
494 }
495 
497  // Deserialize as pointer cast, then convert to void*
498  PlatformPointerCastType pointerCastVal = 0;
499  const SerializeStatus stat = this->deserializeTo(pointerCastVal, mode);
500  if (stat == FW_SERIALIZE_OK) {
501  val = reinterpret_cast<void*>(pointerCastVal);
502  }
503  return stat;
504 }
505 
507  // deserialize as 64-bit int to handle endianness
508  U32 tempVal = 0;
509  SerializeStatus stat = this->deserializeTo(tempVal, mode);
510  if (stat != FW_SERIALIZE_OK) {
511  return stat;
512  }
513  (void)memcpy(&val, &tempVal, sizeof(val));
514 
515  return FW_SERIALIZE_OK;
516 }
517 
519  FwSizeType length_in_out = static_cast<FwSizeType>(length);
520  SerializeStatus status = this->deserializeTo(buff, length_in_out, Serialization::INCLUDE_LENGTH, endianMode);
521  length = static_cast<Serializable::SizeType>(length_in_out);
522  return status;
523 }
524 
526  Serializable::SizeType& length,
527  Serialization::t lengthMode,
528  Endianness endianMode) {
529  FW_ASSERT(this->getBuffAddr());
530 
531  if (lengthMode == Serialization::INCLUDE_LENGTH) {
532  FwSizeStoreType storedLength = 0;
533 
534  SerializeStatus stat = this->deserializeTo(storedLength, endianMode);
535 
536  if (stat != FW_SERIALIZE_OK) {
537  return stat;
538  }
539 
540  // make sure it fits
541  if ((storedLength > this->getDeserializeSizeLeft()) or (storedLength > length)) {
543  }
544 
545  if (storedLength > 0) {
546  FW_ASSERT(buff);
547  }
548  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(storedLength));
549 
550  length = static_cast<FwSizeType>(storedLength);
551 
552  } else {
553  // make sure enough is left
554  if (length > this->getDeserializeSizeLeft()) {
556  }
557 
558  if (length > 0) {
559  FW_ASSERT(buff);
560  }
561  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(length));
562  }
563 
564  this->m_deserLoc += static_cast<Serializable::SizeType>(length);
565  return FW_SERIALIZE_OK;
566 }
567 
569  return val.deserializeFrom(*this, mode);
570 }
571 
573  FW_ASSERT(val.getBuffAddr());
575 
576  FwSizeStoreType storedLength = 0;
577 
578  stat = this->deserializeTo(storedLength, mode);
579 
580  if (stat != FW_SERIALIZE_OK) {
581  return stat;
582  }
583 
584  // make sure destination has enough room
585 
586  if ((storedLength > val.getCapacity()) or (storedLength > this->getDeserializeSizeLeft())) {
588  }
589 
590  FW_ASSERT(this->getBuffAddr());
591  (void)memcpy(val.getBuffAddr(), &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(storedLength));
592 
593  stat = val.setBuffLen(storedLength);
594 
595  if (stat != FW_SERIALIZE_OK) {
596  return stat;
597  }
598 
599  this->m_deserLoc += storedLength;
600 
601  return FW_SERIALIZE_OK;
602 }
603 
605  FwSizeStoreType storedSize = 0;
606  Fw::SerializeStatus status = this->deserializeTo(storedSize, mode);
607  if (status == FW_SERIALIZE_OK) {
608  size = static_cast<FwSizeType>(storedSize);
609  }
610  return status;
611 }
612 
614  this->m_deserLoc = 0;
615  this->m_serLoc = 0;
616 }
617 
619  this->m_deserLoc = 0;
620 }
621 
624  // compute new deser loc
625  const FwSizeType newSerLoc = this->m_serLoc + numBytesToSkip;
626  // check for room
627  if (newSerLoc <= this->getCapacity()) {
628  // update deser loc
629  this->m_serLoc = static_cast<Serializable::SizeType>(newSerLoc);
630  } else {
631  status = FW_SERIALIZE_NO_ROOM_LEFT;
632  }
633  return status;
634 }
635 
637  // check for room
638  if (this->getSize() == this->m_deserLoc) {
640  } else if (this->getSize() - this->m_deserLoc < numBytesToSkip) {
642  }
643  // update location in buffer to skip the value
644  this->m_deserLoc += static_cast<Serializable::SizeType>(numBytesToSkip);
645  return FW_SERIALIZE_OK;
646 }
647 
649  // Reset serialization
650  this->resetSer();
651  // Advance to offset
652  return this->serializeSkip(offset);
653 }
655  // Reset deserialization
656  this->resetDeser();
657  // Advance to offset
658  return this->deserializeSkip(offset);
659 }
660 
662  return this->m_serLoc;
663 }
664 
666  if (this->getCapacity() < length) {
668  } else {
669  FW_ASSERT(src);
670  FW_ASSERT(this->getBuffAddr());
671  (void)memcpy(this->getBuffAddr(), src, static_cast<size_t>(length));
672  this->m_serLoc = length;
673  this->m_deserLoc = 0;
674  return FW_SERIALIZE_OK;
675  }
676 }
677 
679  if (this->getCapacity() < length) {
681  } else {
682  this->m_serLoc = length;
683  this->m_deserLoc = 0;
684  return FW_SERIALIZE_OK;
685  }
686 }
687 
689  FW_ASSERT(this->m_serLoc >= this->m_deserLoc, static_cast<FwAssertArgType>(this->m_serLoc),
690  static_cast<FwAssertArgType>(this->m_deserLoc));
691  return this->m_serLoc - this->m_deserLoc;
692 }
693 
695  FW_ASSERT(static_cast<FwAssertArgType>(this->m_serLoc));
696  return this->getCapacity() - this->m_serLoc;
697 }
698 
700  // make sure there is sufficient size in destination
701  if (dest.getCapacity() < size) {
703  }
704  // make sure there is sufficient buffer in source
705  if (this->getDeserializeSizeLeft() < size) {
707  }
708 
709  // otherwise, set destination buffer to data from deserialization pointer plus size
710  SerializeStatus stat = dest.setBuff(&this->getBuffAddr()[this->m_deserLoc], size);
711  if (stat == FW_SERIALIZE_OK) {
712  this->m_deserLoc += size;
713  }
714  return stat;
715 }
716 
718  // make sure there is sufficient size in destination
719  if (dest.getCapacity() < size + dest.getSize()) {
721  }
722  // make sure there is sufficient buffer in source
723  if (this->getDeserializeSizeLeft() < size) {
725  }
726 
727  // otherwise, serialize bytes to destination without writing length
729  if (stat == FW_SERIALIZE_OK) {
730  this->m_deserLoc += size;
731  }
732  return stat;
733 }
734 
735 // return address of buffer not yet deserialized. This is used
736 // to copy the remainder of a buffer.
738  FW_ASSERT(this->getBuffAddr());
739  return &this->getBuffAddr()[this->m_deserLoc];
740 }
741 
744  FW_ASSERT(this->getBuffAddr());
745  return &this->getBuffAddr()[this->m_serLoc];
746 }
747 
748 #ifdef BUILD_UT
749 bool LinearBufferBase::operator==(const SerializeBufferBase& other) const {
750  if (this->getSize() != other.getSize()) {
751  return false;
752  }
753 
754  const U8* us = this->getBuffAddr();
755  const U8* them = other.getBuffAddr();
756 
757  FW_ASSERT(us);
758  FW_ASSERT(them);
759 
760  for (Serializable::SizeType byte = 0; byte < this->getSize(); byte++) {
761  if (us[byte] != them[byte]) {
762  return false;
763  }
764  }
765 
766  return true;
767 }
768 
769 std::ostream& operator<<(std::ostream& os, const LinearBufferBase& buff) {
770  const U8* us = buff.getBuffAddr();
771 
772  FW_ASSERT(us);
773 
774  for (Serializable::SizeType byte = 0; byte < buff.getSize(); byte++) {
775  os << "[" << std::setw(2) << std::hex << std::setfill('0') << us[byte] << "]" << std::dec;
776  }
777 
778  return os;
779 }
780 #endif
781 
783  this->setExtBuffer(buffPtr, size);
784 }
785 
787  this->clear();
788 }
789 
791  FW_ASSERT(buffPtr != nullptr);
792  this->clear();
793  this->m_buff = buffPtr;
794  this->m_buffSize = size;
795 }
796 
798  this->resetSer();
799  this->resetDeser();
800  this->m_buff = nullptr;
801  this->m_buffSize = 0;
802 }
803 
805  return this->m_buffSize;
806 }
807 
809  return this->m_buff;
810 }
811 
813  return this->m_buff;
814 }
815 
816 // ----------------------------------------------------------------------
817 // Deprecated method implementations for backward compatibility
818 // ----------------------------------------------------------------------
819 
820 Serializable::SizeType LinearBufferBase::getBuffLength() const {
821  return this->getSize();
822 }
823 
824 Serializable::SizeType LinearBufferBase::getBuffLeft() {
825  return this->getDeserializeSizeLeft();
826 }
827 
828 SerializeStatus LinearBufferBase::serialize(U8 val) {
829  return this->serializeFrom(val);
830 }
831 SerializeStatus LinearBufferBase::serialize(I8 val) {
832  return this->serializeFrom(val);
833 }
834 #if FW_HAS_16_BIT == 1
835 SerializeStatus LinearBufferBase::serialize(U16 val) {
836  return this->serializeFrom(val);
837 }
838 SerializeStatus LinearBufferBase::serialize(I16 val) {
839  return this->serializeFrom(val);
840 }
841 #endif
842 #if FW_HAS_32_BIT == 1
843 SerializeStatus LinearBufferBase::serialize(U32 val) {
844  return this->serializeFrom(val);
845 }
846 SerializeStatus LinearBufferBase::serialize(I32 val) {
847  return this->serializeFrom(val);
848 }
849 #endif
850 #if FW_HAS_64_BIT == 1
851 SerializeStatus LinearBufferBase::serialize(U64 val) {
852  return this->serializeFrom(val);
853 }
854 SerializeStatus LinearBufferBase::serialize(I64 val) {
855  return this->serializeFrom(val);
856 }
857 #endif
858 SerializeStatus LinearBufferBase::serialize(F32 val) {
859  return this->serializeFrom(val);
860 }
861 SerializeStatus LinearBufferBase::serialize(F64 val) {
862  return this->serializeFrom(val);
863 }
864 SerializeStatus LinearBufferBase::serialize(bool val) {
865  return this->serializeFrom(val);
866 }
867 SerializeStatus LinearBufferBase::serialize(const void* val) {
868  return this->serializeFrom(val);
869 }
870 
871 // Deprecated method for backward compatibility
872 SerializeStatus LinearBufferBase::serialize(const U8* buff, FwSizeType length, bool noLength) {
874  return this->serializeFrom(buff, length, mode);
875 }
876 
877 SerializeStatus LinearBufferBase::serialize(const U8* buff, FwSizeType length) {
878  return this->serializeFrom(buff, length);
879 }
880 SerializeStatus LinearBufferBase::serialize(const U8* buff, FwSizeType length, Serialization::t mode) {
881  return this->serializeFrom(buff, length, mode);
882 }
883 SerializeStatus LinearBufferBase::serialize(const Serializable& val) {
884  return this->serializeFrom(val);
885 }
886 SerializeStatus LinearBufferBase::serialize(const LinearBufferBase& val) {
887  return this->serializeFrom(val);
888 }
889 
890 SerializeStatus LinearBufferBase::deserialize(U8& val) {
891  return this->deserializeTo(val);
892 }
893 SerializeStatus LinearBufferBase::deserialize(I8& val) {
894  return this->deserializeTo(val);
895 }
896 #if FW_HAS_16_BIT == 1
897 SerializeStatus LinearBufferBase::deserialize(U16& val) {
898  return this->deserializeTo(val);
899 }
900 SerializeStatus LinearBufferBase::deserialize(I16& val) {
901  return this->deserializeTo(val);
902 }
903 #endif
904 #if FW_HAS_32_BIT == 1
905 SerializeStatus LinearBufferBase::deserialize(U32& val) {
906  return this->deserializeTo(val);
907 }
908 SerializeStatus LinearBufferBase::deserialize(I32& val) {
909  return this->deserializeTo(val);
910 }
911 #endif
912 #if FW_HAS_64_BIT == 1
913 SerializeStatus LinearBufferBase::deserialize(U64& val) {
914  return this->deserializeTo(val);
915 }
916 SerializeStatus LinearBufferBase::deserialize(I64& val) {
917  return this->deserializeTo(val);
918 }
919 #endif
920 SerializeStatus LinearBufferBase::deserialize(F32& val) {
921  return this->deserializeTo(val);
922 }
923 SerializeStatus LinearBufferBase::deserialize(F64& val) {
924  return this->deserializeTo(val);
925 }
926 SerializeStatus LinearBufferBase::deserialize(bool& val) {
927  return this->deserializeTo(val);
928 }
929 SerializeStatus LinearBufferBase::deserialize(void*& val) {
930  return this->deserializeTo(val);
931 }
932 
933 // Deprecated method for backward compatibility
934 SerializeStatus LinearBufferBase::deserialize(U8* buff, FwSizeType& length, bool noLength) {
936  return this->deserializeTo(buff, length, mode);
937 }
938 
939 SerializeStatus LinearBufferBase::deserialize(U8* buff, FwSizeType& length) {
940  return this->deserializeTo(buff, length, Serialization::INCLUDE_LENGTH);
941 }
942 
943 SerializeStatus LinearBufferBase::deserialize(U8* buff, FwSizeType& length, Serialization::t mode) {
944  return this->deserializeTo(buff, length, mode);
945 }
946 
947 SerializeStatus LinearBufferBase::deserialize(Serializable& val) {
948  return this->deserializeTo(val);
949 }
950 SerializeStatus LinearBufferBase::deserialize(LinearBufferBase& val) {
951  return this->deserializeTo(val);
952 }
953 
954 Serializable::SizeType ExternalSerializeBuffer::getBuffCapacity() const {
955  return this->getCapacity();
956 }
957 
958 } // namespace Fw
Serialization/Deserialization operation was successful.
void clear()
Clear external buffer.
void copyFrom(const LinearBufferBase &src)
Copy data from source buffer.
virtual Serializable::SizeType getCapacity() const =0
Get buffer capacity.
Deserialization buffer was empty when trying to read more data.
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
PlatformSizeType FwSizeType
SerializeStatus deserializeSize(FwSizeType &size, Endianness mode=Endianness::BIG) override
Deserialize a size value.
virtual SerializeStatus serializeTo(SerialBufferBase &buffer, Endianness mode=Endianness::BIG) const =0
Serialize the contents of this object to a buffer.
const U8 * getBuffAddrLeft() const
Get address of remaining non-deserialized data.
Serializable::SizeType getSize() const override
Get current buffer size.
Serializable::SizeType m_deserLoc
current offset for deserialization
int8_t I8
8-bit signed integer
Definition: BasicTypes.h:50
No room left in the buffer to serialize data.
virtual U8 * getBuffAddr()=0
Get buffer address for data filling (non-const version)
Serializable::SizeType m_buffSize
size of external buffer
virtual SerializeStatus deserializeFrom(SerialBufferBase &buffer, Endianness mode=Endianness::BIG)=0
Deserialize the contents of this object from a buffer.
LinearBufferBase & operator=(const LinearBufferBase &src)
Copy assignment operator.
Deserialization data had incorrect values (unexpected data types)
SerializeStatus serializeSkip(FwSizeType numBytesToSkip) override
Skip specified number of bytes during serialization.
SerializeStatus copyRaw(SerialBufferBase &dest, Serializable::SizeType size) override
Copy raw bytes from this buffer to destination and advance source offset.
virtual SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG)=0
Serialize an 8-bit unsigned integer value.
SerializeStatus copyRawOffset(SerialBufferBase &dest, Serializable::SizeType size) override
Append raw bytes to destination from this buffer and advance source offset.
SerializeStatus serializeSize(const FwSizeType size, Endianness mode=Endianness::BIG) override
Serialize a size value.
ExternalSerializeBuffer()
Default constructor.
SerializeStatus
forward declaration for string
float F32
32-bit floating point
Definition: BasicTypes.h:83
SerializeStatus deserializeSkip(FwSizeType numBytesToSkip) override
Skip specified number of bytes during deserialization.
U16 FwSizeStoreType
The type used to serialize a size value.
LinearBufferBase()
Default constructor.
virtual ~SerialBufferBase()
Virtual destructor.
Serializable::SizeType getCapacity() const
Get buffer capacity.
Data was the wrong format (e.g. wrong packet type)
U8 * m_buff
pointer to external buffer
Omit length from serialization.
Serializable::SizeType m_serLoc
current offset in buffer of serialized data
Data was left in the buffer, but not enough to deserialize.
Serializable::SizeType getDeserializeSizeLeft() const override
Get remaining deserialization buffer size.
FwSizeType SizeType
Serializable()
Default constructor.
SerializeStatus setBuff(const U8 *src, Serializable::SizeType length) override
Set buffer contents from external source.
void resetDeser() override
Reset deserialization pointer to beginning of buffer.
void resetSer() override
Reset serialization pointer to beginning of buffer.
Serializable::SizeType getCapacity() const override=0
Get buffer capacity.
virtual SerializeStatus setBuff(const U8 *src, Serializable::SizeType length)=0
Set buffer contents from external source.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
SerializeStatus moveSerToOffset(FwSizeType offset) override
Move serialization pointer to specified offset.
static U32 min(const U32 a, const U32 b)
Definition: Checksum.cpp:16
void setExtBuffer(U8 *buffPtr, Serializable::SizeType size)
Set the external buffer.
virtual ~Serializable()
Virtual destructor.
SerializeStatus moveDeserToOffset(FwSizeType offset) override
Move deserialization pointer to specified offset.
double F64
64-bit floating point (double). Required for compiler-supplied double promotion.
Definition: BasicTypes.h:85
Include length as first token in serialization.
SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG) override
Deserialize an 8-bit unsigned integer value.
Little endian serialization.
SerializeStatus setBuffLen(Serializable::SizeType length) override
Set buffer length manually.
Implementation of malloc based allocator.
Endianness
virtual Serializable::SizeType getSize() const =0
Get current buffer size.
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Serializable::SizeType getSerializeSizeLeft() const override
Get remaining serialization buffer size.
U8 * getBuffAddrSer()
Get address of end of serialization (DANGEROUS!)
virtual ~LinearBufferBase()
Destructor.
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.
Big endian serialization.
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
#define U64(C)
Definition: sha.h:181