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 #if FW_SERIALIZABLE_TO_STRING || FW_ENABLE_TEXT_LOGGING || BUILD_UT
21 
22 void Serializable::toString(StringBase& text) const {
23  text = "NOSPEC"; // set to not specified.
24 }
25 
26 #endif
27 
28 #ifdef BUILD_UT
29 std::ostream& operator<<(std::ostream& os, const Serializable& val) {
30  Fw::String out;
31  val.toString(out);
32 
33  os << out;
34 
35  return os;
36 }
37 #endif
38 
39 SerializeBufferBase::SerializeBufferBase() : m_serLoc(0), m_deserLoc(0) {}
40 
42 
43 void SerializeBufferBase::copyFrom(const SerializeBufferBase& src) {
44  this->m_serLoc = src.m_serLoc;
45  this->m_deserLoc = src.m_deserLoc;
46  FW_ASSERT(src.getBuffAddr());
47  FW_ASSERT(this->getBuffAddr());
48  // destination has to be same or bigger
49  FW_ASSERT(src.getBuffLength() <= this->getBuffCapacity(), static_cast<FwAssertArgType>(src.getBuffLength()),
50  static_cast<FwAssertArgType>(this->getBuffLength()));
51  (void)memcpy(this->getBuffAddr(), src.getBuffAddr(), static_cast<size_t>(this->m_serLoc));
52 }
53 
54 // Copy constructor doesn't make sense in this virtual class as there is nothing to copy. Derived classes should
55 // call the empty constructor and then call their own copy function
57  this->copyFrom(src);
58  return *this;
59 }
60 
61 // serialization routines
62 
64  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
66  }
67  FW_ASSERT(this->getBuffAddr());
68  this->getBuffAddr()[this->m_serLoc] = val;
69  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
70  this->m_deserLoc = 0;
71 
72  return FW_SERIALIZE_OK;
73 }
74 
76  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
78  }
79  FW_ASSERT(this->getBuffAddr());
80  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val);
81  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
82  this->m_deserLoc = 0;
83  return FW_SERIALIZE_OK;
84 }
85 
86 #if FW_HAS_16_BIT == 1
88  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
90  }
91  FW_ASSERT(this->getBuffAddr());
92  // MSB first
93  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 8);
94  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val);
95  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
96  this->m_deserLoc = 0;
97  return FW_SERIALIZE_OK;
98 }
99 
101  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
103  }
104  FW_ASSERT(this->getBuffAddr());
105  // MSB first
106  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 8);
107  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val);
108  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
109  this->m_deserLoc = 0;
110  return FW_SERIALIZE_OK;
111 }
112 #endif
113 #if FW_HAS_32_BIT == 1
115  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
117  }
118  FW_ASSERT(this->getBuffAddr());
119  // MSB first
120  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 24);
121  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 16);
122  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 8);
123  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val);
124  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
125  this->m_deserLoc = 0;
126  return FW_SERIALIZE_OK;
127 }
128 
130  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
132  }
133  FW_ASSERT(this->getBuffAddr());
134  // MSB first
135  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 24);
136  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 16);
137  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 8);
138  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val);
139  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
140  this->m_deserLoc = 0;
141  return FW_SERIALIZE_OK;
142 }
143 #endif
144 
145 #if FW_HAS_64_BIT == 1
147  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
149  }
150  FW_ASSERT(this->getBuffAddr());
151  // MSB first
152  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 56);
153  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 48);
154  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 40);
155  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val >> 32);
156  this->getBuffAddr()[this->m_serLoc + 4] = static_cast<U8>(val >> 24);
157  this->getBuffAddr()[this->m_serLoc + 5] = static_cast<U8>(val >> 16);
158  this->getBuffAddr()[this->m_serLoc + 6] = static_cast<U8>(val >> 8);
159  this->getBuffAddr()[this->m_serLoc + 7] = static_cast<U8>(val);
160  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
161  this->m_deserLoc = 0;
162  return FW_SERIALIZE_OK;
163 }
164 
166  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(val)) - 1 >= this->getBuffCapacity()) {
168  }
169  FW_ASSERT(this->getBuffAddr());
170  // MSB first
171  this->getBuffAddr()[this->m_serLoc + 0] = static_cast<U8>(val >> 56);
172  this->getBuffAddr()[this->m_serLoc + 1] = static_cast<U8>(val >> 48);
173  this->getBuffAddr()[this->m_serLoc + 2] = static_cast<U8>(val >> 40);
174  this->getBuffAddr()[this->m_serLoc + 3] = static_cast<U8>(val >> 32);
175  this->getBuffAddr()[this->m_serLoc + 4] = static_cast<U8>(val >> 24);
176  this->getBuffAddr()[this->m_serLoc + 5] = static_cast<U8>(val >> 16);
177  this->getBuffAddr()[this->m_serLoc + 6] = static_cast<U8>(val >> 8);
178  this->getBuffAddr()[this->m_serLoc + 7] = static_cast<U8>(val);
179  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(val));
180  this->m_deserLoc = 0;
181  return FW_SERIALIZE_OK;
182 }
183 #endif
184 
186  // floating point values need to be byte-swapped as well, so copy to U64 and use that routine
187  U64 u64Val;
188  (void)memcpy(&u64Val, &val, sizeof(val));
189  return this->serialize(u64Val);
190 }
191 
193  // floating point values need to be byte-swapped as well, so copy to U32 and use that routine
194  U32 u32Val;
195  (void)memcpy(&u32Val, &val, sizeof(val));
196  return this->serialize(u32Val);
197 }
198 
200  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(U8)) - 1 >= this->getBuffCapacity()) {
202  }
203 
204  FW_ASSERT(this->getBuffAddr());
205  if (val) {
206  this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_TRUE_VALUE;
207  } else {
208  this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_FALSE_VALUE;
209  }
210 
211  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(U8));
212  this->m_deserLoc = 0;
213  return FW_SERIALIZE_OK;
214 }
215 
217  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(void*)) - 1 >= this->getBuffCapacity()) {
219  }
220 
221  return this->serialize(reinterpret_cast<PlatformPointerCastType>(val));
222 }
223 
225  return this->serialize(buff, static_cast<FwSizeType>(length), Serialization::INCLUDE_LENGTH);
226 }
227 
229  return this->serialize(buff, static_cast<FwSizeType>(length),
231 }
232 
234  // First serialize length
235  SerializeStatus stat;
236  if (mode == Serialization::INCLUDE_LENGTH) {
237  stat = this->serialize(static_cast<FwSizeStoreType>(length));
238  if (stat != FW_SERIALIZE_OK) {
239  return stat;
240  }
241  }
242 
243  // make sure we have enough space
244  if (this->m_serLoc + length > this->getBuffCapacity()) {
246  }
247 
248  // copy buffer to our buffer
249  (void)memcpy(&this->getBuffAddr()[this->m_serLoc], buff, static_cast<size_t>(length));
250  this->m_serLoc += static_cast<Serializable::SizeType>(length);
251  this->m_deserLoc = 0;
252 
253  return FW_SERIALIZE_OK;
254 }
255 
257  return val.serialize(*this);
258 }
259 
262  if (this->m_serLoc + size + static_cast<Serializable::SizeType>(sizeof(FwSizeStoreType)) >
263  this->getBuffCapacity()) {
265  }
266 
267  // First, serialize size
268  SerializeStatus stat = this->serialize(static_cast<FwSizeStoreType>(size));
269  if (stat != FW_SERIALIZE_OK) {
270  return stat;
271  }
272 
273  FW_ASSERT(this->getBuffAddr());
274  FW_ASSERT(val.getBuffAddr());
275  // serialize buffer
276  (void)memcpy(&this->getBuffAddr()[this->m_serLoc], val.getBuffAddr(), static_cast<size_t>(size));
277  this->m_serLoc += size;
278  this->m_deserLoc = 0;
279 
280  return FW_SERIALIZE_OK;
281 }
282 
285  if ((size < std::numeric_limits<FwSizeStoreType>::min()) || (size > std::numeric_limits<FwSizeStoreType>::max())) {
286  status = FW_SERIALIZE_FORMAT_ERROR;
287  }
288  if (status == FW_SERIALIZE_OK) {
289  status = this->serialize(static_cast<FwSizeStoreType>(size));
290  }
291  return status;
292 }
293 
294 // deserialization routines
295 
297  // check for room
298  if (this->getBuffLength() == this->m_deserLoc) {
300  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
302  }
303  // read from current location
304  FW_ASSERT(this->getBuffAddr());
305  val = this->getBuffAddr()[this->m_deserLoc + 0];
306  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
307  return FW_SERIALIZE_OK;
308 }
309 
311  // check for room
312  if (this->getBuffLength() == this->m_deserLoc) {
314  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
316  }
317  // read from current location
318  FW_ASSERT(this->getBuffAddr());
319  val = static_cast<I8>(this->getBuffAddr()[this->m_deserLoc + 0]);
320  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
321  return FW_SERIALIZE_OK;
322 }
323 
324 #if FW_HAS_16_BIT == 1
326  // check for room
327  if (this->getBuffLength() == this->m_deserLoc) {
329  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
331  }
332  // read from current location
333  FW_ASSERT(this->getBuffAddr());
334  // MSB first
335  val = static_cast<U16>(((this->getBuffAddr()[this->m_deserLoc + 1]) << 0) |
336  ((this->getBuffAddr()[this->m_deserLoc + 0]) << 8));
337  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
338  return FW_SERIALIZE_OK;
339 }
340 
342  // check for room
343  if (this->getBuffLength() == this->m_deserLoc) {
345  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
347  }
348  // read from current location
349  FW_ASSERT(this->getBuffAddr());
350  // MSB first
351  val = static_cast<I16>(((this->getBuffAddr()[this->m_deserLoc + 1]) << 0) |
352  ((this->getBuffAddr()[this->m_deserLoc + 0]) << 8));
353  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
354  return FW_SERIALIZE_OK;
355 }
356 #endif
357 #if FW_HAS_32_BIT == 1
359  // check for room
360  if (this->getBuffLength() == this->m_deserLoc) {
362  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
364  }
365  // read from current location
366  FW_ASSERT(this->getBuffAddr());
367  // MSB first
368  val = (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 0) |
369  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 8) |
370  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 16) |
371  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 24);
372  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
373  return FW_SERIALIZE_OK;
374 }
375 
377  // check for room
378  if (this->getBuffLength() == this->m_deserLoc) {
380  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
382  }
383  // read from current location
384  FW_ASSERT(this->getBuffAddr());
385  // MSB first
386  val = (static_cast<I32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 0) |
387  (static_cast<I32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 8) |
388  (static_cast<I32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 16) |
389  (static_cast<I32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 24);
390  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
391  return FW_SERIALIZE_OK;
392 }
393 #endif
394 
395 #if FW_HAS_64_BIT == 1
396 
398  // check for room
399  if (this->getBuffLength() == this->m_deserLoc) {
401  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
403  }
404  // read from current location
405  FW_ASSERT(this->getBuffAddr());
406  // MSB first
407  val = (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 0) |
408  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 8) |
409  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 16) |
410  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 24) |
411  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 32) |
412  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 40) |
413  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 48) |
414  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 56);
415 
416  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
417  return FW_SERIALIZE_OK;
418 }
419 
421  // check for room
422  if (this->getBuffLength() == this->m_deserLoc) {
424  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
426  }
427  // read from current location
428  FW_ASSERT(this->getBuffAddr());
429  // MSB first
430  val = (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 0) |
431  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 8) |
432  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 16) |
433  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 24) |
434  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 32) |
435  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 40) |
436  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 48) |
437  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 56);
438  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
439  return FW_SERIALIZE_OK;
440 }
441 #endif
442 
444  // deserialize as 64-bit int to handle endianness
445  U64 tempVal;
446  SerializeStatus stat = this->deserialize(tempVal);
447  if (stat != FW_SERIALIZE_OK) {
448  return stat;
449  }
450  // copy to argument
451  (void)memcpy(&val, &tempVal, sizeof(val));
452 
453  return FW_SERIALIZE_OK;
454 }
455 
457  // check for room
458  if (this->getBuffLength() == this->m_deserLoc) {
460  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(U8))) {
462  }
463  // read from current location
464  FW_ASSERT(this->getBuffAddr());
465  if (FW_SERIALIZE_TRUE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
466  val = true;
467  } else if (FW_SERIALIZE_FALSE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
468  val = false;
469  } else {
471  }
472 
473  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(U8));
474  return FW_SERIALIZE_OK;
475 }
476 
478  // Deserialize as pointer cast, then convert to void*
479  PlatformPointerCastType pointerCastVal = 0;
480  const SerializeStatus stat = this->deserialize(pointerCastVal);
481  if (stat == FW_SERIALIZE_OK) {
482  val = reinterpret_cast<void*>(pointerCastVal);
483  }
484  return stat;
485 }
486 
488  // deserialize as 64-bit int to handle endianness
489  U32 tempVal;
490  SerializeStatus stat = this->deserialize(tempVal);
491  if (stat != FW_SERIALIZE_OK) {
492  return stat;
493  }
494  (void)memcpy(&val, &tempVal, sizeof(val));
495 
496  return FW_SERIALIZE_OK;
497 }
498 
500  FwSizeType length_in_out = static_cast<FwSizeType>(length);
501  SerializeStatus status = this->deserialize(buff, length_in_out, Serialization::INCLUDE_LENGTH);
502  length = static_cast<Serializable::SizeType>(length_in_out);
503  return status;
504 }
505 
507  FwSizeType length_in_out = static_cast<FwSizeType>(length);
508  SerializeStatus status =
509  this->deserialize(buff, length_in_out, noLength ? Serialization::OMIT_LENGTH : Serialization::INCLUDE_LENGTH);
510  length = static_cast<Serializable::SizeType>(length_in_out);
511  return status;
512 }
513 
515  FW_ASSERT(this->getBuffAddr());
516 
517  if (mode == Serialization::INCLUDE_LENGTH) {
518  FwSizeStoreType storedLength;
519 
520  SerializeStatus stat = this->deserialize(storedLength);
521 
522  if (stat != FW_SERIALIZE_OK) {
523  return stat;
524  }
525 
526  // make sure it fits
527  if ((storedLength > this->getBuffLeft()) or (storedLength > length)) {
529  }
530 
531  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(storedLength));
532 
533  length = static_cast<FwSizeType>(storedLength);
534 
535  } else {
536  // make sure enough is left
537  if (length > this->getBuffLeft()) {
539  }
540 
541  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(length));
542  }
543 
544  this->m_deserLoc += static_cast<Serializable::SizeType>(length);
545  return FW_SERIALIZE_OK;
546 }
547 
549  return val.deserialize(*this);
550 }
551 
553  FW_ASSERT(val.getBuffAddr());
555 
556  FwSizeStoreType storedLength;
557 
558  stat = this->deserialize(storedLength);
559 
560  if (stat != FW_SERIALIZE_OK) {
561  return stat;
562  }
563 
564  // make sure destination has enough room
565 
566  if ((storedLength > val.getBuffCapacity()) or (storedLength > this->getBuffLeft())) {
568  }
569 
570  FW_ASSERT(this->getBuffAddr());
571  (void)memcpy(val.getBuffAddr(), &this->getBuffAddr()[this->m_deserLoc], static_cast<size_t>(storedLength));
572 
573  stat = val.setBuffLen(storedLength);
574 
575  if (stat != FW_SERIALIZE_OK) {
576  return stat;
577  }
578 
579  this->m_deserLoc += storedLength;
580 
581  return FW_SERIALIZE_OK;
582 }
583 
585  FwSizeStoreType storedSize = 0;
586  Fw::SerializeStatus status = this->deserialize(storedSize);
587  if (status == FW_SERIALIZE_OK) {
588  size = static_cast<FwSizeType>(storedSize);
589  }
590  return status;
591 }
592 
594  this->m_deserLoc = 0;
595  this->m_serLoc = 0;
596 }
597 
599  this->m_deserLoc = 0;
600 }
601 
604  // compute new deser loc
605  const FwSizeType newSerLoc = this->m_serLoc + numBytesToSkip;
606  // check for room
607  if (newSerLoc <= this->getBuffCapacity()) {
608  // update deser loc
609  this->m_serLoc = static_cast<Serializable::SizeType>(newSerLoc);
610  } else {
611  status = FW_SERIALIZE_NO_ROOM_LEFT;
612  }
613  return status;
614 }
615 
617  // check for room
618  if (this->getBuffLength() == this->m_deserLoc) {
620  } else if (this->getBuffLength() - this->m_deserLoc < numBytesToSkip) {
622  }
623  // update location in buffer to skip the value
624  this->m_deserLoc += static_cast<Serializable::SizeType>(numBytesToSkip);
625  return FW_SERIALIZE_OK;
626 }
627 
629  // Reset serialization
630  this->resetSer();
631  // Advance to offset
632  return this->serializeSkip(offset);
633 }
635  // Reset deserialization
636  this->resetDeser();
637  // Advance to offset
638  return this->deserializeSkip(offset);
639 }
640 
642  return this->m_serLoc;
643 }
644 
646  if (this->getBuffCapacity() < length) {
648  } else {
649  FW_ASSERT(src);
650  FW_ASSERT(this->getBuffAddr());
651  (void)memcpy(this->getBuffAddr(), src, static_cast<size_t>(length));
652  this->m_serLoc = length;
653  this->m_deserLoc = 0;
654  return FW_SERIALIZE_OK;
655  }
656 }
657 
659  if (this->getBuffCapacity() < length) {
661  } else {
662  this->m_serLoc = length;
663  this->m_deserLoc = 0;
664  return FW_SERIALIZE_OK;
665  }
666 }
667 
669  FW_ASSERT(this->m_serLoc >= this->m_deserLoc, static_cast<FwAssertArgType>(this->m_serLoc),
670  static_cast<FwAssertArgType>(this->m_deserLoc));
671  return this->m_serLoc - this->m_deserLoc;
672 }
673 
675  // make sure there is sufficient size in destination
676  if (dest.getBuffCapacity() < size) {
678  }
679  // otherwise, set destination buffer to data from deserialization pointer plus size
680  SerializeStatus stat = dest.setBuff(&this->getBuffAddr()[this->m_deserLoc], size);
681  if (stat == FW_SERIALIZE_OK) {
682  this->m_deserLoc += size;
683  }
684  return stat;
685 }
686 
688  // make sure there is sufficient size in destination
689  if (dest.getBuffCapacity() < size + dest.getBuffLength()) {
691  }
692  // make sure there is sufficient buffer in source
693  if (this->getBuffLeft() < size) {
695  }
696 
697  // otherwise, serialize bytes to destination without writing length
698  SerializeStatus stat = dest.serialize(&this->getBuffAddr()[this->m_deserLoc], size, true);
699  if (stat == FW_SERIALIZE_OK) {
700  this->m_deserLoc += size;
701  }
702  return stat;
703 }
704 
705 // return address of buffer not yet deserialized. This is used
706 // to copy the remainder of a buffer.
708  return &this->getBuffAddr()[this->m_deserLoc];
709 }
710 
713  return &this->getBuffAddr()[this->m_serLoc];
714 }
715 
716 #ifdef BUILD_UT
717 bool SerializeBufferBase::operator==(const SerializeBufferBase& other) const {
718  if (this->getBuffLength() != other.getBuffLength()) {
719  return false;
720  }
721 
722  const U8* us = this->getBuffAddr();
723  const U8* them = other.getBuffAddr();
724 
725  FW_ASSERT(us);
726  FW_ASSERT(them);
727 
728  for (Serializable::SizeType byte = 0; byte < this->getBuffLength(); byte++) {
729  if (us[byte] != them[byte]) {
730  return false;
731  }
732  }
733 
734  return true;
735 }
736 
737 std::ostream& operator<<(std::ostream& os, const SerializeBufferBase& buff) {
738  const U8* us = buff.getBuffAddr();
739 
740  FW_ASSERT(us);
741 
742  for (Serializable::SizeType byte = 0; byte < buff.getBuffLength(); byte++) {
743  os << "[" << std::setw(2) << std::hex << std::setfill('0') << us[byte] << "]" << std::dec;
744  }
745 
746  return os;
747 }
748 #endif
749 
751  this->setExtBuffer(buffPtr, size);
752 }
753 
755  this->clear();
756 }
757 
759  FW_ASSERT(buffPtr != nullptr);
760  this->clear();
761  this->m_buff = buffPtr;
762  this->m_buffSize = size;
763 }
764 
766  this->resetSer();
767  this->resetDeser();
768  this->m_buff = nullptr;
769  this->m_buffSize = 0;
770 }
771 
773  return this->m_buffSize;
774 }
775 
777  return this->m_buff;
778 }
779 
781  return this->m_buff;
782 }
783 
784 } // namespace Fw
Serialization/Deserialization operation was successful.
void clear()
clear external buffer
SerializeBufferBase()
default constructor
Deserialization buffer was empty when trying to read more data.
PlatformSizeType FwSizeType
void resetSer()
reset to beginning of buffer to reuse for serialization
SerializeStatus copyRaw(SerializeBufferBase &dest, Serializable::SizeType size)
directly copies buffer without looking for a size in the stream.
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
int8_t I8
8-bit signed integer
Definition: BasicTypes.h:53
No room left in the buffer to serialize data.
#define FW_SERIALIZE_FALSE_VALUE
Value encoded during serialization for boolean false.
Definition: FpConfig.h:48
Serializable::SizeType m_buffSize
size of external buffer
virtual ~SerializeBufferBase()
destructor
Deserialization data had incorrect values (unexpected data types)
Serializable::SizeType m_serLoc
current offset in buffer of serialized data
const U8 * getBuffAddrLeft() const
gets address of remaining non-deserialized data.
ExternalSerializeBuffer()
default constructor
SerializeStatus
forward declaration for string
float F32
32-bit floating point
Definition: BasicTypes.h:86
U16 FwSizeStoreType
The type used to serialize a size value.
Serializable::SizeType getBuffLength() const
returns current buffer size
Serializable::SizeType getBuffLeft() const
returns how much deserialization buffer is left
Include length as first token in serialization.
Data was the wrong format (e.g. wrong packet type)
virtual SerializeStatus serialize(SerializeBufferBase &buffer) const =0
serialize contents
U8 * m_buff
pointer to external buffer
#define FW_SERIALIZE_TRUE_VALUE
Value encoded during serialization for boolean true.
Definition: FpConfig.h:44
SerializeStatus serializeSize(const FwSizeType size)
serialize a size value
Data was left in the buffer, but not enough to deserialize.
FwSizeType SizeType
SerializeStatus deserializeSize(FwSizeType &size)
deserialize a size value
Serializable()
Default constructor.
void resetDeser()
reset deserialization to beginning
SerializeStatus copyRawOffset(SerializeBufferBase &dest, Serializable::SizeType size)
directly copies buffer without looking for a size in the stream.
SerializeStatus moveDeserToOffset(FwSizeType offset)
Moves deserialization to the specified offset.
virtual SerializeStatus deserialize(SerializeBufferBase &buffer)=0
deserialize to contents
SerializeStatus moveSerToOffset(FwSizeType offset)
Moves serialization to the specified offset.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:56
virtual Serializable::SizeType getBuffCapacity() const =0
returns capacity, not current size, of buffer
SerializeStatus deserializeSkip(FwSizeType numBytesToSkip)
Skips the number of specified bytes for deserialization.
static U32 min(const U32 a, const U32 b)
Definition: Checksum.cpp:16
void setExtBuffer(U8 *buffPtr, Serializable::SizeType size)
Omit length from serialization.
virtual ~Serializable()
destructor
Serializable::SizeType m_deserLoc
current offset for deserialization
SerializeStatus deserialize(U8 &val)
deserialize 8-bit unsigned int
double F64
64-bit floating point (double). Required for compiler-supplied double promotion.
Definition: BasicTypes.h:88
SerializeBufferBase & operator=(const SerializeBufferBase &src)
copy assignment operator
SerializeStatus setBuff(const U8 *src, Serializable::SizeType length)
sets buffer contents and size
forward declaration
Serializable::SizeType getBuffCapacity() const
returns capacity, not current size, of buffer
virtual U8 * getBuffAddr()=0
gets buffer address for data filling
#define FW_ASSERT(...)
Definition: Assert.hpp:14
SerializeStatus serializeSkip(FwSizeType numBytesToSkip)
Skips the number of specified bytes for serialization.
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.
U8 * getBuffAddr()
gets buffer address for data filling
SerializeStatus setBuffLen(Serializable::SizeType length)
sets buffer length manually after filling with data
#define U64(C)
Definition: sha.h:180