F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
Serializable.cpp
Go to the documentation of this file.
1 #include <FpConfig.hpp>
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(), 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 
185 #if FW_HAS_F64 && FW_HAS_64_BIT
186 
188  // floating point values need to be byte-swapped as well, so copy to U64 and use that routine
189  U64 u64Val;
190  (void)memcpy(&u64Val, &val, sizeof(val));
191  return this->serialize(u64Val);
192 }
193 
194 #endif
195 
197  // floating point values need to be byte-swapped as well, so copy to U32 and use that routine
198  U32 u32Val;
199  (void)memcpy(&u32Val, &val, sizeof(val));
200  return this->serialize(u32Val);
201 }
202 
204  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(U8)) - 1 >= this->getBuffCapacity()) {
206  }
207 
208  FW_ASSERT(this->getBuffAddr());
209  if (val) {
210  this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_TRUE_VALUE;
211  } else {
212  this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_FALSE_VALUE;
213  }
214 
215  this->m_serLoc += static_cast<Serializable::SizeType>(sizeof(U8));
216  this->m_deserLoc = 0;
217  return FW_SERIALIZE_OK;
218 }
219 
221  if (this->m_serLoc + static_cast<Serializable::SizeType>(sizeof(void*)) - 1 >= this->getBuffCapacity()) {
223  }
224 
225  return this->serialize(reinterpret_cast<POINTER_CAST>(val));
226 }
227 
229  return this->serialize(buff, static_cast<FwSizeType>(length), Serialization::INCLUDE_LENGTH);
230 }
231 
233  return this->serialize(buff, static_cast<FwSizeType>(length),
235 }
236 
238  // First serialize length
239  SerializeStatus stat;
240  if (mode == Serialization::INCLUDE_LENGTH) {
241  stat = this->serialize(static_cast<FwSizeStoreType>(length));
242  if (stat != FW_SERIALIZE_OK) {
243  return stat;
244  }
245  }
246 
247  // make sure we have enough space
248  if (this->m_serLoc + length > this->getBuffCapacity()) {
250  }
251 
252  // copy buffer to our buffer
253  (void)memcpy(&this->getBuffAddr()[this->m_serLoc], buff, length);
254  this->m_serLoc += static_cast<Serializable::SizeType>(length);
255  this->m_deserLoc = 0;
256 
257  return FW_SERIALIZE_OK;
258 }
259 
261  return val.serialize(*this);
262 }
263 
266  if (this->m_serLoc + size + static_cast<Serializable::SizeType>(sizeof(FwSizeStoreType)) >
267  this->getBuffCapacity()) {
269  }
270 
271  // First, serialize size
272  SerializeStatus stat = this->serialize(static_cast<FwSizeStoreType>(size));
273  if (stat != FW_SERIALIZE_OK) {
274  return stat;
275  }
276 
277  FW_ASSERT(this->getBuffAddr());
278  FW_ASSERT(val.getBuffAddr());
279  // serialize buffer
280  (void)memcpy(&this->getBuffAddr()[this->m_serLoc], val.getBuffAddr(), size);
281  this->m_serLoc += size;
282  this->m_deserLoc = 0;
283 
284  return FW_SERIALIZE_OK;
285 }
286 
289  if ((size < std::numeric_limits<FwSizeStoreType>::min()) || (size > std::numeric_limits<FwSizeStoreType>::max())) {
290  status = FW_SERIALIZE_FORMAT_ERROR;
291  }
292  if (status == FW_SERIALIZE_OK) {
293  status = this->serialize(static_cast<FwSizeStoreType>(size));
294  }
295  return status;
296 }
297 
298 // deserialization routines
299 
301  // check for room
302  if (this->getBuffLength() == this->m_deserLoc) {
304  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
306  }
307  // read from current location
308  FW_ASSERT(this->getBuffAddr());
309  val = this->getBuffAddr()[this->m_deserLoc + 0];
310  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
311  return FW_SERIALIZE_OK;
312 }
313 
315  // check for room
316  if (this->getBuffLength() == this->m_deserLoc) {
318  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
320  }
321  // read from current location
322  FW_ASSERT(this->getBuffAddr());
323  val = static_cast<I8>(this->getBuffAddr()[this->m_deserLoc + 0]);
324  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
325  return FW_SERIALIZE_OK;
326 }
327 
328 #if FW_HAS_16_BIT == 1
330  // check for room
331  if (this->getBuffLength() == this->m_deserLoc) {
333  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
335  }
336  // read from current location
337  FW_ASSERT(this->getBuffAddr());
338  // MSB first
339  val = static_cast<U16>(((this->getBuffAddr()[this->m_deserLoc + 1]) << 0) |
340  ((this->getBuffAddr()[this->m_deserLoc + 0]) << 8));
341  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
342  return FW_SERIALIZE_OK;
343 }
344 
346  // check for room
347  if (this->getBuffLength() == this->m_deserLoc) {
349  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
351  }
352  // read from current location
353  FW_ASSERT(this->getBuffAddr());
354  // MSB first
355  val = static_cast<I16>(((this->getBuffAddr()[this->m_deserLoc + 1]) << 0) |
356  ((this->getBuffAddr()[this->m_deserLoc + 0]) << 8));
357  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
358  return FW_SERIALIZE_OK;
359 }
360 #endif
361 #if FW_HAS_32_BIT == 1
363  // check for room
364  if (this->getBuffLength() == this->m_deserLoc) {
366  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
368  }
369  // read from current location
370  FW_ASSERT(this->getBuffAddr());
371  // MSB first
372  val = (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 0) |
373  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 8) |
374  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 16) |
375  (static_cast<U32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 24);
376  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
377  return FW_SERIALIZE_OK;
378 }
379 
381  // check for room
382  if (this->getBuffLength() == this->m_deserLoc) {
384  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
386  }
387  // read from current location
388  FW_ASSERT(this->getBuffAddr());
389  // MSB first
390  val = (static_cast<I32>(this->getBuffAddr()[this->m_deserLoc + 3]) << 0) |
391  (static_cast<I32>(this->getBuffAddr()[this->m_deserLoc + 2]) << 8) |
392  (static_cast<I32>(this->getBuffAddr()[this->m_deserLoc + 1]) << 16) |
393  (static_cast<I32>(this->getBuffAddr()[this->m_deserLoc + 0]) << 24);
394  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
395  return FW_SERIALIZE_OK;
396 }
397 #endif
398 
399 #if FW_HAS_64_BIT == 1
400 
402  // check for room
403  if (this->getBuffLength() == this->m_deserLoc) {
405  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
407  }
408  // read from current location
409  FW_ASSERT(this->getBuffAddr());
410  // MSB first
411  val = (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 0) |
412  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 8) |
413  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 16) |
414  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 24) |
415  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 32) |
416  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 40) |
417  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 48) |
418  (static_cast<U64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 56);
419 
420  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
421  return FW_SERIALIZE_OK;
422 }
423 
425  // check for room
426  if (this->getBuffLength() == this->m_deserLoc) {
428  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(val))) {
430  }
431  // read from current location
432  FW_ASSERT(this->getBuffAddr());
433  // MSB first
434  val = (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 7]) << 0) |
435  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 6]) << 8) |
436  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 5]) << 16) |
437  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 4]) << 24) |
438  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 3]) << 32) |
439  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 2]) << 40) |
440  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 1]) << 48) |
441  (static_cast<I64>(this->getBuffAddr()[this->m_deserLoc + 0]) << 56);
442  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(val));
443  return FW_SERIALIZE_OK;
444 }
445 #endif
446 
447 #if FW_HAS_F64
448 
450  // deserialize as 64-bit int to handle endianness
451  U64 tempVal;
452  SerializeStatus stat = this->deserialize(tempVal);
453  if (stat != FW_SERIALIZE_OK) {
454  return stat;
455  }
456  // copy to argument
457  (void)memcpy(&val, &tempVal, sizeof(val));
458 
459  return FW_SERIALIZE_OK;
460 }
461 
462 #endif
463 
465  // check for room
466  if (this->getBuffLength() == this->m_deserLoc) {
468  } else if (this->getBuffLength() - this->m_deserLoc < static_cast<Serializable::SizeType>(sizeof(U8))) {
470  }
471  // read from current location
472  FW_ASSERT(this->getBuffAddr());
473  if (FW_SERIALIZE_TRUE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
474  val = true;
475  } else if (FW_SERIALIZE_FALSE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
476  val = false;
477  } else {
479  }
480 
481  this->m_deserLoc += static_cast<Serializable::SizeType>(sizeof(U8));
482  return FW_SERIALIZE_OK;
483 }
484 
486  // Deserialize as pointer cast, then convert to void*
487  PlatformPointerCastType pointerCastVal = 0;
488  const SerializeStatus stat = this->deserialize(pointerCastVal);
489  if (stat == FW_SERIALIZE_OK) {
490  val = reinterpret_cast<void*>(pointerCastVal);
491  }
492  return stat;
493 }
494 
496  // deserialize as 64-bit int to handle endianness
497  U32 tempVal;
498  SerializeStatus stat = this->deserialize(tempVal);
499  if (stat != FW_SERIALIZE_OK) {
500  return stat;
501  }
502  (void)memcpy(&val, &tempVal, sizeof(val));
503 
504  return FW_SERIALIZE_OK;
505 }
506 
508  FwSizeType length_in_out = static_cast<FwSizeType>(length);
509  SerializeStatus status = this->deserialize(buff, length_in_out, Serialization::INCLUDE_LENGTH);
510  length = static_cast<Serializable::SizeType>(length_in_out);
511  return status;
512 }
513 
515  FwSizeType length_in_out = static_cast<FwSizeType>(length);
516  SerializeStatus status =
517  this->deserialize(buff, length_in_out, noLength ? Serialization::OMIT_LENGTH : Serialization::INCLUDE_LENGTH);
518  length = static_cast<Serializable::SizeType>(length_in_out);
519  return status;
520 }
521 
523  FW_ASSERT(this->getBuffAddr());
524 
525  if (mode == Serialization::INCLUDE_LENGTH) {
526  FwSizeStoreType storedLength;
527 
528  SerializeStatus stat = this->deserialize(storedLength);
529 
530  if (stat != FW_SERIALIZE_OK) {
531  return stat;
532  }
533 
534  // make sure it fits
535  if ((storedLength > this->getBuffLeft()) or (storedLength > length)) {
537  }
538 
539  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], storedLength);
540 
541  length = static_cast<FwSizeType>(storedLength);
542 
543  } else {
544  // make sure enough is left
545  if (length > this->getBuffLeft()) {
547  }
548 
549  (void)memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], length);
550  }
551 
552  this->m_deserLoc += static_cast<Serializable::SizeType>(length);
553  return FW_SERIALIZE_OK;
554 }
555 
557  return val.deserialize(*this);
558 }
559 
561  FW_ASSERT(val.getBuffAddr());
563 
564  FwSizeStoreType storedLength;
565 
566  stat = this->deserialize(storedLength);
567 
568  if (stat != FW_SERIALIZE_OK) {
569  return stat;
570  }
571 
572  // make sure destination has enough room
573 
574  if ((storedLength > val.getBuffCapacity()) or (storedLength > this->getBuffLeft())) {
576  }
577 
578  FW_ASSERT(this->getBuffAddr());
579  (void)memcpy(val.getBuffAddr(), &this->getBuffAddr()[this->m_deserLoc], storedLength);
580 
581  stat = val.setBuffLen(storedLength);
582 
583  if (stat != FW_SERIALIZE_OK) {
584  return stat;
585  }
586 
587  this->m_deserLoc += storedLength;
588 
589  return FW_SERIALIZE_OK;
590 }
591 
593  FwSizeStoreType storedSize = 0;
594  Fw::SerializeStatus status = this->deserialize(storedSize);
595  if (status == FW_SERIALIZE_OK) {
596  size = static_cast<FwSizeType>(storedSize);
597  }
598  return status;
599 }
600 
602  this->m_deserLoc = 0;
603  this->m_serLoc = 0;
604 }
605 
607  this->m_deserLoc = 0;
608 }
609 
612  // compute new deser loc
613  const FwSizeType newSerLoc = this->m_serLoc + numBytesToSkip;
614  // check for room
615  if (newSerLoc <= this->getBuffCapacity()) {
616  // update deser loc
617  this->m_serLoc = static_cast<Serializable::SizeType>(newSerLoc);
618  } else {
619  status = FW_SERIALIZE_NO_ROOM_LEFT;
620  }
621  return status;
622 }
623 
625  // check for room
626  if (this->getBuffLength() == this->m_deserLoc) {
628  } else if (this->getBuffLength() - this->m_deserLoc < numBytesToSkip) {
630  }
631  // update location in buffer to skip the value
632  this->m_deserLoc += static_cast<Serializable::SizeType>(numBytesToSkip);
633  return FW_SERIALIZE_OK;
634 }
635 
637  // Reset serialization
638  this->resetSer();
639  // Advance to offset
640  return this->serializeSkip(offset);
641 }
643  // Reset deserialization
644  this->resetDeser();
645  // Advance to offset
646  return this->deserializeSkip(offset);
647 }
648 
650  return this->m_serLoc;
651 }
652 
654  if (this->getBuffCapacity() < length) {
656  } else {
657  FW_ASSERT(src);
658  FW_ASSERT(this->getBuffAddr());
659  memcpy(this->getBuffAddr(), src, length);
660  this->m_serLoc = length;
661  this->m_deserLoc = 0;
662  return FW_SERIALIZE_OK;
663  }
664 }
665 
667  if (this->getBuffCapacity() < length) {
669  } else {
670  this->m_serLoc = length;
671  this->m_deserLoc = 0;
672  return FW_SERIALIZE_OK;
673  }
674 }
675 
677  FW_ASSERT(this->m_serLoc >= this->m_deserLoc, static_cast<FwAssertArgType>(this->m_serLoc),
678  static_cast<FwAssertArgType>(this->m_deserLoc));
679  return this->m_serLoc - this->m_deserLoc;
680 }
681 
683  // make sure there is sufficient size in destination
684  if (dest.getBuffCapacity() < size) {
686  }
687  // otherwise, set destination buffer to data from deserialization pointer plus size
688  SerializeStatus stat = dest.setBuff(&this->getBuffAddr()[this->m_deserLoc], size);
689  if (stat == FW_SERIALIZE_OK) {
690  this->m_deserLoc += size;
691  }
692  return stat;
693 }
694 
696  // make sure there is sufficient size in destination
697  if (dest.getBuffCapacity() < size + dest.getBuffLength()) {
699  }
700  // make sure there is sufficient buffer in source
701  if (this->getBuffLeft() < size) {
703  }
704 
705  // otherwise, serialize bytes to destination without writing length
706  SerializeStatus stat = dest.serialize(&this->getBuffAddr()[this->m_deserLoc], size, true);
707  if (stat == FW_SERIALIZE_OK) {
708  this->m_deserLoc += size;
709  }
710  return stat;
711 }
712 
713 // return address of buffer not yet deserialized. This is used
714 // to copy the remainder of a buffer.
716  return &this->getBuffAddr()[this->m_deserLoc];
717 }
718 
721  return &this->getBuffAddr()[this->m_serLoc];
722 }
723 
724 #ifdef BUILD_UT
725 bool SerializeBufferBase::operator==(const SerializeBufferBase& other) const {
726  if (this->getBuffLength() != other.getBuffLength()) {
727  return false;
728  }
729 
730  const U8* us = this->getBuffAddr();
731  const U8* them = other.getBuffAddr();
732 
733  FW_ASSERT(us);
734  FW_ASSERT(them);
735 
736  for (Serializable::SizeType byte = 0; byte < this->getBuffLength(); byte++) {
737  if (us[byte] != them[byte]) {
738  return false;
739  }
740  }
741 
742  return true;
743 }
744 
745 std::ostream& operator<<(std::ostream& os, const SerializeBufferBase& buff) {
746  const U8* us = buff.getBuffAddr();
747 
748  FW_ASSERT(us);
749 
750  for (Serializable::SizeType byte = 0; byte < buff.getBuffLength(); byte++) {
751  os << "[" << std::setw(2) << std::hex << std::setfill('0') << us[byte] << "]" << std::dec;
752  }
753 
754  return os;
755 }
756 #endif
757 
759  this->setExtBuffer(buffPtr, size);
760 }
761 
763  this->clear();
764 }
765 
767  FW_ASSERT(buffPtr != nullptr);
768  this->clear();
769  this->m_buff = buffPtr;
770  this->m_buffSize = size;
771 }
772 
774  this->resetSer();
775  this->resetDeser();
776  this->m_buff = nullptr;
777  this->m_buffSize = 0;
778 }
779 
781  return this->m_buffSize;
782 }
783 
785  return this->m_buff;
786 }
787 
789  return this->m_buff;
790 }
791 
792 } // namespace Fw
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformPointerCastType POINTER_CAST
Definition: BasicTypes.h:57
int8_t I8
8-bit signed integer
Definition: BasicTypes.h:29
float F32
32-bit floating point
Definition: BasicTypes.h:49
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:30
static U32 min(const U32 a, const U32 b)
Definition: Checksum.cpp:16
uint8_t PlatformPointerCastType
PlatformAssertArgType FwAssertArgType
Definition: FpConfig.h:39
#define FW_SERIALIZE_TRUE_VALUE
Value encoded during serialization for boolean true.
Definition: FpConfig.h:139
#define FW_SERIALIZE_FALSE_VALUE
Value encoded during serialization for boolean false.
Definition: FpConfig.h:143
U16 FwSizeStoreType
Definition: FpConfig.h:59
PlatformSizeType FwSizeType
Definition: FpConfig.h:35
C++-compatible configuration header for fprime configuration.
U8 * getBuffAddr()
gets buffer address for data filling
Serializable::SizeType getBuffCapacity() const
returns capacity, not current size, of buffer
U8 * m_buff
pointer to external buffer
void setExtBuffer(U8 *buffPtr, Serializable::SizeType size)
void clear()
clear external buffer
ExternalSerializeBuffer()
default constructor
Serializable::SizeType m_buffSize
size of external buffer
forward declaration
NATIVE_UINT_TYPE SizeType
Serializable()
Default constructor.
virtual ~Serializable()
destructor
virtual SerializeStatus deserialize(SerializeBufferBase &buffer)=0
deserialize to contents
virtual SerializeStatus serialize(SerializeBufferBase &buffer) const =0
serialize contents
@ OMIT_LENGTH
Omit length from serialization.
@ INCLUDE_LENGTH
Include length as first token in serialization.
virtual U8 * getBuffAddr()=0
gets buffer address for data filling
SerializeStatus deserializeSize(FwSizeType &size)
deserialize a size value
SerializeStatus setBuffLen(Serializable::SizeType length)
sets buffer length manually after filling with data
void resetDeser()
reset deserialization to beginning
SerializeStatus moveDeserToOffset(FwSizeType offset)
Moves deserialization to the specified offset.
Serializable::SizeType getBuffLeft() const
returns how much deserialization buffer is left
const U8 * getBuffAddrLeft() const
gets address of remaining non-deserialized data.
void resetSer()
reset to beginning of buffer to reuse for serialization
SerializeStatus serializeSkip(FwSizeType numBytesToSkip)
Skips the number of specified bytes for serialization.
SerializeStatus moveSerToOffset(FwSizeType offset)
Moves serialization to the specified offset.
SerializeBufferBase()
default constructor
Serializable::SizeType getBuffLength() const
returns current buffer size
SerializeBufferBase & operator=(const SerializeBufferBase &src)
copy assignment operator
SerializeStatus setBuff(const U8 *src, Serializable::SizeType length)
sets buffer contents and size
SerializeStatus deserialize(U8 &val)
deserialize 8-bit unsigned int
virtual ~SerializeBufferBase()
destructor
SerializeStatus deserializeSkip(FwSizeType numBytesToSkip)
Skips the number of specified bytes for deserialization.
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
SerializeStatus copyRawOffset(SerializeBufferBase &dest, Serializable::SizeType size)
directly copies buffer without looking for a size in the stream.
virtual Serializable::SizeType getBuffCapacity() const =0
returns capacity, not current size, of buffer
SerializeStatus serializeSize(const FwSizeType size)
serialize a size value
SerializeStatus
forward declaration for string
@ FW_DESERIALIZE_FORMAT_ERROR
Deserialization data had incorrect values (unexpected data types)
@ FW_DESERIALIZE_BUFFER_EMPTY
Deserialization buffer was empty when trying to read more data.
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
@ FW_SERIALIZE_FORMAT_ERROR
Data was the wrong format (e.g. wrong packet type)
@ FW_DESERIALIZE_SIZE_MISMATCH
Data was left in the buffer, but not enough to deserialize.
@ FW_SERIALIZE_NO_ROOM_LEFT
No room left in the buffer to serialize data.
#define U64(C)
Definition: sha.h:176