RTI Connext Traditional C++ API Version 7.3.0
BuilderHelper.hpp
1/*
2(c) Copyright, Real-Time Innovations, 2018.
3All rights reserved.
4
5No duplications, whole or partial, manual or electronic, may be made
6without express written permission. Any such copies, or
7revisions thereof, must display this notice unaltered.
8This code contains trade secrets of Real-Time Innovations, Inc.
9*/
10
11#ifndef RTI_DDS_FLAT_BUILDERHELPER_HPP_
12#define RTI_DDS_FLAT_BUILDERHELPER_HPP_
13
14namespace rti { namespace flat {
15
16template <typename T>
17class PrimitiveSequenceBuilder;
18
19template <typename ElementBuilder>
20class MutableSequenceBuilder;
21
22template <typename ElementOffset>
23class FinalSequenceBuilder;
24
25template <typename ElementBuilder, unsigned int N>
26class MutableArrayBuilder;
27
28class StringBuilder;
29
30namespace detail {
31
32//
33// lc_code:
34//
35
36template <size_t PrimitiveSize>
37struct primitive_lc_code_helper;
38
39template <>
40struct primitive_lc_code_helper<1> {
41 enum {
42 single = 0, // LC = 1 => member length is 1
43 sequence = 5 // LC = 5 => member length is also NEXTINT
44 };
45};
46
47template <>
48struct primitive_lc_code_helper<2> {
49 enum {
50 single = 1, // LC = 1 => member length is 2
51 sequence = 4 // LC = 4 => member length is provided as an additional int
52 };
53};
54
55template <>
56struct primitive_lc_code_helper<4> {
57 enum {
58 single = 2, // LC = 2 => member length is 4
59 sequence = 6 // LC = 6 => member length is 4 * NEXTINT
60 };
61};
62
63template <>
64struct primitive_lc_code_helper<8> {
65 enum {
66 single = 3, // LC = 3 => member length is 8
67 sequence = 7 // LC = 7 => member length is 8 * NEXTINT
68 };
69};
70
71template <typename T>
72struct primitive_lc_code {
73 enum { value = primitive_lc_code_helper<sizeof(T)>::single };
74};
75
76// In general, use LC = 5, for mutable aggregation types. Final aggregation
77// types don't use this 'lc_code' trait type. The other cases are specialized
78// after this.
79template <typename T, typename Enable = void>
80struct lc_code {
81 static int value()
82 {
83 return 5; // LC = 5 => member length is provided in NEXTINT/
84 }
85};
86
87// For collections of complex types and enums, if we serialize the DHeader
88// (XCDR2 compliant behavior) we use LC = 5; if we don't (legacy RTI behavior)
89// we use LC = 4, since we codify the length in the member header.
90template <typename T>
91struct lc_code<MutableSequenceBuilder<T> > {
92 static int value()
93 {
94 return is_dheader_required_in_non_primitive_collections() ? 5 : 4;
95 }
96};
97
98template <typename T>
99struct lc_code<FinalSequenceBuilder<T> > {
100 static int value()
101 {
102 return is_dheader_required_in_non_primitive_collections() ? 5 : 4;
103 }
104};
105
106template <typename T, unsigned int N>
107struct lc_code<MutableArrayBuilder<T, N> > {
108 static int value()
109 {
110 return is_dheader_required_in_non_primitive_collections() ? 5 : 4;
111 }
112};
113
114#if defined(RTI_FLAT_DATA_NO_EXCEPTIONS)
115
116// Traditional C++: no support for std::is_enum<T>
117
118template <typename T>
119struct lc_code<PrimitiveSequenceBuilder<T> > {
120 static int value()
121 {
122 return primitive_lc_code_helper<sizeof(T)>::sequence;
123 }
124};
125
126#else
127
128template <typename T>
129struct lc_code<
130 PrimitiveSequenceBuilder<T>,
131 typename std::enable_if<!std::is_enum<T>::value>::type> {
132 static int value()
133 {
134 return primitive_lc_code_helper<sizeof(T)>::sequence;
135 }
136};
137
138template <typename T>
139struct lc_code<
140 PrimitiveSequenceBuilder<T>,
141 typename std::enable_if<std::is_enum<T>::value>::type> {
142 static int value()
143 {
144 return is_dheader_required_in_enum_collections()
145 ? 5
146 : primitive_lc_code_helper<sizeof(T)>::sequence;
147 }
148};
149
150#endif
151
152
153//
154// Initialization of final types
155//
156
157template <typename Offset>
158struct final_offset_initializer {
159
160 static bool initialize(Offset& offset)
161 {
162 return RTI_XCDR_TRUE == RTIXCdrFlatData_initializeSample(
163 (char *) offset.get_buffer(),
164 offset.get_buffer_size(),
165 rti::xcdr::type_programs<rti::flat::Sample<Offset> >::get());
166 }
167
168};
169
170// This will be specialized for enums in generated code (traditional C++)
171// and for enum classes in FlatDataTraits.hpp (modern C++)
172template <typename T, typename Enable = void>
173struct default_primitive_value {
174 static T get()
175 {
176 return (T) 0;
177 }
178};
179
180template <typename T, unsigned int N>
181struct final_offset_initializer<rti::flat::PrimitiveArrayOffset<T, N> > {
182
183 static bool initialize(rti::flat::PrimitiveArrayOffset<T, N>& array)
184 {
185 T default_value = default_primitive_value<T>::get();
186 if (default_value == (T) 0) { // don't need to deal with endianness
187 memset(array.get_buffer(), 0, array.get_buffer_size());
188 } else {
189 for (unsigned int i = 0; i < array.element_count(); i++) {
190 array.set_element(i, default_value);
191 }
192 }
193 return true;
194 }
195};
196
197template <typename T, unsigned int N>
198struct final_offset_initializer<rti::flat::FinalAlignedArrayOffset<T, N> > {
199
200 static bool initialize(rti::flat::FinalAlignedArrayOffset<T, N>& array)
201 {
202 for (unsigned int i = 0; i < N; i++) {
203 T offset = array.get_element(i);
204 if (offset.is_null()) {
205 return false;
206 }
207
208 if (!final_offset_initializer<T>::initialize(offset)) {
209 return false;
210 }
211 }
212
213 return true;
214 }
215};
216
217} } }
218
219#endif // RTI_DDS_FLAT_BUILDERHELPER_HPP_
220
bool set_element(unsigned int i, T value)
Sets an element by index.
Definition: SequenceOffsets.hpp:111
Offset to an array of final elements.
Definition: SequenceOffsets.hpp:776
ElementOffset get_element(unsigned int i)
Gets the Offset to an element.
Definition: SequenceOffsets.hpp:815
const unsigned char * get_buffer() const
Gets this member's position in the buffer.
Definition: Offset.hpp:627
offset_t get_buffer_size() const
Gets the size, in bytes, of this member in the buffer.
Definition: Offset.hpp:641
Offset to an array of primitive elements.
Definition: SequenceOffsets.hpp:241
unsigned int element_count() const
Returns the number of elements, N.
Definition: SequenceOffsets.hpp:263
The generic definition of FlatData topic-types.
Definition: FlatSample.hpp:148
The RTI namespace.
Definition: AggregationBuilders.hpp:17