OpenDDS  Snapshot(2023/04/28-20:55)
TypeSupportImpl.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> // Only the _pch include should start with DCPS/
7 
8 #include "TypeSupportImpl.h"
9 
10 #include "Registered_Data_Types.h"
11 #include "Service_Participant.h"
13 
15 
16 namespace OpenDDS {
17 namespace DCPS {
18 
20 
22 {}
23 
25 TypeSupportImpl::register_type(DDS::DomainParticipant_ptr participant,
26  const char* type_name)
27 {
28  const char* const type =
29  (!type_name || !type_name[0]) ? name() : type_name;
30  return Registered_Data_Types->register_type(participant, type, this);
31 }
32 
34 TypeSupportImpl::unregister_type(DDS::DomainParticipant_ptr participant,
35  const char* type_name)
36 {
37  if (type_name == 0 || type_name[0] == '\0') {
39  } else {
40  return Registered_Data_Types->unregister_type(participant, type_name, this);
41  }
42 }
43 
44 char*
46 {
47  CORBA::String_var type = name();
48  return type._retn();
49 }
50 
51 namespace {
52  void log_ti_not_found(const char* method_name, const char* name, const XTypes::TypeIdentifier& ti)
53  {
54  if (log_level >= LogLevel::Error) {
55  const XTypes::EquivalenceKind ek = ti.kind();
56  String str;
57  if (ek == XTypes::EK_COMPLETE || ek == XTypes::EK_MINIMAL) {
58  str = ek == XTypes::EK_MINIMAL ? "minimal " : "complete ";
59  str += XTypes::equivalence_hash_to_string(ti.equivalence_hash());
60  } else {
61  str = "not an equivalence hash";
62  }
63  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: TypeSupportImpl::%C: "
64  "TypeIdentifier \"%C\" of topic type \"%C\" not found in local type map.\n",
65  method_name, str.c_str(), name));
66  }
67  }
68 }
69 
71  const XTypes::TypeIdentifier& ti,
72  const XTypes::TypeMap& type_map) const
73 {
74  const XTypes::TypeMap::const_iterator pos = type_map.find(ti);
75 
76  if (pos == type_map.end()) {
77  log_ti_not_found("to_type_info_i", name(), ti);
80  } else if (TheServiceParticipant->type_object_encoding() == Service_Participant::Encoding_WriteOldFormat) {
82  encoding.skip_sequence_dheader(true);
83  const XTypes::TypeObject& to = pos->second;
84  ti_with_deps.typeid_with_size.type_id = makeTypeIdentifier(to, &encoding);
85  const size_t sz = serialized_size(encoding, to);
86  ti_with_deps.typeid_with_size.typeobject_serialized_size = static_cast<unsigned>(sz);
87  } else {
88  ti_with_deps.typeid_with_size.type_id = ti;
89  const XTypes::TypeObject& to = pos->second;
90  const size_t sz = serialized_size(XTypes::get_typeobject_encoding(), to);
91  ti_with_deps.typeid_with_size.typeobject_serialized_size = static_cast<unsigned>(sz);
92  }
93 
95 }
96 
98 {
99  const XTypes::TypeInformation* const preset = preset_type_info();
100  if (preset) {
101  type_info = *preset;
102  return;
103  }
104 
106 
107  // Properly populate the complete member if complete TypeObjects are generated.
108  const XTypes::TypeIdentifier& complete_ti = getCompleteTypeIdentifier();
109  if (complete_ti.kind() != XTypes::TK_NONE) {
110  to_type_info_i(type_info.complete, complete_ti, getCompleteTypeMap());
111  } else {
113  }
114 }
115 
117 {
118  using namespace XTypes;
119  if (preset_type_info()) {
120  // In the case where TypeInformation was pre-set, the participant's TypeLookupService
121  // already has the types and dependencies based on responses to RPC requests.
122  return;
123  }
124  const TypeMap& minTypeMap = getMinimalTypeMap();
125  tls->add(minTypeMap.begin(), minTypeMap.end());
126  const TypeMap& comTypeMap = getCompleteTypeMap();
127  tls->add(comTypeMap.begin(), comTypeMap.end());
128 
129  if (TheServiceParticipant->type_object_encoding() != Service_Participant::Encoding_Normal) {
130  // In this mode we need to be able to recognize TypeIdentifiers received over the network
131  // by peers that may have encoded them incorrectly. Populate the TypeLookupService with
132  // additional entries that map the alternate (wrong) TypeIdentifiers to the same TypeObjects.
134  encoding.skip_sequence_dheader(true);
135  TypeMap altMinMap;
136  for (TypeMap::const_iterator iter = minTypeMap.begin(); iter != minTypeMap.end(); ++iter) {
137  const TypeObject& minTypeObject = iter->second;
138  const TypeIdentifier typeId = makeTypeIdentifier(minTypeObject, &encoding);
139  altMinMap[typeId] = minTypeObject;
140  }
141  tls->add(altMinMap.begin(), altMinMap.end());
142 
143  TypeMap altComMap;
144  for (TypeMap::const_iterator iter = comTypeMap.begin(); iter != comTypeMap.end(); ++iter) {
145  const TypeObject& comTypeObject = iter->second;
146  const TypeIdentifier typeId = makeTypeIdentifier(comTypeObject, &encoding);
147  altComMap[typeId] = comTypeObject;
148  }
149  tls->add(altComMap.begin(), altComMap.end());
150  }
153 }
154 
156  XTypes::EquivalenceKind ek) const
157 {
158  if (ek != XTypes::EK_MINIMAL && ek != XTypes::EK_COMPLETE) {
159  return;
160  }
161 
162  OPENDDS_SET(XTypes::TypeIdentifier) dependencies;
163  const XTypes::TypeIdentifier& type_id = ek == XTypes::EK_MINIMAL ?
165  const XTypes::TypeMap& type_map = ek == XTypes::EK_MINIMAL ?
167 
168  XTypes::compute_dependencies(type_map, type_id, dependencies);
169 
170  XTypes::TypeIdentifierWithSizeSeq deps_with_size;
171  OPENDDS_SET(XTypes::TypeIdentifier)::const_iterator it = dependencies.begin();
172  for (; it != dependencies.end(); ++it) {
173  XTypes::TypeMap::const_iterator iter = type_map.find(*it);
174  if (iter != type_map.end()) {
175  const size_t tobj_size = serialized_size(XTypes::get_typeobject_encoding(), iter->second);
176  XTypes::TypeIdentifierWithSize ti_with_size(*it, static_cast<ACE_CDR::ULong>(tobj_size));
177  deps_with_size.append(ti_with_size);
178  } else if (XTypes::has_type_object(*it)) {
179  log_ti_not_found("populate_dependencies_i", name(), *it);
180  }
181  }
182  tls->add_type_dependencies(type_id, deps_with_size);
183 }
184 
185 
186 #ifndef OPENDDS_SAFETY_PROFILE
188 {
189  if (!type_) {
190  if (!type_lookup_service_) {
191  type_lookup_service_ = make_rch<XTypes::TypeLookupService>();
193  }
194 
196  const XTypes::TypeMap& ctm = getCompleteTypeMap();
198  const XTypes::TypeMap& mtm = getMinimalTypeMap();
200  type_lookup_service_->type_identifier_to_dynamic(cti, GUID_UNKNOWN));
201  if (dt) {
203  dt->set_complete_type_map(ctm);
205  dt->set_minimal_type_map(mtm);
206  }
207  type_ = dt;
208  }
209 }
210 #endif
211 
214 };
215 
219  {}
220 };
221 
223 {
224  switch (representation) {
226  return new JsonRepresentationFormatImpl;
230  return new CdrRepresentationFormatImpl(representation);
231  default:
232  return 0;
233  }
234 }
235 
236 
237 }
238 }
239 
RepresentationFormat * make_format(DDS::DataRepresentationId_t representation)
#define ACE_ERROR(X)
CdrRepresentationFormatImpl(DDS::DataRepresentationId_t)
std::string String
const Encoding & get_typeobject_encoding()
Definition: TypeObject.cpp:27
void compute_dependencies(const TypeMap &type_map, const TypeIdentifier &type_identifier, OPENDDS_SET(TypeIdentifier)&dependencies)
const GUID_t GUID_UNKNOWN
Nil value for GUID.
Definition: GuidUtils.h:59
ACE_CDR::Octet kind() const
Definition: TypeObject.h:748
void set_complete_type_map(const TypeMap &tm)
const DDS::DataRepresentationId_t JSON_DATA_REPRESENTATION
const DataRepresentationId_t XCDR_DATA_REPRESENTATION
void serialized_size(const Encoding &encoding, size_t &size, const SequenceNumber &)
XTypes::TypeLookupService_rch type_lookup_service_
virtual const XTypes::TypeIdentifier & getMinimalTypeIdentifier() const =0
virtual DDS::ReturnCode_t register_type(DDS::DomainParticipant_ptr participant, const char *type_name)
static const ACE_CDR::Long TYPE_INFO_DEPENDENT_COUNT_NOT_PROVIDED
void set_minimal_type_map(const TypeMap &tm)
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
#define Registered_Data_Types
virtual const char * name() const =0
const DataRepresentationId_t XCDR2_DATA_REPRESENTATION
TypeIdentifierWithDependencies complete
Definition: TypeObject.h:3374
void add_types(const XTypes::TypeLookupService_rch &tls) const
DCPS::String equivalence_hash_to_string(const EquivalenceHash &equivalence_hash)
Definition: TypeObject.cpp:33
bool skip_sequence_dheader() const
Definition: Serializer.inl:100
void populate_dependencies_i(const XTypes::TypeLookupService_rch &tls, XTypes::EquivalenceKind ek) const
void set_complete_type_identifier(const TypeIdentifier &ti)
const DDS::DataRepresentationId_t UNALIGNED_CDR_DATA_REPRESENTATION
Sequence & append(const T &member)
Definition: TypeObject.h:155
character_type * _retn(void)
virtual const XTypes::TypeIdentifier & getCompleteTypeIdentifier() const =0
virtual const XTypes::TypeMap & getCompleteTypeMap() const =0
ACE_INT32 Long
ACE_CDR::Octet EquivalenceKind
Definition: TypeObject.h:204
OpenDDS_Dcps_Export LogLevel log_level
void set_minimal_type_identifier(const TypeIdentifier &ti)
void to_type_info(XTypes::TypeInformation &type_info) const
virtual const XTypes::TypeInformation * preset_type_info() const
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
virtual const XTypes::TypeMap & getMinimalTypeMap() const =0
short DataRepresentationId_t
const DCPS::Encoding encoding(DCPS::Encoding::KIND_UNALIGNED_CDR, DCPS::ENDIAN_BIG)
#define TheServiceParticipant
const TypeKind TK_NONE
Definition: TypeObject.h:213
virtual DDS::ReturnCode_t unregister_type(DDS::DomainParticipant_ptr participant, const char *type_name)
LM_ERROR
TypeIdentifier makeTypeIdentifier(const TypeObject &type_object, const DCPS::Encoding *encoding_option)
Definition: TypeObject.cpp:254
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
TypeIdentifierWithDependencies minimal
Definition: TypeObject.h:3373
bool has_type_object(const TypeIdentifier &ti)
Definition: TypeObject.cpp:461
void to_type_info_i(XTypes::TypeIdentifierWithDependencies &ti_with_deps, const XTypes::TypeIdentifier &ti, const XTypes::TypeMap &type_map) const
typedef OPENDDS_SET(NetworkAddress) AddrSet
const ReturnCode_t RETCODE_BAD_PARAMETER