OpenDDS  Snapshot(2023/04/28-20:55)
DynamicTypeSupport.cpp
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 #include <DCPS/DdsDcps_pch.h>
7 
8 #ifndef OPENDDS_SAFETY_PROFILE
9 #include "DynamicTypeSupport.h"
10 
11 #include "DynamicDataImpl.h"
12 #include "DynamicDataReaderImpl.h"
13 #include "DynamicDataWriterImpl.h"
15 #include "DynamicTypeImpl.h"
16 #include "Utils.h"
17 
18 #include <dds/DCPS/debug.h>
19 #include <dds/DCPS/DCPS_Utils.h>
20 
21 #include <ace/Malloc_Base.h>
22 
24 namespace OpenDDS {
25  namespace DCPS {
26 
28  {
29  return sample.deserialize(strm);
30  }
31 
33  {
34  sample.value.set_key_only(true);
35  return sample.value.deserialize(strm);
36  }
37 
38 #ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE
39  static ComparatorBase::Ptr make_nested_cmp(const std::string& field, ComparatorBase::Ptr inner,
40  ComparatorBase::Ptr next);
41 
42  static ComparatorBase::Ptr make_dynamic_cmp(const std::string& field,
44 
45  template <>
46  struct MetaStructImpl<XTypes::DynamicSample> : MetaStruct {
47 
48  Value getValue(const void* stru, DDS::MemberId memberId) const
49  {
50  const XTypes::DynamicSample& typed = *static_cast<const XTypes::DynamicSample*>(stru);
51  const DDS::DynamicData_var dd = typed.dynamic_data();
52  XTypes::DynamicDataBase* const ddb = dynamic_cast<XTypes::DynamicDataBase*>(dd.in());
53  Value v(0);
54  if (ddb) {
55  ddb->get_simple_value(v, memberId);
56  }
57  return v;
58  }
59 
60  Value getValue(const void* stru, const char* field) const
61  {
62  const XTypes::DynamicSample& typed = *static_cast<const XTypes::DynamicSample*>(stru);
63  const DDS::DynamicData_var dd = typed.dynamic_data();
64  return getValueImpl(dd, field);
65  }
66 
67  Value getValue(Serializer& strm, const char* field, const TypeSupportImpl* ts) const
68  {
69  DDS::DynamicType_var type = ts->get_type();
70  const DDS::DynamicData_var dd = new XTypes::DynamicDataXcdrReadImpl(strm, type);
71  return getValueImpl(dd, field);
72  }
73 
74  static Value getValueImpl(const DDS::DynamicData_var& dd, const char* field)
75  {
76  const char* const dot = std::strchr(field, '.');
77  if (dot) {
78  const String local(field, dot - field);
79  const DDS::MemberId id = dd->get_member_id_by_name(local.c_str());
80  DDS::DynamicData_var nested;
81  if (dd->get_complex_value(nested, id) != DDS::RETCODE_OK) {
82  return Value(0);
83  }
84  return getValueImpl(nested, dot + 1);
85  }
86  const DDS::MemberId id = dd->get_member_id_by_name(field);
87  XTypes::DynamicDataBase* const ddb = dynamic_cast<XTypes::DynamicDataBase*>(dd.in());
88  Value v(0);
89  if (ddb) {
90  ddb->get_simple_value(v, id);
91  }
92  return v;
93  }
94 
96  {
97  const char* const dot = std::strchr(field, '.');
98  return dot ? make_nested_cmp(String(field, dot - field), make_dynamic_cmp(dot + 1), next)
99  : make_dynamic_cmp(field, next);
100  }
101 
102 #ifndef OPENDDS_NO_MULTI_TOPIC
103  void* allocate() const { return 0; }
104 
105  void deallocate(void*) const {}
106 
107  size_t numDcpsKeys() const { return 0; }
108 
109  const char** getFieldNames() const { return 0; }
110 
111  const void* getRawField(const void*, const char*) const { return 0; }
112 
113  void assign(void*, const char*, const void*, const char*, const MetaStruct&) const {}
114 
115  bool compare(const void*, const void*, const char*) const { return false; }
116 #endif
117  };
118 
119  template <>
121  const MetaStruct& getMetaStruct<XTypes::DynamicSample>()
122  {
124  return m;
125  }
126 
127  /// Dynamic version of FieldComparator in Comparator_T.h
129  DynamicComparator(const std::string& field, Ptr next)
130  : ComparatorBase(next)
131  , field_(field)
132  {}
133 
134  int cmp(void* lhs, void* rhs) const
135  {
136  const XTypes::DynamicSample& left = *static_cast<XTypes::DynamicSample*>(lhs);
137  const XTypes::DynamicSample& right = *static_cast<XTypes::DynamicSample*>(rhs);
138  const DDS::DynamicData_var l(left.dynamic_data()), r(right.dynamic_data());
139  const DDS::MemberId id = l->get_member_id_by_name(field_.c_str());
140  int result;
141  if (XTypes::compare_members(result, l, r, id) != DDS::RETCODE_OK) {
142  return 1; // warning already logged
143  }
144  return result;
145  }
146 
147  bool less(void* lhs, void* rhs) const
148  {
149  return cmp(lhs, rhs) < 0;
150  }
151 
152  bool equal(void* lhs, void* rhs) const
153  {
154  return cmp(lhs, rhs) == 0;
155  }
156 
157  const std::string field_;
158  };
159 
161  {
162  return make_rch<DynamicComparator>(field, next);
163  }
164 
165  /// Dynamic version of StructComparator in Comparator_T.h
167  NestedComparator(const std::string& field, Ptr inner, Ptr next)
168  : ComparatorBase(next)
169  , field_(field)
170  , inner_(inner)
171  {}
172 
174  {
175  const XTypes::DynamicSample& outer_typed = *static_cast<XTypes::DynamicSample*>(outer);
176  const DDS::DynamicData_var outer_dd = outer_typed.dynamic_data();
177  DDS::DynamicData_var inner_dd;
178  const DDS::MemberId id = outer_dd->get_member_id_by_name(field_.c_str());
179  if (outer_dd->get_complex_value(inner_dd, id) != DDS::RETCODE_OK) {
180  return XTypes::DynamicSample();
181  }
182  return XTypes::DynamicSample(inner_dd);
183  }
184 
185  bool less(void* lhs, void* rhs) const
186  {
187  XTypes::DynamicSample left(get_nested(lhs)), right(get_nested(rhs));
188  return inner_->less(&left, &right);
189  }
190 
191  bool equal(void* lhs, void* rhs) const
192  {
193  XTypes::DynamicSample left(get_nested(lhs)), right(get_nested(rhs));
194  return inner_->equal(&left, &right);
195  }
196 
197  const std::string field_;
198  const Ptr inner_;
199  };
200 
201  ComparatorBase::Ptr make_nested_cmp(const std::string& field, ComparatorBase::Ptr inner,
202  ComparatorBase::Ptr next)
203  {
204  return make_rch<NestedComparator>(field, inner, next);
205  }
206 
207 #endif
208 
209  }
210 
211  namespace XTypes {
212  template <>
214  DDS::DynamicType_ptr, const DynamicSample& value)
215  {
216  return value.dynamic_data()._retn();
217  }
218 
219  template <>
221  DDS::DynamicType_ptr, DynamicSample& value)
222  {
223  return value.dynamic_data()._retn();
224  }
225  }
226 }
227 
228 namespace DDS {
229 
230  using namespace OpenDDS::XTypes;
231  using namespace OpenDDS::DCPS;
232 
233  void DynamicTypeSupport::representations_allowed_by_type(DataRepresentationIdSeq& seq)
234  {
235  // TODO: Need to be able to read annotations?
236  seq.length(1);
237  seq[0] = XCDR2_DATA_REPRESENTATION;
238  }
239 
241  {
242  size_t count = 0;
243  const ReturnCode_t rc = OpenDDS::XTypes::key_count(type_, count);
244  if (rc != RETCODE_OK && log_level >= LogLevel::Error) {
245  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicTypeSupport::key_count: "
246  "could not get correct key count for DynamicType %C: %C\n",
247  name(), retcode_to_string(rc)));
248  }
249  return count;
250  }
251 
252  bool DynamicTypeSupport::is_dcps_key(const char* field) const
253  {
254  return OpenDDS::XTypes::is_key(type_, field);
255  }
256 
257  Extensibility DynamicTypeSupport::base_extensibility() const
258  {
260  const ReturnCode_t rc = extensibility(type_, ext);
261  if (rc != RETCODE_OK && log_level >= LogLevel::Error) {
262  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicTypeSupport::base_extensibility: "
263  "could not get correct extensibility for DynamicType %C: %C\n",
264  name(), retcode_to_string(rc)));
265  }
266  return ext;
267  }
268 
270  {
272  const ReturnCode_t rc = OpenDDS::XTypes::max_extensibility(type_, ext);
273  if (rc != RETCODE_OK && log_level >= LogLevel::Error) {
274  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicTypeSupport::max_extensibility: "
275  "could not get correct max extensibility for DynamicType %C: %C\n",
276  name(), retcode_to_string(rc)));
277  }
278  return ext;
279  }
280 
281  DataWriter_ptr DynamicTypeSupport::create_datawriter()
282  {
283  return new DynamicDataWriterImpl();
284  }
285 
286  DataReader_ptr DynamicTypeSupport::create_datareader()
287  {
288  return new DynamicDataReaderImpl();
289  }
290 
291 #ifndef OPENDDS_NO_MULTI_TOPIC
292  DataReader_ptr DynamicTypeSupport::create_multitopic_datareader()
293  {
294  // TODO
295  return 0;
296  }
297 #endif
298 
300  {
301  DynamicTypeImpl* const dti = dynamic_cast<DynamicTypeImpl*>(type_.in());
302  return dti->get_minimal_type_identifier();
303  }
304 
306  {
307  DynamicTypeImpl* const dti = dynamic_cast<DynamicTypeImpl*>(type_.in());
308  return dti->get_minimal_type_map();
309  }
310 
312  {
313  DynamicTypeImpl* const dti = dynamic_cast<DynamicTypeImpl*>(type_.in());
314  return dti->get_complete_type_identifier();
315  }
316 
318  {
319  DynamicTypeImpl* const dti = dynamic_cast<DynamicTypeImpl*>(type_.in());
320  return dti->get_complete_type_map();
321  }
322 
323  const OpenDDS::XTypes::TypeInformation* DynamicTypeSupport::preset_type_info() const
324  {
325  DynamicTypeImpl* dti = dynamic_cast<DynamicTypeImpl*>(type_.in());
326  return dti->get_preset_type_info();
327  }
328 
329 #ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE
330  const OpenDDS::DCPS::MetaStruct& DynamicTypeSupport::getMetaStructForType() const
331  {
332  return getMetaStruct<OpenDDS::XTypes::DynamicSample>();
333  }
334 #endif
335 
336  DynamicTypeSupport_ptr DynamicTypeSupport::_duplicate(DynamicTypeSupport_ptr obj)
337  {
338  if (obj) {
339  obj->_add_ref();
340  }
341  return obj;
342  }
343 
344 }
346 
348 namespace TAO {
349 
350  DDS::DynamicTypeSupport_ptr Objref_Traits<DDS::DynamicTypeSupport>::duplicate(DDS::DynamicTypeSupport_ptr p)
351  {
353  }
354 
355  void Objref_Traits<DDS::DynamicTypeSupport>::release(DDS::DynamicTypeSupport_ptr p)
356  {
357  CORBA::release(p);
358  }
359 
360  DDS::DynamicTypeSupport_ptr Objref_Traits<DDS::DynamicTypeSupport>::nil()
361  {
362  return static_cast<DDS::DynamicTypeSupport_ptr>(0);
363  }
364 
365  CORBA::Boolean Objref_Traits<DDS::DynamicTypeSupport>::marshal(
367  {
368  return false;
369  }
370 
371 }
373 
374 #endif
bool is_key(DDS::DynamicType_ptr type, const char *field)
ComparatorBase::Ptr create_qc_comparator(const char *field, ComparatorBase::Ptr next) const
#define ACE_ERROR(X)
#define TAO_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_CDR::ULong MemberId
Definition: TypeObject.h:910
const XTypes::TypeIdentifier & getCompleteTypeIdentifier()
const LogLevel::Value value
Definition: debug.cpp:61
std::string String
void release(T x)
const XTypes::TypeMap & getMinimalTypeMap()
const TypeMap & get_complete_type_map() const
bool deserialize(DCPS::Serializer &ser)
#define OpenDDS_Dcps_Export
Definition: dcps_export.h:24
Value getValue(Serializer &strm, const char *field, const TypeSupportImpl *ts) const
const TypeIdentifier & get_minimal_type_identifier() const
const TypeIdentifier & get_complete_type_identifier() const
sequence< DataRepresentationId_t > DataRepresentationIdSeq
Value getValue(const void *stru, DDS::MemberId memberId) const
Dynamic version of FieldComparator in Comparator_T.h.
DDS::ReturnCode_t compare_members(int &result, DDS::DynamicData_ptr a, DDS::DynamicData_ptr b, DDS::MemberId id)
const DataRepresentationId_t XCDR2_DATA_REPRESENTATION
DDS::DynamicData_ptr get_dynamic_data_adapter< DynamicSample, DynamicSample >(DDS::DynamicType_ptr, DynamicSample &value)
Class to serialize and deserialize data for DDS.
Definition: Serializer.h:369
const TypeInformation * get_preset_type_info() const
const void * getRawField(const void *, const char *) const
ACE_CDR::Boolean Boolean
virtual DDS::DynamicType_ptr get_type() const
bool compare(const void *, const void *, const char *) const
int cmp(void *lhs, void *rhs) const
DDS::DynamicData_var dynamic_data() const
Definition: DynamicSample.h:74
void assign(void *, const char *, const void *, const char *, const MetaStruct &) const
static ComparatorBase::Ptr make_nested_cmp(const std::string &field, ComparatorBase::Ptr inner, ComparatorBase::Ptr next)
const XTypes::TypeMap & getCompleteTypeMap()
The End User API.
DynamicComparator(const std::string &field, Ptr next)
static Value getValueImpl(const DDS::DynamicData_var &dd, const char *field)
const char *const name
Definition: debug.cpp:60
NestedComparator(const std::string &field, Ptr inner, Ptr next)
static DynamicTypeSupport_ptr _duplicate(DynamicTypeSupport_ptr obj)
const XTypes::TypeIdentifier & getMinimalTypeIdentifier()
OpenDDS_Dcps_Export LogLevel log_level
const char * retcode_to_string(DDS::ReturnCode_t value)
Definition: DCPS_Utils.cpp:29
virtual DDS::ReturnCode_t get_simple_value(DCPS::Value &value, DDS::MemberId id)
bool less(void *lhs, void *rhs) const
XTypes::DynamicSample get_nested(void *outer) const
FilterEvaluator::Operand * field_
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
Dynamic version of StructComparator in Comparator_T.h.
Value getValue(const void *stru, const char *field) const
bool less(void *lhs, void *rhs) const
ACE_CDR::Boolean operator>>(Serializer &serializer, CoherentChangeControl &value)
const ReturnCode_t RETCODE_OK
static ComparatorBase::Ptr make_dynamic_cmp(const std::string &field, ComparatorBase::Ptr next=ComparatorBase::Ptr())
bool equal(void *lhs, void *rhs) const
DDS::ReturnCode_t max_extensibility(DDS::DynamicType_ptr type, DCPS::Extensibility &ext)
#define TAO_END_VERSIONED_NAMESPACE_DECL
LM_ERROR
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
DDS::ReturnCode_t key_count(DDS::DynamicType_ptr type, size_t &count)
bool equal(void *lhs, void *rhs) const
extensibility(MUTABLE) struct TypeLookup_getTypes_In
Definition: TypeLookup.idl:29
const TypeMap & get_minimal_type_map() const