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 namespace Fw {
13 
15 
17 
18 // ----------------------------------------------------------------------
19 #if FW_SERIALIZABLE_TO_STRING || FW_ENABLE_TEXT_LOGGING || BUILD_UT
20 
21 void Serializable::toString(StringBase& text) const {
22  text = "NOSPEC"; // set to not specified.
23 }
24 
25 #endif
26 
27 #ifdef BUILD_UT
28 std::ostream& operator<<(std::ostream& os, const Serializable& val) {
29  Fw::String out;
30  val.toString(out);
31 
32  os << out;
33 
34  return os;
35 }
36 #endif
37 
39 
41  : m_buffAddr(buffAddr), m_capacity(capacity), m_serLoc(0), m_deserLoc(0) {
42  // Ensure buffAddr & capacity are consistent
43  FW_ASSERT((buffAddr == nullptr) == (capacity == 0), static_cast<FwAssertArgType>(capacity));
44 }
45 
47 
49  this->m_serLoc = src.m_serLoc;
50  this->m_deserLoc = src.m_deserLoc;
51  const U8* srcBuffAddr = src.m_buffAddr;
52  U8* thisBuffAddr = this->m_buffAddr;
53  FW_ASSERT(srcBuffAddr != nullptr);
54  FW_ASSERT(thisBuffAddr != nullptr);
55  // destination has to be same or bigger
56  FW_ASSERT(src.m_serLoc <= this->m_capacity, static_cast<FwAssertArgType>(src.m_serLoc),
57  static_cast<FwAssertArgType>(this->m_capacity));
58  (void)memcpy(thisBuffAddr, srcBuffAddr, static_cast<size_t>(this->m_serLoc));
59 }
60 
61 // Copy constructor doesn't make sense in this virtual class as there is nothing to copy. Derived classes should
62 // call the empty constructor and then call their own copy function
63 LinearBufferBase& LinearBufferBase::operator=(const LinearBufferBase& src) { // lgtm[cpp/rule-of-two]
64  this->copyFrom(src);
65  return *this;
66 }
67 
68 // serialization routines
69 
71  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->m_capacity) {
73  }
74  U8* buffAddr = this->m_buffAddr;
75  FW_ASSERT(buffAddr != nullptr);
76  buffAddr[this->m_serLoc] = val;
77  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
78  this->m_deserLoc = 0;
79 
80  return FW_SERIALIZE_OK;
81 }
82 
84  return serializeFrom(static_cast<U8>(val), mode);
85 }
86 
87 #if FW_HAS_16_BIT == 1
89  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->m_capacity) {
91  }
92  U8* buffAddr = this->m_buffAddr;
93  FW_ASSERT(buffAddr != nullptr);
94  switch (mode) {
95  case Endianness::BIG:
96  // MSB first
97  buffAddr[this->m_serLoc + 0] = static_cast<U8>(val >> 8);
98  buffAddr[this->m_serLoc + 1] = static_cast<U8>(val);
99  break;
100  case Endianness::LITTLE:
101  // LSB first
102  buffAddr[this->m_serLoc + 0] = static_cast<U8>(val);
103  buffAddr[this->m_serLoc + 1] = static_cast<U8>(val >> 8);
104  break;
105  default:
106  FW_ASSERT(false);
107  break;
108  }
109  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
110  this->m_deserLoc = 0;
111  return FW_SERIALIZE_OK;
112 }
113 
115  return serializeFrom(static_cast<U16>(val), mode);
116 }
117 #endif
118 #if FW_HAS_32_BIT == 1
120  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->m_capacity) {
122  }
123  U8* buffAddr = this->m_buffAddr;
124  FW_ASSERT(buffAddr != nullptr);
125  switch (mode) {
126  case Endianness::BIG:
127  // MSB first
128  buffAddr[this->m_serLoc + 0] = static_cast<U8>(val >> 24);
129  buffAddr[this->m_serLoc + 1] = static_cast<U8>(val >> 16);
130  buffAddr[this->m_serLoc + 2] = static_cast<U8>(val >> 8);
131  buffAddr[this->m_serLoc + 3] = static_cast<U8>(val);
132  break;
133  case Endianness::LITTLE:
134  // LSB first
135  buffAddr[this->m_serLoc + 0] = static_cast<U8>(val);
136  buffAddr[this->m_serLoc + 1] = static_cast<U8>(val >> 8);
137  buffAddr[this->m_serLoc + 2] = static_cast<U8>(val >> 16);
138  buffAddr[this->m_serLoc + 3] = static_cast<U8>(val >> 24);
139  break;
140  default:
141  FW_ASSERT(false);
142  break;
143  }
144  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
145  this->m_deserLoc = 0;
146  return FW_SERIALIZE_OK;
147 }
148 
150  return serializeFrom(static_cast<U32>(val), mode);
151 }
152 #endif
153 
154 #if FW_HAS_64_BIT == 1
156  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->m_capacity) {
158  }
159  U8* buffAddr = this->m_buffAddr;
160  FW_ASSERT(buffAddr != nullptr);
161  switch (mode) {
162  case Endianness::BIG:
163  // MSB first
164  buffAddr[this->m_serLoc + 0] = static_cast<U8>(val >> 56);
165  buffAddr[this->m_serLoc + 1] = static_cast<U8>(val >> 48);
166  buffAddr[this->m_serLoc + 2] = static_cast<U8>(val >> 40);
167  buffAddr[this->m_serLoc + 3] = static_cast<U8>(val >> 32);
168  buffAddr[this->m_serLoc + 4] = static_cast<U8>(val >> 24);
169  buffAddr[this->m_serLoc + 5] = static_cast<U8>(val >> 16);
170  buffAddr[this->m_serLoc + 6] = static_cast<U8>(val >> 8);
171  buffAddr[this->m_serLoc + 7] = static_cast<U8>(val);
172  break;
173  case Endianness::LITTLE:
174  // LSB first
175  buffAddr[this->m_serLoc + 0] = static_cast<U8>(val);
176  buffAddr[this->m_serLoc + 1] = static_cast<U8>(val >> 8);
177  buffAddr[this->m_serLoc + 2] = static_cast<U8>(val >> 16);
178  buffAddr[this->m_serLoc + 3] = static_cast<U8>(val >> 24);
179  buffAddr[this->m_serLoc + 4] = static_cast<U8>(val >> 32);
180  buffAddr[this->m_serLoc + 5] = static_cast<U8>(val >> 40);
181  buffAddr[this->m_serLoc + 6] = static_cast<U8>(val >> 48);
182  buffAddr[this->m_serLoc + 7] = static_cast<U8>(val >> 56);
183  break;
184  default:
185  FW_ASSERT(false);
186  break;
187  }
188  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
189  this->m_deserLoc = 0;
190  return FW_SERIALIZE_OK;
191 }
192 
194  return serializeFrom(static_cast<U64>(val), mode);
195 }
196 #endif
197 
199  // floating point values need to be byte-swapped as well, so copy to U64 and use that routine
200  U64 u64Val;
201  (void)memcpy(&u64Val, &val, sizeof(val));
202  return this->serializeFrom(u64Val, mode);
203 }
204 
206  // floating point values need to be byte-swapped as well, so copy to U32 and use that routine
207  U32 u32Val;
208  (void)memcpy(&u32Val, &val, sizeof(val));
209  return this->serializeFrom(u32Val, mode);
210 }
211 
213  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(U8)) - 1 >= this->m_capacity) {
215  }
216 
217  U8* buffAddr = this->m_buffAddr;
218  FW_ASSERT(buffAddr != nullptr);
219  if (val) {
220  buffAddr[this->m_serLoc + 0] = FW_SERIALIZE_TRUE_VALUE;
221  } else {
222  buffAddr[this->m_serLoc + 0] = FW_SERIALIZE_FALSE_VALUE;
223  }
224 
225  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(U8));
226  this->m_deserLoc = 0;
227  return FW_SERIALIZE_OK;
228 }
229 
231  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(void*)) - 1 >= this->m_capacity) {
233  }
234 
235  return this->serializeFrom(reinterpret_cast<PlatformPointerCastType>(val), mode);
236 }
237 
239  Serializable::SizeType length,
240  Endianness endianMode) {
241  return this->serializeFrom(buff, static_cast<FwSizeType>(length), Serialization::INCLUDE_LENGTH, endianMode);
242 }
243 
246  FwSizeType length,
247  Serialization::t lengthMode,
248  Endianness endianMode) { // First serialize length
249  SerializeStatus stat;
250  if (lengthMode == Serialization::INCLUDE_LENGTH) {
251  stat = this->serializeFrom(static_cast<FwSizeStoreType>(length), endianMode);
252  if (stat != FW_SERIALIZE_OK) {
253  return stat;
254  }
255  }
256 
257  // make sure we have enough space
258  if (this->m_serLoc + length > this->m_capacity) {
260  }
261 
262  if (length > 0) {
263  FW_ASSERT(buff != nullptr);
264  }
265  U8* buffAddr = this->m_buffAddr;
266  FW_ASSERT(buffAddr != nullptr);
267  // copy buffer to our buffer; memmove is used because the source may overlap this buffer
268  (void)memmove(&buffAddr[this->m_serLoc], buff, static_cast<size_t>(length));
269  this->m_serLoc += static_cast<Serializable::SizeType>(length);
270  this->m_deserLoc = 0;
271 
272  return FW_SERIALIZE_OK;
273 }
274 
276  Endianness mode) {
277  return val.serializeTo(*this, mode);
278 }
279 
281  Endianness mode) {
282  Serializable::SizeType size = val.getSize();
283  if (this->m_serLoc + size + static_cast<Serializable::SizeType>(sizeof(FwSizeStoreType)) > this->m_capacity) {
285  }
286 
287  // First, serialize size
288  SerializeStatus stat = this->serializeFrom(static_cast<FwSizeStoreType>(size), mode);
289  if (stat != FW_SERIALIZE_OK) {
290  return stat;
291  }
292 
293  U8* thisBuffAddr = this->m_buffAddr;
294  const U8* valBuffAddr = val.getBuffAddr();
295  FW_ASSERT(thisBuffAddr != nullptr);
296  FW_ASSERT(valBuffAddr != nullptr);
297  // serialize buffer
298  (void)memcpy(&thisBuffAddr[this->m_serLoc], valBuffAddr, static_cast<size_t>(size));
299  this->m_serLoc += size;
300  this->m_deserLoc = 0;
301 
302  return FW_SERIALIZE_OK;
303 }
304 
307  if ((size < std::numeric_limits<FwSizeStoreType>::min()) || (size > std::numeric_limits<FwSizeStoreType>::max())) {
308  status = FW_SERIALIZE_FORMAT_ERROR;
309  }
310  if (status == FW_SERIALIZE_OK) {
311  status = this->serializeFrom(static_cast<FwSizeStoreType>(size), mode);
312  }
313  return status;
314 }
315 
316 // deserialization routines
317 
319  // check for room
320  const Serializable::SizeType size = this->m_serLoc;
321  if (size == this->m_deserLoc) {
323  } else if (size - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
325  }
326  // read from current location
327  U8* buffAddr = this->m_buffAddr;
328  FW_ASSERT(buffAddr != nullptr);
329  val = buffAddr[this->m_deserLoc + 0];
330  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
331  return FW_SERIALIZE_OK;
332 }
333 
335  // check for room
336  const Serializable::SizeType size = this->m_serLoc;
337  if (size == this->m_deserLoc) {
339  } else if (size - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
341  }
342  // read from current location
343  U8* buffAddr = this->m_buffAddr;
344  FW_ASSERT(buffAddr != nullptr);
345  val = static_cast<I8>(buffAddr[this->m_deserLoc + 0]);
346  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
347  return FW_SERIALIZE_OK;
348 }
349 
350 #if FW_HAS_16_BIT == 1
352  // check for room
353  const Serializable::SizeType size = this->m_serLoc;
354  if (size == this->m_deserLoc) {
356  } else if (size - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
358  }
359  // read from current location
360  U8* buffAddr = this->m_buffAddr;
361  FW_ASSERT(buffAddr != nullptr);
362  switch (mode) {
363  case Endianness::BIG:
364  // MSB first
365  val = static_cast<U16>(((buffAddr[this->m_deserLoc + 1]) << 0) | ((buffAddr[this->m_deserLoc + 0]) << 8));
366  break;
367  case Endianness::LITTLE:
368  // LSB first
369  val = static_cast<U16>(((buffAddr[this->m_deserLoc + 0]) << 0) | ((buffAddr[this->m_deserLoc + 1]) << 8));
370  break;
371  default:
372  FW_ASSERT(false);
373  break;
374  }
375  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
376  return FW_SERIALIZE_OK;
377 }
378 
380  U16 unsignVal = 0;
381  SerializeStatus res = deserializeTo(unsignVal, mode);
383  val = static_cast<I16>(unsignVal);
384  }
385  return res;
386 }
387 #endif
388 #if FW_HAS_32_BIT == 1
390  // check for room
391  const Serializable::SizeType size = this->m_serLoc;
392  if (size == this->m_deserLoc) {
394  } else if (size - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
396  }
397  // read from current location
398  U8* buffAddr = this->m_buffAddr;
399  FW_ASSERT(buffAddr != nullptr);
400  switch (mode) {
401  case Endianness::BIG:
402  // MSB first
403  val = (static_cast<U32>(buffAddr[this->m_deserLoc + 3]) << 0) |
404  (static_cast<U32>(buffAddr[this->m_deserLoc + 2]) << 8) |
405  (static_cast<U32>(buffAddr[this->m_deserLoc + 1]) << 16) |
406  (static_cast<U32>(buffAddr[this->m_deserLoc + 0]) << 24);
407  break;
408  case Endianness::LITTLE:
409  // LSB first
410  val = (static_cast<U32>(buffAddr[this->m_deserLoc + 0]) << 0) |
411  (static_cast<U32>(buffAddr[this->m_deserLoc + 1]) << 8) |
412  (static_cast<U32>(buffAddr[this->m_deserLoc + 2]) << 16) |
413  (static_cast<U32>(buffAddr[this->m_deserLoc + 3]) << 24);
414  break;
415  default:
416  FW_ASSERT(false);
417  break;
418  }
419  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
420  return FW_SERIALIZE_OK;
421 }
422 
424  U32 unsignVal = 0;
425  SerializeStatus res = deserializeTo(unsignVal, mode);
427  val = static_cast<I32>(unsignVal);
428  }
429  return res;
430 }
431 #endif
432 
433 #if FW_HAS_64_BIT == 1
434 
436  // check for room
437  if (this->m_serLoc == this->m_deserLoc) {
439  } else if (this->m_serLoc - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
441  }
442  // read from current location
443  U8* buffAddr = this->m_buffAddr;
444  FW_ASSERT(buffAddr != nullptr);
445  switch (mode) {
446  case Endianness::BIG:
447  // MSB first
448  val = (static_cast<U64>(buffAddr[this->m_deserLoc + 7]) << 0) |
449  (static_cast<U64>(buffAddr[this->m_deserLoc + 6]) << 8) |
450  (static_cast<U64>(buffAddr[this->m_deserLoc + 5]) << 16) |
451  (static_cast<U64>(buffAddr[this->m_deserLoc + 4]) << 24) |
452  (static_cast<U64>(buffAddr[this->m_deserLoc + 3]) << 32) |
453  (static_cast<U64>(buffAddr[this->m_deserLoc + 2]) << 40) |
454  (static_cast<U64>(buffAddr[this->m_deserLoc + 1]) << 48) |
455  (static_cast<U64>(buffAddr[this->m_deserLoc + 0]) << 56);
456  break;
457  case Endianness::LITTLE:
458  // LSB first
459  val = (static_cast<U64>(buffAddr[this->m_deserLoc + 0]) << 0) |
460  (static_cast<U64>(buffAddr[this->m_deserLoc + 1]) << 8) |
461  (static_cast<U64>(buffAddr[this->m_deserLoc + 2]) << 16) |
462  (static_cast<U64>(buffAddr[this->m_deserLoc + 3]) << 24) |
463  (static_cast<U64>(buffAddr[this->m_deserLoc + 4]) << 32) |
464  (static_cast<U64>(buffAddr[this->m_deserLoc + 5]) << 40) |
465  (static_cast<U64>(buffAddr[this->m_deserLoc + 6]) << 48) |
466  (static_cast<U64>(buffAddr[this->m_deserLoc + 7]) << 56);
467  break;
468  default:
469  FW_ASSERT(false);
470  break;
471  }
472  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
473  return FW_SERIALIZE_OK;
474 }
475 
477  U64 unsignVal;
478  SerializeStatus res = deserializeTo(unsignVal, mode);
480  val = static_cast<I64>(unsignVal);
481  }
482  return res;
483 }
484 #endif
485 
487  // deserialize as 64-bit int to handle endianness
488  U64 tempVal;
489  SerializeStatus stat = this->deserializeTo(tempVal, mode);
490  if (stat != FW_SERIALIZE_OK) {
491  return stat;
492  }
493  // copy to argument
494  (void)memcpy(&val, &tempVal, sizeof(val));
495 
496  return FW_SERIALIZE_OK;
497 }
498 
500  // check for room
501  const Serializable::SizeType size = this->m_serLoc;
502  if (size == this->m_deserLoc) {
504  } else if (size - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(U8))) {
506  }
507  // read from current location
508  U8* buffAddr = this->m_buffAddr;
509  FW_ASSERT(buffAddr != nullptr);
510  const U8 byteVal = buffAddr[this->m_deserLoc + 0];
511  if (FW_SERIALIZE_TRUE_VALUE == byteVal) {
512  val = true;
513  } else if (FW_SERIALIZE_FALSE_VALUE == byteVal) {
514  val = false;
515  } else {
517  }
518 
519  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(U8));
520  return FW_SERIALIZE_OK;
521 }
522 
524  // Deserialize as pointer cast, then convert to void*
525  PlatformPointerCastType pointerCastVal = 0;
526  const SerializeStatus stat = this->deserializeTo(pointerCastVal, mode);
527  if (stat == FW_SERIALIZE_OK) {
528  val = reinterpret_cast<void*>(pointerCastVal);
529  }
530  return stat;
531 }
532 
534  // deserialize as 32-bit int to handle endianness
535  U32 tempVal = 0;
536  SerializeStatus stat = this->deserializeTo(tempVal, mode);
537  if (stat != FW_SERIALIZE_OK) {
538  return stat;
539  }
540  (void)memcpy(&val, &tempVal, sizeof(val));
541 
542  return FW_SERIALIZE_OK;
543 }
544 
546  Serializable::SizeType& length,
547  Endianness endianMode) {
548  FwSizeType length_in_out = static_cast<FwSizeType>(length);
549  SerializeStatus status = this->deserializeTo(buff, length_in_out, Serialization::INCLUDE_LENGTH, endianMode);
550  length = static_cast<Serializable::SizeType>(length_in_out);
551  return status;
552 }
553 
555  Serializable::SizeType& length,
556  Serialization::t lengthMode,
557  Endianness endianMode) {
558  U8* buffAddr = this->m_buffAddr;
559  FW_ASSERT(buffAddr != nullptr);
560 
561  if (lengthMode == Serialization::INCLUDE_LENGTH) {
562  FwSizeStoreType storedLength = 0;
563 
564  SerializeStatus stat = this->deserializeTo(storedLength, endianMode);
565 
566  if (stat != FW_SERIALIZE_OK) {
567  return stat;
568  }
569 
570  // make sure it fits
571  if ((storedLength > this->getDeserializeSizeLeft()) || (storedLength > length)) {
573  }
574 
575  if (storedLength > 0) {
576  FW_ASSERT(buff != nullptr);
577  }
578  (void)memcpy(buff, &buffAddr[this->m_deserLoc], static_cast<size_t>(storedLength));
579 
580  length = static_cast<FwSizeType>(storedLength);
581 
582  } else {
583  // make sure enough is left
584  if (length > this->getDeserializeSizeLeft()) {
586  }
587 
588  if (length > 0) {
589  FW_ASSERT(buff != nullptr);
590  }
591  (void)memcpy(buff, &buffAddr[this->m_deserLoc], static_cast<size_t>(length));
592  }
593 
594  this->m_deserLoc += static_cast<Serializable::SizeType>(length);
595  return FW_SERIALIZE_OK;
596 }
597 
599  return val.deserializeFrom(*this, mode);
600 }
601 
603  U8* valBuffAddr = val.getBuffAddr();
604  FW_ASSERT(valBuffAddr != nullptr);
606 
607  FwSizeStoreType storedLength = 0;
608 
609  stat = this->deserializeTo(storedLength, mode);
610 
611  if (stat != FW_SERIALIZE_OK) {
612  return stat;
613  }
614 
615  // make sure destination has enough room
616 
617  if ((storedLength > val.getCapacity()) || (storedLength > this->getDeserializeSizeLeft())) {
619  }
620 
621  U8* thisBuffAddr = this->m_buffAddr;
622  FW_ASSERT(thisBuffAddr != nullptr);
623  (void)memcpy(valBuffAddr, &thisBuffAddr[this->m_deserLoc], static_cast<size_t>(storedLength));
624 
625  stat = val.setBuffLen(storedLength);
626 
627  if (stat != FW_SERIALIZE_OK) {
628  return stat;
629  }
630 
631  this->m_deserLoc += storedLength;
632 
633  return FW_SERIALIZE_OK;
634 }
635 
637  FwSizeStoreType storedSize = 0;
638  Fw::SerializeStatus status = this->deserializeTo(storedSize, mode);
639  if (status == FW_SERIALIZE_OK) {
640  size = static_cast<FwSizeType>(storedSize);
641  }
642  return status;
643 }
644 
646  this->m_deserLoc = 0;
647  this->m_serLoc = 0;
648 }
649 
651  this->m_deserLoc = 0;
652 }
653 
656  // compute new ser loc
657  const FwSizeType newSerLoc = this->m_serLoc + numBytesToSkip;
658  // check for room
659  if (newSerLoc <= this->m_capacity) {
660  // update ser loc
661  this->m_serLoc = static_cast<Serializable::SizeType>(newSerLoc);
662  } else {
663  status = FW_SERIALIZE_NO_ROOM_LEFT;
664  }
665  return status;
666 }
667 
669  // check for room
670  const Serializable::SizeType size = this->m_serLoc;
671  if (size == this->m_deserLoc) {
673  } else if (size - this->m_deserLoc < numBytesToSkip) {
675  }
676  // update location in buffer to skip the value
677  this->m_deserLoc += static_cast<Serializable::SizeType>(numBytesToSkip);
678  return FW_SERIALIZE_OK;
679 }
680 
682  // Reset serialization
683  this->resetSer();
684  // Advance to offset
685  return this->serializeSkip(offset);
686 }
688  // Reset deserialization
689  this->resetDeser();
690  // Advance to offset
691  return this->deserializeSkip(offset);
692 }
693 
695  return this->m_serLoc;
696 }
697 
699  if (this->m_capacity < length) {
701  } else {
702  FW_ASSERT(src);
703  U8* buffAddr = this->m_buffAddr;
704  FW_ASSERT(buffAddr != nullptr);
705  (void)memcpy(buffAddr, src, static_cast<size_t>(length));
706  this->m_serLoc = length;
707  this->m_deserLoc = 0;
708  return FW_SERIALIZE_OK;
709  }
710 }
711 
713  if (this->m_capacity < length) {
715  } else {
716  this->m_serLoc = length;
717  this->m_deserLoc = 0;
718  return FW_SERIALIZE_OK;
719  }
720 }
721 
723  FW_ASSERT(this->m_serLoc >= this->m_deserLoc, static_cast<FwAssertArgType>(this->m_serLoc),
724  static_cast<FwAssertArgType>(this->m_deserLoc));
725  return this->m_serLoc - this->m_deserLoc;
726 }
727 
729  FW_ASSERT(this->m_capacity >= this->m_serLoc, static_cast<FwAssertArgType>(this->m_capacity),
730  static_cast<FwAssertArgType>(this->m_serLoc));
731  return this->m_capacity - this->m_serLoc;
732 }
733 
735  Serializable::SizeType size) {
736  // make sure there is sufficient size in destination
737  if (dest.getCapacity() < size) {
739  }
740  // make sure there is sufficient buffer in source
741  if (this->getDeserializeSizeLeft() < size) {
743  }
744 
745  // otherwise, set destination buffer to data from deserialization pointer plus size
746  U8* buffAddr = this->m_buffAddr;
747 
748  FW_ASSERT(buffAddr);
749  SerializeStatus stat = dest.setBuff(&buffAddr[this->m_deserLoc], size);
750  if (stat == FW_SERIALIZE_OK) {
751  this->m_deserLoc += size;
752  }
753  return stat;
754 }
755 
757  Serializable::SizeType size) {
758  // make sure there is sufficient size in destination
759  const Serializable::SizeType destCapacity = dest.getCapacity();
760  const Serializable::SizeType destSize = dest.getSize();
761  if (destCapacity < size + destSize) {
763  }
764  // make sure there is sufficient buffer in source
765  if (this->getDeserializeSizeLeft() < size) {
767  }
768 
769  // otherwise, serialize bytes to destination without writing length
770  U8* buffAddr = this->m_buffAddr;
771  SerializeStatus stat = dest.serializeFrom(&buffAddr[this->m_deserLoc], size, Serialization::OMIT_LENGTH);
772  if (stat == FW_SERIALIZE_OK) {
773  this->m_deserLoc += size;
774  }
775  return stat;
776 }
777 
778 // return address of buffer not yet deserialized. This is used
779 // to copy the remainder of a buffer.
781  const U8* buffAddr = this->m_buffAddr;
782  FW_ASSERT(buffAddr != nullptr);
783  return &buffAddr[this->m_deserLoc];
784 }
785 
788  U8* buffAddr = this->m_buffAddr;
789  FW_ASSERT(buffAddr != nullptr);
790  return &buffAddr[this->m_serLoc];
791 }
792 
793 #ifdef BUILD_UT
794 bool LinearBufferBase::operator==(const LinearBufferBase& other) const {
795  if (this->m_serLoc != other.getSize()) {
796  return false;
797  }
798 
799  const U8* us = this->m_buffAddr;
800  const U8* them = other.getBuffAddr();
801 
802  FW_ASSERT(us);
803  FW_ASSERT(them);
804 
805  for (Serializable::SizeType byte = 0; byte < this->m_serLoc; byte++) {
806  if (us[byte] != them[byte]) {
807  return false;
808  }
809  }
810 
811  return true;
812 }
813 
814 std::ostream& operator<<(std::ostream& os, const LinearBufferBase& buff) {
815  const U8* us = buff.getBuffAddr();
816 
817  FW_ASSERT(us);
818 
819  for (Serializable::SizeType byte = 0; byte < buff.getSize(); byte++) {
820  os << "[" << std::setw(2) << std::hex << std::setfill('0') << us[byte] << "]" << std::dec;
821  }
822 
823  return os;
824 }
825 #endif
826 
828  : LinearBufferBase(nullptr, 0) {
829  this->setExtBuffer(buffPtr, size);
830 }
831 
833  this->clear();
834 }
835 
837  // Allow setting buffer with null pointer and zero size (for initialization/reset)
838  // but reject null pointer with non-zero size
839  FW_ASSERT((buffPtr != nullptr) || (size == 0), static_cast<FwAssertArgType>(size));
840  this->clear();
841  this->setBuffAddrInternal(buffPtr);
842  this->setCapacityInternal(size);
843 }
844 
846  this->resetSer();
847  this->resetDeser();
848  this->setBuffAddrInternal(nullptr);
849  this->setCapacityInternal(0);
850 }
851 
852 // ----------------------------------------------------------------------
853 // Deprecated method implementations for backward compatibility
854 // ----------------------------------------------------------------------
855 
856 Serializable::SizeType LinearBufferBase::getBuffLength() const {
857  return this->m_serLoc;
858 }
859 
860 Serializable::SizeType LinearBufferBase::getBuffLeft() {
861  return this->getDeserializeSizeLeft();
862 }
863 
864 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(U8 val) {
865  return this->serializeFrom(val);
866 }
867 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(I8 val) {
868  return this->serializeFrom(val);
869 }
870 #if FW_HAS_16_BIT == 1
871 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(U16 val) {
872  return this->serializeFrom(val);
873 }
874 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(I16 val) {
875  return this->serializeFrom(val);
876 }
877 #endif
878 #if FW_HAS_32_BIT == 1
879 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(U32 val) {
880  return this->serializeFrom(val);
881 }
882 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(I32 val) {
883  return this->serializeFrom(val);
884 }
885 #endif
886 #if FW_HAS_64_BIT == 1
887 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(U64 val) {
888  return this->serializeFrom(val);
889 }
890 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(I64 val) {
891  return this->serializeFrom(val);
892 }
893 #endif
894 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(F32 val) {
895  return this->serializeFrom(val);
896 }
897 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(F64 val) {
898  return this->serializeFrom(val);
899 }
900 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(bool val) {
901  return this->serializeFrom(val);
902 }
903 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(const void* val) {
904  return this->serializeFrom(val);
905 }
906 
907 // Deprecated method for backward compatibility
908 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(const U8* buff,
909  FwSizeType length,
910  bool noLength) {
912  return this->serializeFrom(buff, length, mode);
913 }
914 
915 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(const U8* buff, FwSizeType length) {
916  return this->serializeFrom(buff, length);
917 }
918 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(const U8* buff,
919  FwSizeType length,
920  Serialization::t mode) {
921  return this->serializeFrom(buff, length, mode);
922 }
923 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(const Serializable& val) {
924  return this->serializeFrom(val);
925 }
926 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::serialize(const LinearBufferBase& val) {
927  return this->serializeFrom(val);
928 }
929 
930 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(U8& val) {
931  return this->deserializeTo(val);
932 }
933 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(I8& val) {
934  return this->deserializeTo(val);
935 }
936 #if FW_HAS_16_BIT == 1
937 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(U16& val) {
938  return this->deserializeTo(val);
939 }
940 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(I16& val) {
941  return this->deserializeTo(val);
942 }
943 #endif
944 #if FW_HAS_32_BIT == 1
945 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(U32& val) {
946  return this->deserializeTo(val);
947 }
948 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(I32& val) {
949  return this->deserializeTo(val);
950 }
951 #endif
952 #if FW_HAS_64_BIT == 1
953 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(U64& val) {
954  return this->deserializeTo(val);
955 }
956 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(I64& val) {
957  return this->deserializeTo(val);
958 }
959 #endif
960 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(F32& val) {
961  return this->deserializeTo(val);
962 }
963 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(F64& val) {
964  return this->deserializeTo(val);
965 }
966 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(bool& val) {
967  return this->deserializeTo(val);
968 }
969 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(void*& val) {
970  return this->deserializeTo(val);
971 }
972 
973 // Deprecated method for backward compatibility
974 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(U8* buff,
975  FwSizeType& length,
976  bool noLength) {
978  return this->deserializeTo(buff, length, mode);
979 }
980 
981 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(U8* buff, FwSizeType& length) {
982  return this->deserializeTo(buff, length, Serialization::INCLUDE_LENGTH);
983 }
984 
985 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(U8* buff,
986  FwSizeType& length,
987  Serialization::t mode) {
988  return this->deserializeTo(buff, length, mode);
989 }
990 
991 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(Serializable& val) {
992  return this->deserializeTo(val);
993 }
994 FW_SERIALIZE_FORCE_INLINE_LBB SerializeStatus LinearBufferBase::deserialize(LinearBufferBase& val) {
995  return this->deserializeTo(val);
996 }
997 
998 Serializable::SizeType ExternalSerializeBuffer::getBuffCapacity() const {
999  return this->getCapacity();
1000 }
1001 
1002 } // 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 setBuff(const U8 *src, Serializable::SizeType length) override
Set buffer contents from external source.
PlatformSizeType FwSizeType
SerializeStatus moveSerToOffset(FwSizeType offset) override
Move serialization pointer to specified offset.
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.
SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG) override
Deserialize an 8-bit unsigned integer value.
int8_t I8
8-bit signed integer
Definition: BasicTypes.h:51
No room left in the buffer to serialize data.
void setBuffAddrInternal(U8 *addr)
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 serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
virtual SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG)=0
Serialize an 8-bit unsigned integer value.
Serializable::SizeType getCapacity() const override
Get buffer capacity.
SerializeStatus deserializeSkip(FwSizeType numBytesToSkip) override
Skip specified number of bytes during deserialization.
ExternalSerializeBuffer()
Default constructor.
SerializeStatus
forward declaration for string
float F32
32-bit floating point
Definition: BasicTypes.h:84
U16 FwSizeStoreType
The type used to serialize a size value.
virtual ~SerialBufferBase()
Virtual destructor.
Data was the wrong format (e.g. wrong packet type)
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
SerializeStatus moveDeserToOffset(FwSizeType offset) override
Move deserialization pointer to specified offset.
Omit length from serialization.
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.
void resetDeser() override
Reset deserialization pointer to beginning of buffer.
void resetSer() override
Reset serialization pointer to beginning of buffer.
void setCapacityInternal(Serializable::SizeType capacity)
#define FW_SERIALIZE_FORCE_INLINE_LBB
Definition: FpConfig.h:154
SerializeStatus copyRawOffset(SerialBufferBase &dest, Serializable::SizeType size) override
Append raw bytes to destination from this buffer and advance source offset.
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:54
SerializeStatus setBuffLen(Serializable::SizeType length) override
Set buffer length manually.
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.
double F64
64-bit floating point (double). Required for compiler-supplied double promotion.
Definition: BasicTypes.h:86
SerializeStatus deserializeSize(FwSizeType &size, Endianness mode=Endianness::BIG) override
Deserialize a size value.
SerializeStatus copyRaw(SerialBufferBase &dest, Serializable::SizeType size) override
Copy raw bytes from this buffer to destination and advance source offset.
Include length as first token in serialization.
Little endian serialization.
SerializeStatus serializeSize(const FwSizeType size, Endianness mode=Endianness::BIG) override
Serialize a size value.
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.
SerializeStatus serializeSkip(FwSizeType numBytesToSkip) override
Skip specified number of bytes during serialization.
U8 * getBuffAddrSer()
Get address of end of serialization (DANGEROUS!)
virtual ~LinearBufferBase()
Destructor.
Big endian serialization.