OpenDDS  Snapshot(2023/04/28-20:55)
Serializer.h
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.opendds.org/license.html
4  */
5 
6 /**
7  * @file Serializer.h
8  *
9  * The serialization interface for a C++ type called Type consists of the
10  * following overloads:
11  *
12  * void serialized_size(
13  * const Encoding& encoding, size_t& size, const Type& value);
14  * Get the size (in bytes) of the encoded representation of value.
15  *
16  * bool operator<<(Serializer& serializer, const Type& value);
17  * Tries to encode value into the stream of the serializer. Returns true if
18  * successful, else false.
19  *
20  * bool operator>>(Serializer& serializer, Type& value);
21  * Tries to decode a representation of Type located at the current
22  * position of the stream and use that to set value. Returns true if
23  * successful, else false.
24  */
25 
26 #ifndef OPENDDS_DCPS_SERIALIZER_H
27 #define OPENDDS_DCPS_SERIALIZER_H
28 
29 #include <ace/config-macros.h>
30 #ifndef ACE_LACKS_PRAGMA_ONCE
31 # pragma once
32 #endif /* ACE_LACKS_PRAGMA_ONCE */
33 
34 #include "Definitions.h"
35 #include "PoolAllocator.h"
36 #include "Message_Block_Ptr.h"
37 #include "dcps_export.h"
38 
39 #include <ace/CDR_Base.h>
40 #include <ace/CDR_Stream.h>
41 
42 #include <limits>
43 #include <string>
44 
46 class ACE_Message_Block;
48 
50 
51 namespace OpenDDS {
52 namespace DCPS {
53 
54 enum Endianness {
57 #ifdef ACE_LITTLE_ENDIAN
60 #else
62  ENDIAN_NONNATIVE = ENDIAN_LITTLE
63 #endif
64 };
65 
68 
73 };
74 
75 inline const char* ext_to_string(Extensibility ext)
76 {
77  switch (ext) {
78  case FINAL:
79  return "final";
80  case APPENDABLE:
81  return "appendable";
82  case MUTABLE:
83  return "mutable";
84  default:
85  return "invalid";
86  }
87 }
88 
89 const size_t boolean_cdr_size = 1;
90 const size_t byte_cdr_size = 1;
91 const size_t int8_cdr_size = 1;
92 const size_t uint8_cdr_size = 1;
93 const size_t int16_cdr_size = 2;
94 const size_t uint16_cdr_size = 2;
95 const size_t int32_cdr_size = 4;
96 const size_t uint32_cdr_size = 4;
97 const size_t int64_cdr_size = 8;
98 const size_t uint64_cdr_size = 8;
99 const size_t float32_cdr_size = 4;
100 const size_t float64_cdr_size = 8;
101 const size_t float128_cdr_size = 16;
102 const size_t char8_cdr_size = 1;
103 const size_t char16_cdr_size = 2;
104 const size_t xcdr1_pid_alignment = 4;
105 
106 /// Align "value" by "by" if it's not already
108 void align(size_t& value, size_t by);
109 
110 /**
111  * Represents the serialization rules. Used to construct a
112  * Serializer and to pass to functions that are used without
113  * a Serializer like serialized_size() and max_serialized_size()
114  */
116 public:
117  /**
118  * Kinds are the overall algorithm for serialization.
119  * A Kind value along with other details like alignment and endianness
120  * comprise an Encoding.
121  */
122  enum Kind {
123  /**
124  * Extensible CDR version 1 from XTypes.
125  * This represents standard non-XTypes CDR if the type is final.
126  */
128  /**
129  * Extensible CDR version 2 from XTypes.
130  */
132  /**
133  * This is the classic encoding of OpenDDS used when there is no RTPS
134  * transport being used. It has no padding bytes and no XCDR behavior.
135  */
136  KIND_UNALIGNED_CDR
137  };
138 
139  enum Alignment {
140  ALIGN_NONE = 0, ///< No Alignment Needed
141  ALIGN_CDR = 8, ///< Align for CDR and XCDR1
142  ALIGN_XCDR2 = 4, ///< Align for XCDR2
143  ALIGN_MAX = ALIGN_CDR ///< Maximum alignment that could be used
144  };
145 
146  /**
147  * XCDR version derived from the Encoding kind.
148  */
149  enum XcdrVersion {
152  XCDR_VERSION_2
153  };
154 
155  /// Encoding with KIND_XCDR1 and ENDIAN_NATIVE
156  Encoding();
157 
158  explicit Encoding(Kind kind, Endianness endianness = ENDIAN_NATIVE);
159 
160  Encoding(Kind kind, bool swap_bytes);
161 
162  Kind kind() const;
163  void kind(Kind value);
164 
165  Endianness endianness() const;
166  void endianness(Endianness value);
167 
168  Alignment alignment() const;
169  void alignment(Alignment value);
170 
171  ///@{
172  /**
173  * Should the padding bytes being inserted into the stream be zero
174  * initialized?
175  */
176  bool zero_init_padding() const;
177  void zero_init_padding(bool value);
178  ///@}
179 
180  ///@{
181  /**
182  * Should the XCDR2 sequence DHEADER be skipped?
183  * This is not spec compliant -- used for compatibility with earlier
184  * OpenDDS versions that had a bug.
185  * Only used for XTypes::TypeObject and related structs.
186  */
187  bool skip_sequence_dheader() const;
188  void skip_sequence_dheader(bool value);
189  ///@}
190 
191  /// Return the maximum alignment dictated by the alignment policy.
192  size_t max_align() const;
193 
194  /// Align "value" to "by" and according to the stream's alignment.
195  void align(size_t& value, size_t by = (std::numeric_limits<size_t>::max)()) const;
196 
197  XcdrVersion xcdr_version() const;
198  void xcdr_version(XcdrVersion value);
199 
200  ///@{
201  /**
202  * Returns true if the encoding kind is excepted to have a header for RTPS
203  * serialized data payloads.
204  */
205  static bool is_encapsulated(Kind kind);
206  bool is_encapsulated() const;
207  ///@}
208 
209  String to_string() const;
210  static String kind_to_string(Kind value);
211 
212 private:
219 };
220 
221 /**
222  * Represents the RTPS encapsulation header for serialized data.
223  *
224  * This consists of 4 bytes that appear in front of the data. The first two
225  * bytes represents the kind of the encoding the data uses and the last two
226  * bytes (known as "options") are traditionally reserved.
227  *
228  * See XTypes 1.3 7.6.3.1.2
229  */
231 public:
232  /**
233  * The known possible values of the first 2 bytes represented as big endian
234  * integers.
235  */
236  enum Kind {
237  KIND_CDR_BE = 0x0000,
238  KIND_CDR_LE = 0x0001,
239  KIND_PL_CDR_BE = 0x0002,
240  KIND_PL_CDR_LE = 0x0003,
241  KIND_CDR2_BE = 0x0006,
242  KIND_CDR2_LE = 0x0007,
243  KIND_D_CDR2_BE = 0x0008,
244  KIND_D_CDR2_LE = 0x0009,
245  KIND_PL_CDR2_BE = 0x000a,
246  KIND_PL_CDR2_LE = 0x000b,
247  KIND_XML = 0x0004,
248  KIND_INVALID = 0xFFFF
249  };
250 
251  const static size_t serialized_size = 4;
252  const static size_t padding_marker_byte_index = 3;
253  const static size_t padding_marker_alignment = 4;
254 
255  EncapsulationHeader(Kind k = KIND_CDR_BE, ACE_CDR::UShort options = 0);
256 
257  /**
258  * Success can be verified using is_good()
259  */
260  EncapsulationHeader(const Encoding& enc, Extensibility ext, ACE_CDR::UShort options = 0);
261 
262  Kind kind() const;
263  void kind(Kind value);
264 
265  ACE_UINT16 options() const;
266  void options(ACE_UINT16 value);
267 
268  /**
269  * post-initialization test for a successful call to from_encoding during
270  * construction of this encapsulation header.
271  */
272  bool is_good() const;
273 
274  /**
275  * Translate from an encoding, returns false if it failed.
276  */
277  bool from_encoding(const Encoding& encoding, Extensibility extensibility);
278 
279  /**
280  * Translate to an encoding, returns false if it failed.
281  */
282  bool to_encoding(Encoding& encoding, Extensibility expected_extensibility);
283 
284  /**
285  * Like to_encoding, but without an expected extensibility.
286  */
287  bool to_any_encoding(Encoding& encoding);
288 
289  String to_string() const;
290 
291  static bool set_encapsulation_options(Message_Block_Ptr& mb);
292 
293 private:
294  /// The first two bytes as a big endian integer
296  /// The last two bytes as a big endian integer
298 
299  bool to_encoding_i(Encoding& encoding, Extensibility* expected_extensibility_ptr);
300 };
301 
302 class Serializer;
303 
305 bool operator>>(Serializer& s, EncapsulationHeader& value);
306 
308 bool operator<<(Serializer& s, const EncapsulationHeader& value);
309 
310 /**
311  * Convenience function for the serialized_size of a single value with no
312  * alignment needed.
313  */
314 template <typename T>
315 size_t serialized_size(const Encoding& encoding, const T& value)
316 {
317  size_t size = 0;
318  serialized_size(encoding, size, value);
319  return size;
320 }
321 
322 /**
323  * This helper class can be used to construct ACE message blocks from
324  * IDL sequences of octet (or compatible substitutes) and be used with
325  * the Serializer to serialize/deserialize directly into the byte
326  * buffer. The sequence must have its length set before constructing
327  * this object. T should provide a length() method which is the size
328  * of the buffer and get_buffer() which returns a pointer to the
329  * underlying byte sequence.
330  */
331 template <typename T>
333 public:
334  /**
335  * This constructor receives an already populated OctetSeq so the write pointer is advanced
336  */
337  explicit MessageBlockHelper(const T& seq)
338  : db_(seq.length(), ACE_Message_Block::MB_DATA,
339  reinterpret_cast<const char*>(seq.get_buffer()),
340  0 /*alloc*/, 0 /*lock*/, ACE_Message_Block::DONT_DELETE, 0 /*db_alloc*/)
341  , mb_(&db_, ACE_Message_Block::DONT_DELETE, 0 /*mb_alloc*/)
342  {
343  mb_.wr_ptr(mb_.space());
344  }
345 
346  explicit MessageBlockHelper(T& seq)
347  : db_(seq.length(), ACE_Message_Block::MB_DATA,
348  reinterpret_cast<const char*>(seq.get_buffer()),
349  0 /*alloc*/, 0 /*lock*/, ACE_Message_Block::DONT_DELETE, 0 /*db_alloc*/)
350  , mb_(&db_, ACE_Message_Block::DONT_DELETE, 0 /*mb_alloc*/)
351  {}
352 
353  operator ACE_Message_Block*() { return &mb_; }
354 
355 private:
358 };
359 
360 /**
361  * @class Serializer
362  *
363  * @brief Class to serialize and deserialize data for DDS.
364  *
365  * This class provides a mechanism to insert and extract data to and
366  * from an ACE_Message_Block chain that represents the data which
367  * can be transported on the wire to other DDS service participants.
368  */
370 public:
371  /// Flags and reserved ids used in parameter list ids.
372  ///@{
373  static const ACE_CDR::UShort pid_extended = 0x3f01;
374  /**
375  * Note that this is different than OpenDDS::RTPS::PID_SENTINEL(0x0001). See
376  * XTypes 1.3 Table 34 for details.
377  */
378  static const ACE_CDR::UShort pid_list_end = 0x3f02;
379  static const ACE_CDR::UShort pid_impl_extension = 0x8000;
380  static const ACE_CDR::UShort pid_must_understand = 0x4000;
381  ///@}
382 
383  // EMHEADER must understand flag
384  static const ACE_CDR::ULong emheader_must_understand = 1U << 31U;
385 
386  /// Maximum value for member id.
387  static const ACE_CDR::ULong MEMBER_ID_MAX = 0x0FFFFFFF;
388  static const ACE_CDR::ULong MEMBER_ID_MASK = MEMBER_ID_MAX;
389 
390  /**
391  * Constructor with a message block chain. This installs the
392  * message block chain and sets the current block to the first in
393  * the chain. Memory management is the responsibility of the owner
394  * of this object, and is not performed internally. Ownership of
395  * the message block chain is retained by the owner of this object
396  * and the lifetime of the chain must be longer than the use of
397  * this object.
398  *
399  * This constructor is meant for using a specific predefined encoding scheme.
400  */
402 
403  /**
404  * More convenient version of the constructor above if you don't need to
405  * reuse the Encoding object.
406  */
408  Endianness endianness = ENDIAN_NATIVE);
409 
410  /**
411  * Equivalent to: Serializer(chain, kind, swap_bytes ? ENDIAN_NONNATIVE : ENDIAN_NATIVE)
412  */
413  Serializer(ACE_Message_Block* chain, Encoding::Kind kind, bool swap_bytes);
414 
415  virtual ~Serializer();
416 
417  const Encoding& encoding() const;
418  void encoding(const Encoding& value);
419 
420  void swap_bytes(bool do_swap);
421  bool swap_bytes() const;
422 
423  Endianness endianness() const;
424  void endianness(Endianness value);
425 
426  Encoding::Alignment alignment() const;
427  void alignment(Encoding::Alignment value);
428 
429  /// Reset alignment as if a new instance were created
430  void reset_alignment();
431 
432  bool good_bit() const;
433 
434  /// Number of bytes left to read in message block chain
435  size_t length() const;
436 
437  typedef ACE_CDR::Char* (*StrAllocate)(ACE_CDR::ULong);
438  typedef void (*StrFree)(ACE_CDR::Char*);
439  typedef ACE_CDR::WChar* (*WStrAllocate)(ACE_CDR::ULong);
440  typedef void (*WStrFree)(ACE_CDR::WChar*);
441 
442  size_t read_string(ACE_CDR::Char*& dest,
443  StrAllocate str_alloc = 0,
444  StrFree str_free = 0);
445 
446  void free_string(ACE_CDR::Char* str,
447  StrFree str_free = 0);
448 
449  size_t read_string(ACE_CDR::WChar*& dest,
450  WStrAllocate str_alloc = 0,
451  WStrFree str_free = 0);
452 
453  void free_string(ACE_CDR::WChar* str,
454  WStrFree str_free = 0);
455 
456  /// Skip the logical rd_ptr() over a given number of bytes = n * size.
457  /// If alignment is enabled, skips any padding to align to 'size' before
458  /// skipping the n * size bytes.
459  /// This is used by the RTPS protocol to allow reading messages from
460  /// future versions of the spec which may have additional optional fields.
461  bool skip(size_t n, int size = 1);
462 
463  /// Return a duplicated Message Block (chain) which starts at the current
464  /// read position (rpos) and extends for n bytes.
465  /// This can be used to treat a subset of the original message as if it
466  /// was itself a full message, for example the SerializedPayload or the
467  /// Parameter value inside a ParameterList.
468  /// The returned object should be release()'d (use Message_Block_Ptr)
469  ACE_Message_Block* trim(size_t n) const;
470 
471  const char* pos_rd() const { return current_ ? current_->rd_ptr() : 0; }
472  const char* pos_wr() const { return current_ ? current_->wr_ptr() : 0; }
473 
474  /// Examine the logical reading position of the stream.
475  size_t rpos() const { return rpos_; }
476 
477  /// Examine the logical writing position of the stream.
478  size_t wpos() const { return wpos_; }
479 
481  {
482  return current_;
483  }
484 
485  /**
486  * Read basic IDL types arrays
487  * The buffer @a x must be large enough to contain @a length
488  * elements.
489  * Return @c false on failure and @c true on success.
490  */
491  ///@{
492  bool read_boolean_array(ACE_CDR::Boolean* x, ACE_CDR::ULong length);
493  bool read_char_array(ACE_CDR::Char* x, ACE_CDR::ULong length);
494  bool read_wchar_array(ACE_CDR::WChar* x, ACE_CDR::ULong length);
495  bool read_octet_array(ACE_CDR::Octet* x, ACE_CDR::ULong length);
496 #if OPENDDS_HAS_EXPLICIT_INTS
497  bool read_int8_array(ACE_CDR::Int8* x, ACE_CDR::ULong length);
498  bool read_uint8_array(ACE_CDR::UInt8* x, ACE_CDR::ULong length);
499 #endif
500  bool read_short_array(ACE_CDR::Short* x, ACE_CDR::ULong length);
501  bool read_ushort_array(ACE_CDR::UShort* x, ACE_CDR::ULong length);
502  bool read_long_array(ACE_CDR::Long* x, ACE_CDR::ULong length);
503  bool read_ulong_array(ACE_CDR::ULong* x, ACE_CDR::ULong length);
504  bool read_longlong_array(ACE_CDR::LongLong* x, ACE_CDR::ULong length);
505  bool read_ulonglong_array(ACE_CDR::ULongLong* x, ACE_CDR::ULong length);
506  bool read_float_array(ACE_CDR::Float* x, ACE_CDR::ULong length);
507  bool read_double_array(ACE_CDR::Double* x, ACE_CDR::ULong length);
508  bool read_longdouble_array(ACE_CDR::LongDouble* x, ACE_CDR::ULong length);
509  ///@}
510 
511  /// Array write operations
512  /// Note: the portion written starts at x and ends
513  /// at x + length.
514  /// The length is *NOT* stored into the CDR stream.
515  ///@{
516  bool write_boolean_array(const ACE_CDR::Boolean* x, ACE_CDR::ULong length);
517  bool write_char_array(const ACE_CDR::Char* x, ACE_CDR::ULong length);
518  bool write_wchar_array(const ACE_CDR::WChar* x, ACE_CDR::ULong length);
519  bool write_octet_array(const ACE_CDR::Octet* x, ACE_CDR::ULong length);
520 #if OPENDDS_HAS_EXPLICIT_INTS
521  bool write_int8_array(const ACE_CDR::Int8* x, ACE_CDR::ULong length);
522  bool write_uint8_array(const ACE_CDR::UInt8* x, ACE_CDR::ULong length);
523 #endif
524  bool write_short_array(const ACE_CDR::Short* x, ACE_CDR::ULong length);
525  bool write_ushort_array(const ACE_CDR::UShort* x, ACE_CDR::ULong length);
526  bool write_long_array(const ACE_CDR::Long* x, ACE_CDR::ULong length);
527  bool write_ulong_array(const ACE_CDR::ULong* x, ACE_CDR::ULong length);
528  bool write_longlong_array(const ACE_CDR::LongLong* x, ACE_CDR::ULong length);
529  bool write_ulonglong_array(const ACE_CDR::ULongLong* x, ACE_CDR::ULong length);
530  bool write_float_array(const ACE_CDR::Float* x, ACE_CDR::ULong length);
531  bool write_double_array(const ACE_CDR::Double* x, ACE_CDR::ULong length);
532  bool write_longdouble_array(const ACE_CDR::LongDouble* x, ACE_CDR::ULong length);
533  ///@}
534 
535  friend OpenDDS_Dcps_Export
536  bool operator<<(Serializer& s, ACE_CDR::Char x);
537  friend OpenDDS_Dcps_Export
539  friend OpenDDS_Dcps_Export
541  friend OpenDDS_Dcps_Export
542  bool operator<<(Serializer& s, ACE_CDR::Long x);
543  friend OpenDDS_Dcps_Export
545  friend OpenDDS_Dcps_Export
547  friend OpenDDS_Dcps_Export
549  friend OpenDDS_Dcps_Export
551  friend OpenDDS_Dcps_Export
553  friend OpenDDS_Dcps_Export
555  friend OpenDDS_Dcps_Export
556  bool operator<<(Serializer& s, const ACE_CDR::Char* x);
557  friend OpenDDS_Dcps_Export
558  bool operator<<(Serializer& s, const ACE_CDR::WChar* x);
559 
560 #ifdef NONNATIVE_LONGDOUBLE
561  friend OpenDDS_Dcps_Export
562  bool operator<<(Serializer& s, long double x);
563 #endif
564 
565  // Using the ACE CDR Stream disambiguators.
566  friend OpenDDS_Dcps_Export
568  friend OpenDDS_Dcps_Export
570  friend OpenDDS_Dcps_Export
572  friend OpenDDS_Dcps_Export
574  friend OpenDDS_Dcps_Export
576  friend OpenDDS_Dcps_Export
578 #if OPENDDS_HAS_EXPLICIT_INTS
579  friend OpenDDS_Dcps_Export
581  friend OpenDDS_Dcps_Export
583 #endif
584 
585  friend OpenDDS_Dcps_Export
586  bool operator<<(Serializer& s, const String& x);
587 
588  template <typename CharT>
590  typedef std::basic_string<CharT, std::char_traits<CharT>,
593  : str_(str), bound_(bound) {}
594  const string_t& str_;
596  };
597 
598  friend OpenDDS_Dcps_Export
599  bool operator<<(Serializer& s, FromBoundedString<char> x);
600 
601 #ifdef DDS_HAS_WCHAR
602  friend OpenDDS_Dcps_Export
603  bool operator<<(Serializer& s, const WString& x);
604 
605  friend OpenDDS_Dcps_Export
606  bool operator<<(Serializer& s, FromBoundedString<wchar_t> x);
607 #endif /* DDS_HAS_WCHAR */
608 
609  // Extraction operators.
610  friend OpenDDS_Dcps_Export
611  bool operator>>(Serializer& s, ACE_CDR::Char& x);
612  friend OpenDDS_Dcps_Export
613  bool operator>>(Serializer& s, ACE_CDR::Short& x);
614  friend OpenDDS_Dcps_Export
616  friend OpenDDS_Dcps_Export
617  bool operator>>(Serializer& s, ACE_CDR::Long& x);
618  friend OpenDDS_Dcps_Export
619  bool operator>>(Serializer& s, ACE_CDR::ULong& x);
620  friend OpenDDS_Dcps_Export
622  friend OpenDDS_Dcps_Export
624  friend OpenDDS_Dcps_Export
625  bool operator>>(Serializer& s, ACE_CDR::Float& x);
626  friend OpenDDS_Dcps_Export
628  friend OpenDDS_Dcps_Export
630  friend OpenDDS_Dcps_Export
631  bool operator>>(Serializer& s, ACE_CDR::Char*& x);
632  friend OpenDDS_Dcps_Export
633  bool operator>>(Serializer& s, ACE_CDR::WChar*& x);
634 
635 #ifdef NONNATIVE_LONGDOUBLE
636  friend OpenDDS_Dcps_Export
637  bool operator>>(Serializer& s, long double& x);
638 #endif
639 
640  // Using the ACE CDR Stream disambiguators.
641  friend OpenDDS_Dcps_Export
643  friend OpenDDS_Dcps_Export
645  friend OpenDDS_Dcps_Export
647  friend OpenDDS_Dcps_Export
649  friend OpenDDS_Dcps_Export
651  friend OpenDDS_Dcps_Export
653 #if OPENDDS_HAS_EXPLICIT_INTS
654  friend OpenDDS_Dcps_Export
656  friend OpenDDS_Dcps_Export
658 #endif
659 
660  friend OpenDDS_Dcps_Export
661  bool operator>>(Serializer& s, String& x);
662 
663  template <typename CharT>
665  typedef std::basic_string<CharT, std::char_traits<CharT>,
668  : str_(str), bound_(bound) {}
671  };
672 
673  friend OpenDDS_Dcps_Export
675 
676 #ifdef DDS_HAS_WCHAR
677  friend OpenDDS_Dcps_Export
678  bool operator>>(Serializer& s, WString& x);
679 
680  friend OpenDDS_Dcps_Export
682 #endif /* DDS_HAS_WCHAR */
683 
684  /// Read from the chain into a destination buffer.
685  // This method doesn't respect alignment, so use with care.
686  // Any of the other public methods (which know the type) are preferred.
687  void buffer_read(char* dest, size_t size, bool swap);
688 
689  /// Align for reading: moves current_->rd_ptr() past the alignment padding.
690  /// Alignments of 2, 4, or 8 are supported by CDR and this implementation.
691  bool align_r(size_t alignment);
692 
693  /// Align for writing: moves current_->wr_ptr() past the padding, possibly
694  /// zero-filling the pad bytes (based on the alignment_ setting).
695  /// Alignments of 2, 4, or 8 are supported by CDR and this implementation.
696  bool align_w(size_t alignment);
697 
698  /**
699  * Read a XCDR parameter ID used in XCDR parameter lists.
700  *
701  * Returns true if successful.
702  */
703  bool read_parameter_id(unsigned& id, size_t& size, bool& must_understand);
704 
705  /**
706  * Write a XCDR parameter ID used in XCDR parameter lists.
707  *
708  * Returns true if successful.
709  */
710  bool write_parameter_id(const unsigned id, size_t size, bool must_understand = false);
711 
712  /**
713  * Write the parameter ID that marks the end of XCDR1 parameter lists.
714  *
715  * Returns true if successful.
716  */
717  bool write_list_end_parameter_id();
718 
719  /**
720  * Skip a delimiter used for XCDR2 delimited data.
721  *
722  * Returns true if successful
723  */
724  bool skip_delimiter();
725 
726  /**
727  * Read a delimiter used for XCDR2 delimited data.
728  *
729  * Returns true if successful and size will be set to the size of the CDR
730  * value excluding the delimiter.
731  */
732  bool read_delimiter(size_t& size);
733 
734  /**
735  * Write a delimiter used for XCDR2 delimited data.
736  *
737  * Size is assumed to include the delimiter as serialized_size would return.
738  * Returns true if successful.
739  */
740  bool write_delimiter(size_t size);
741 
745  BoundConstructionFailure
746  };
747 
748  ConstructionStatus get_construction_status() const;
749 
750  void set_construction_status(ConstructionStatus cs);
751 
753  explicit ScopedAlignmentContext(Serializer& ser, size_t min_read = 0);
754  virtual ~ScopedAlignmentContext() { restore(ser_); }
755 
756  void restore(Serializer& ser) const;
757 
759  const size_t max_align_;
760  const size_t start_rpos_;
761  const size_t rblock_;
762  const size_t min_read_;
763  const size_t start_wpos_;
764  const size_t wblock_;
765  };
766 
767  template <typename T>
768  bool peek_helper(ACE_Message_Block* const block, size_t bytes, T& t)
769  {
770  bool result = false;
771  char* const rd_ptr = block->rd_ptr();
772  const size_t length = block->length();
773  if (!block->cont() || length == 0 || (bytes != 0 && bytes <= length)) {
774  result = *this >> t;
775  } else {
776  result = peek_helper(block->cont(), bytes - length, t);
777  }
778  block->rd_ptr(rd_ptr);
779  return result;
780  }
781 
782  template <typename T>
783  bool peek(T& t)
784  {
785  // save
786  const size_t rpos = rpos_;
787  const unsigned char align_rshift = align_rshift_;
788  ACE_Message_Block* const current = current_;
789 
790  // read
791  if (!peek_helper(current_, 0, t)) {
792  return false;
793  }
794 
795  // reset
796  current_ = current;
797  align_rshift_ = align_rshift;
798  rpos_ = rpos;
799  return true;
800  }
801 
802  bool peek(ACE_CDR::ULong& t);
803 
804  // This is used by DynamicData and must have all reading-related members of
805  // of Serializer for DynamicData to work correctly.
806  struct RdState {
807  explicit RdState(unsigned char shift = 0, size_t pos = 0)
808  : align_rshift(shift), rpos(pos) {}
809  unsigned char align_rshift;
810  size_t rpos;
811  };
812 
813  RdState rdstate() const;
814  void rdstate(const RdState& state);
815 
816 private:
817  ///@{
818  /// Read an array of values from the chain.
819  /// NOTE: This assumes that the buffer contains elements that are
820  /// properly aligned. The buffer must have padding if the
821  /// elements are not naturally aligned; or this routine should
822  /// not be used.
823  void read_array(char* x, size_t size, ACE_CDR::ULong length);
824  void read_array(char* x, size_t size, ACE_CDR::ULong length, bool swap);
825  ///@}
826 
827  /// Write to the chain from a source buffer.
828  void buffer_write(const char* src, size_t size, bool swap);
829 
830  ///@{
831  /// Write an array of values to the chain.
832  /// NOTE: This assumes that there is _no_ padding between the array
833  /// elements. If this is not the case, do not use this
834  /// method. If padding exists in the array, it will be
835  /// written when _not_ swapping, and will _not_ be written
836  /// when swapping, resulting in corrupted data.
837  void write_array(const char* x, size_t size, ACE_CDR::ULong length);
838  void write_array(const char* x, size_t size, ACE_CDR::ULong length, bool swap);
839  ///@}
840 
841  /// Efficient straight copy for quad words and shorter. This is
842  /// an instance method to match the swapcpy semantics.
843  void smemcpy(char* to, const char* from, size_t n);
844 
845  /// Efficient swapping copy for quad words and shorter. This is an
846  /// instance method to allow clearing the good_bit_ on error.
847  void swapcpy(char* to, const char* from, size_t n);
848 
849  /// Implementation of the actual read from the chain.
850  size_t doread(char* dest, size_t size, bool swap, size_t offset);
851 
852  /// Implementation of the actual write to the chain.
853  size_t dowrite(const char* dest, size_t size, bool swap, size_t offset);
854 
855  /// Update alignment state when a cont() chain is followed during a read.
856  void align_cont_r();
857 
858  /// Update alignment state when a cont() chain is followed during a write.
859  void align_cont_w();
860 
861  static unsigned char offset(char* index, size_t start, size_t align);
862 
863  /// Currently active message block in chain.
865 
866  /// Encoding Settings
868 
869  /// Indicates whether bytes will be swapped for this stream.
871 
872  /// Indicates the current state of the stream abstraction.
873  bool good_bit_;
874 
875  /// The way to judge whether tryconstruct trim is able to be properly done
877 
878  /**
879  * Number of bytes off of max alignment that the current_ block's rd_ptr()
880  * started at.
881  */
882  unsigned char align_rshift_;
883 
884  /**
885  * Number of bytes off of max alignment that the current_ block's wr_ptr()
886  * started at.
887  */
888  unsigned char align_wshift_;
889 
890  /// Logical reading position of the stream.
891  size_t rpos_;
892 
893  /// Logical writing position of the stream.
894  size_t wpos_;
895 
896  /// Buffer that is copied for zero padding
897  static const char ALIGN_PAD[Encoding::ALIGN_MAX];
898 };
899 
900 template<typename Type>
901 struct KeyOnly {
902  explicit KeyOnly(Type& value)
903  : value(value)
904  {
905  }
906 
907  operator Type&() const
908  {
909  return value;
910  }
911 
912  Type& value;
913 };
914 
915 template<typename Type>
917  explicit NestedKeyOnly(Type& value)
918  : value(value)
919  {
920  }
921 
922  operator Type&() const
923  {
924  return value;
925  }
926 
927  Type& value;
928 };
929 
930 namespace IDL {
931  // Although similar to C++11 reference_wrapper, this template has the
932  // additional Tag parameter to allow the IDL compiler to generate distinct
933  // overloads for sequence/array typedefs that map to the same C++ types.
934  template <typename T, typename /*Tag*/>
935  struct DistinctType {
936  typedef T value_type;
937  T* val_;
938  DistinctType(T& val) : val_(&val) {}
939  operator T&() const { return *val_; }
940  };
941 }
942 
943 template<typename Type>
944 void set_default(Type&)
945 {
946  OPENDDS_ASSERT(false);
947 }
948 
949 template<typename Type, typename Tag>
951 {
952  OPENDDS_ASSERT(false);
953 }
954 
955 // predefined type methods
958  const Encoding& encoding, size_t& size, const ACE_CDR::Short& value,
959  size_t count = 1);
962  const Encoding& encoding, size_t& size, const ACE_CDR::UShort& value,
963  size_t count = 1);
966  const Encoding& encoding, size_t& size, const ACE_CDR::Long& value,
967  size_t count = 1);
970  const Encoding& encoding, size_t& size, const ACE_CDR::ULong& value,
971  size_t count = 1);
974  const Encoding& encoding, size_t& size, const ACE_CDR::LongLong& value,
975  size_t count = 1);
978  const Encoding& encoding, size_t& size, const ACE_CDR::ULongLong& value,
979  size_t count = 1);
982  const Encoding& encoding, size_t& size, const ACE_CDR::Float& value,
983  size_t count = 1);
986  const Encoding& encoding, size_t& size, const ACE_CDR::Double& value,
987  size_t count = 1);
990  const Encoding& encoding, size_t& size, const ACE_CDR::LongDouble& value,
991  size_t count = 1);
992 
993 // predefined type method disambiguators.
996  const Encoding& encoding, size_t& size,
997  const ACE_OutputCDR::from_boolean value, size_t count = 1);
1000  const Encoding& encoding, size_t& size,
1001  const ACE_OutputCDR::from_char value, size_t count = 1);
1004  const Encoding& encoding, size_t& size,
1005  const ACE_OutputCDR::from_wchar value, size_t count = 1);
1008  const Encoding& encoding, size_t& size,
1009  const ACE_OutputCDR::from_octet value, size_t count = 1);
1010 #if OPENDDS_HAS_EXPLICIT_INTS
1013  const Encoding& encoding, size_t& size,
1014  const ACE_OutputCDR::from_uint8 value, size_t count = 1);
1017  const Encoding& encoding, size_t& size,
1018  const ACE_OutputCDR::from_int8 value, size_t count = 1);
1019 #endif
1020 
1021 // predefined type method explicit disambiguators.
1023 void primitive_serialized_size_boolean(const Encoding& encoding, size_t& size,
1024  size_t count = 1);
1026 void primitive_serialized_size_char(const Encoding& encoding, size_t& size,
1027  size_t count = 1);
1029 void primitive_serialized_size_wchar(const Encoding& encoding, size_t& size,
1030  size_t count = 1);
1032 void primitive_serialized_size_octet(const Encoding& encoding, size_t& size,
1033  size_t count = 1);
1035 void primitive_serialized_size_ulong(const Encoding& encoding, size_t& size,
1036  size_t count = 1);
1037 #if OPENDDS_HAS_EXPLICIT_INTS
1039 void primitive_serialized_size_uint8(const Encoding& encoding, size_t& size,
1040  size_t count = 1);
1042 void primitive_serialized_size_int8(const Encoding& encoding, size_t& size,
1043  size_t count = 1);
1044 #endif
1045 
1046 /// Add delimiter to the size of a serialized size if the encoding has them.
1048 void serialized_size_delimiter(const Encoding& encoding, size_t& size);
1049 
1052  const Encoding& encoding, size_t& size, size_t& running_size);
1053 
1056  const Encoding& encoding, size_t& size, size_t& running_size);
1057 
1058 } // namespace DCPS
1059 } // namespace OpenDDS
1060 
1062 
1063 #ifdef __ACE_INLINE__
1064 # include "Serializer.inl"
1065 #endif
1066 
1067 #endif /* OPENDDS_DCPS_SERIALIZER_H */
ACE_Byte Octet
const size_t boolean_cdr_size
Definition: Serializer.h:89
#define ACE_BEGIN_VERSIONED_NAMESPACE_DECL
void swap(MessageBlock &lhs, MessageBlock &rhs)
std::wstring WString
size_t rpos() const
Examine the logical reading position of the stream.
Definition: Serializer.h:475
const size_t int8_cdr_size
Definition: Serializer.h:91
ACE_INT64 LongLong
const LogLevel::Value value
Definition: debug.cpp:61
const size_t uint64_cdr_size
Definition: Serializer.h:98
std::string String
bool swap_bytes_
Indicates whether bytes will be swapped for this stream.
Definition: Serializer.h:870
OpenDDS_Dcps_Export void primitive_serialized_size_ulong(const Encoding &encoding, size_t &size, size_t count=1)
const size_t int64_cdr_size
Definition: Serializer.h:97
size_t length(void) const
size_t wpos() const
Examine the logical writing position of the stream.
Definition: Serializer.h:478
ToBoundedString(string_t &str, ACE_CDR::ULong bound)
Definition: Serializer.h:667
ConstructionStatus construction_status_
The way to judge whether tryconstruct trim is able to be properly done.
Definition: Serializer.h:876
Kind kind_
The first two bytes as a big endian integer.
Definition: Serializer.h:295
void set_default(Type &)
Definition: Serializer.h:944
#define OpenDDS_Dcps_Export
Definition: dcps_export.h:24
YARD is all original work While it may rely on standard YARD does not include code from other sources We have chosen to release our work as public domain code This means that YARD has been released outside the copyright system Feel free to use the code in any way you wish especially in an academic plagiarism has very little to do with copyright In an academic or in any situation where you are expected to give credit to other people s you will need to cite YARD as a source The author is Christopher and the appropriate date is December the release date for we can t make any promises regarding whether YARD will do what you or whether we will make any changes you ask for You are free to hire your own expert for that If you choose to distribute YARD you ll probably want to read up on the laws covering warranties in your state
Definition: COPYING.txt:14
OpenDDS_Dcps_Export void serialized_size_delimiter(const Encoding &encoding, size_t &size)
Add delimiter to the size of a serialized size if the encoding has them.
ACE_UINT64 ULongLong
OpenDDS_Dcps_Export void primitive_serialized_size_octet(const Encoding &encoding, size_t &size, size_t count=1)
#define OPENDDS_ASSERT(C)
Definition: Definitions.h:72
const size_t float64_cdr_size
Definition: Serializer.h:100
String endianness_to_string(Endianness endianness)
Definition: Serializer.cpp:57
RdState(unsigned char shift=0, size_t pos=0)
Definition: Serializer.h:807
const size_t int16_cdr_size
Definition: Serializer.h:93
void serialized_size(const Encoding &encoding, size_t &size, const SequenceNumber &)
const size_t uint32_cdr_size
Definition: Serializer.h:96
char * rd_ptr(void) const
Encoding encoding_
Encoding Settings.
Definition: Serializer.h:867
ACE_CDR::UShort options_
The last two bytes as a big endian integer.
Definition: Serializer.h:297
const size_t float32_cdr_size
Definition: Serializer.h:99
#define OPENDDS_ALLOCATOR(T)
OpenDDS_Dcps_Export void primitive_serialized_size_char(const Encoding &encoding, size_t &size, size_t count=1)
ACE_INT16 Short
Class to serialize and deserialize data for DDS.
Definition: Serializer.h:369
ACE_CDR::Boolean operator<<(Serializer &serializer, CoherentChangeControl &value)
Marshal/Insertion into a buffer.
const size_t xcdr1_pid_alignment
Definition: Serializer.h:104
OpenDDS_Dcps_Export void primitive_serialized_size_wchar(const Encoding &encoding, size_t &size, size_t count=1)
unsigned char align_wshift_
Definition: Serializer.h:888
const size_t char8_cdr_size
Definition: Serializer.h:102
char Char
FromBoundedString(const string_t &str, ACE_CDR::ULong bound)
Definition: Serializer.h:592
size_t wpos_
Logical writing position of the stream.
Definition: Serializer.h:894
ACE_UINT16 UShort
ACE_Message_Block * current() const
Definition: Serializer.h:480
ACE_Message_Block * cont(void) const
#define ACE_END_VERSIONED_NAMESPACE_DECL
const size_t uint8_cdr_size
Definition: Serializer.h:92
ACE_UINT32 ULong
OpenDDS_Dcps_Export void align(size_t &value, size_t by)
Align "value" by "by" if it&#39;s not already.
Definition: Serializer.inl:23
const size_t int32_cdr_size
Definition: Serializer.h:95
bool good_bit_
Indicates the current state of the stream abstraction.
Definition: Serializer.h:873
OpenDDS_Dcps_Export void serialized_size_parameter_id(const Encoding &encoding, size_t &size, size_t &running_size)
ACE_INT32 Long
std::basic_string< CharT, std::char_traits< CharT >, OPENDDS_ALLOCATOR(CharT) > string_t
Definition: Serializer.h:666
KeyOnly(Type &value)
Definition: Serializer.h:902
const size_t char16_cdr_size
Definition: Serializer.h:103
ACE_INT8 Int8
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
ACE_Message_Block * current_
Currently active message block in chain.
Definition: Serializer.h:864
bool peek_helper(ACE_Message_Block *const block, size_t bytes, T &t)
Definition: Serializer.h:768
ACE_CDR::Boolean operator>>(Serializer &serializer, CoherentChangeControl &value)
const size_t uint16_cdr_size
Definition: Serializer.h:94
const char * to_string(MessageId value)
unsigned char align_rshift_
Definition: Serializer.h:882
ACE_WCHAR_T WChar
const char * pos_rd() const
Definition: Serializer.h:471
const DCPS::Encoding encoding(DCPS::Encoding::KIND_UNALIGNED_CDR, DCPS::ENDIAN_BIG)
const size_t byte_cdr_size
Definition: Serializer.h:90
size_t rpos_
Logical reading position of the stream.
Definition: Serializer.h:891
bool Boolean
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
std::basic_string< CharT, std::char_traits< CharT >, OPENDDS_ALLOCATOR(CharT) > string_t
Definition: Serializer.h:591
OpenDDS_Dcps_Export void serialized_size_list_end_parameter_id(const Encoding &encoding, size_t &size, size_t &running_size)
const char * ext_to_string(Extensibility ext)
Definition: Serializer.h:75
OpenDDS_Dcps_Export void primitive_serialized_size_boolean(const Encoding &encoding, size_t &size, size_t count=1)
const char * pos_wr() const
Definition: Serializer.h:472
ACE_UINT8 UInt8
const size_t float128_cdr_size
Definition: Serializer.h:101
extensibility(MUTABLE) struct TypeLookup_getTypes_In
Definition: TypeLookup.idl:29
XcdrVersion xcdr_version_
Definition: Serializer.h:218
Maximum alignment that could be used.
Definition: Serializer.h:143
OpenDDS_Dcps_Export bool primitive_serialized_size(const Encoding &encoding, size_t &size, const ACE_CDR::Short &value, size_t count=1)