RTI Routing Service  Version 6.0.1
 All Data Structures Files Functions Typedefs Enumerations Enumerator Groups Pages
DynamicDataConverter.hpp
1 /*
2  * (c) Copyright, Real-Time Innovations, 2016-.
3  * All rights reserved.
4  * No duplications, whole or partial, manual or electronic, may be made
5  * without express written permission. Any such copies, or
6  * revisions thereof, must display this notice unaltered.
7  * This code contains trade secrets of Real-Time Innovations, Inc.
8  */
9 
10 #ifndef HPP_SERVICE_DYNAMIC_DATA_CONVERTER_HPP_
11 #define HPP_SERVICE_DYNAMIC_DATA_CONVERTER_HPP_
12 
13 
14 // IMPORTANT: macros.hpp must be the first RTI header included in every header
15 // file so that symbols are exported correctly on Windows
16 #include <dds/core/macros.hpp>
17 
18 #include "osapi/osapi_heap.h"
19 #include "routingservice/routingservice_log.h"
20 #include "routingservice/routingservice_common.h"
21 
22 #include <dds/core/Value.hpp>
23 #include <dds/core/types.hpp>
24 #include <rtiboost/assert.hpp>
25 #include <dds/core/xtypes/DynamicType.hpp>
26 #include <dds/core/xtypes/DynamicData.hpp>
27 #include <rti/core/NativeValueType.hpp>
28 #include <rti/service/ServiceException.hpp>
29 #include <rti/service/DynamicBuffer.hpp>
30 
31 namespace rti { namespace service {
32 
33 class DynamicDataConverter {
34 public:
35 
36  class ScopedSample {
37  public:
38 
39  ScopedSample(
40  ROUTERDynamicDataConverter *converter,
41  DDS_DynamicData *native) :
42  converter_(converter),
43  native_(native)
44  {
45  }
46 
47  ~ScopedSample()
48  {
49  ROUTERDynamicDataConverter_returnSample(converter_, native_);
50  }
51 
52  dds::core::xtypes::DynamicData& get()
53  {
54  return rti::core::native_conversions::cast_from_native<
55  dds::core::xtypes::DynamicData>(*native_);
56  }
57 
58  private:
59  ROUTERDynamicDataConverter *converter_;
60  DDS_DynamicData *native_;
61  };
62 
63  class ScopedBuffer {
64  public:
65 
66  ScopedBuffer() : converter_(NULL), native_(NULL), native_length_(0)
67  {
68  }
69 
70  ScopedBuffer(
71  ROUTERDynamicDataConverter *converter,
72  void *native,
73  uint32_t native_length) :
74  converter_(converter),
75  native_(native),
76  native_length_(native_length)
77  {
78  }
79 
80  ~ScopedBuffer()
81  {
82  if (native_ != NULL) {
83  ROUTERDynamicDataConverter_returnBuffer(converter_, native_);
84  }
85  }
86 
87  void clear()
88  {
89  assign(converter_, NULL, 0);
90  }
91 
92  void assign(
93  ROUTERDynamicDataConverter *converter,
94  void *native,
95  uint32_t native_length)
96  {
97  if (native_ != NULL) {
98  ROUTERDynamicDataConverter_returnBuffer(
99  converter_,
100  const_cast<void *>(native_));
101  }
102  converter_ = converter;
103  native_ = native;
104  native_length_ = native_length;
105  }
106 
107  ScopedBuffer& operator =(ScopedBuffer& other)
108  {
109  assign(other.converter_, other.native_, other.native_length_);
110  return *this;
111  }
112 
113  const void * get()
114  {
115  return native_;
116  }
117 
118  template <typename T>
119  const T * get() {
120  return static_cast<const T *>(native_);
121  }
122 
123  uint32_t length()
124  {
125  return native_length_;
126  }
127 
128  private:
129  ROUTERDynamicDataConverter *converter_;
130  void *native_;
131  uint32_t native_length_;
132  };
133 
138  DynamicDataConverter() : initialized_(false) {}
139 
144  DynamicDataConverter(
145  const dds::core::xtypes::DynamicType& type_code,
146  const DynamicBufferProperty &property) :
147  initialized_(false)
148  {
149  set(type_code, property);
150  }
151 
158  void set(
159  const dds::core::xtypes::DynamicType& type_code,
160  const DynamicBufferProperty &property)
161  {
162  if (!initialized_) {
163  if (!ROUTERDynamicDataConverter_initialize(
164  &converter_,
165  &(type_code.native()),
166  (RTI_UINT32) property.min_size())) {
167  RTI_THROW_SERVICE_EXCEPTION(
168  &RTI_LOG_INIT_FAILURE_s,
169  "native converter");
170  }
171  initialized_ = true;
172  }
173  }
174 
175  ~DynamicDataConverter()
176  {
177  if (initialized_) {
178  ROUTERDynamicDataConverter_finalize(&converter_);
179  }
180  }
181 
182  ScopedSample sample(
183  const dds::core::xtypes::DynamicData& sample,
184  const DDS_DataRepresentationId_t target_representation)
185  {
186  DDS_DynamicData *native = ROUTERDynamicDataConverter_getSample(
187  &converter_,
188  const_cast<DDS_DynamicData *>(&sample.native()),
189  target_representation);
190  if (native == NULL) {
191  RTI_THROW_SERVICE_EXCEPTION(
192  &RTI_LOG_ANY_FAILURE_s,
193  "get native sample");
194  }
195  return ScopedSample(&converter_, native);
196  }
197 
198  ScopedBuffer buffer(
199  const dds::core::xtypes::DynamicData& sample,
200  const DDS_DataRepresentationId_t target_representation)
201  {
202  DDS_UnsignedLong native_length = 0;
203  void *native = ROUTERDynamicDataConverter_getBuffer(
204  &converter_,
205  &native_length,
206  const_cast<DDS_DynamicData *>(&sample.native()),
207  target_representation);
208  if (native == NULL) {
209  RTI_THROW_SERVICE_EXCEPTION(
210  &RTI_LOG_ANY_FAILURE_s,
211  "get native buffer");
212  }
213  return ScopedBuffer(&converter_, native, (uint32_t) native_length);
214  }
215 
216  void buffer(
217  ScopedBuffer& scoped_buffer,
218  const dds::core::xtypes::DynamicData& sample,
219  const DDS_DataRepresentationId_t target_representation)
220  {
221  DDS_UnsignedLong native_length = 0;
222  /*
223  * The scoped buffer has to be cleared before we can use it again. The
224  * buffer will automatically be returned to this converter. After this,
225  * we can safely get the buffer again from the dynamic data sample and
226  * reassign to the scoped buffer.
227  */
228  scoped_buffer.clear();
229  void *native = ROUTERDynamicDataConverter_getBuffer(
230  &converter_,
231  &native_length,
232  const_cast<DDS_DynamicData *>(&sample.native()),
233  target_representation);
234  if (native == NULL) {
235  RTI_THROW_SERVICE_EXCEPTION(
236  &RTI_LOG_ANY_FAILURE_s,
237  "get native buffer");
238  }
239  scoped_buffer.assign(&converter_, native, (uint32_t) native_length);
240  }
241 
242 private:
243  ROUTERDynamicDataConverter converter_;
244  bool initialized_;
245 };
246 
247 
248 } } // rti::service
249 #endif /* HPP_SERVICE_DYNAMIC_DATA_CONVERTER_HPP_ */

RTI Routing Service Version 6.0.1 Copyright © Sun Nov 17 2019 Real-Time Innovations, Inc