Line data Source code
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 : #include "DynamicDataAdapter.h"
9 :
10 : #include <dds/DCPS/debug.h>
11 : #include <dds/DCPS/DCPS_Utils.h>
12 :
13 : #if OPENDDS_HAS_DYNAMIC_DATA_ADAPTER
14 :
15 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
16 :
17 : namespace OpenDDS {
18 : namespace XTypes {
19 :
20 : using DCPS::LogLevel;
21 : using DCPS::log_level;
22 : using DCPS::retcode_to_string;
23 :
24 12 : DDS::UInt32 DynamicDataAdapter::get_item_count()
25 : {
26 12 : const TypeKind tk = type_->get_kind();
27 12 : switch (tk) {
28 0 : case TK_BOOLEAN:
29 : case TK_BYTE:
30 : case TK_UINT8:
31 : case TK_UINT16:
32 : case TK_UINT32:
33 : case TK_UINT64:
34 : case TK_INT8:
35 : case TK_INT16:
36 : case TK_INT32:
37 : case TK_INT64:
38 : case TK_FLOAT32:
39 : case TK_FLOAT64:
40 : case TK_FLOAT128:
41 : case TK_CHAR8:
42 : case TK_CHAR16:
43 : case TK_ENUM:
44 0 : return 1;
45 12 : case TK_UNION:
46 : {
47 : bool branch_active;
48 12 : DDS::MemberDescriptor_var active_branch;
49 12 : DDS::ReturnCode_t rc = get_selected_union_branch(branch_active, active_branch);
50 12 : if (rc != DDS::RETCODE_OK) {
51 0 : if (DCPS::log_level >= DCPS::LogLevel::Warning) {
52 0 : const CORBA::String_var type_name = type_->get_name();
53 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataAdapterImpl<%C>::item: "
54 : "get_selected_union_branch returned %C\n",
55 : type_name.in(), retcode_to_string(rc)));
56 0 : }
57 0 : return MEMBER_ID_INVALID;
58 : }
59 12 : return branch_active ? 2 : 1;
60 12 : }
61 : break;
62 0 : case TK_STRING8:
63 : case TK_STRING16:
64 : case TK_SEQUENCE:
65 : case TK_BITMASK:
66 : case TK_ARRAY:
67 : case TK_STRUCTURE:
68 : case TK_MAP:
69 : case TK_BITSET:
70 0 : if (log_level >= LogLevel::Error) {
71 0 : const CORBA::String_var type_name = type_->get_name();
72 0 : ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicDataAdapterImpl<%C>::get_item_count: "
73 : "this %C should have implemented get_item_count\n",
74 : type_name.in(), typekind_to_string(tk)));
75 0 : }
76 0 : return 0;
77 0 : case TK_ALIAS:
78 : case TK_ANNOTATION:
79 : default:
80 0 : if (log_level >= LogLevel::Warning) {
81 0 : const CORBA::String_var type_name = type_->get_name();
82 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataAdapterImpl<%C>::get_item_count: "
83 : "unexpected type %C\n", type_name.in(), typekind_to_string(tk)));
84 0 : }
85 0 : return 0;
86 : }
87 : }
88 :
89 0 : DDS::MemberId DynamicDataAdapter::get_member_id_by_name(const char* name)
90 : {
91 0 : DDS::DynamicTypeMember_var dtm;
92 0 : if (type_->get_member_by_name(dtm, name) != DDS::RETCODE_OK) {
93 0 : return MEMBER_ID_INVALID;
94 : }
95 0 : return dtm->get_id();
96 0 : }
97 :
98 0 : DDS::MemberId DynamicDataAdapter::get_member_id_at_index_impl(DDS::UInt32)
99 : {
100 0 : OPENDDS_ASSERT(false);
101 : return MEMBER_ID_INVALID;
102 : }
103 :
104 340 : DDS::MemberId DynamicDataAdapter::get_member_id_at_index(DDS::UInt32 index)
105 : {
106 : DDS::ReturnCode_t rc;
107 340 : const TypeKind tk = type_->get_kind();
108 340 : switch (tk) {
109 0 : case TK_STRUCTURE:
110 : {
111 0 : DDS::DynamicTypeMember_var dtm;
112 0 : rc = type_->get_member_by_index(dtm, index);
113 0 : if (rc != DDS::RETCODE_OK) {
114 0 : if (DCPS::log_level >= DCPS::LogLevel::Warning) {
115 0 : const CORBA::String_var type_name = type_->get_name();
116 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataAdapterImpl<%C>::get_member_id_at_index: "
117 : "get_member_by_index returned %C\n",
118 : type_name.in(), retcode_to_string(rc)));
119 0 : }
120 0 : return MEMBER_ID_INVALID;
121 : }
122 0 : return dtm->get_id();
123 0 : }
124 12 : case TK_UNION:
125 : {
126 12 : if (index == 0) {
127 0 : return DISCRIMINATOR_ID;
128 12 : } else if (index == 1) {
129 : bool branch_active;
130 12 : DDS::MemberDescriptor_var active_branch;
131 12 : DDS::ReturnCode_t rc = get_selected_union_branch(branch_active, active_branch);
132 12 : if (rc != DDS::RETCODE_OK) {
133 0 : if (DCPS::log_level >= DCPS::LogLevel::Warning) {
134 0 : const CORBA::String_var type_name = type_->get_name();
135 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataAdapterImpl<%C>::get_member_id_at_index: "
136 : "get_selected_union_branch returned %C\n",
137 : type_name.in(), retcode_to_string(rc)));
138 0 : }
139 0 : return MEMBER_ID_INVALID;
140 : }
141 12 : if (branch_active) {
142 12 : return active_branch->id();
143 0 : } else if (DCPS::log_level >= DCPS::LogLevel::Warning) {
144 0 : const CORBA::String_var type_name = type_->get_name();
145 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataAdapterImpl<%C>::get_member_id_at_index: "
146 : "union doesn't have an active branch, so index 1 is invalid\n",
147 : type_name.in()));
148 0 : }
149 12 : } else if (DCPS::log_level >= DCPS::LogLevel::Warning) {
150 0 : const CORBA::String_var type_name = type_->get_name();
151 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataAdapterImpl<%C>::get_member_id_at_index: "
152 : "index %u is invalid for unions\n",
153 : type_name.in(), index));
154 0 : }
155 0 : return MEMBER_ID_INVALID;
156 : }
157 164 : case TK_SEQUENCE:
158 164 : return get_member_id_at_index_impl(index);
159 164 : case TK_ARRAY:
160 : {
161 164 : DDS::ReturnCode_t rc = check_index("get_member_id_at_index", index, bound_total(type_desc_));
162 164 : if (rc != DDS::RETCODE_OK) {
163 0 : if (DCPS::log_level >= DCPS::LogLevel::Warning) {
164 0 : const CORBA::String_var type_name = type_->get_name();
165 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataAdapterImpl<%C>::get_member_id_at_index: "
166 : "check_index returned %C\n",
167 : type_name.in(), retcode_to_string(rc)));
168 0 : }
169 0 : return MEMBER_ID_INVALID;
170 : }
171 164 : return index;
172 : }
173 0 : default:
174 0 : if (DCPS::log_level >= DCPS::LogLevel::Warning) {
175 0 : const CORBA::String_var type_name = type_->get_name();
176 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataAdapterImpl<%C>::get_member_id_at_index: "
177 : "not supported for %C\n",
178 : type_name.in(), typekind_to_string(tk)));
179 0 : }
180 0 : return MEMBER_ID_INVALID;
181 : }
182 : }
183 :
184 0 : DDS::ReturnCode_t DynamicDataAdapter::clear_all_values()
185 : {
186 0 : return unsupported_method("DynamicDataAdapater::clear_all_values");
187 : }
188 :
189 0 : DDS::ReturnCode_t DynamicDataAdapter::clear_nonkey_values()
190 : {
191 0 : return unsupported_method("DynamicDataAdapater::clear_nonkey_values");
192 : }
193 :
194 0 : DDS::ReturnCode_t DynamicDataAdapter::clear_value(DDS::MemberId)
195 : {
196 0 : return unsupported_method("DynamicDataAdapater::clear_value");
197 : }
198 :
199 0 : DDS::DynamicData_ptr DynamicDataAdapter::clone()
200 : {
201 0 : unsupported_method("DynamicDataAdapater::clone");
202 0 : return 0;
203 : }
204 :
205 0 : DDS::ReturnCode_t DynamicDataAdapter::invalid_id(const char* method, DDS::MemberId id) const
206 : {
207 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
208 0 : const CORBA::String_var type_name = type_->get_name();
209 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataAdapterImpl<%C>::%C: invalid member id %u\n",
210 : type_name.in(), method, id));
211 0 : }
212 0 : return DDS::RETCODE_BAD_PARAMETER;
213 : }
214 :
215 0 : DDS::ReturnCode_t DynamicDataAdapter::missing_dda(const char* method, DDS::MemberId id) const
216 : {
217 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
218 0 : const CORBA::String_var type_name = type_->get_name();
219 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataAdapterImpl<%C>::%C: "
220 : "member id %u doesn't have a DynamicDataAdapterImpl\n",
221 : type_name.in(), method, id));
222 0 : }
223 0 : return DDS::RETCODE_BAD_PARAMETER;
224 : }
225 :
226 200 : DDS::ReturnCode_t DynamicDataAdapter::assert_mutable(const char* method) const
227 : {
228 200 : if (read_only_) {
229 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
230 0 : const CORBA::String_var type_name = type_->get_name();
231 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataAdapterImpl<%C>::%C: "
232 : "can't set values as this DynamicDataAdapter is read only\n",
233 : type_name.in(), method));
234 0 : }
235 0 : return DDS::RETCODE_ILLEGAL_OPERATION;
236 : }
237 200 : return DDS::RETCODE_OK;
238 : }
239 :
240 574 : DDS::ReturnCode_t DynamicDataAdapter::check_index(
241 : const char* method, DDS::UInt32 index, DDS::UInt32 size) const
242 : {
243 574 : if (index >= size) {
244 0 : if (OpenDDS::DCPS::log_level >= OpenDDS::DCPS::LogLevel::Notice) {
245 0 : const CORBA::String_var type_name = type_->get_name();
246 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataAdapterImpl<%C>::%C: "
247 : "index %u is larger or equal to than the size (%u)\n",
248 : type_name.in(), method, index, size));
249 0 : }
250 0 : return DDS::RETCODE_BAD_PARAMETER;
251 : }
252 574 : return DDS::RETCODE_OK;
253 : }
254 :
255 635 : DDS::ReturnCode_t DynamicDataAdapter::check_member(
256 : DDS::DynamicType_var& member_type, const char* method, DDS::TypeKind tk, DDS::MemberId id)
257 : {
258 635 : return DynamicDataBase::check_member(member_type, method, "access", id, tk);
259 : }
260 :
261 425 : DDS::ReturnCode_t DynamicDataAdapter::check_member(
262 : const char* method, DDS::TypeKind tk, DDS::MemberId id)
263 : {
264 425 : DDS::DynamicType_var member_type;
265 850 : return check_member(member_type, method, tk, id);
266 425 : }
267 :
268 10 : DDS::ReturnCode_t DynamicDataAdapter::get_s8_raw_value(
269 : const char* method, void* dest, DDS::TypeKind tk, const char* source, DDS::MemberId id)
270 : {
271 10 : const DDS::ReturnCode_t rc = check_member(method, tk, id);
272 10 : if (rc != DDS::RETCODE_OK) {
273 0 : return rc;
274 : }
275 10 : char*& dest_value = *static_cast<char**>(dest);
276 10 : CORBA::string_free(dest_value);
277 10 : dest_value = CORBA::string_dup(source);
278 10 : return rc;
279 : }
280 :
281 10 : DDS::ReturnCode_t DynamicDataAdapter::set_s8_raw_value(
282 : const char* method, char*& dest, DDS::MemberId id, const void* source, DDS::TypeKind tk)
283 : {
284 10 : const DDS::ReturnCode_t rc = check_member(method, tk, id);
285 10 : if (rc != DDS::RETCODE_OK) {
286 0 : return rc;
287 : }
288 10 : CORBA::string_free(dest);
289 10 : dest = CORBA::string_dup(static_cast<const char*>(source));
290 10 : return rc;
291 : }
292 :
293 0 : DDS::ReturnCode_t DynamicDataAdapter::get_cpp11_s8_raw_value(
294 : const char* method, void* dest, DDS::TypeKind tk,
295 : const std::string& source, DDS::MemberId id)
296 : {
297 0 : const DDS::ReturnCode_t rc = check_member(method, tk, id);
298 0 : if (rc != DDS::RETCODE_OK) {
299 0 : return rc;
300 : }
301 0 : char*& dest_value = *static_cast<char**>(dest);
302 0 : CORBA::string_free(dest_value);
303 0 : dest_value = CORBA::string_dup(source.c_str());
304 0 : return rc;
305 : }
306 :
307 0 : DDS::ReturnCode_t DynamicDataAdapter::set_cpp11_s8_raw_value(
308 : const char* method, std::string& dest, DDS::MemberId id,
309 : const void* source, DDS::TypeKind tk)
310 : {
311 0 : const DDS::ReturnCode_t rc = check_member(method, tk, id);
312 0 : if (rc == DDS::RETCODE_OK) {
313 0 : dest = static_cast<const char*>(source);
314 : }
315 0 : return rc;
316 : }
317 :
318 9 : DDS::ReturnCode_t DynamicDataAdapter::get_s16_raw_value(
319 : const char* method, void* dest, DDS::TypeKind tk,
320 : const DDS::Char16* source, DDS::MemberId id)
321 : {
322 9 : const DDS::ReturnCode_t rc = check_member(method, tk, id);
323 9 : if (rc != DDS::RETCODE_OK) {
324 0 : return rc;
325 : }
326 9 : DDS::Char16*& dest_value = *static_cast<DDS::Char16**>(dest);
327 9 : CORBA::wstring_free(dest_value);
328 9 : dest_value = CORBA::wstring_dup(source);
329 9 : return rc;
330 : }
331 :
332 9 : DDS::ReturnCode_t DynamicDataAdapter::set_s16_raw_value(
333 : const char* method, DDS::Char16*& dest, DDS::MemberId id,
334 : const void* source, DDS::TypeKind tk)
335 : {
336 9 : const DDS::ReturnCode_t rc = check_member(method, tk, id);
337 9 : if (rc != DDS::RETCODE_OK) {
338 0 : return rc;
339 : }
340 9 : CORBA::wstring_free(dest);
341 9 : dest = CORBA::wstring_dup(static_cast<const DDS::Char16*>(source));
342 9 : return rc;
343 : }
344 :
345 0 : DDS::ReturnCode_t DynamicDataAdapter::get_cpp11_s16_raw_value(
346 : const char* method, void* dest, DDS::TypeKind tk,
347 : const std::wstring& source, DDS::MemberId id)
348 : {
349 0 : const DDS::ReturnCode_t rc = check_member(method, tk, id);
350 0 : if (rc != DDS::RETCODE_OK) {
351 0 : return rc;
352 : }
353 0 : DDS::Char16*& dest_value = *static_cast<DDS::Char16**>(dest);
354 0 : CORBA::wstring_free(dest_value);
355 0 : dest_value = CORBA::wstring_dup(source.c_str());
356 0 : return rc;
357 : }
358 :
359 0 : DDS::ReturnCode_t DynamicDataAdapter::set_cpp11_s16_raw_value(
360 : const char* method, std::wstring& dest, DDS::MemberId id,
361 : const void* source, DDS::TypeKind tk)
362 : {
363 0 : const DDS::ReturnCode_t rc = check_member(method, tk, id);
364 0 : if (rc == DDS::RETCODE_OK) {
365 0 : dest = static_cast<const DDS::Char16*>(source);
366 : }
367 0 : return rc;
368 : }
369 :
370 : } // namespace XTypes
371 : } // namespace OpenDDS
372 :
373 : OPENDDS_END_VERSIONED_NAMESPACE_DECL
374 :
375 : #endif // OPENDDS_HAS_DYNAMIC_DATA_ADAPTER
|