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  // 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 
263  Serializable::SizeType size = val.getSize();
264  if (this->m_serLoc + size + static_cast<Serializable::SizeType>(sizeof(FwSizeStoreType)) > this->getCapacity()) {
266  }
267 
268  // First, serialize size
269  SerializeStatus stat = this->serializeFrom(static_cast<FwSizeStoreType>(size), mode);
270  if (stat != FW_SERIALIZE_OK) {
271  return stat;
272  }
273 
274  FW_ASSERT(this->getBuffAddr());
275  FW_ASSERT(val.getBuffAddr());
276  // serialize buffer
277  (void)memcpy(&this->getBuffAddr()[this->m_serLoc], val.getBuffAddr(), static_cast<size_t>(size));
278  this->m_serLoc += size;
279  this->m_deserLoc = 0;
280 
281  return FW_SERIALIZE_OK;
282 }
283 
286  if ((size < std::numeric_limits<FwSizeStoreType>::min()) || (size > std::numeric_limits<FwSizeStoreType>::max())) {
287  status = FW_SERIALIZE_FORMAT_ERROR;
288  }
289  if (status == FW_SERIALIZE_OK) {
290  status = this->serializeFrom(static_cast<FwSizeStoreType>(size), mode);
291  }
292  return status;
293 }
294 
295 // deserialization routines
296 
298  // check for room
299  if (this->getSize() == this->m_deserLoc) {
301  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
303  }
304  // read from current location
305  FW_ASSERT(this->getBuffAddr());
306  val = this->getBuffAddr()[this->m_deserLoc + 0];
307  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
308  return FW_SERIALIZE_OK;
309 }
310 
312  // check for room
313  if (this->getSize() == this->m_deserLoc) {
315  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
317  }
318  // read from current location
319  FW_ASSERT(this->getBuffAddr());
320  val = static_cast<I8>(this->getBuffAddr()[this->m_deserLoc + 0]);
321  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
322  return FW_SERIALIZE_OK;
323 }
324 
325 #if FW_HAS_16_BIT == 1
327  // check for room
328  if (this->getSize() == this->m_deserLoc) {
330  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
332  }
333  // read from current location
334  FW_ASSERT(this->getBuffAddr());
335  switch (mode) {
336  case Endianness::BIG:
337  // MSB first
338  val = static_cast<U16>(((this->getBuffAddr()[this->m_deserLoc + 1]) << 0) |
339  ((this->getBuffAddr()[this->m_deserLoc + 0]) << 8));
340  break;
341  case Endianness::LITTLE:
342  // LSB first
343  val = static_cast<U16>(((this->getBuffAddr()[this->m_deserLoc + 0]) << 0) |
344  ((this->getBuffAddr()[this->m_deserLoc + 1]) << 8));
345  break;
346  default:
347  FW_ASSERT(false);
348  break;
349  }
350  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
351  return FW_SERIALIZE_OK;
352 }
353 
355  U16 unsignVal;
356  SerializeStatus res = deserializeTo(unsignVal, mode);
358  val = static_cast<I16>(unsignVal);
359  }
360  return res;
361 }
362 #endif
363 #if FW_HAS_32_BIT == 1
365  // check for room
366  if (this->getSize() == this->m_deserLoc) {
368  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
370  }
371  // read from current location
372  FW_ASSERT(this->getBuffAddr());
373  switch (mode) {
374  case Endianness::BIG:
375  // MSB first
376  val = (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 0) |
377  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 8) |
378  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 16) |
379  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 24);
380  break;
381  case Endianness::LITTLE:
382  // LSB first
383  val = (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 0) |
384  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 8) |
385  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 16) |
386  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 24);
387  break;
388  default:
389  FW_ASSERT(false);
390  break;
391  }
392  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
393  return FW_SERIALIZE_OK;
394 }
395 
397  U32 unsignVal;
398  SerializeStatus res = deserializeTo(unsignVal, mode);
400  val = static_cast<I32>(unsignVal);
401  }
402  return res;
403 }
404 #endif
405 
406 #if FW_HAS_64_BIT == 1
407 
409  // check for room
410  if (this->getSize() == this->m_deserLoc) {
412  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
414  }
415  // read from current location
416  FW_ASSERT(this->getBuffAddr());
417  switch (mode) {
418  case Endianness::BIG:
419  // MSB first
420  val = (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 0) |
421  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 8) |
422  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 16) |
423  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 24) |
424  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 32) |
425  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 40) |
426  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 48) |
427  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 56);
428  break;
429  case Endianness::LITTLE:
430  // LSB first
431  val = (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 0) |
432  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 8) |
433  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 16) |
434  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 24) |
435  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 32) |
436  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 40) |
437  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 48) |
438  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 56);
439  break;
440  default:
441  FW_ASSERT(false);
442  break;
443  }
444  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
445  return FW_SERIALIZE_OK;
446 }
447 
449  U64 unsignVal;
450  SerializeStatus res = deserializeTo(unsignVal, mode);
452  val = static_cast<I64>(unsignVal);
453  }
454  return res;
455 }
456 #endif
457 
459  // deserialize as 64-bit int to handle endianness
460  U64 tempVal;
461  SerializeStatus stat = this->deserializeTo(tempVal, mode);
462  if (stat != FW_SERIALIZE_OK) {
463  return stat;
464  }
465  // copy to argument
466  (void)memcpy(&val, &tempVal, sizeof(val));
467 
468  return FW_SERIALIZE_OK;
469 }
470 
472  // check for room
473  if (this->getSize() == this->m_deserLoc) {
475  } else if (this->getSize() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(U8))) {
477  }
478  // read from current location
479  FW_ASSERT(this->getBuffAddr());
480  if (FW_SERIALIZE_TRUE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
481  val = true;
482  } else if (FW_SERIALIZE_FALSE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
483  val = false;
484  } else {
486  }
487 
488  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(U8));
489  return FW_SERIALIZE_OK;
490 }
491 
493  // Deserialize as pointer cast, then convert to void*
494  PlatformPointerCastType pointerCastVal = 0;
495  const SerializeStatus stat = this->deserializeTo(pointerCastVal, mode);
496  if (stat == FW_SERIALIZE_OK) {
497  val = reinterpret_cast<void*>(pointerCastVal);
498  }
499  return stat;
500 }
501 
503  // deserialize as 64-bit int to handle endianness
504  U32 tempVal;
505  SerializeStatus stat = this->deserializeTo(tempVal, mode);
506  if (stat != FW_SERIALIZE_OK) {
507  return stat;
508  }
509  (void)memcpy(&val, &tempVal, sizeof(val));
510 
511  return FW_SERIALIZE_OK;
512 }
513 
515  FwSizeType length_in_out = static_cast<FwSizeType>(length);
516  SerializeStatus status = this->deserializeTo(buff, length_in_out, Serialization::INCLUDE_LENGTH, endianMode);
517  length = static_cast<Serializable::SizeType>(length_in_out);
518  return status;
519 }
520 
522  Serializable::SizeType& length,
523  Serialization::t lengthMode,
524  Endianness endianMode) {
525  FW_ASSERT(this->getBuffAddr());
526 
527  if (lengthMode == Serialization::INCLUDE_LENGTH) {
528  FwSizeStoreType storedLength;
529 
530  SerializeStatus stat = this->deserializeTo(storedLength, endianMode);
531 
532  if (stat != FW_SERIALIZE_OK) {
533  return stat;
534  }
535 
536  // make sure it fits
537  if ((storedLength > this->getDeserializeSizeLeft()) or (storedLength > length)) {
539  }
540 
541  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(storedLength));
542 
543  length = static_cast<FwSizeType>(storedLength);
544 
545  } else {
546  // make sure enough is left
547  if (length > this->getDeserializeSizeLeft()) {
549  }
550 
551  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(length));
552  }
553 
554  this->m_deserLoc += static_cast<Serializable::SizeType>(length);
555  return FW_SERIALIZE_OK;
556 }
557 
559  return val.deserializeFrom(*this, mode);
560 }
561 
563  FW_ASSERT(val.getBuffAddr());
565 
566  FwSizeStoreType storedLength;
567 
568  stat = this->deserializeTo(storedLength, mode);
569 
570  if (stat != FW_SERIALIZE_OK) {
571  return stat;
572  }
573 
574  // make sure destination has enough room
575 
576  if ((storedLength > val.getCapacity()) or (storedLength > this->getDeserializeSizeLeft())) {
578  }
579 
580  FW_ASSERT(this->getBuffAddr());
581  (void)memcpy(val.getBuffAddr(), &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(storedLength));
582 
583  stat = val.setBuffLen(storedLength);
584 
585  if (stat != FW_SERIALIZE_OK) {
586  return stat;
587  }
588 
589  this->m_deserLoc += storedLength;
590 
591  return FW_SERIALIZE_OK;
592 }
593 
595  FwSizeStoreType storedSize = 0;
596  Fw::SerializeStatus status = this->deserializeTo(storedSize, mode);
597  if (status == FW_SERIALIZE_OK) {
598  size = static_cast<FwSizeType>(storedSize);
599  }
600  return status;
601 }
602 
604  this->m_deserLoc = 0;
605  this->m_serLoc = 0;
606 }
607 
609  this->m_deserLoc = 0;
610 }
611 
614  // compute new deser loc
615  const FwSizeType newSerLoc = this->m_serLoc + numBytesToSkip;
616  // check for room
617  if (newSerLoc <= this->getCapacity()) {
618  // update deser loc
619  this->m_serLoc = static_cast<Serializable::SizeType>(newSerLoc);
620  } else {
621  status = FW_SERIALIZE_NO_ROOM_LEFT;
622  }
623  return status;
624 }
625 
627  // check for room
628  if (this->getSize() == this->m_deserLoc) {
630  } else if (this->getSize() - this->m_deserLoc < numBytesToSkip) {
632  }
633  // update location in buffer to skip the value
634  this->m_deserLoc += static_cast<Serializable::SizeType>(numBytesToSkip);
635  return FW_SERIALIZE_OK;
636 }
637 
639  // Reset serialization
640  this->resetSer();
641  // Advance to offset
642  return this->serializeSkip(offset);
643 }
645  // Reset deserialization
646  this->resetDeser();
647  // Advance to offset
648  return this->deserializeSkip(offset);
649 }
650 
652  return this->m_serLoc;
653 }
654 
656  if (this->getCapacity() < length) {
658  } else {
659  FW_ASSERT(src);
660  FW_ASSERT(this->getBuffAddr());
661  (void)memcpy(this->getBuffAddr(), src, static_cast<size_t>(length));
662  this->m_serLoc = length;
663  this->m_deserLoc = 0;
664  return FW_SERIALIZE_OK;
665  }
666 }
667 
669  if (this->getCapacity() < length) {
671  } else {
672  this->m_serLoc = length;
673  this->m_deserLoc = 0;
674  return FW_SERIALIZE_OK;
675  }
676 }
677 
679  FW_ASSERT(this->m_serLoc >= this->m_deserLoc, static_cast<FwAssertArgType>(this->m_serLoc),
680  static_cast<FwAssertArgType>(this->m_deserLoc));
681  return this->m_serLoc - this->m_deserLoc;
682 }
683 
685  FW_ASSERT(static_cast<FwAssertArgType>(this->m_serLoc));
686  return this->getCapacity() - this->m_serLoc;
687 }
688 
690  // make sure there is sufficient size in destination
691  if (dest.getCapacity() < size) {
693  }
694  // make sure there is sufficient buffer in source
695  if (this->getDeserializeSizeLeft() < size) {
697  }
698 
699  // otherwise, set destination buffer to data from deserialization pointer plus size
700  SerializeStatus stat = dest.setBuff(&this->getBuffAddr()[this->m_deserLoc], size);
701  if (stat == FW_SERIALIZE_OK) {
702  this->m_deserLoc += size;
703  }
704  return stat;
705 }
706 
708  // make sure there is sufficient size in destination
709  if (dest.getCapacity() < size + dest.getSize()) {
711  }
712  // make sure there is sufficient buffer in source
713  if (this->getDeserializeSizeLeft() < size) {
715  }
716 
717  // otherwise, serialize bytes to destination without writing length
719  if (stat == FW_SERIALIZE_OK) {
720  this->m_deserLoc += size;
721  }
722  return stat;
723 }
724 
725 // return address of buffer not yet deserialized. This is used
726 // to copy the remainder of a buffer.
728  return &this->getBuffAddr()[this->m_deserLoc];
729 }
730 
733  return &this->getBuffAddr()[this->m_serLoc];
734 }
735 
736 #ifdef BUILD_UT
737 bool LinearBufferBase::operator==(const SerializeBufferBase& other) const {
738  if (this->getSize() != other.getSize()) {
739  return false;
740  }
741 
742  const U8* us = this->getBuffAddr();
743  const U8* them = other.getBuffAddr();
744 
745  FW_ASSERT(us);
746  FW_ASSERT(them);
747 
748  for (Serializable::SizeType byte = 0; byte < this->getSize(); byte++) {
749  if (us[byte] != them[byte]) {
750  return false;
751  }
752  }
753 
754  return true;
755 }
756 
757 std::ostream& operator<<(std::ostream& os, const LinearBufferBase& buff) {
758  const U8* us = buff.getBuffAddr();
759 
760  FW_ASSERT(us);
761 
762  for (Serializable::SizeType byte = 0; byte < buff.getSize(); byte++) {
763  os << "[" << std::setw(2) << std::hex << std::setfill('0') << us[byte] << "]" << std::dec;
764  }
765 
766  return os;
767 }
768 #endif
769 
771  this->setExtBuffer(buffPtr, size);
772 }
773 
775  this->clear();
776 }
777 
779  FW_ASSERT(buffPtr != nullptr);
780  this->clear();
781  this->m_buff = buffPtr;
782  this->m_buffSize = size;
783 }
784 
786  this->resetSer();
787  this->resetDeser();
788  this->m_buff = nullptr;
789  this->m_buffSize = 0;
790 }
791 
793  return this->m_buffSize;
794 }
795 
797  return this->m_buff;
798 }
799 
801  return this->m_buff;
802 }
803 
804 // ----------------------------------------------------------------------
805 // Deprecated method implementations for backward compatibility
806 // ----------------------------------------------------------------------
807 
808 Serializable::SizeType LinearBufferBase::getBuffLength() const {
809  return this->getSize();
810 }
811 
812 Serializable::SizeType LinearBufferBase::getBuffLeft() {
813  return this->getDeserializeSizeLeft();
814 }
815 
816 SerializeStatus LinearBufferBase::serialize(U8 val) {
817  return this->serializeFrom(val);
818 }
819 SerializeStatus LinearBufferBase::serialize(I8 val) {
820  return this->serializeFrom(val);
821 }
822 #if FW_HAS_16_BIT == 1
823 SerializeStatus LinearBufferBase::serialize(U16 val) {
824  return this->serializeFrom(val);
825 }
826 SerializeStatus LinearBufferBase::serialize(I16 val) {
827  return this->serializeFrom(val);
828 }
829 #endif
830 #if FW_HAS_32_BIT == 1
831 SerializeStatus LinearBufferBase::serialize(U32 val) {
832  return this->serializeFrom(val);
833 }
834 SerializeStatus LinearBufferBase::serialize(I32 val) {
835  return this->serializeFrom(val);
836 }
837 #endif
838 #if FW_HAS_64_BIT == 1
839 SerializeStatus LinearBufferBase::serialize(U64 val) {
840  return this->serializeFrom(val);
841 }
842 SerializeStatus LinearBufferBase::serialize(I64 val) {
843  return this->serializeFrom(val);
844 }
845 #endif
846 SerializeStatus LinearBufferBase::serialize(F32 val) {
847  return this->serializeFrom(val);
848 }
849 SerializeStatus LinearBufferBase::serialize(F64 val) {
850  return this->serializeFrom(val);
851 }
852 SerializeStatus LinearBufferBase::serialize(bool val) {
853  return this->serializeFrom(val);
854 }
855 SerializeStatus LinearBufferBase::serialize(const void* val) {
856  return this->serializeFrom(val);
857 }
858 
859 // Deprecated method for backward compatibility
860 SerializeStatus LinearBufferBase::serialize(const U8* buff, FwSizeType length, bool noLength) {
862  return this->serializeFrom(buff, length, mode);
863 }
864 
865 SerializeStatus LinearBufferBase::serialize(const U8* buff, FwSizeType length) {
866  return this->serializeFrom(buff, length);
867 }
868 SerializeStatus LinearBufferBase::serialize(const U8* buff, FwSizeType length, Serialization::t mode) {
869  return this->serializeFrom(buff, length, mode);
870 }
871 SerializeStatus LinearBufferBase::serialize(const Serializable& val) {
872  return this->serializeFrom(val);
873 }
874 SerializeStatus LinearBufferBase::serialize(const LinearBufferBase& val) {
875  return this->serializeFrom(val);
876 }
877 
878 SerializeStatus LinearBufferBase::deserialize(U8& val) {
879  return this->deserializeTo(val);
880 }
881 SerializeStatus LinearBufferBase::deserialize(I8& val) {
882  return this->deserializeTo(val);
883 }
884 #if FW_HAS_16_BIT == 1
885 SerializeStatus LinearBufferBase::deserialize(U16& val) {
886  return this->deserializeTo(val);
887 }
888 SerializeStatus LinearBufferBase::deserialize(I16& val) {
889  return this->deserializeTo(val);
890 }
891 #endif
892 #if FW_HAS_32_BIT == 1
893 SerializeStatus LinearBufferBase::deserialize(U32& val) {
894  return this->deserializeTo(val);
895 }
896 SerializeStatus LinearBufferBase::deserialize(I32& val) {
897  return this->deserializeTo(val);
898 }
899 #endif
900 #if FW_HAS_64_BIT == 1
901 SerializeStatus LinearBufferBase::deserialize(U64& val) {
902  return this->deserializeTo(val);
903 }
904 SerializeStatus LinearBufferBase::deserialize(I64& val) {
905  return this->deserializeTo(val);
906 }
907 #endif
908 SerializeStatus LinearBufferBase::deserialize(F32& val) {
909  return this->deserializeTo(val);
910 }
911 SerializeStatus LinearBufferBase::deserialize(F64& val) {
912  return this->deserializeTo(val);
913 }
914 SerializeStatus LinearBufferBase::deserialize(bool& val) {
915  return this->deserializeTo(val);
916 }
917 SerializeStatus LinearBufferBase::deserialize(void*& val) {
918  return this->deserializeTo(val);
919 }
920 
921 // Deprecated method for backward compatibility
922 SerializeStatus LinearBufferBase::deserialize(U8* buff, FwSizeType& length, bool noLength) {
924  return this->deserializeTo(buff, length, mode);
925 }
926 
927 SerializeStatus LinearBufferBase::deserialize(U8* buff, FwSizeType& length) {
928  return this->deserializeTo(buff, length, Serialization::INCLUDE_LENGTH);
929 }
930 
931 SerializeStatus LinearBufferBase::deserialize(U8* buff, FwSizeType& length, Serialization::t mode) {
932  return this->deserializeTo(buff, length, mode);
933 }
934 
935 SerializeStatus LinearBufferBase::deserialize(Serializable& val) {
936  return this->deserializeTo(val);
937 }
938 SerializeStatus LinearBufferBase::deserialize(LinearBufferBase& val) {
939  return this->deserializeTo(val);
940 }
941 
942 Serializable::SizeType ExternalSerializeBuffer::getBuffCapacity() const {
943  return this->getCapacity();
944 }
945 
946 } // 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