11#ifndef RTI_DDS_FLAT_SEQUENCEBUILDERS_HPP_
12#define RTI_DDS_FLAT_SEQUENCEBUILDERS_HPP_
14#include "rti/flat/Builder.hpp"
37namespace rti {
namespace flat {
41template <
bool IsForEnum>
42struct DHeaderGeneratorImpl {
43 static bool reserve_dheader(rti::xcdr::Stream& stream)
45 if (collection_dheader_traits<IsForEnum>::dheader_required()) {
46 return stream.serialize_dheader() != NULL;
52 static bool finish_dheader(
53 rti::xcdr::Stream& stream,
54 unsigned char *dheader_position)
56 if (collection_dheader_traits<IsForEnum>::dheader_required()) {
57 return stream.finish_dheader((
char *) dheader_position);
63 static bool move_after_dheader(
64 rti::xcdr::Stream& stream,
65 unsigned char *begin_position)
67 stream.current_position(begin_position);
69 if (collection_dheader_traits<IsForEnum>::dheader_required()) {
70 return stream.skip(RTI_XCDR_DHEADER_SIZE);
77struct NoDHeaderGenerator {
78 static bool reserve_dheader(rti::xcdr::Stream&)
83 static bool finish_dheader(rti::xcdr::Stream&,
unsigned char *)
88 static bool move_after_dheader(
89 rti::xcdr::Stream& stream,
90 unsigned char *begin_position)
92 stream.current_position(begin_position);
97typedef DHeaderGeneratorImpl<false> DHeaderGenerator;
98typedef DHeaderGeneratorImpl<true> DHeaderGeneratorForEnum;
101template <
typename T,
typename Enable =
void>
102struct primitive_sequence_dheader_gen {
103 typedef NoDHeaderGenerator type;
122template <
typename DHeaderGen>
131 unsigned int alignment)
135 DHeaderGen::reserve_dheader(stream());
138 template <
typename ElementBuilder>
139 ElementBuilder build_next()
141 rti::xcdr::Stream::Memento stream_memento(stream());
142 return build_element<ElementBuilder>(stream_memento);
145 template <
typename ElementOffset>
146 ElementOffset add_next()
148 RTI_FLAT_BUILDER_CHECK_VALID(
return ElementOffset());
151 rti::xcdr::Stream::Memento stream_memento(stream());
153 if (!stream().align(ElementOffset::required_alignment)) {
154 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return ElementOffset());
157 ElementOffset element = add_element<ElementOffset>();
158 if (element.is_null()) {
159 return ElementOffset();
163 stream_memento.discard();
169 template <
typename ElementOffset>
170 void add_n(
unsigned int count)
172 RTI_FLAT_BUILDER_CHECK_VALID(
return);
178 if (!stream().align(ElementOffset::required_alignment)) {
179 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return);
182 offset_t elements_size = ElementOffset::serialized_size(0)
183 + ElementOffset::serialized_size_w_padding() * (count - 1);
184 if (!stream().skip(elements_size)) {
185 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return);
188 element_count_ += count;
196 return element_count_;
199#if defined(RTI_FLAT_DATA_CXX11_RVALUE_REFERENCES)
203 if (
this == &other) {
207 finish_untyped_impl();
209 AbstractBuilder::operator=(
static_cast<AbstractBuilder&&
>(other));
211 element_count_ = other.element_count_;
212 other.element_count_ = 0;
219 struct AbstractListBuilderMoveProxy : AbstractBuilderMoveProxy {
220 unsigned int element_count_;
223 operator AbstractListBuilderMoveProxy () throw()
225 AbstractListBuilderMoveProxy other;
231 void move_from(AbstractListBuilderMoveProxy& other)
233 AbstractBuilder::move_from(other);
234 element_count_ = other.element_count_;
237 void move_to(AbstractListBuilderMoveProxy& other)
239 AbstractBuilder::move_to(other);
240 other.element_count_ = element_count_;
246 friend class AbstractBuilder;
248 virtual void finish_member()
250 RTI_FLAT_BUILDER_CHECK_VALID(
return);
256 AbstractBuilder::finish_member();
260 bool finish_dheader()
262 return DHeaderGen::finish_dheader(stream(), begin_position());
265 unsigned int element_count_;
304template <
typename ElementBuilder,
unsigned int N>
320 finish_untyped_impl();
323#if defined(RTI_FLAT_DATA_CXX11_RVALUE_REFERENCES)
324 MutableArrayBuilder(MutableArrayBuilder&& other) =
default;
326 MutableArrayBuilder& operator=(MutableArrayBuilder&& other)
328 finish_untyped_impl();
329 Base::operator=(
static_cast<Base&&
>(other));
335 void finish_untyped_impl()
341 Base::finish_dheader();
342 Base::finish_untyped_impl();
346 friend class AbstractBuilder;
350 AbstractBuilder& parent,
351 unsigned int alignment = 0)
352 : AbstractListBuilder(nested_tag_t(), parent, alignment)
366 RTI_FLAT_BUILDER_PRECONDITION_ERROR(
367 "Array builder build_next: too many elements",
368 return ElementBuilder());
371 return AbstractListBuilder::build_next<ElementBuilder>();
383 RTI_FLAT_BUILDER_CHECK_CAN_FINISH(
return Offset());
386 RTI_FLAT_BUILDER_PRECONDITION_ERROR(
387 "Cannot finish array builder: too few elements",
391 if (!finish_dheader()) {
392 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return Offset());
395 return finish_impl<Offset>();
398 RTI_FLAT_BUILDER_DEFINE_MOVE_OPERATIONS_IMPL(\
414template <
typename DHeaderGen>
422 using typename Base::nested_tag_t;
423 #if !defined(RTI_FLAT_DATA_CXX11_RVALUE_REFERENCES)
424 using typename Base::AbstractListBuilderMoveProxy;
436 unsigned int alignment)
437 : Base(nested_tag_t(), parent, alignment)
440 if (!stream().check_size(
sizeof(rti::xcdr::length_t))) {
441 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(this->invalidate());
445 stream().template serialize_fast<rti::xcdr::length_t>(0);
451 ~AbstractSequenceBuilder()
453 finish_untyped_impl();
456#if defined(RTI_FLAT_DATA_CXX11_RVALUE_REFERENCES)
457 AbstractSequenceBuilder(AbstractSequenceBuilder&& other) =
default;
458 AbstractSequenceBuilder& operator=(AbstractSequenceBuilder&& other)
460 finish_untyped_impl();
461 Base::operator=(
static_cast<Base&&
>(other));
467 void finish_untyped_impl()
473 Base::finish_dheader();
475 Base::finish_untyped_impl();
479 template <
typename Offset>
482 RTI_FLAT_BUILDER_CHECK_VALID(
return Offset());
483 RTI_FLAT_BUILDER_CHECK_CAN_FINISH(
return Offset());
485 Base::finish_dheader();
487 return Base::template finish_impl<Offset>();
494 rti::xcdr::Stream::Memento stream_memento(stream());
495 DHeaderGen::move_after_dheader(stream(), Base::begin_position());
501 stream().template serialize_fast<rti::xcdr::length_t>(
element_count());
533template <
typename ElementBuilder>
554 unsigned int alignment = RTI_XCDR_DHEADER_ALIGNMENT)
555 : Base(nested_tag_t(), parent, alignment)
568 return AbstractListBuilder::build_next<ElementBuilder>();
580 return finish_impl<Offset>();
583 RTI_FLAT_BUILDER_DEFINE_MOVE_OPERATIONS_IMPL(
586 AbstractListBuilderMoveProxy)
621template <
typename ElementOffset>
637 unsigned int alignment = RTI_XCDR_SEQ_LENGTH_ALIGNMENT)
650 return AbstractListBuilder::add_next<ElementOffset>();
663 AbstractListBuilder::add_n<ElementOffset>(count);
675 return finish_impl<Offset>();
678 RTI_FLAT_BUILDER_DEFINE_MOVE_OPERATIONS_IMPL(\
692 typename detail::primitive_sequence_dheader_gen<T>::type> {
696 typename detail::primitive_sequence_dheader_gen<T>::type>
700 using typename Base::nested_tag_t;
701#if !defined(RTI_FLAT_DATA_CXX11_RVALUE_REFERENCES)
702 using typename Base::AbstractListBuilderMoveProxy;
715 unsigned int alignment = RTI_XCDR_SEQ_LENGTH_ALIGNMENT)
716 :
Base(nested_tag_t(), parent, alignment)
728 RTI_FLAT_BUILDER_CHECK_VALID(
return *
this);
730 if (!stream().
template serialize<T>(value)) {
731 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return *
this);
734 Base::element_count_++;
746 RTI_FLAT_BUILDER_CHECK_VALID(
return *
this);
748 if (RTIXCdrUnsignedLong_MAX /
static_cast<unsigned int>(
sizeof(T))
750 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return *
this);
753 if (!stream().check_size(
static_cast<unsigned int>(
sizeof(T)) * count)) {
754 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return *
this);
757 if (stream().needs_byte_swap() &&
sizeof(T) > 1) {
758 for (
unsigned int i = 0; i < count; i++) {
759 stream().template serialize_fast<T>(array[i]);
762 stream().serialize_fast((
void *) array, count *
static_cast<unsigned int>(
sizeof(T)));
765 Base::element_count_ += count;
784 RTI_FLAT_BUILDER_CHECK_VALID(
return *
this);
786 if (RTIXCdrUnsignedLong_MAX /
static_cast<unsigned int>(
sizeof(T))
788 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return *
this);
791 if (!stream().check_size(
static_cast<unsigned int>(
sizeof(T)) * count)) {
792 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return *
this);
795 for (
unsigned int i = 0; i < count; i++) {
796 stream().template serialize_fast<T>(value);
798 Base::element_count_ += count;
824 RTI_FLAT_BUILDER_CHECK_VALID(
return *
this);
826 if (RTIXCdrUnsignedLong_MAX /
static_cast<unsigned int>(
sizeof(T))
828 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return *
this);
831 if (!stream().skip(
static_cast<unsigned int>(
sizeof(T)) * count)) {
832 RTI_FLAT_BUILDER_OUT_OF_RESOURCES_ERROR(
return *
this);
835 Base::element_count_ += count;
848 this->finish_dheader();
849 return Base::template finish_impl<Offset>();
853 RTI_FLAT_BUILDER_DEFINE_MOVE_OPERATIONS_IMPL(\
878 using typename Base::nested_tag_t;
890 unsigned int alignment = RTI_XCDR_SEQ_LENGTH_ALIGNMENT)
891 :
Base(nested_tag_t(), parent, alignment)
901 RTI_FLAT_BUILDER_CHECK_VALID(
return *
this);
905 if (Base::element_count_ != 0) {
906 stream().current_position(begin_position());
907 stream().serialize_fast<rti::xcdr::length_t>(0);
908 Base::element_count_ = 0;
911 unsigned int length =
static_cast<unsigned int>(strlen(value)) + 1;
912 add_n(value, length);
924 RTI_FLAT_BUILDER_CHECK_VALID(
return Offset());
926 if (element_count_ == 0) {
930 Base::finish_dheader();
931 return finish_impl<Offset>();
934 RTI_FLAT_BUILDER_DEFINE_MOVE_OPERATIONS_IMPL(\
939typedef PrimitiveSequenceBuilder<unsigned char> WStringBuilder;
Base class of all Builders.
Definition: Builder.hpp:512
bool is_valid() const
Whether this Builder is valid.
Definition: Builder.hpp:899
bool is_nested() const
Returns whether this is a member Builder.
Definition: Builder.hpp:882
Base class of all array and sequence builders.
Definition: SequenceBuilders.hpp:123
unsigned int element_count() const
Returns the current number of elements that have been added.
Definition: SequenceBuilders.hpp:194
Base class of Builders for sequence members.
Definition: SequenceBuilders.hpp:415
unsigned int element_count() const
Returns the current number of elements that have been added.
Definition: SequenceBuilders.hpp:194
Builds a sequence member of fixed-size elements.
Definition: SequenceBuilders.hpp:623
Offset finish()
Finishes building the sequence.
Definition: SequenceBuilders.hpp:673
FinalSequenceBuilder & add_n(unsigned int count)
Adds a number of elements at once.
Definition: SequenceBuilders.hpp:661
ElementOffset add_next()
Adds the next element.
Definition: SequenceBuilders.hpp:648
Builds an array member of variable-size elements.
Definition: SequenceBuilders.hpp:305
ElementBuilder build_next()
Begins building the next element.
Definition: SequenceBuilders.hpp:363
Offset finish()
Finishes building the array.
Definition: SequenceBuilders.hpp:381
MutableArrayOffset< typename ElementBuilder::Offset, N > Offset
The related Offset type.
Definition: SequenceBuilders.hpp:310
Offset to an array of variable-size elements.
Definition: SequenceOffsets.hpp:621
Builds a sequence member of variable-size elements.
Definition: SequenceBuilders.hpp:535
SequenceOffset< typename ElementBuilder::Offset > Offset
The related Offset type.
Definition: SequenceBuilders.hpp:540
ElementBuilder build_next()
Begins building the next element.
Definition: SequenceBuilders.hpp:566
Offset finish()
Finishes building the sequence.
Definition: SequenceBuilders.hpp:578
Builds a sequence of primitive members.
Definition: SequenceBuilders.hpp:692
PrimitiveSequenceBuilder & add_n(unsigned int count, T value)
Adds a number of elements with the same value.
Definition: SequenceBuilders.hpp:782
PrimitiveSequenceBuilder & add_n(const T *array, unsigned int count)
Adds all the elements in an array.
Definition: SequenceBuilders.hpp:744
PrimitiveSequenceBuilder & add_n(unsigned int count)
Adds a number of uninitialized elements.
Definition: SequenceBuilders.hpp:822
PrimitiveSequenceBuilder & add_next(T value)
Adds the next element.
Definition: SequenceBuilders.hpp:726
Offset finish()
Finishes building the sequence.
Definition: SequenceBuilders.hpp:846
Offset to a sequence of primitive elements.
Definition: SequenceOffsets.hpp:146
Offset to a sequence of non-primitive elements.
Definition: SequenceOffsets.hpp:501
Builds a string.
Definition: SequenceBuilders.hpp:872
Offset finish()
Finishes building the string.
Definition: SequenceBuilders.hpp:922
StringBuilder & set_string(const char *value)
Sets the string value.
Definition: SequenceBuilders.hpp:899
Offset to a string.
Definition: SequenceOffsets.hpp:291
The RTI namespace.
Definition: AggregationBuilders.hpp:17