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 : #ifndef OPENDDS_SAFETY_PROFILE
9 : # include "DynamicDataXcdrReadImpl.h"
10 :
11 : # include "DynamicTypeMemberImpl.h"
12 : # include "Utils.h"
13 :
14 : # include <dds/DCPS/debug.h>
15 : # include <dds/DCPS/FilterEvaluator.h>
16 : # include <dds/DCPS/SafetyProfileStreams.h>
17 : # include <dds/DCPS/ValueHelper.h>
18 :
19 : # include <dds/DdsDcpsCoreTypeSupportImpl.h>
20 : # include <dds/DdsDcpsInfrastructureC.h>
21 : # include <dds/DdsDynamicDataSeqTypeSupportImpl.h>
22 : # include <dds/CorbaSeq/LongSeqTypeSupportImpl.h>
23 : # include <dds/CorbaSeq/ULongSeqTypeSupportImpl.h>
24 : # include <dds/CorbaSeq/Int8SeqTypeSupportImpl.h>
25 : # include <dds/CorbaSeq/UInt8SeqTypeSupportImpl.h>
26 : # include <dds/CorbaSeq/ShortSeqTypeSupportImpl.h>
27 : # include <dds/CorbaSeq/UShortSeqTypeSupportImpl.h>
28 : # include <dds/CorbaSeq/LongLongSeqTypeSupportImpl.h>
29 : # include <dds/CorbaSeq/ULongLongSeqTypeSupportImpl.h>
30 : # include <dds/CorbaSeq/FloatSeqTypeSupportImpl.h>
31 : # include <dds/CorbaSeq/DoubleSeqTypeSupportImpl.h>
32 : # include <dds/CorbaSeq/LongDoubleSeqTypeSupportImpl.h>
33 : # include <dds/CorbaSeq/CharSeqTypeSupportImpl.h>
34 : # include <dds/CorbaSeq/WCharSeqTypeSupportImpl.h>
35 : # include <dds/CorbaSeq/OctetSeqTypeSupportImpl.h>
36 : # include <dds/CorbaSeq/BooleanSeqTypeSupportImpl.h>
37 : # include <dds/CorbaSeq/StringSeqTypeSupportImpl.h>
38 : # include <dds/CorbaSeq/WStringSeqTypeSupportImpl.h>
39 :
40 : # include <ace/OS_NS_string.h>
41 :
42 : # include <stdexcept>
43 :
44 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
45 : namespace OpenDDS {
46 : namespace XTypes {
47 :
48 : using DCPS::log_level;
49 : using DCPS::LogLevel;
50 :
51 0 : DynamicDataXcdrReadImpl::DynamicDataXcdrReadImpl()
52 0 : : chain_(0)
53 0 : , encoding_(DCPS::Encoding::KIND_XCDR2)
54 0 : , extent_(DCPS::Sample::Full)
55 0 : , reset_align_state_(false)
56 0 : , strm_(0, encoding_)
57 0 : , item_count_(ITEM_COUNT_INVALID)
58 0 : {}
59 :
60 131 : DynamicDataXcdrReadImpl::DynamicDataXcdrReadImpl(ACE_Message_Block* chain,
61 : const DCPS::Encoding& encoding,
62 : DDS::DynamicType_ptr type,
63 131 : DCPS::Sample::Extent ext)
64 : : DynamicDataBase(type)
65 262 : , chain_(chain->duplicate())
66 131 : , encoding_(encoding)
67 131 : , extent_(ext)
68 131 : , reset_align_state_(false)
69 131 : , strm_(chain_, encoding_)
70 262 : , item_count_(ITEM_COUNT_INVALID)
71 : {
72 214 : if (encoding_.xcdr_version() != DCPS::Encoding::XCDR_VERSION_1 &&
73 83 : encoding_.xcdr_version() != DCPS::Encoding::XCDR_VERSION_2) {
74 0 : throw std::runtime_error("DynamicDataXcdrReadImpl only supports XCDR1 and XCDR2");
75 : }
76 131 : }
77 :
78 231 : DynamicDataXcdrReadImpl::DynamicDataXcdrReadImpl(DCPS::Serializer& ser, DDS::DynamicType_ptr type,
79 231 : DCPS::Sample::Extent ext)
80 : : DynamicDataBase(type)
81 231 : , chain_(ser.current()->duplicate())
82 231 : , encoding_(ser.encoding())
83 231 : , extent_(ext)
84 231 : , reset_align_state_(true)
85 231 : , align_state_(ser.rdstate())
86 231 : , strm_(chain_, encoding_)
87 462 : , item_count_(ITEM_COUNT_INVALID)
88 : {
89 372 : if (encoding_.xcdr_version() != DCPS::Encoding::XCDR_VERSION_1 &&
90 141 : encoding_.xcdr_version() != DCPS::Encoding::XCDR_VERSION_2) {
91 0 : throw std::runtime_error("DynamicDataXcdrReadImpl only supports XCDR1 and XCDR2");
92 : }
93 :
94 231 : strm_.rdstate(align_state_);
95 231 : }
96 :
97 0 : DynamicDataXcdrReadImpl::DynamicDataXcdrReadImpl(const DynamicDataXcdrReadImpl& other)
98 : : CORBA::Object()
99 : , DDS::DynamicData()
100 : , CORBA::LocalObject()
101 : , RcObject()
102 : , DynamicDataBase()
103 0 : , chain_(0)
104 0 : , strm_(0, other.encoding_)
105 : {
106 0 : copy(other);
107 0 : }
108 :
109 0 : DynamicDataXcdrReadImpl& DynamicDataXcdrReadImpl::operator=(const DynamicDataXcdrReadImpl& other)
110 : {
111 0 : if (this != &other) {
112 0 : copy(other);
113 : }
114 0 : return *this;
115 : }
116 :
117 537 : DynamicDataXcdrReadImpl::~DynamicDataXcdrReadImpl()
118 : {
119 362 : ACE_Message_Block::release(chain_);
120 537 : }
121 :
122 0 : void DynamicDataXcdrReadImpl::copy(const DynamicDataXcdrReadImpl& other)
123 : {
124 0 : ACE_Message_Block::release(chain_);
125 0 : chain_ = other.chain_->duplicate();
126 0 : encoding_ = other.encoding_;
127 0 : extent_ = other.extent_;
128 0 : reset_align_state_ = other.reset_align_state_;
129 0 : align_state_ = other.align_state_;
130 0 : strm_ = other.strm_;
131 0 : type_ = other.type_;
132 0 : item_count_ = other.item_count_;
133 0 : }
134 :
135 0 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::set_descriptor(MemberId, DDS::MemberDescriptor*)
136 : {
137 0 : return DDS::RETCODE_UNSUPPORTED;
138 : }
139 :
140 234 : bool DynamicDataXcdrReadImpl::has_optional_member(bool& has_optional) const
141 : {
142 234 : if (type_->get_kind() != TK_STRUCTURE) {
143 0 : return false;
144 : }
145 :
146 234 : const ACE_CDR::ULong count = type_->get_member_count();
147 3718 : for (unsigned i = 0; i < count; ++i) {
148 3512 : DDS::DynamicTypeMember_var member;
149 3512 : if (type_->get_member_by_index(member, i) != DDS::RETCODE_OK) {
150 0 : return false;
151 : }
152 3512 : DDS::MemberDescriptor_var descriptor;
153 3512 : if (member->get_descriptor(descriptor) != DDS::RETCODE_OK) {
154 0 : return false;
155 : }
156 3512 : if (descriptor->is_optional()) {
157 28 : has_optional = true;
158 28 : return true;
159 : }
160 3540 : }
161 206 : has_optional = false;
162 206 : return true;
163 : }
164 :
165 184 : DDS::MemberId DynamicDataXcdrReadImpl::get_member_id_at_index(ACE_CDR::ULong index)
166 : {
167 184 : if (item_count_ == ITEM_COUNT_INVALID) {
168 184 : get_item_count();
169 : }
170 184 : if (index >= item_count_) {
171 0 : return MEMBER_ID_INVALID;
172 : }
173 :
174 184 : ScopedChainManager chain_manager(*this);
175 :
176 184 : const TypeKind tk = type_->get_kind();
177 184 : switch (tk) {
178 0 : case TK_BOOLEAN:
179 : case TK_BYTE:
180 : case TK_INT16:
181 : case TK_INT32:
182 : case TK_INT64:
183 : case TK_UINT16:
184 : case TK_UINT32:
185 : case TK_UINT64:
186 : case TK_FLOAT32:
187 : case TK_FLOAT64:
188 : case TK_FLOAT128:
189 : case TK_INT8:
190 : case TK_UINT8:
191 : case TK_CHAR8:
192 : #ifdef DDS_HAS_WCHAR
193 : case TK_CHAR16:
194 : #endif
195 : case TK_ENUM:
196 : // Value of enum or primitive types can be indicated by Id MEMBER_ID_INVALID
197 : // or by index 0 (Section 7.5.2.11.1).
198 0 : if (index != 0 && DCPS::log_level >= DCPS::LogLevel::Notice) {
199 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_member_id_at_index:"
200 : " Received invalid index (%d) for type %C\n", index, typekind_to_string(tk)));
201 : }
202 0 : return MEMBER_ID_INVALID;
203 49 : case TK_STRING8:
204 : #ifdef DDS_HAS_WCHAR
205 : case TK_STRING16:
206 : #endif
207 : case TK_BITMASK:
208 : case TK_SEQUENCE:
209 : case TK_ARRAY:
210 : case TK_MAP:
211 49 : return index;
212 124 : case TK_STRUCTURE:
213 : {
214 124 : DDS::TypeDescriptor_var descriptor;
215 124 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
216 0 : return MEMBER_ID_INVALID;
217 : }
218 124 : const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
219 124 : if (ek == DDS::APPENDABLE || ek == DDS::MUTABLE) {
220 79 : if (!strm_.skip_delimiter()) {
221 0 : return MEMBER_ID_INVALID;
222 : }
223 : }
224 :
225 124 : if (ek == DDS::FINAL || ek == DDS::APPENDABLE) {
226 : bool has_optional;
227 90 : if (!has_optional_member(has_optional)) {
228 0 : return MEMBER_ID_INVALID;
229 : }
230 :
231 90 : if (extent_ != DCPS::Sample::Full) {
232 4 : const bool struct_has_explicit_keys = has_explicit_keys(type_);
233 4 : if (struct_has_explicit_keys) {
234 : // All and only explicit keys will be present in the binary stream.
235 : // Index of the next member in the binary stream.
236 3 : ACE_CDR::ULong curr_index = 0;
237 7 : for (ACE_CDR::ULong i = 0; i < type_->get_member_count(); ++i) {
238 7 : DDS::DynamicTypeMember_var dtm;
239 7 : if (type_->get_member_by_index(dtm, i) != DDS::RETCODE_OK) {
240 0 : return MEMBER_ID_INVALID;
241 : }
242 7 : DDS::MemberDescriptor_var md;
243 7 : if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
244 0 : return MEMBER_ID_INVALID;
245 : }
246 7 : if (exclude_member(extent_, md->is_key(), struct_has_explicit_keys)) {
247 4 : continue;
248 : }
249 3 : if (curr_index == index) {
250 3 : return md->id();
251 : }
252 0 : ++curr_index;
253 14 : }
254 : // Should never reach here!
255 0 : return MEMBER_ID_INVALID;
256 1 : } else if (extent_ == DCPS::Sample::KeyOnly) {
257 0 : return MEMBER_ID_INVALID;
258 : }
259 : }
260 :
261 : // A Full sample or a NestedKeyOnly sample with no explicit key.
262 87 : if (!has_optional) {
263 77 : DDS::DynamicTypeMember_var member;
264 77 : if (type_->get_member_by_index(member, index) != DDS::RETCODE_OK) {
265 0 : return MEMBER_ID_INVALID;
266 : }
267 77 : return member->get_id();
268 77 : } else {
269 10 : MemberId id = MEMBER_ID_INVALID;
270 10 : ACE_CDR::ULong total_skipped = 0;
271 52 : for (ACE_CDR::ULong i = 0; i < type_->get_member_count(); ++i) {
272 : ACE_CDR::ULong num_skipped;
273 52 : if (!skip_struct_member_at_index(i, num_skipped)) {
274 10 : break;
275 : }
276 52 : total_skipped += num_skipped;
277 52 : if (total_skipped == index + 1) {
278 10 : DDS::DynamicTypeMember_var member;
279 10 : if (type_->get_member_by_index(member, i) == DDS::RETCODE_OK) {
280 10 : id = member->get_id();
281 : }
282 10 : break;
283 10 : }
284 : }
285 10 : return id;
286 : }
287 : } else { // Mutable
288 : ACE_CDR::ULong member_id;
289 : size_t member_size;
290 : bool must_understand;
291 34 : bool good = true;
292 224 : for (unsigned i = 0; i < index; ++i) {
293 190 : if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
294 0 : good = false;
295 0 : break;
296 : }
297 :
298 190 : DDS::DynamicTypeMember_var dtm;
299 190 : if (type_->get_member(dtm, member_id) != DDS::RETCODE_OK) {
300 0 : good = false;
301 0 : break;
302 : }
303 190 : DDS::MemberDescriptor_var descriptor;
304 190 : if (dtm->get_descriptor(descriptor) != DDS::RETCODE_OK) {
305 0 : good = false;
306 0 : break;
307 : }
308 190 : const DDS::DynamicType_ptr mt = descriptor->type();
309 190 : if (!mt) {
310 0 : good = false;
311 0 : break;
312 : }
313 190 : const DDS::DynamicType_var member = get_base_type(mt);
314 190 : if (member->get_kind() == TK_SEQUENCE) {
315 0 : if (!skip_sequence_member(member)) {
316 0 : good = false;
317 0 : break;
318 : }
319 190 : } else if (!strm_.skip(member_size)) {
320 0 : good = false;
321 0 : break;
322 : }
323 190 : }
324 :
325 34 : if (!good || !strm_.read_parameter_id(member_id, member_size, must_understand)) {
326 0 : member_id = MEMBER_ID_INVALID;
327 : }
328 34 : return member_id;
329 : }
330 124 : }
331 11 : case TK_UNION:
332 : {
333 11 : if (extent_ == DCPS::Sample::KeyOnly) {
334 0 : DDS::DynamicTypeMember_var disc_dtm;
335 0 : if (type_->get_member(disc_dtm, DISCRIMINATOR_ID) != DDS::RETCODE_OK) {
336 0 : return MEMBER_ID_INVALID;
337 : }
338 0 : DDS::MemberDescriptor_var disc_md;
339 0 : if (disc_dtm->get_descriptor(disc_md) != DDS::RETCODE_OK) {
340 0 : return MEMBER_ID_INVALID;
341 : }
342 0 : if (!disc_md->is_key()) {
343 : // The sample is empty.
344 0 : return MEMBER_ID_INVALID;
345 : }
346 0 : }
347 :
348 11 : if (index == 0) {
349 11 : return DISCRIMINATOR_ID;
350 : }
351 :
352 0 : if (extent_ != DCPS::Sample::Full) {
353 : // KeyOnly or NestedKeyOnly sample can only contain discriminator.
354 0 : return MEMBER_ID_INVALID;
355 : }
356 :
357 : // Get the Id of the selected member.
358 0 : DDS::MemberDescriptor_var selected_md = get_union_selected_member();
359 0 : if (!selected_md) {
360 0 : return MEMBER_ID_INVALID;
361 : }
362 :
363 0 : return selected_md->id();
364 0 : }
365 : }
366 :
367 0 : if (DCPS::DCPS_debug_level >= 1) {
368 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_member_id_at_index -")
369 : ACE_TEXT(" Calling on an unexpected type %C\n"), typekind_to_string(tk)));
370 : }
371 0 : return MEMBER_ID_INVALID;
372 184 : }
373 :
374 223 : ACE_CDR::ULong DynamicDataXcdrReadImpl::get_item_count()
375 : {
376 223 : if (item_count_ != ITEM_COUNT_INVALID) {
377 0 : return item_count_;
378 : }
379 :
380 223 : ScopedChainManager chain_manager(*this);
381 :
382 223 : DDS::TypeDescriptor_var descriptor;
383 223 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
384 0 : return 0;
385 : }
386 :
387 223 : const TypeKind tk = type_->get_kind();
388 223 : switch (tk) {
389 0 : case TK_BOOLEAN:
390 : case TK_BYTE:
391 : case TK_INT16:
392 : case TK_INT32:
393 : case TK_INT64:
394 : case TK_UINT16:
395 : case TK_UINT32:
396 : case TK_UINT64:
397 : case TK_FLOAT32:
398 : case TK_FLOAT64:
399 : case TK_FLOAT128:
400 : case TK_INT8:
401 : case TK_UINT8:
402 : case TK_CHAR8:
403 : case TK_CHAR16:
404 : case TK_ENUM:
405 0 : return 1;
406 0 : case TK_STRING8:
407 : case TK_STRING16:
408 : {
409 : ACE_CDR::ULong bytes;
410 0 : if (!(strm_ >> bytes)) {
411 0 : return 0;
412 : }
413 0 : return (type_->get_kind() == TK_STRING8) ? bytes : bytes/2;
414 : }
415 0 : case TK_BITMASK:
416 0 : return descriptor->bound()[0];
417 144 : case TK_STRUCTURE:
418 : {
419 : bool has_optional;
420 144 : if (!has_optional_member(has_optional)) {
421 0 : return 0;
422 : }
423 :
424 144 : if (extent_ != DCPS::Sample::Full) {
425 15 : const bool struct_has_explicit_keys = has_explicit_keys(type_);
426 15 : if (struct_has_explicit_keys) {
427 13 : ACE_CDR::ULong num_explicit_keys = 0;
428 64 : for (ACE_CDR::ULong i = 0; i < type_->get_member_count(); ++i) {
429 51 : DDS::DynamicTypeMember_var dtm;
430 51 : if (type_->get_member_by_index(dtm, i) != DDS::RETCODE_OK) {
431 0 : return 0;
432 : }
433 51 : DDS::MemberDescriptor_var md;
434 51 : if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
435 0 : return 0;
436 : }
437 51 : if (md->is_key()) {
438 16 : ++num_explicit_keys;
439 : }
440 51 : }
441 13 : return num_explicit_keys;
442 2 : } else if (extent_ == DCPS::Sample::KeyOnly) {
443 0 : return 0;
444 : }
445 : }
446 :
447 : // Full sample or NestedKeyOnly sample with no explicit key.
448 131 : if (!has_optional) {
449 113 : return type_->get_member_count();
450 : }
451 :
452 : // Optional members can be omitted, so we need to count members one by one.
453 18 : ACE_CDR::ULong actual_count = 0;
454 18 : const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
455 18 : if (ek == DDS::FINAL || ek == DDS::APPENDABLE) {
456 12 : if (ek == DDS::APPENDABLE) {
457 6 : if (!strm_.skip_delimiter()) {
458 0 : return 0;
459 : }
460 : }
461 240 : for (ACE_CDR::ULong i = 0; i < type_->get_member_count(); ++i) {
462 : ACE_CDR::ULong num_skipped;
463 228 : if (!skip_struct_member_at_index(i, num_skipped)) {
464 0 : actual_count = 0;
465 0 : break;
466 : }
467 228 : actual_count += num_skipped;
468 : }
469 12 : } else { // Mutable
470 6 : size_t dheader = 0;
471 6 : if (!strm_.read_delimiter(dheader)) {
472 0 : return 0;
473 : }
474 :
475 6 : const size_t end_of_struct = strm_.rpos() + dheader;
476 108 : while (strm_.rpos() < end_of_struct) {
477 : ACE_CDR::ULong member_id;
478 : size_t member_size;
479 : bool must_understand;
480 102 : if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
481 0 : actual_count = 0;
482 0 : break;
483 : }
484 :
485 102 : DDS::DynamicTypeMember_var dtm;
486 102 : if (type_->get_member(dtm, member_id) != DDS::RETCODE_OK) {
487 0 : actual_count = 0;
488 0 : break;
489 : }
490 102 : DDS::MemberDescriptor_var descriptor;
491 102 : if (dtm->get_descriptor(descriptor) != DDS::RETCODE_OK) {
492 0 : actual_count = 0;
493 0 : break;
494 : }
495 102 : const DDS::DynamicType_ptr mt = descriptor->type();
496 102 : if (!mt) {
497 0 : actual_count = 0;
498 0 : break;
499 : }
500 102 : const DDS::DynamicType_var member = get_base_type(mt);
501 102 : if (member->get_kind() == TK_SEQUENCE) {
502 0 : if (!skip_sequence_member(member)) {
503 0 : actual_count = 0;
504 0 : break;
505 : }
506 102 : } else if (!strm_.skip(member_size)) {
507 0 : actual_count = 0;
508 0 : break;
509 : }
510 102 : ++actual_count;
511 102 : }
512 : }
513 18 : return actual_count;
514 : }
515 12 : case TK_UNION:
516 : {
517 12 : if (extent_ == DCPS::Sample::KeyOnly) {
518 0 : DDS::DynamicTypeMember_var disc_dtm;
519 0 : if (type_->get_member(disc_dtm, DISCRIMINATOR_ID) != DDS::RETCODE_OK) {
520 0 : return 0;
521 : }
522 0 : DDS::MemberDescriptor_var disc_md;
523 0 : if (disc_dtm->get_descriptor(disc_md) != DDS::RETCODE_OK) {
524 0 : return 0;
525 : }
526 0 : if (!disc_md->is_key()) {
527 0 : return 0;
528 : }
529 0 : }
530 12 : if (extent_ != DCPS::Sample::Full) {
531 2 : return 1;
532 : }
533 :
534 10 : const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
535 10 : if (ek == DDS::APPENDABLE || ek == DDS::MUTABLE) {
536 6 : if (!strm_.skip_delimiter()) {
537 0 : return 0;
538 : }
539 : }
540 10 : const DDS::DynamicType_var disc_type = get_base_type(descriptor->discriminator_type());
541 10 : const DDS::ExtensibilityKind extend = descriptor->extensibility_kind();
542 : ACE_CDR::Long label;
543 10 : if (!read_discriminator(disc_type, extend, label)) {
544 0 : return 0;
545 : }
546 :
547 10 : DDS::DynamicTypeMembersById_var members;
548 10 : if (type_->get_all_members(members) != DDS::RETCODE_OK) {
549 0 : return 0;
550 : }
551 10 : DynamicTypeMembersByIdImpl* members_impl = dynamic_cast<DynamicTypeMembersByIdImpl*>(members.in());
552 10 : if (!members_impl) {
553 0 : return 0;
554 : }
555 15 : for (DynamicTypeMembersByIdImpl::const_iterator it = members_impl->begin(); it != members_impl->end(); ++it) {
556 15 : DDS::MemberDescriptor_var md;
557 15 : if (it->second->get_descriptor(md) != DDS::RETCODE_OK) {
558 0 : return 0;
559 : }
560 15 : if (md->is_default_label()) {
561 0 : return 2;
562 : }
563 15 : const DDS::UnionCaseLabelSeq& labels = md->label();
564 20 : for (ACE_CDR::ULong i = 0; i < labels.length(); ++i) {
565 15 : if (label == labels[i]) {
566 10 : return 2;
567 : }
568 : }
569 15 : }
570 0 : return 1;
571 10 : }
572 34 : case TK_SEQUENCE:
573 : {
574 34 : const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
575 34 : if (!is_primitive(elem_type->get_kind())) {
576 24 : if (!strm_.skip_delimiter()) {
577 0 : return 0;
578 : }
579 : }
580 : ACE_CDR::ULong length;
581 34 : if (!(strm_ >> length)) {
582 0 : return 0;
583 : }
584 34 : return length;
585 34 : }
586 33 : case TK_ARRAY:
587 33 : return bound_total(type_desc_);
588 0 : case TK_MAP:
589 : {
590 0 : const DDS::DynamicType_var key_type = get_base_type(descriptor->key_element_type());
591 0 : const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
592 0 : if (is_primitive(key_type->get_kind()) &&
593 0 : is_primitive(elem_type->get_kind())) {
594 : ACE_CDR::ULong length;
595 0 : if (!(strm_ >> length)) {
596 0 : return 0;
597 : }
598 0 : return length;
599 : }
600 :
601 : size_t dheader;
602 0 : if (!strm_.read_delimiter(dheader)) {
603 0 : return 0;
604 : }
605 0 : const size_t end_of_map = strm_.rpos() + dheader;
606 :
607 0 : ACE_CDR::ULong length = 0;
608 0 : while (strm_.rpos() < end_of_map) {
609 0 : if (!skip_member(key_type) || !skip_member(elem_type)) {
610 0 : length = 0;
611 0 : break;
612 : }
613 0 : ++length;
614 : }
615 0 : return length;
616 0 : }
617 : }
618 :
619 0 : if (DCPS::DCPS_debug_level >= 1) {
620 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_item_count -")
621 : ACE_TEXT(" Calling on an unexpected type %C\n"), typekind_to_string(tk)));
622 : }
623 0 : return 0;
624 223 : }
625 :
626 0 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::clear_all_values()
627 : {
628 0 : return DDS::RETCODE_UNSUPPORTED;
629 : }
630 :
631 0 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::clear_nonkey_values()
632 : {
633 0 : return DDS::RETCODE_UNSUPPORTED;
634 : }
635 :
636 0 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::clear_value(DDS::MemberId /*id*/)
637 : {
638 0 : return DDS::RETCODE_UNSUPPORTED;
639 : }
640 :
641 0 : DDS::DynamicData_ptr DynamicDataXcdrReadImpl::loan_value(DDS::MemberId /*id*/)
642 : {
643 0 : ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicDataXcdrReadImpl::loan_value: Not implemented\n"));
644 0 : return 0;
645 : }
646 :
647 0 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::return_loaned_value(DDS::DynamicData_ptr /*value*/)
648 : {
649 0 : ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicDataXcdrReadImpl::return_loaned_value: Not implemented\n"));
650 0 : return DDS::RETCODE_UNSUPPORTED;
651 : }
652 :
653 :
654 0 : DDS::DynamicData_ptr DynamicDataXcdrReadImpl::clone()
655 : {
656 0 : return new DynamicDataXcdrReadImpl(chain_, strm_.encoding(), type_, extent_);
657 : }
658 :
659 : template<typename ValueType>
660 384 : bool DynamicDataXcdrReadImpl::read_value(ValueType& value, TypeKind tk)
661 : {
662 384 : switch (tk) {
663 384 : case TK_INT32:
664 : case TK_UINT32:
665 : case TK_INT16:
666 : case TK_UINT16:
667 : case TK_INT64:
668 : case TK_UINT64:
669 : case TK_FLOAT32:
670 : case TK_FLOAT64:
671 : case TK_FLOAT128:
672 : case TK_INT8:
673 : case TK_UINT8:
674 : case TK_CHAR8:
675 : case TK_CHAR16:
676 : case TK_BYTE:
677 : case TK_BOOLEAN:
678 : case TK_STRING8:
679 : case TK_STRING16:
680 384 : if (strm_ >> value) {
681 384 : return true;
682 : }
683 0 : break;
684 0 : default:
685 0 : if (log_level >= LogLevel::Notice) {
686 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::read_value: "
687 : "Calling on an unexpected type %C\n", typekind_to_string(tk)));
688 : }
689 0 : return false;
690 : }
691 :
692 0 : if (log_level >= LogLevel::Notice) {
693 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::read_value: "
694 : "failed to deserialize type %C\n", typekind_to_string(tk)));
695 : }
696 0 : return false;
697 : }
698 :
699 : // Check if a struct member with the given Id is excluded from a sample (in case of
700 : // KeyOnly or NestedKeyOnly serialization).
701 404 : bool DynamicDataXcdrReadImpl::exclude_struct_member(MemberId id, DDS::MemberDescriptor_var& md) const
702 : {
703 404 : DDS::DynamicTypeMember_var dtm;
704 404 : if (type_->get_member(dtm, id) != DDS::RETCODE_OK) {
705 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
706 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::exclude_struct_member:"
707 : " Failed to get DynamicTypeMember for member with ID %d\n", id));
708 :
709 : }
710 0 : return false;
711 : }
712 404 : if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
713 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
714 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::exclude_struct_member:"
715 : " Failed to get MemberDescriptor for member with ID %d\n", id));
716 : }
717 0 : return false;
718 : }
719 404 : return exclude_member(extent_, md->is_key(), has_explicit_keys(type_));
720 404 : }
721 :
722 : template<TypeKind MemberTypeKind, typename MemberType>
723 141 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_value_from_struct(MemberType& value, MemberId id,
724 : TypeKind enum_or_bitmask, LBound lower, LBound upper)
725 : {
726 141 : DDS::MemberDescriptor_var md;
727 141 : if (exclude_struct_member(id, md)) {
728 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
729 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_value_from_struct:"
730 : " Attempted to read an excluded member from a %C sample\n",
731 : extent_ == DCPS::Sample::KeyOnly ? "KeyOnly" : "NestedKeyOnly"));
732 : }
733 0 : return DDS::RETCODE_NO_DATA;
734 : }
735 :
736 : DDS::ReturnCode_t rc;
737 141 : if (get_from_struct_common_checks(md, id, MemberTypeKind)) {
738 129 : rc = skip_to_struct_member(md, id);
739 129 : if (rc != DDS::RETCODE_OK) {
740 0 : return rc;
741 : }
742 129 : return read_value(value, MemberTypeKind) ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
743 : }
744 :
745 12 : if (get_from_struct_common_checks(md, id, enum_or_bitmask)) {
746 12 : const DDS::DynamicType_ptr member_type = md->type();
747 12 : if (member_type) {
748 12 : DDS::TypeDescriptor_var td;
749 12 : rc = get_base_type(member_type)->get_descriptor(td);
750 12 : if (rc != DDS::RETCODE_OK) {
751 0 : return rc;
752 : }
753 12 : const LBound bit_bound = td->bound()[0];
754 12 : if (bit_bound >= lower && bit_bound <= upper) {
755 12 : rc = skip_to_struct_member(md, id);
756 12 : if (rc != DDS::RETCODE_OK) {
757 0 : return rc;
758 : }
759 12 : if (read_value(value, MemberTypeKind)) {
760 12 : return DDS::RETCODE_OK;
761 : }
762 : }
763 12 : }
764 : }
765 :
766 0 : return DDS::RETCODE_ERROR;
767 141 : }
768 :
769 130 : DDS::MemberDescriptor* DynamicDataXcdrReadImpl::get_union_selected_member()
770 : {
771 130 : DDS::TypeDescriptor_var descriptor;
772 130 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
773 0 : return 0;
774 : }
775 :
776 130 : const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
777 130 : if (ek == DDS::APPENDABLE || ek == DDS::MUTABLE) {
778 78 : if (!strm_.skip_delimiter()) {
779 0 : return 0;
780 : }
781 : }
782 :
783 130 : const DDS::DynamicType_var disc_type = get_base_type(descriptor->discriminator_type());
784 : ACE_CDR::Long label;
785 130 : if (!read_discriminator(disc_type, ek, label)) {
786 0 : return 0;
787 : }
788 :
789 130 : DDS::DynamicTypeMembersById_var members;
790 130 : if (type_->get_all_members(members) != DDS::RETCODE_OK) {
791 0 : return 0;
792 : }
793 130 : DynamicTypeMembersByIdImpl* members_impl = dynamic_cast<DynamicTypeMembersByIdImpl*>(members.in());
794 130 : if (!members_impl) {
795 0 : return 0;
796 : }
797 :
798 130 : bool has_default = false;
799 130 : DDS::MemberDescriptor_var default_member;
800 1300 : for (DynamicTypeMembersByIdImpl::const_iterator it = members_impl->begin(); it != members_impl->end(); ++it) {
801 1290 : DDS::MemberDescriptor_var md;
802 1290 : if (it->second->get_descriptor(md) != DDS::RETCODE_OK) {
803 0 : return 0;
804 : }
805 1290 : const DDS::UnionCaseLabelSeq& labels = md->label();
806 2440 : for (ACE_CDR::ULong i = 0; i < labels.length(); ++i) {
807 1270 : if (label == labels[i]) {
808 120 : return md._retn();
809 : }
810 : }
811 :
812 1170 : if (md->is_default_label()) {
813 10 : has_default = true;
814 10 : default_member = md;
815 : }
816 1290 : }
817 :
818 10 : if (has_default) {
819 10 : return default_member._retn();;
820 : }
821 :
822 : // The union has no selected member.
823 0 : return 0;
824 130 : }
825 :
826 130 : DDS::MemberDescriptor* DynamicDataXcdrReadImpl::get_from_union_common_checks(MemberId id, const char* func_name)
827 : {
828 130 : DDS::MemberDescriptor_var md = get_union_selected_member();
829 130 : if (!md) {
830 0 : if (DCPS::DCPS_debug_level >= 1) {
831 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::%C - Could not find")
832 : ACE_TEXT(" MemberDescriptor for the selected union member\n"), func_name));
833 : }
834 0 : return 0;
835 : }
836 :
837 130 : if (md->id() == MEMBER_ID_INVALID) {
838 0 : if (DCPS::DCPS_debug_level >= 1) {
839 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::%C - Union has no selected member\n"), func_name));
840 : }
841 0 : return 0;
842 : }
843 :
844 130 : if (md->id() != id) {
845 25 : if (DCPS::DCPS_debug_level >= 1) {
846 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::%C -")
847 : ACE_TEXT(" ID of the selected member (%d) is not the requested ID (%d)\n"),
848 : func_name, md->id(), id));
849 : }
850 25 : return 0;
851 : }
852 :
853 105 : return md._retn();
854 130 : }
855 :
856 161 : bool DynamicDataXcdrReadImpl::exclude_union_member(MemberId id) const
857 : {
858 161 : if (extent_ == DCPS::Sample::Full) {
859 160 : return false;
860 : }
861 :
862 1 : if (id != DISCRIMINATOR_ID) {
863 0 : return true;
864 : }
865 :
866 1 : if (extent_ == DCPS::Sample::KeyOnly) {
867 : // Discriminator not marked as key is not included in a KeyOnly sample.
868 0 : DDS::DynamicTypeMember_var disc_dtm;
869 0 : if (type_->get_member(disc_dtm, DISCRIMINATOR_ID) != DDS::RETCODE_OK) {
870 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
871 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::exclude_union_member:"
872 : " Failed to get DynamicTypeMember for discriminator\n"));
873 : }
874 0 : return false;
875 : }
876 0 : DDS::MemberDescriptor_var disc_md;
877 0 : if (disc_dtm->get_descriptor(disc_md) != DDS::RETCODE_OK) {
878 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
879 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::exclude_union_member:"
880 : " Failed to get MemberDescriptor for discriminator\n"));
881 : }
882 0 : return false;
883 : }
884 0 : if (!disc_md->is_key()) {
885 0 : return true;
886 : }
887 0 : }
888 1 : return false;
889 : }
890 :
891 : template<TypeKind MemberTypeKind, typename MemberType>
892 141 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_value_from_union(
893 : MemberType& value, MemberId id, TypeKind enum_or_bitmask, LBound lower, LBound upper)
894 : {
895 141 : if (exclude_union_member(id)) {
896 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
897 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_value_from_union:"
898 : " Reading an excluded member with Id %u\n", id));
899 : }
900 0 : return DDS::RETCODE_NO_DATA;
901 : }
902 :
903 141 : DDS::TypeDescriptor_var descriptor;
904 141 : DDS::ReturnCode_t rc = type_->get_descriptor(descriptor);
905 141 : if (rc != DDS::RETCODE_OK) {
906 0 : return rc;
907 : }
908 :
909 141 : DDS::DynamicType_var member_type;
910 141 : if (id == DISCRIMINATOR_ID) {
911 21 : const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
912 21 : if (ek == DDS::APPENDABLE || ek == DDS::MUTABLE) {
913 12 : if (!strm_.skip_delimiter()) {
914 0 : return DDS::RETCODE_ERROR;
915 : }
916 : }
917 21 : member_type = get_base_type(descriptor->discriminator_type());
918 : } else {
919 120 : DDS::MemberDescriptor_var md = get_from_union_common_checks(id, "get_value_from_union");
920 120 : if (!md) {
921 25 : return DDS::RETCODE_ERROR;
922 : }
923 :
924 95 : const DDS::DynamicType_ptr type = md->type();
925 95 : if (!type) {
926 0 : if (DCPS::DCPS_debug_level >= 1) {
927 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_value_from_union -")
928 : ACE_TEXT(" Could not get DynamicType of the selected member\n")));
929 : }
930 0 : return DDS::RETCODE_ERROR;
931 : }
932 95 : member_type = get_base_type(type);
933 120 : }
934 :
935 116 : const TypeKind member_tk = member_type->get_kind();
936 116 : if (member_tk != MemberTypeKind && member_tk != enum_or_bitmask) {
937 0 : if (DCPS::DCPS_debug_level >= 1) {
938 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_value_from_union -")
939 : ACE_TEXT(" Could not read a value of type %C from type %C\n"),
940 : typekind_to_string(MemberTypeKind), typekind_to_string(member_tk)));
941 : }
942 0 : return DDS::RETCODE_ERROR;
943 : }
944 :
945 116 : if (descriptor->extensibility_kind() == DDS::MUTABLE) {
946 : unsigned member_id;
947 : size_t member_size;
948 : bool must_understand;
949 23 : if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
950 0 : return DDS::RETCODE_ERROR;
951 : }
952 : }
953 :
954 116 : if (member_tk == MemberTypeKind) {
955 90 : return read_value(value, MemberTypeKind) ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
956 : }
957 :
958 26 : DDS::TypeDescriptor_var td;
959 26 : rc = member_type->get_descriptor(td);
960 26 : if (rc != DDS::RETCODE_OK) {
961 0 : return rc;
962 : }
963 26 : const LBound bit_bound = td->bound()[0];
964 26 : return bit_bound >= lower && bit_bound <= upper &&
965 52 : read_value(value, MemberTypeKind) ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
966 141 : }
967 :
968 59 : bool DynamicDataXcdrReadImpl::skip_to_sequence_element(MemberId id, DDS::DynamicType_ptr coll_type)
969 : {
970 59 : DDS::TypeDescriptor_var descriptor;
971 59 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
972 0 : return false;
973 : }
974 :
975 59 : DDS::DynamicType_var elem_type;
976 59 : bool skip_all = false;
977 59 : if (!coll_type) {
978 17 : elem_type = get_base_type(descriptor->element_type());
979 : } else {
980 42 : DDS::TypeDescriptor_var descriptor;
981 42 : if (coll_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
982 0 : return false;
983 : }
984 42 : elem_type = get_base_type(descriptor->element_type());
985 42 : skip_all = true;
986 42 : }
987 : ACE_CDR::ULong size;
988 59 : if (get_primitive_size(elem_type, size)) {
989 : ACE_CDR::ULong length, index;
990 5 : return (strm_ >> length) &&
991 10 : get_index_from_id(id, index, length) &&
992 10 : strm_.skip(index, size);
993 : } else {
994 : ACE_CDR::ULong length, index;
995 54 : if (!strm_.skip_delimiter() || !(strm_ >> length)) {
996 0 : return false;
997 : }
998 54 : if (skip_all) {
999 42 : index = length;
1000 12 : } else if (!get_index_from_id(id, index, length)) {
1001 0 : return false;
1002 : }
1003 140 : for (ACE_CDR::ULong i = 0; i < index; ++i) {
1004 86 : if (!skip_member(elem_type)) {
1005 0 : return false;
1006 : }
1007 : }
1008 54 : return true;
1009 : }
1010 59 : }
1011 :
1012 32 : bool DynamicDataXcdrReadImpl::skip_to_array_element(MemberId id, DDS::DynamicType_ptr coll_type)
1013 : {
1014 32 : DDS::TypeDescriptor_var descriptor;
1015 32 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1016 0 : return false;
1017 : }
1018 :
1019 32 : DDS::DynamicType_var elem_type;
1020 32 : bool skip_all = false;
1021 32 : DDS::TypeDescriptor_var coll_descriptor;
1022 :
1023 32 : if (!coll_type) {
1024 32 : elem_type = get_base_type(descriptor->element_type());
1025 32 : coll_type = type_;
1026 32 : if (coll_type->get_descriptor(coll_descriptor) != DDS::RETCODE_OK) {
1027 0 : return false;
1028 : }
1029 : } else {
1030 0 : if (coll_type->get_descriptor(coll_descriptor) != DDS::RETCODE_OK) {
1031 0 : return false;
1032 : }
1033 0 : elem_type = get_base_type(coll_descriptor->element_type());
1034 0 : skip_all = true;
1035 : }
1036 :
1037 32 : const ACE_CDR::ULong length = bound_total(coll_descriptor);
1038 :
1039 : ACE_CDR::ULong size;
1040 32 : if (get_primitive_size(elem_type, size)) {
1041 : ACE_CDR::ULong index;
1042 32 : return get_index_from_id(id, index, length) && strm_.skip(index, size);
1043 : } else {
1044 0 : if (!strm_.skip_delimiter()) {
1045 0 : return false;
1046 : }
1047 : ACE_CDR::ULong index;
1048 0 : if (skip_all) {
1049 0 : index = length;
1050 0 : } else if (!get_index_from_id(id, index, length)) {
1051 0 : return false;
1052 : }
1053 0 : for (ACE_CDR::ULong i = 0; i < index; ++i) {
1054 0 : if (!skip_member(elem_type)) {
1055 0 : return false;
1056 : }
1057 : }
1058 0 : return true;
1059 : }
1060 32 : }
1061 :
1062 0 : bool DynamicDataXcdrReadImpl::skip_to_map_element(MemberId id)
1063 : {
1064 0 : DDS::TypeDescriptor_var descriptor;
1065 0 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1066 0 : return false;
1067 : }
1068 :
1069 0 : const DDS::DynamicType_var key_type = get_base_type(descriptor->key_element_type());
1070 0 : const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1071 : ACE_CDR::ULong key_size, elem_size;
1072 :
1073 0 : if (get_primitive_size(key_type, key_size) &&
1074 0 : get_primitive_size(elem_type, elem_size)) {
1075 : ACE_CDR::ULong length, index;
1076 0 : if (!(strm_ >> length) || !get_index_from_id(id, index, length)) {
1077 0 : return false;
1078 : }
1079 :
1080 0 : for (ACE_CDR::ULong i = 0; i < index; ++i) {
1081 0 : if (!strm_.skip(1, key_size) || !strm_.skip(1, elem_size)) {
1082 0 : return false;
1083 : }
1084 : }
1085 0 : return strm_.skip(1, key_size);
1086 : } else {
1087 : size_t dheader;
1088 : ACE_CDR::ULong index;
1089 0 : if (!strm_.read_delimiter(dheader) || !get_index_from_id(id, index, ACE_UINT32_MAX)) {
1090 0 : return false;
1091 : }
1092 0 : const size_t end_of_map = strm_.rpos() + dheader;
1093 :
1094 0 : for (ACE_CDR::ULong i = 0; i < index; ++i) {
1095 0 : if (strm_.rpos() >= end_of_map || !skip_member(key_type) || !skip_member(elem_type)) {
1096 0 : return false;
1097 : }
1098 : }
1099 0 : return (strm_.rpos() < end_of_map) && skip_member(key_type);
1100 : }
1101 0 : }
1102 :
1103 : template<TypeKind ElementTypeKind, typename ElementType>
1104 47 : bool DynamicDataXcdrReadImpl::get_value_from_collection(ElementType& value, MemberId id, TypeKind collection_tk,
1105 : TypeKind enum_or_bitmask, LBound lower, LBound upper)
1106 : {
1107 47 : DDS::TypeDescriptor_var descriptor;
1108 47 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1109 0 : return false;
1110 : }
1111 :
1112 47 : DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1113 47 : const TypeKind elem_tk = elem_type->get_kind();
1114 :
1115 47 : if (elem_tk != ElementTypeKind && elem_tk != enum_or_bitmask) {
1116 0 : if (DCPS::DCPS_debug_level >= 1) {
1117 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_value_from_collection -")
1118 : ACE_TEXT(" Could not read a value of type %C from %C with element type %C\n"),
1119 : typekind_to_string(ElementTypeKind), typekind_to_string(collection_tk),
1120 : typekind_to_string(elem_tk)));
1121 : }
1122 0 : return false;
1123 : }
1124 :
1125 47 : if (elem_tk == enum_or_bitmask) {
1126 5 : DDS::TypeDescriptor_var td;
1127 5 : if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1128 0 : return false;
1129 : }
1130 5 : const LBound bit_bound = td->bound()[0];
1131 5 : if (bit_bound < lower || bit_bound > upper) {
1132 0 : return false;
1133 : }
1134 5 : }
1135 :
1136 47 : switch (collection_tk) {
1137 15 : case TK_SEQUENCE:
1138 15 : if (!skip_to_sequence_element(id)) {
1139 0 : return false;
1140 : }
1141 15 : break;
1142 32 : case TK_ARRAY:
1143 32 : if (!skip_to_array_element(id)) {
1144 0 : return false;
1145 : }
1146 32 : break;
1147 0 : case TK_MAP:
1148 0 : if (!skip_to_map_element(id)) {
1149 0 : return false;
1150 : }
1151 0 : break;
1152 0 : default:
1153 0 : return false;
1154 : }
1155 :
1156 47 : return read_value(value, ElementTypeKind);
1157 47 : }
1158 :
1159 1136 : void DynamicDataXcdrReadImpl::setup_stream(ACE_Message_Block* chain)
1160 : {
1161 1136 : strm_ = DCPS::Serializer(chain, encoding_);
1162 1136 : if (reset_align_state_) {
1163 349 : strm_.rdstate(align_state_);
1164 : }
1165 1136 : }
1166 :
1167 : template<TypeKind ValueTypeKind, typename ValueType>
1168 392 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_single_value(ValueType& value, MemberId id,
1169 : TypeKind enum_or_bitmask, LBound lower, LBound upper)
1170 : {
1171 392 : if (!is_type_supported(ValueTypeKind, "get_single_value")) {
1172 0 : return DDS::RETCODE_ERROR;
1173 : }
1174 :
1175 392 : ScopedChainManager chain_manager(*this);
1176 :
1177 392 : const TypeKind tk = type_->get_kind();
1178 392 : bool good = true;
1179 :
1180 : // This is an extension to the XTypes spec where the value of a bitmask DynamicData
1181 : // can be read as a whole as a unsigned integer.
1182 392 : if (tk == enum_or_bitmask) {
1183 : // Per XTypes spec, the value of a DynamicData object of primitive type or TK_ENUM is
1184 : // accessed with MEMBER_ID_INVALID Id. However, there is only a single value in such
1185 : // a DynamicData object, and checking for MEMBER_ID_INVALID from the input is perhaps
1186 : // unnecessary. So, we read the value immediately here.
1187 20 : DDS::TypeDescriptor_var descriptor;
1188 20 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1189 0 : return DDS::RETCODE_ERROR;
1190 : }
1191 20 : const LBound bit_bound = descriptor->bound()[0];
1192 20 : good = bit_bound >= lower && bit_bound <= upper && read_value(value, ValueTypeKind);
1193 20 : } else {
1194 372 : switch (tk) {
1195 80 : case ValueTypeKind:
1196 80 : good = is_primitive(tk) && read_value(value, ValueTypeKind);
1197 80 : break;
1198 124 : case TK_STRUCTURE:
1199 : {
1200 : const DDS::ReturnCode_t rc =
1201 124 : get_value_from_struct<ValueTypeKind>(value, id, enum_or_bitmask, lower, upper);
1202 124 : if (rc == DDS::RETCODE_NO_DATA) {
1203 0 : return rc;
1204 : }
1205 124 : good = rc == DDS::RETCODE_OK;
1206 : }
1207 124 : break;
1208 121 : case TK_UNION:
1209 : {
1210 : const DDS::ReturnCode_t rc =
1211 121 : get_value_from_union<ValueTypeKind>(value, id, enum_or_bitmask, lower, upper);
1212 121 : if (rc == DDS::RETCODE_NO_DATA) {
1213 0 : return rc;
1214 : }
1215 121 : good = rc == DDS::RETCODE_OK;
1216 : }
1217 121 : break;
1218 47 : case TK_SEQUENCE:
1219 : case TK_ARRAY:
1220 : case TK_MAP:
1221 47 : good = get_value_from_collection<ValueTypeKind>(value, id, tk, enum_or_bitmask, lower, upper);
1222 47 : break;
1223 0 : default:
1224 0 : good = false;
1225 0 : break;
1226 : }
1227 : }
1228 :
1229 392 : if (!good && DCPS::DCPS_debug_level >= 1) {
1230 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_single_value -")
1231 : ACE_TEXT(" Failed to read a value of %C from a DynamicData object of type %C\n"),
1232 : typekind_to_string(ValueTypeKind), typekind_to_string(tk)));
1233 : }
1234 392 : return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1235 392 : }
1236 :
1237 119 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_int32_value(ACE_CDR::Long& value, MemberId id)
1238 : {
1239 119 : return get_single_value<TK_INT32>(value, id, TK_ENUM,
1240 119 : static_cast<LBound>(17), static_cast<LBound>(32));
1241 : }
1242 :
1243 33 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_uint32_value(ACE_CDR::ULong& value, MemberId id)
1244 : {
1245 33 : return get_single_value<TK_UINT32>(value, id, TK_BITMASK,
1246 33 : static_cast<LBound>(17), static_cast<LBound>(32));
1247 : }
1248 :
1249 37 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_int8_value(ACE_CDR::Int8& value, MemberId id)
1250 : {
1251 37 : ACE_InputCDR::to_int8 to_int8(value);
1252 74 : return get_single_value<TK_INT8>(to_int8, id, TK_ENUM, 1, 8);
1253 : }
1254 :
1255 15 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_uint8_value(ACE_CDR::UInt8& value, MemberId id)
1256 : {
1257 15 : ACE_InputCDR::to_uint8 to_uint8(value);
1258 30 : return get_single_value<TK_UINT8>(to_uint8, id, TK_BITMASK, 1, 8);
1259 : }
1260 :
1261 28 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_int16_value(ACE_CDR::Short& value, MemberId id)
1262 : {
1263 28 : return get_single_value<TK_INT16>(value, id, TK_ENUM, 9, 16);
1264 : }
1265 :
1266 18 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_uint16_value(ACE_CDR::UShort& value, MemberId id)
1267 : {
1268 18 : return get_single_value<TK_UINT16>(value, id, TK_BITMASK, 9, 16);
1269 : }
1270 :
1271 15 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_int64_value_impl(ACE_CDR::LongLong& value, MemberId id)
1272 : {
1273 15 : return get_single_value<TK_INT64>(value, id);
1274 : }
1275 :
1276 15 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_uint64_value_impl(ACE_CDR::ULongLong& value, MemberId id)
1277 : {
1278 15 : return get_single_value<TK_UINT64>(value, id, TK_BITMASK, 33, 64);
1279 : }
1280 :
1281 15 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_float32_value(ACE_CDR::Float& value, MemberId id)
1282 : {
1283 15 : return get_single_value<TK_FLOAT32>(value, id);
1284 : }
1285 :
1286 15 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_float64_value(ACE_CDR::Double& value, MemberId id)
1287 : {
1288 15 : return get_single_value<TK_FLOAT64>(value, id);
1289 : }
1290 :
1291 15 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_float128_value(ACE_CDR::LongDouble& value, MemberId id)
1292 : {
1293 15 : return get_single_value<TK_FLOAT128>(value, id);
1294 : }
1295 :
1296 : template<TypeKind CharKind, TypeKind StringKind, typename ToCharT, typename CharT>
1297 30 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_char_common(CharT& value, MemberId id)
1298 : {
1299 30 : ScopedChainManager chain_manager(*this);
1300 :
1301 30 : const TypeKind tk = type_->get_kind();
1302 30 : bool good = true;
1303 :
1304 30 : switch (tk) {
1305 10 : case CharKind:
1306 : {
1307 10 : ToCharT wrap(value);
1308 10 : good = strm_ >> wrap;
1309 10 : break;
1310 : }
1311 0 : case StringKind:
1312 : {
1313 : CharT* str;
1314 0 : if (!(strm_ >> str)) {
1315 0 : if (DCPS::DCPS_debug_level >= 1) {
1316 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_char_common -")
1317 : ACE_TEXT(" Failed to read wstring with ID %d\n"), id));
1318 : }
1319 0 : good = false;
1320 0 : break;
1321 : }
1322 : ACE_CDR::ULong index;
1323 0 : const size_t str_len = ACE_OS::strlen(str);
1324 0 : if (!get_index_from_id(id, index, static_cast<ACE_CDR::ULong>(str_len))) {
1325 0 : if (DCPS::DCPS_debug_level >= 1) {
1326 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_char_common -")
1327 : ACE_TEXT(" ID %d is not valid in a string (or wstring) with length %d\n"),
1328 : id, str_len));
1329 : }
1330 0 : good = false;
1331 : } else {
1332 0 : value = str[index];
1333 : }
1334 0 : break;
1335 : }
1336 10 : case TK_STRUCTURE:
1337 : {
1338 10 : ToCharT wrap(value);
1339 10 : const DDS::ReturnCode_t rc = get_value_from_struct<CharKind>(wrap, id, extent_);
1340 10 : if (rc == DDS::RETCODE_NO_DATA) {
1341 0 : return rc;
1342 : }
1343 10 : good = rc == DDS::RETCODE_OK;
1344 10 : break;
1345 : }
1346 10 : case TK_UNION:
1347 : {
1348 10 : ToCharT wrap(value);
1349 10 : const DDS::ReturnCode_t rc = get_value_from_union<CharKind>(wrap, id);
1350 10 : if (rc == DDS::RETCODE_NO_DATA) {
1351 0 : return rc;
1352 : }
1353 10 : good = rc == DDS::RETCODE_OK;
1354 10 : break;
1355 : }
1356 0 : case TK_SEQUENCE:
1357 : case TK_ARRAY:
1358 : case TK_MAP:
1359 : {
1360 0 : ToCharT wrap(value);
1361 0 : good = get_value_from_collection<CharKind>(wrap, id, tk);
1362 0 : break;
1363 : }
1364 0 : default:
1365 0 : good = false;
1366 0 : break;
1367 : }
1368 :
1369 30 : if (!good && DCPS::DCPS_debug_level >= 1) {
1370 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_char_common -")
1371 : ACE_TEXT(" Failed to read DynamicData object of type %C\n"), typekind_to_string(tk)));
1372 : }
1373 30 : return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1374 30 : }
1375 :
1376 15 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_char8_value(ACE_CDR::Char& value, MemberId id)
1377 : {
1378 15 : return get_char_common<TK_CHAR8, TK_STRING8, ACE_InputCDR::to_char>(value, id);
1379 : }
1380 :
1381 15 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_char16_value(ACE_CDR::WChar& value, MemberId id)
1382 : {
1383 : #ifdef DDS_HAS_WCHAR
1384 15 : return get_char_common<TK_CHAR16, TK_STRING16, ACE_InputCDR::to_wchar>(value, id);
1385 : #else
1386 : return DDS::RETCODE_UNSUPPORTED;
1387 : #endif
1388 : }
1389 :
1390 22 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_byte_value(ACE_CDR::Octet& value, MemberId id)
1391 : {
1392 22 : ACE_InputCDR::to_octet to_octet(value);
1393 44 : return get_single_value<TK_BYTE>(to_octet, id);
1394 : }
1395 :
1396 : template<typename UIntType, TypeKind UIntTypeKind>
1397 0 : bool DynamicDataXcdrReadImpl::get_boolean_from_bitmask(ACE_CDR::ULong index, ACE_CDR::Boolean& value)
1398 : {
1399 : UIntType bitmask;
1400 0 : if (!read_value(bitmask, UIntTypeKind)) {
1401 0 : return false;
1402 : }
1403 :
1404 0 : value = ((1ULL << index) & bitmask) ? true : false;
1405 0 : return true;
1406 : }
1407 :
1408 22 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_boolean_value(ACE_CDR::Boolean& value, MemberId id)
1409 : {
1410 22 : ScopedChainManager chain_manager(*this);
1411 :
1412 22 : const TypeKind tk = type_->get_kind();
1413 22 : bool good = true;
1414 :
1415 22 : switch (tk) {
1416 5 : case TK_BOOLEAN:
1417 5 : good = strm_ >> ACE_InputCDR::to_boolean(value);
1418 5 : break;
1419 0 : case TK_BITMASK:
1420 : {
1421 0 : DDS::TypeDescriptor_var descriptor;
1422 0 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1423 0 : return DDS::RETCODE_ERROR;
1424 : }
1425 0 : const LBound bit_bound = descriptor->bound()[0];
1426 : ACE_CDR::ULong index;
1427 0 : if (!get_index_from_id(id, index, bit_bound)) {
1428 0 : if (DCPS::DCPS_debug_level >= 1) {
1429 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_boolean_value -")
1430 : ACE_TEXT(" Id %d is not valid in a bitmask with bit_bound %d\n"),
1431 : id, bit_bound));
1432 : }
1433 0 : good = false;
1434 0 : break;
1435 : }
1436 :
1437 : // Bit with index 0 is the least-significant bit of the representing integer.
1438 0 : if (bit_bound >= 1 && bit_bound <= 8) {
1439 : ACE_CDR::UInt8 bitmask;
1440 0 : ACE_InputCDR::to_uint8 to_uint8(bitmask);
1441 0 : if (!read_value(to_uint8, TK_UINT8)) {
1442 0 : good = false;
1443 : } else {
1444 0 : value = ((1 << index) & bitmask) ? true : false;
1445 : }
1446 0 : } else if (bit_bound >= 9 && bit_bound <= 16) {
1447 0 : good = get_boolean_from_bitmask<ACE_CDR::UInt16, TK_UINT16>(index, value);
1448 0 : } else if (bit_bound >= 17 && bit_bound <= 32) {
1449 0 : good = get_boolean_from_bitmask<ACE_CDR::UInt32, TK_UINT32>(index, value);
1450 : } else {
1451 0 : good = get_boolean_from_bitmask<ACE_CDR::UInt64, TK_UINT64>(index, value);
1452 : }
1453 0 : break;
1454 0 : }
1455 7 : case TK_STRUCTURE:
1456 : {
1457 7 : ACE_InputCDR::to_boolean to_bool(value);
1458 7 : const DDS::ReturnCode_t rc = get_value_from_struct<TK_BOOLEAN>(to_bool, id, extent_);
1459 7 : if (rc == DDS::RETCODE_NO_DATA) {
1460 0 : return rc;
1461 : }
1462 7 : good = rc == DDS::RETCODE_OK;
1463 7 : break;
1464 : }
1465 10 : case TK_UNION:
1466 : {
1467 10 : ACE_InputCDR::to_boolean to_bool(value);
1468 10 : const DDS::ReturnCode_t rc = get_value_from_union<TK_BOOLEAN>(to_bool, id);
1469 10 : if (rc == DDS::RETCODE_NO_DATA) {
1470 0 : return rc;
1471 : }
1472 10 : good = rc == DDS::RETCODE_OK;
1473 10 : break;
1474 : }
1475 0 : case TK_SEQUENCE:
1476 : case TK_ARRAY:
1477 : case TK_MAP:
1478 : {
1479 0 : ACE_InputCDR::to_boolean to_bool(value);
1480 0 : good = get_value_from_collection<TK_BOOLEAN>(to_bool, id, tk);
1481 0 : break;
1482 : }
1483 0 : default:
1484 0 : good = false;
1485 0 : break;
1486 : }
1487 :
1488 22 : if (!good && DCPS::DCPS_debug_level >= 1) {
1489 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_boolean_value -")
1490 : ACE_TEXT(" Failed to read DynamicData object of type %C\n"), typekind_to_string(tk)));
1491 : }
1492 22 : return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1493 22 : }
1494 :
1495 21 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_string_value(ACE_CDR::Char*& value, MemberId id)
1496 : {
1497 21 : if (enum_string_helper(value, id)) {
1498 1 : return DDS::RETCODE_OK;
1499 : }
1500 20 : CORBA::string_free(value);
1501 20 : return get_single_value<TK_STRING8>(value, id);
1502 : }
1503 :
1504 25 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_wstring_value(ACE_CDR::WChar*& value, MemberId id)
1505 : {
1506 : #ifdef DDS_HAS_WCHAR
1507 25 : CORBA::wstring_free(value);
1508 25 : return get_single_value<TK_STRING16>(value, id);
1509 : #else
1510 : return DDS::RETCODE_UNSUPPORTED;
1511 : #endif
1512 : }
1513 :
1514 175 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_complex_value(DDS::DynamicData_ptr& value, MemberId id)
1515 : {
1516 175 : ScopedChainManager chain_manager(*this);
1517 :
1518 175 : DDS::TypeDescriptor_var descriptor;
1519 175 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1520 0 : return DDS::RETCODE_ERROR;
1521 : }
1522 :
1523 175 : const TypeKind tk = type_->get_kind();
1524 175 : bool good = true;
1525 :
1526 175 : switch (tk) {
1527 163 : case TK_STRUCTURE:
1528 : {
1529 163 : DDS::MemberDescriptor_var md;
1530 163 : if (exclude_struct_member(id, md)) {
1531 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1532 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_complex_value:"
1533 : " Attempted to read an excluded member from a %C struct sample\n",
1534 : extent_ == DCPS::Sample::KeyOnly ? "KeyOnly" : "NestedKeyOnly"));
1535 : }
1536 0 : return DDS::RETCODE_NO_DATA;
1537 : }
1538 :
1539 163 : const DDS::ReturnCode_t rc = skip_to_struct_member(md, id);
1540 163 : if (rc == DDS::RETCODE_NO_DATA) {
1541 0 : return rc;
1542 163 : } else if (rc == DDS::RETCODE_OK) {
1543 163 : DDS::DynamicType_ptr member_type = md->type();
1544 163 : if (!member_type) {
1545 0 : good = false;
1546 : } else {
1547 163 : CORBA::release(value);
1548 163 : value = new DynamicDataXcdrReadImpl(strm_, member_type, nested(extent_));
1549 : }
1550 : } else {
1551 0 : good = false;
1552 : }
1553 163 : break;
1554 163 : }
1555 10 : case TK_UNION:
1556 : {
1557 10 : if (exclude_union_member(id)) {
1558 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1559 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_complex_value:"
1560 : " Attempted to read an excluded member from a %C union sample\n",
1561 : extent_ == DCPS::Sample::KeyOnly ? "KeyOnly" : "NestedKeyOnly"));
1562 : }
1563 0 : good = false;
1564 0 : break;
1565 : }
1566 :
1567 10 : if (id == DISCRIMINATOR_ID) {
1568 10 : if (descriptor->extensibility_kind() == DDS::APPENDABLE || descriptor->extensibility_kind() == DDS::MUTABLE) {
1569 6 : if (!strm_.skip_delimiter()) {
1570 0 : good = false;
1571 0 : break;
1572 : }
1573 : }
1574 :
1575 10 : const DDS::DynamicType_var disc_type = get_base_type(descriptor->discriminator_type());
1576 10 : if (descriptor->extensibility_kind() == DDS::MUTABLE) {
1577 : unsigned id;
1578 : size_t size;
1579 : bool must_understand;
1580 2 : if (!strm_.read_parameter_id(id, size, must_understand)) {
1581 0 : good = false;
1582 0 : break;
1583 : }
1584 : }
1585 10 : CORBA::release(value);
1586 10 : value = new DynamicDataXcdrReadImpl(strm_, disc_type, nested(extent_));
1587 10 : break;
1588 10 : }
1589 :
1590 0 : DDS::MemberDescriptor_var md = get_from_union_common_checks(id, "get_complex_value");
1591 0 : if (!md) {
1592 0 : good = false;
1593 0 : break;
1594 : }
1595 :
1596 0 : if (descriptor->extensibility_kind() == DDS::MUTABLE) {
1597 : unsigned id;
1598 : size_t size;
1599 : bool must_understand;
1600 0 : if (!strm_.read_parameter_id(id, size, must_understand)) {
1601 0 : good = false;
1602 0 : break;
1603 : }
1604 : }
1605 0 : const DDS::DynamicType_ptr member_type = md->type();
1606 0 : if (!member_type) {
1607 0 : good = false;
1608 : } else {
1609 0 : CORBA::release(value);
1610 0 : value = new DynamicDataXcdrReadImpl(strm_, member_type, nested(extent_));
1611 : }
1612 0 : break;
1613 0 : }
1614 2 : case TK_SEQUENCE:
1615 : case TK_ARRAY:
1616 : case TK_MAP:
1617 : {
1618 2 : if ((tk == TK_SEQUENCE && !skip_to_sequence_element(id)) ||
1619 4 : (tk == TK_ARRAY && !skip_to_array_element(id)) ||
1620 0 : (tk == TK_MAP && !skip_to_map_element(id))) {
1621 0 : good = false;
1622 : } else {
1623 2 : CORBA::release(value);
1624 2 : value = new DynamicDataXcdrReadImpl(strm_, descriptor->element_type(), nested(extent_));
1625 : }
1626 2 : break;
1627 : }
1628 0 : default:
1629 0 : if (DCPS::DCPS_debug_level >= 1) {
1630 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_complex_value -")
1631 : ACE_TEXT(" Called on an unsupported type (%C)\n"), typekind_to_string(tk)));
1632 : }
1633 0 : good = false;
1634 0 : break;
1635 : }
1636 175 : return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1637 175 : }
1638 :
1639 : template<typename SequenceType>
1640 105 : bool DynamicDataXcdrReadImpl::read_values(SequenceType& value, TypeKind elem_tk)
1641 : {
1642 : using OpenDDS::DCPS::operator>>;
1643 :
1644 105 : switch(elem_tk) {
1645 95 : case TK_INT32:
1646 : case TK_UINT32:
1647 : case TK_INT16:
1648 : case TK_UINT16:
1649 : case TK_INT64:
1650 : case TK_UINT64:
1651 : case TK_FLOAT32:
1652 : case TK_FLOAT64:
1653 : case TK_FLOAT128:
1654 : case TK_INT8:
1655 : case TK_UINT8:
1656 : case TK_CHAR8:
1657 : case TK_CHAR16:
1658 : case TK_BYTE:
1659 : case TK_BOOLEAN:
1660 : case TK_STRING8:
1661 : case TK_STRING16:
1662 95 : if (strm_ >> value) {
1663 95 : return true;
1664 : }
1665 0 : break;
1666 10 : case TK_ENUM:
1667 : case TK_BITMASK:
1668 10 : if (strm_.skip_delimiter() && strm_ >> value) {
1669 10 : return true;
1670 : }
1671 0 : break;
1672 0 : default:
1673 0 : if (log_level >= LogLevel::Notice) {
1674 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::read_values: "
1675 : "Calling on an unexpected element type %C\n", typekind_to_string(elem_tk)));
1676 : }
1677 0 : return false;
1678 : }
1679 :
1680 0 : if (log_level >= LogLevel::Notice) {
1681 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::read_values: "
1682 : "failed to deserialize element type %C\n", typekind_to_string(elem_tk)));
1683 : }
1684 0 : return false;
1685 : }
1686 :
1687 : template<TypeKind ElementTypeKind, typename SequenceType>
1688 100 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_values_from_struct(SequenceType& value, MemberId id,
1689 : TypeKind enum_or_bitmask, LBound lower, LBound upper)
1690 : {
1691 100 : DDS::MemberDescriptor_var md;
1692 100 : if (exclude_struct_member(id, md)) {
1693 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1694 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_values_from_struct:"
1695 : " Attempted to read a member not included in a %C sample\n",
1696 : extent_ == DCPS::Sample::KeyOnly ? "KeyOnly" : "NestedKeyOnly"));
1697 : }
1698 0 : return DDS::RETCODE_NO_DATA;
1699 : }
1700 :
1701 100 : if (get_from_struct_common_checks(md, id, ElementTypeKind, true)) {
1702 85 : const DDS::ReturnCode_t rc = skip_to_struct_member(md, id);
1703 85 : if (rc != DDS::RETCODE_OK) {
1704 0 : return rc;
1705 : }
1706 85 : return read_values(value, ElementTypeKind) ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1707 : }
1708 :
1709 15 : if (get_from_struct_common_checks(md, id, enum_or_bitmask, true)) {
1710 10 : const DDS::DynamicType_ptr member_type = md->type();
1711 10 : if (member_type) {
1712 10 : DDS::TypeDescriptor_var td;
1713 10 : DDS::ReturnCode_t rc = get_base_type(member_type)->get_descriptor(td);
1714 10 : if (rc != DDS::RETCODE_OK) {
1715 0 : return rc;
1716 : }
1717 10 : DDS::TypeDescriptor_var etd;
1718 10 : rc = get_base_type(td->element_type())->get_descriptor(etd);
1719 10 : if (rc != DDS::RETCODE_OK) {
1720 0 : return rc;
1721 : }
1722 10 : const LBound bit_bound = etd->bound()[0];
1723 10 : if (bit_bound >= lower && bit_bound <= upper) {
1724 10 : const DDS::ReturnCode_t rc = skip_to_struct_member(md, id);
1725 10 : if (rc != DDS::RETCODE_OK) {
1726 0 : return rc;
1727 : }
1728 10 : if (read_values(value, enum_or_bitmask)) {
1729 10 : return DDS::RETCODE_OK;
1730 : }
1731 : }
1732 20 : }
1733 : }
1734 :
1735 5 : return DDS::RETCODE_ERROR;
1736 100 : }
1737 :
1738 : template<TypeKind ElementTypeKind, typename SequenceType>
1739 10 : bool DynamicDataXcdrReadImpl::get_values_from_union(SequenceType& value, MemberId id,
1740 : TypeKind enum_or_bitmask, LBound lower, LBound upper)
1741 : {
1742 10 : if (id == DISCRIMINATOR_ID) {
1743 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1744 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_values_from_union:"
1745 : " Attempted to read discriminator as a sequence\n"));
1746 : }
1747 0 : return false;
1748 : }
1749 :
1750 10 : if (exclude_union_member(id)) {
1751 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1752 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_values_from_union:"
1753 : " Attempted to read an excluded member with Id %u\n", id));
1754 : }
1755 0 : return false;
1756 : }
1757 :
1758 10 : DDS::MemberDescriptor_var md = get_from_union_common_checks(id, "get_values_from_union");
1759 10 : if (!md) {
1760 0 : return false;
1761 : }
1762 :
1763 10 : const DDS::DynamicType_ptr member_type = md->type();
1764 10 : if (!member_type) {
1765 0 : if (DCPS::DCPS_debug_level >= 1) {
1766 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_union -")
1767 : ACE_TEXT(" Could not get DynamicType of the selected member\n")));
1768 : }
1769 0 : return false;
1770 : }
1771 :
1772 10 : DDS::DynamicType_var selected_type = get_base_type(member_type);
1773 10 : const TypeKind selected_tk = selected_type->get_kind();
1774 10 : if (selected_tk != TK_SEQUENCE) {
1775 0 : if (DCPS::DCPS_debug_level >= 1) {
1776 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_union -")
1777 : ACE_TEXT(" The selected member is not a sequence, but %C\n"),
1778 : typekind_to_string(selected_tk)));
1779 : }
1780 0 : return false;
1781 : }
1782 :
1783 10 : DDS::TypeDescriptor_var td;
1784 10 : if (selected_type->get_descriptor(td) != DDS::RETCODE_OK) {
1785 0 : return false;
1786 : }
1787 10 : const DDS::DynamicType_var elem_type = get_base_type(td->element_type());
1788 10 : const TypeKind elem_tk = elem_type->get_kind();
1789 10 : if (elem_tk != ElementTypeKind && elem_tk != enum_or_bitmask) {
1790 0 : if (DCPS::DCPS_debug_level >= 1) {
1791 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_union -")
1792 : ACE_TEXT(" Could not read a sequence of %C from a sequence of %C\n"),
1793 : typekind_to_string(ElementTypeKind), typekind_to_string(elem_tk)));
1794 : }
1795 0 : return false;
1796 : }
1797 :
1798 10 : DDS::TypeDescriptor_var descriptor;
1799 10 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1800 0 : return false;
1801 : }
1802 :
1803 10 : if (descriptor->extensibility_kind() == DDS::MUTABLE) {
1804 : unsigned member_id;
1805 : size_t member_size;
1806 : bool must_understand;
1807 2 : if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
1808 0 : return false;
1809 : }
1810 : }
1811 :
1812 10 : if (elem_tk == ElementTypeKind) {
1813 10 : return read_values(value, ElementTypeKind);
1814 : }
1815 :
1816 : // Reset.
1817 0 : td = 0;
1818 0 : if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1819 0 : return false;
1820 : }
1821 0 : const LBound bit_bound = td->bound()[0];
1822 0 : return bit_bound >= lower && bit_bound <= upper && read_values(value, enum_or_bitmask);
1823 10 : }
1824 :
1825 : template<TypeKind ElementTypeKind, typename SequenceType>
1826 0 : bool DynamicDataXcdrReadImpl::get_values_from_sequence(SequenceType& value, MemberId id,
1827 : TypeKind enum_or_bitmask, LBound lower, LBound upper)
1828 : {
1829 0 : DDS::TypeDescriptor_var descriptor;
1830 0 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1831 0 : return false;
1832 : }
1833 :
1834 0 : const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1835 0 : const TypeKind elem_tk = elem_type->get_kind();
1836 :
1837 0 : if (elem_tk == ElementTypeKind) {
1838 0 : return read_values(value, ElementTypeKind);
1839 0 : } else if (elem_tk == enum_or_bitmask) {
1840 : // Read from a sequence of enums or bitmasks.
1841 0 : DDS::TypeDescriptor_var td;
1842 0 : if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1843 0 : return false;
1844 : }
1845 0 : const LBound bit_bound = td->bound()[0];
1846 0 : return bit_bound >= lower && bit_bound <= upper && read_values(value, enum_or_bitmask);
1847 0 : } else if (elem_tk == TK_SEQUENCE) {
1848 0 : DDS::TypeDescriptor_var td;
1849 0 : if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1850 0 : return false;
1851 : }
1852 0 : const DDS::DynamicType_var nested_elem_type = get_base_type(td->element_type());
1853 0 : const TypeKind nested_elem_tk = nested_elem_type->get_kind();
1854 0 : if (nested_elem_tk == ElementTypeKind) {
1855 : // Read from a sequence of sequences of ElementTypeKind.
1856 0 : return skip_to_sequence_element(id) && read_values(value, ElementTypeKind);
1857 0 : } else if (nested_elem_tk == enum_or_bitmask) {
1858 : // Read from a sequence of sequences of enums or bitmasks.
1859 0 : DDS::TypeDescriptor_var td;
1860 0 : if (nested_elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1861 0 : return false;
1862 : }
1863 0 : const LBound bit_bound = td->bound()[0];
1864 0 : return bit_bound >= lower && bit_bound <= upper &&
1865 0 : skip_to_sequence_element(id) && read_values(value, enum_or_bitmask);
1866 0 : }
1867 0 : }
1868 :
1869 0 : if (DCPS::DCPS_debug_level >= 1) {
1870 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_sequence -")
1871 : ACE_TEXT(" Could not read a sequence of %C from an incompatible type\n"),
1872 : typekind_to_string(ElementTypeKind)));
1873 : }
1874 0 : return false;
1875 0 : }
1876 :
1877 : template<TypeKind ElementTypeKind, typename SequenceType>
1878 0 : bool DynamicDataXcdrReadImpl::get_values_from_array(SequenceType& value, MemberId id,
1879 : TypeKind enum_or_bitmask, LBound lower, LBound upper)
1880 : {
1881 0 : DDS::TypeDescriptor_var descriptor;
1882 0 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1883 0 : return false;
1884 : }
1885 :
1886 0 : const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1887 0 : if (elem_type->get_kind() != TK_SEQUENCE) {
1888 0 : if (DCPS::DCPS_debug_level >= 1) {
1889 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_array -")
1890 : ACE_TEXT(" Could not read a sequence of %C from an array of %C\n"),
1891 : typekind_to_string(ElementTypeKind), typekind_to_string(elem_type->get_kind())));
1892 : }
1893 0 : return false;
1894 : }
1895 :
1896 0 : DDS::TypeDescriptor_var td;
1897 0 : if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1898 0 : return false;
1899 : }
1900 0 : const DDS::DynamicType_var nested_elem_type = get_base_type(td->element_type());
1901 0 : const TypeKind nested_elem_tk = nested_elem_type->get_kind();
1902 0 : if (nested_elem_tk == ElementTypeKind) {
1903 0 : return skip_to_array_element(id) && read_values(value, nested_elem_tk);
1904 0 : } else if (nested_elem_tk == enum_or_bitmask) {
1905 0 : DDS::TypeDescriptor_var td;
1906 0 : if (nested_elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1907 0 : return false;
1908 : }
1909 0 : const LBound bit_bound = td->bound()[0];
1910 0 : return bit_bound >= lower && bit_bound <= upper &&
1911 0 : skip_to_array_element(id) && read_values(value, nested_elem_tk);
1912 0 : }
1913 :
1914 0 : if (DCPS::DCPS_debug_level >= 1) {
1915 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_array -")
1916 : ACE_TEXT(" Could not read a sequence of %C from an array of sequence of %C\n"),
1917 : typekind_to_string(ElementTypeKind), typekind_to_string(nested_elem_tk)));
1918 : }
1919 0 : return false;
1920 0 : }
1921 :
1922 : template<TypeKind ElementTypeKind, typename SequenceType>
1923 0 : bool DynamicDataXcdrReadImpl::get_values_from_map(SequenceType& value, MemberId id,
1924 : TypeKind enum_or_bitmask, LBound lower, LBound upper)
1925 : {
1926 0 : DDS::TypeDescriptor_var descriptor;
1927 0 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1928 0 : return false;
1929 : }
1930 :
1931 0 : const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1932 0 : if (elem_type->get_kind() != TK_SEQUENCE) {
1933 0 : if (DCPS::DCPS_debug_level >= 1) {
1934 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_map -")
1935 : ACE_TEXT(" Getting sequence<%C> from a map with element type of %C\n"),
1936 : typekind_to_string(ElementTypeKind), typekind_to_string(elem_type->get_kind())));
1937 : }
1938 0 : return false;
1939 : }
1940 :
1941 0 : DDS::TypeDescriptor_var td;
1942 0 : if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1943 0 : return false;
1944 : }
1945 0 : const DDS::DynamicType_var nested_elem_type = get_base_type(td->element_type());
1946 0 : const TypeKind nested_elem_tk = nested_elem_type->get_kind();
1947 0 : if (nested_elem_tk == ElementTypeKind) {
1948 0 : return skip_to_map_element(id) && read_values(value, nested_elem_tk);
1949 0 : } else if (nested_elem_tk == enum_or_bitmask) {
1950 0 : DDS::TypeDescriptor_var td;
1951 0 : if (nested_elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1952 0 : return false;
1953 : }
1954 0 : const LBound bit_bound = td->bound()[0];
1955 0 : return bit_bound >= lower && bit_bound <= upper &&
1956 0 : skip_to_map_element(id) && read_values(value, nested_elem_tk);
1957 0 : }
1958 :
1959 0 : if (DCPS::DCPS_debug_level >= 1) {
1960 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_map -")
1961 : ACE_TEXT(" Could not read a sequence of %C from a map with element type sequence of %C\n"),
1962 : typekind_to_string(ElementTypeKind), typekind_to_string(nested_elem_tk)));
1963 : }
1964 0 : return false;
1965 0 : }
1966 :
1967 : template<TypeKind ElementTypeKind, typename SequenceType>
1968 110 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_sequence_values(SequenceType& value, MemberId id,
1969 : TypeKind enum_or_bitmask, LBound lower, LBound upper)
1970 : {
1971 110 : if (!is_type_supported(ElementTypeKind, "get_sequence_values")) {
1972 0 : return DDS::RETCODE_ERROR;
1973 : }
1974 :
1975 110 : ScopedChainManager chain_manager(*this);
1976 :
1977 110 : const TypeKind tk = type_->get_kind();
1978 110 : bool good = true;
1979 :
1980 110 : switch (tk) {
1981 100 : case TK_STRUCTURE:
1982 : {
1983 : const DDS::ReturnCode_t rc =
1984 100 : get_values_from_struct<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
1985 100 : if (rc == DDS::RETCODE_NO_DATA) {
1986 0 : return rc;
1987 : }
1988 100 : good = rc == DDS::RETCODE_OK;
1989 : }
1990 100 : break;
1991 10 : case TK_UNION:
1992 10 : good = get_values_from_union<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
1993 10 : break;
1994 0 : case TK_SEQUENCE:
1995 0 : good = get_values_from_sequence<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
1996 0 : break;
1997 0 : case TK_ARRAY:
1998 0 : good = get_values_from_array<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
1999 0 : break;
2000 0 : case TK_MAP:
2001 0 : good = get_values_from_map<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
2002 0 : break;
2003 0 : default:
2004 0 : if (DCPS::DCPS_debug_level >= 1) {
2005 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_sequence_values -")
2006 : ACE_TEXT(" A sequence<%C> can't be read as a member of type %C"),
2007 : typekind_to_string(ElementTypeKind), typekind_to_string(tk)));
2008 : }
2009 0 : return DDS::RETCODE_ERROR;
2010 : }
2011 :
2012 110 : if (!good && DCPS::DCPS_debug_level >= 1) {
2013 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_sequence_values -")
2014 : ACE_TEXT(" Failed to read sequence<%C> from a DynamicData object of type %C\n"),
2015 : typekind_to_string(ElementTypeKind), typekind_to_string(tk)));
2016 : }
2017 110 : return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
2018 110 : }
2019 :
2020 20 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_int32_values(DDS::Int32Seq& value, MemberId id)
2021 : {
2022 20 : return get_sequence_values<TK_INT32>(value, id, TK_ENUM, 17, 32);
2023 : }
2024 :
2025 15 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_uint32_values(DDS::UInt32Seq& value, MemberId id)
2026 : {
2027 15 : return get_sequence_values<TK_UINT32>(value, id, TK_BITMASK, 17, 32);
2028 : }
2029 :
2030 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_int8_values(DDS::Int8Seq& value, MemberId id)
2031 : {
2032 5 : return get_sequence_values<TK_INT8>(value, id, TK_ENUM, 1, 8);
2033 : }
2034 :
2035 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_uint8_values(DDS::UInt8Seq& value, MemberId id)
2036 : {
2037 5 : return get_sequence_values<TK_UINT8>(value, id, TK_BITMASK, 1, 8);
2038 : }
2039 :
2040 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_int16_values(DDS::Int16Seq& value, MemberId id)
2041 : {
2042 5 : return get_sequence_values<TK_INT16>(value, id, TK_ENUM, 9, 16);
2043 : }
2044 :
2045 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_uint16_values(DDS::UInt16Seq& value, MemberId id)
2046 : {
2047 5 : return get_sequence_values<TK_UINT16>(value, id, TK_BITMASK, 9, 16);
2048 : }
2049 :
2050 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_int64_values(DDS::Int64Seq& value, MemberId id)
2051 : {
2052 5 : return get_sequence_values<TK_INT64>(value, id);
2053 : }
2054 :
2055 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_uint64_values(DDS::UInt64Seq& value, MemberId id)
2056 : {
2057 5 : return get_sequence_values<TK_UINT64>(value, id, TK_BITMASK, 33, 64);
2058 : }
2059 :
2060 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_float32_values(DDS::Float32Seq& value, MemberId id)
2061 : {
2062 5 : return get_sequence_values<TK_FLOAT32>(value, id);
2063 : }
2064 :
2065 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_float64_values(DDS::Float64Seq& value, MemberId id)
2066 : {
2067 5 : return get_sequence_values<TK_FLOAT64>(value, id);
2068 : }
2069 :
2070 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_float128_values(DDS::Float128Seq& value, MemberId id)
2071 : {
2072 5 : return get_sequence_values<TK_FLOAT128>(value, id);
2073 : }
2074 :
2075 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_char8_values(DDS::CharSeq& value, MemberId id)
2076 : {
2077 5 : return get_sequence_values<TK_CHAR8>(value, id);
2078 : }
2079 :
2080 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_char16_values(DDS::WcharSeq& value, MemberId id)
2081 : {
2082 : #ifdef DDS_HAS_WCHAR
2083 5 : return get_sequence_values<TK_CHAR16>(value, id);
2084 : #else
2085 : return DDS::RETCODE_UNSUPPORTED;
2086 : #endif
2087 : }
2088 :
2089 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_byte_values(DDS::ByteSeq& value, MemberId id)
2090 : {
2091 5 : return get_sequence_values<TK_BYTE>(value, id);
2092 : }
2093 :
2094 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_boolean_values(DDS::BooleanSeq& value, MemberId id)
2095 : {
2096 5 : return get_sequence_values<TK_BOOLEAN>(value, id);
2097 : }
2098 :
2099 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_string_values(DDS::StringSeq& value, MemberId id)
2100 : {
2101 5 : return get_sequence_values<TK_STRING8>(value, id);
2102 : }
2103 :
2104 5 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_wstring_values(DDS::WstringSeq& value, MemberId id)
2105 : {
2106 : #ifdef DDS_HAS_WCHAR
2107 5 : return get_sequence_values<TK_STRING16>(value, id);
2108 : #else
2109 : return DDS::RETCODE_UNSUPPORTED;
2110 : #endif
2111 : }
2112 :
2113 0 : DDS::DynamicType_ptr DynamicDataXcdrReadImpl::type()
2114 : {
2115 0 : return DDS::DynamicType::_duplicate(type_);
2116 : }
2117 :
2118 0 : bool DynamicDataXcdrReadImpl::check_xcdr1_mutable(DDS::DynamicType_ptr dt)
2119 : {
2120 0 : DynamicTypeNameSet dtns;
2121 0 : return check_xcdr1_mutable_i(dt, dtns);
2122 0 : }
2123 :
2124 0 : CORBA::Boolean DynamicDataXcdrReadImpl::equals(DDS::DynamicData_ptr)
2125 : {
2126 : // FUTURE: Implement this.
2127 0 : ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicDataXcdrReadImpl::equals: Not implemented\n"));
2128 0 : return false;
2129 : }
2130 :
2131 399 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::skip_to_struct_member(DDS::MemberDescriptor* member_desc, MemberId id)
2132 : {
2133 399 : DDS::TypeDescriptor_var descriptor;
2134 399 : DDS::ReturnCode_t rc = type_->get_descriptor(descriptor);
2135 399 : if (rc != DDS::RETCODE_OK) {
2136 0 : return rc;
2137 : }
2138 :
2139 399 : const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
2140 399 : if (ek == DDS::FINAL || ek == DDS::APPENDABLE) {
2141 314 : size_t dheader = 0;
2142 314 : const bool xcdr2_appendable = encoding_.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2 &&
2143 314 : ek == DDS::APPENDABLE;
2144 314 : if (xcdr2_appendable && !strm_.read_delimiter(dheader)) {
2145 0 : if (log_level >= LogLevel::Notice) {
2146 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::skip_to_struct_member: "
2147 : "Failed to read DHEADER for member ID %d\n", id));
2148 : }
2149 0 : return DDS::RETCODE_ERROR;
2150 : }
2151 314 : const size_t end_of_struct = strm_.rpos() + dheader;
2152 :
2153 2380 : for (ACE_CDR::ULong i = 0; i < member_desc->index(); ++i) {
2154 2066 : DDS::DynamicTypeMember_var dtm;
2155 2066 : rc = type_->get_member_by_index(dtm, i);
2156 2066 : if (rc != DDS::RETCODE_OK) {
2157 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2158 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::skip_to_struct_member:"
2159 : " Failed to get DynamicTypeMember for member at index %d\n", i));
2160 : }
2161 0 : return rc;
2162 : }
2163 2066 : DDS::MemberDescriptor_var md;
2164 2066 : rc = dtm->get_descriptor(md);
2165 2066 : if (rc != DDS::RETCODE_OK) {
2166 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2167 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::skip_to_struct_member:"
2168 : " Failed to get MemberDescriptor for member at index %d\n", i));
2169 : }
2170 0 : return rc;
2171 : }
2172 2066 : if (exclude_member(extent_, md->is_key(), has_explicit_keys(type_))) {
2173 : // This member is not present in the sample, don't need to do anything.
2174 4 : continue;
2175 : }
2176 :
2177 : ACE_CDR::ULong num_skipped;
2178 2062 : if (!skip_struct_member_at_index(i, num_skipped)) {
2179 0 : if (DCPS::DCPS_debug_level >= 1) {
2180 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2181 : ACE_TEXT(" Failed to skip member at index %d\n"), i));
2182 : }
2183 0 : return DDS::RETCODE_ERROR;
2184 : }
2185 2062 : if (xcdr2_appendable && strm_.rpos() >= end_of_struct) {
2186 0 : return DDS::RETCODE_NO_DATA;
2187 : }
2188 2070 : }
2189 314 : return DDS::RETCODE_OK;
2190 : } else {
2191 85 : size_t dheader = 0;
2192 85 : if (!strm_.read_delimiter(dheader)) {
2193 0 : if (DCPS::DCPS_debug_level >= 1) {
2194 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2195 : ACE_TEXT(" Failed to read DHEADER for member ID %d\n"), id));
2196 : }
2197 0 : return DDS::RETCODE_ERROR;
2198 : }
2199 :
2200 85 : const size_t end_of_struct = strm_.rpos() + dheader;
2201 : while (true) {
2202 605 : if (strm_.rpos() >= end_of_struct) {
2203 0 : if (DCPS::DCPS_debug_level >= 1) {
2204 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2205 : ACE_TEXT(" Could not find a member with ID %d\n"), id));
2206 : }
2207 85 : return DDS::RETCODE_NO_DATA;
2208 : }
2209 :
2210 : ACE_CDR::ULong member_id;
2211 : size_t member_size;
2212 : bool must_understand;
2213 605 : if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
2214 0 : if (DCPS::DCPS_debug_level >= 1) {
2215 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2216 : ACE_TEXT(" Failed to read EMHEADER while finding member ID %d\n"), id));
2217 : }
2218 0 : return DDS::RETCODE_ERROR;
2219 : }
2220 :
2221 605 : if (member_id == id) {
2222 85 : return DDS::RETCODE_OK;
2223 : }
2224 :
2225 520 : if (!strm_.skip(member_size)) {
2226 0 : if (DCPS::DCPS_debug_level >= 1) {
2227 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2228 : ACE_TEXT(" Failed to skip a member with ID %d\n"), member_id));
2229 : }
2230 0 : return DDS::RETCODE_ERROR;
2231 : }
2232 520 : }
2233 : }
2234 399 : }
2235 :
2236 268 : bool DynamicDataXcdrReadImpl::get_from_struct_common_checks(const DDS::MemberDescriptor_var& md,
2237 : MemberId id, TypeKind kind, bool is_sequence)
2238 : {
2239 268 : const DDS::DynamicType_ptr member_dt = md->type();
2240 268 : if (!member_dt) {
2241 0 : if (DCPS::DCPS_debug_level >= 1) {
2242 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_from_struct_common_checks -")
2243 : ACE_TEXT(" Could not get DynamicType for member with ID %d\n"), id));
2244 : }
2245 0 : return false;
2246 : }
2247 :
2248 268 : const DDS::DynamicType_var member_type = get_base_type(member_dt);
2249 268 : const TypeKind member_kind = member_type->get_kind();
2250 :
2251 268 : if ((!is_sequence && member_kind != kind) || (is_sequence && member_kind != TK_SEQUENCE)) {
2252 12 : if (DCPS::DCPS_debug_level >= 1) {
2253 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_from_struct_common_checks -")
2254 : ACE_TEXT(" Member with ID %d has kind %C, not %C\n"),
2255 : id, typekind_to_string(member_kind),
2256 : is_sequence ? typekind_to_string(TK_SEQUENCE) : typekind_to_string(kind)));
2257 : }
2258 12 : return false;
2259 : }
2260 :
2261 256 : if (member_kind == TK_SEQUENCE) {
2262 115 : DDS::TypeDescriptor_var member_td;
2263 115 : if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) {
2264 0 : if (DCPS::DCPS_debug_level >= 1) {
2265 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_from_struct_common_checks -")
2266 : ACE_TEXT(" Could not get type descriptor for member %d\n"),
2267 : id));
2268 : }
2269 0 : return false;
2270 : }
2271 115 : const TypeKind elem_kind = get_base_type(member_td->element_type())->get_kind();
2272 115 : if (elem_kind != kind) {
2273 20 : if (DCPS::DCPS_debug_level >= 1) {
2274 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_from_struct_common_checks -")
2275 : ACE_TEXT(" Member with ID %d is a sequence of %C, not %C\n"),
2276 : id, typekind_to_string(elem_kind), typekind_to_string(kind)));
2277 : }
2278 20 : return false;
2279 : }
2280 115 : }
2281 :
2282 236 : return true;
2283 268 : }
2284 :
2285 2396 : bool DynamicDataXcdrReadImpl::skip_struct_member_at_index(ACE_CDR::ULong index, ACE_CDR::ULong& num_skipped)
2286 : {
2287 2396 : DDS::DynamicTypeMember_var member;
2288 2396 : if (type_->get_member_by_index(member, index) != DDS::RETCODE_OK) {
2289 0 : if (DCPS::DCPS_debug_level >= 1) {
2290 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_struct_member_at_index -")
2291 : ACE_TEXT(" Failed to get DynamicTypeMember for member index %d\n"), index));
2292 : }
2293 0 : return false;
2294 : }
2295 :
2296 2396 : DDS::MemberDescriptor_var md;
2297 2396 : if (member->get_descriptor(md) != DDS::RETCODE_OK) {
2298 0 : return false;
2299 : }
2300 2396 : if (strm_.encoding().kind() == DCPS::Encoding::KIND_XCDR2 && md->is_optional()) {
2301 : ACE_CDR::Boolean present;
2302 36 : if (!(strm_ >> ACE_InputCDR::to_boolean(present))) {
2303 36 : return false;
2304 : }
2305 : // Optional member that is omitted is not counted as a skipped member.
2306 36 : if (!present) {
2307 36 : num_skipped = 0;
2308 36 : return true;
2309 : }
2310 : }
2311 :
2312 2360 : num_skipped = 1;
2313 2360 : const DDS::DynamicType_ptr member_type = md->type();
2314 2360 : return member_type && skip_member(member_type);
2315 2396 : }
2316 :
2317 2448 : bool DynamicDataXcdrReadImpl::skip_member(DDS::DynamicType_ptr type)
2318 : {
2319 2448 : const DDS::DynamicType_var member_type = get_base_type(type);
2320 2448 : const TypeKind member_kind = member_type->get_kind();
2321 :
2322 2448 : switch (member_kind) {
2323 406 : case TK_BOOLEAN:
2324 : case TK_BYTE:
2325 : case TK_INT8:
2326 : case TK_UINT8:
2327 : case TK_CHAR8:
2328 406 : if (!skip("skip_member", "Failed to skip a member of size 1 byte", 1, 1)) {
2329 0 : return false;
2330 : }
2331 406 : break;
2332 270 : case TK_INT16:
2333 : case TK_UINT16:
2334 : case TK_CHAR16:
2335 270 : if (!skip("skip_member", "Failed to skip a member of size 2 bytes", 1, 2)) {
2336 0 : return false;
2337 : }
2338 270 : break;
2339 411 : case TK_INT32:
2340 : case TK_UINT32:
2341 : case TK_FLOAT32:
2342 411 : if (!skip("skip_member", "Failed to skip a member of size 4 bytes", 1, 4)) {
2343 0 : return false;
2344 : }
2345 411 : break;
2346 258 : case TK_INT64:
2347 : case TK_UINT64:
2348 : case TK_FLOAT64:
2349 258 : if (!skip("skip_member", "Failed to skip a member of size 8 bytes", 1, 8)) {
2350 0 : return false;
2351 : }
2352 258 : break;
2353 64 : case TK_FLOAT128:
2354 64 : if (!skip("skip_member", "Failed to skip a member of size 16 bytes", 1, 16)) {
2355 0 : return false;
2356 : }
2357 64 : break;
2358 41 : case TK_STRING8:
2359 : case TK_STRING16:
2360 : {
2361 41 : const char* str_kind = member_kind == TK_STRING8 ? "string" : "wstring";
2362 : ACE_CDR::ULong bytes;
2363 41 : if (!(strm_ >> bytes)) {
2364 0 : if (DCPS::DCPS_debug_level >= 1) {
2365 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_member -")
2366 : ACE_TEXT(" Failed to read length of a %C member\n"), str_kind));
2367 : }
2368 0 : return false;
2369 : }
2370 :
2371 82 : const DCPS::String err_msg = DCPS::String("Failed to skip a ") + str_kind + " member";
2372 41 : if (!skip("skip_member", err_msg.c_str(), bytes)) {
2373 0 : return false;
2374 : }
2375 41 : break;
2376 41 : }
2377 246 : case TK_ENUM:
2378 : case TK_BITMASK:
2379 : {
2380 246 : DDS::TypeDescriptor_var member_td;
2381 246 : if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) {
2382 0 : return false;
2383 : }
2384 246 : const ACE_CDR::ULong bit_bound = member_td->bound()[0];
2385 246 : const char* err_msg = member_kind == TK_ENUM ?
2386 : "Failed to skip an enum member" : "Failed to skip a bitmask member";
2387 :
2388 246 : if (bit_bound >= 1 && bit_bound <= 8) {
2389 0 : if (!skip("skip_member", err_msg, 1, 1)) {
2390 0 : return false;
2391 : }
2392 246 : } else if (bit_bound >= 9 && bit_bound <= 16) {
2393 0 : if (!skip("skip_member", err_msg, 1, 2)) {
2394 0 : return false;
2395 : }
2396 246 : } else if (bit_bound >= 17 && bit_bound <= 32) {
2397 246 : if (!skip("skip_member", err_msg, 1, 4)) {
2398 0 : return false;
2399 : }
2400 0 : } else if (bit_bound >= 33 && bit_bound <= 64 && member_kind == TK_BITMASK) {
2401 0 : if (!skip("skip_member", err_msg, 1, 8)) {
2402 0 : return false;
2403 : }
2404 : } else {
2405 0 : if (DCPS::DCPS_debug_level >= 1) {
2406 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_member - Found a%C")
2407 : ACE_TEXT(" member with bit bound %d\n"),
2408 : member_kind == TK_ENUM ? "n enum" : " bitmask", bit_bound));
2409 : }
2410 0 : return false;
2411 : }
2412 246 : break;
2413 246 : }
2414 56 : case TK_STRUCTURE:
2415 : case TK_UNION:
2416 56 : return skip_aggregated_member(member_type);
2417 684 : case TK_SEQUENCE:
2418 684 : return skip_sequence_member(member_type);
2419 12 : case TK_ARRAY:
2420 12 : return skip_array_member(member_type);
2421 0 : case TK_MAP:
2422 0 : return skip_map_member(member_type);
2423 0 : default:
2424 : {
2425 0 : if (DCPS::DCPS_debug_level >= 1) {
2426 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_member -")
2427 : ACE_TEXT(" Found a member of kind %C\n"), typekind_to_string(member_kind)));
2428 : }
2429 0 : return false;
2430 : }
2431 : }
2432 :
2433 1696 : return true;
2434 2448 : }
2435 :
2436 684 : bool DynamicDataXcdrReadImpl::skip_sequence_member(DDS::DynamicType_ptr seq_type)
2437 : {
2438 684 : DDS::TypeDescriptor_var descriptor;
2439 684 : if (seq_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2440 0 : return false;
2441 : }
2442 684 : const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
2443 :
2444 684 : ACE_CDR::ULong primitive_size = 0;
2445 684 : if (get_primitive_size(elem_type, primitive_size)) {
2446 : ACE_CDR::ULong length;
2447 600 : if (!(strm_ >> length)) {
2448 0 : if (DCPS::DCPS_debug_level >= 1) {
2449 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_sequence_member -")
2450 : ACE_TEXT(" Failed to deserialize a primitive sequence member\n")));
2451 : }
2452 0 : return false;
2453 : }
2454 :
2455 600 : return skip("skip_sequence_member", "Failed to skip a primitive sequence member",
2456 600 : length, primitive_size);
2457 : } else {
2458 84 : return skip_collection_member(seq_type);
2459 : }
2460 684 : }
2461 :
2462 12 : bool DynamicDataXcdrReadImpl::skip_array_member(DDS::DynamicType_ptr array_type)
2463 : {
2464 12 : DDS::TypeDescriptor_var descriptor;
2465 12 : if (array_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2466 0 : return false;
2467 : }
2468 12 : const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
2469 :
2470 12 : ACE_CDR::ULong primitive_size = 0;
2471 12 : if (get_primitive_size(elem_type, primitive_size)) {
2472 36 : return skip("skip_array_member", "Failed to skip a primitive array member",
2473 12 : bound_total(descriptor), primitive_size);
2474 : } else {
2475 0 : return skip_collection_member(array_type);
2476 : }
2477 12 : }
2478 :
2479 0 : bool DynamicDataXcdrReadImpl::skip_map_member(DDS::DynamicType_ptr map_type)
2480 : {
2481 0 : DDS::TypeDescriptor_var descriptor;
2482 0 : if (map_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2483 0 : return false;
2484 : }
2485 0 : const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
2486 0 : const DDS::DynamicType_var key_type = get_base_type(descriptor->key_element_type());
2487 :
2488 0 : ACE_CDR::ULong key_primitive_size = 0, elem_primitive_size = 0;
2489 0 : if (get_primitive_size(key_type, key_primitive_size) &&
2490 0 : get_primitive_size(elem_type, elem_primitive_size)) {
2491 : ACE_CDR::ULong length;
2492 0 : if (!(strm_ >> length)) {
2493 0 : if (DCPS::DCPS_debug_level >= 1) {
2494 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_map_member -")
2495 : ACE_TEXT(" Failed to deserialize length of a primitive map member\n")));
2496 : }
2497 0 : return false;
2498 : }
2499 :
2500 0 : for (unsigned i = 0; i < length; ++i) {
2501 0 : if (!skip("skip_map_member", "Failed to skip a key of a primitive map member",
2502 : 1, key_primitive_size)) {
2503 0 : return false;
2504 : }
2505 0 : if (!skip("skip_map_member", "Failed to skip an element of a primitive map member",
2506 : 1, elem_primitive_size)) {
2507 0 : return false;
2508 : }
2509 : }
2510 0 : return true;
2511 : } else {
2512 0 : return skip_collection_member(map_type);
2513 : }
2514 0 : }
2515 :
2516 84 : bool DynamicDataXcdrReadImpl::skip_collection_member(DDS::DynamicType_ptr coll_type)
2517 : {
2518 84 : const TypeKind kind = coll_type->get_kind();
2519 84 : if (kind == TK_SEQUENCE || kind == TK_ARRAY || kind == TK_MAP) {
2520 84 : const char* kind_str = typekind_to_string(kind);
2521 84 : if (strm_.encoding().kind() == DCPS::Encoding::KIND_XCDR2) {
2522 : size_t dheader;
2523 42 : if (!strm_.read_delimiter(dheader)) {
2524 0 : if (DCPS::DCPS_debug_level >= 1) {
2525 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_collection_member -")
2526 : ACE_TEXT(" Failed to deserialize DHEADER of a non-primitive %C member\n"),
2527 : kind_str));
2528 : }
2529 0 : return false;
2530 : }
2531 84 : const DCPS::String err_msg = DCPS::String("Failed to skip a non-primitive ") + kind_str + " member";
2532 42 : return skip("skip_collection_member", err_msg.c_str(), dheader);
2533 84 : } else if (kind == TK_SEQUENCE) {
2534 42 : return skip_to_sequence_element(0, coll_type);
2535 0 : } else if (kind == TK_ARRAY) {
2536 0 : return skip_to_array_element(0, coll_type);
2537 0 : } else if (kind == TK_MAP) {
2538 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2539 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::skip_collection_member: "
2540 : "DynamicData does not currently support XCDR1 maps\n"));
2541 : }
2542 0 : return false;
2543 : }
2544 : }
2545 :
2546 0 : return false;
2547 : }
2548 :
2549 56 : bool DynamicDataXcdrReadImpl::skip_aggregated_member(DDS::DynamicType_ptr member_type)
2550 : {
2551 56 : DynamicDataXcdrReadImpl nested_data(strm_, member_type);
2552 56 : if (!nested_data.skip_all()) {
2553 0 : return false;
2554 : }
2555 :
2556 : // Collect the intermediate message block chains that were created recursively
2557 : // when skipping nested_data.
2558 56 : const IntermediateChains& chains = nested_data.get_intermediate_chains();
2559 56 : chains_to_release.insert(chains_to_release.end(), chains.begin(), chains.end());
2560 :
2561 56 : ACE_Message_Block* const result_chain = nested_data.strm_.current()->duplicate();
2562 56 : strm_ = DCPS::Serializer(result_chain, encoding_);
2563 56 : const DCPS::Serializer::RdState curr_state = nested_data.strm_.rdstate();
2564 56 : strm_.rdstate(curr_state);
2565 56 : chains_to_release.push_back(result_chain);
2566 56 : return true;
2567 56 : }
2568 :
2569 1136 : void DynamicDataXcdrReadImpl::release_chains()
2570 : {
2571 1192 : for (ACE_CDR::ULong i = 0; i < chains_to_release.size(); ++i) {
2572 56 : ACE_Message_Block::release(chains_to_release[i]);
2573 : }
2574 1136 : chains_to_release.clear();
2575 1136 : }
2576 :
2577 142 : bool DynamicDataXcdrReadImpl::read_discriminator(const DDS::DynamicType_ptr disc_type, DDS::ExtensibilityKind union_ek, ACE_CDR::Long& label)
2578 : {
2579 142 : if (union_ek == DDS::MUTABLE) {
2580 : unsigned id;
2581 : size_t size;
2582 : bool must_understand;
2583 28 : if (!strm_.read_parameter_id(id, size, must_understand)) { return false; }
2584 : }
2585 :
2586 142 : const TypeKind disc_tk = disc_type->get_kind();
2587 142 : switch (disc_tk) {
2588 0 : case TK_BOOLEAN:
2589 : {
2590 : ACE_CDR::Boolean value;
2591 0 : if (!(strm_ >> ACE_InputCDR::to_boolean(value))) { return false; }
2592 0 : label = static_cast<ACE_CDR::Long>(value);
2593 0 : return true;
2594 : }
2595 0 : case TK_BYTE:
2596 : {
2597 : ACE_CDR::Octet value;
2598 0 : if (!(strm_ >> ACE_InputCDR::to_octet(value))) { return false; }
2599 0 : label = static_cast<ACE_CDR::Long>(value);
2600 0 : return true;
2601 : }
2602 0 : case TK_CHAR8:
2603 : {
2604 : ACE_CDR::Char value;
2605 0 : if (!(strm_ >> ACE_InputCDR::to_char(value))) { return false; }
2606 0 : label = static_cast<ACE_CDR::Long>(value);
2607 0 : return true;
2608 : }
2609 0 : case TK_CHAR16:
2610 : {
2611 : ACE_CDR::WChar value;
2612 0 : if (!(strm_ >> ACE_InputCDR::to_wchar(value))) { return false; }
2613 0 : label = static_cast<ACE_CDR::Long>(value);
2614 0 : return true;
2615 : }
2616 0 : case TK_INT8:
2617 : {
2618 : ACE_CDR::Int8 value;
2619 0 : if (!(strm_ >> ACE_InputCDR::to_int8(value))) { return false; }
2620 0 : label = static_cast<ACE_CDR::Long>(value);
2621 0 : return true;
2622 : }
2623 0 : case TK_UINT8:
2624 : {
2625 : ACE_CDR::UInt8 value;
2626 0 : if (!(strm_ >> ACE_InputCDR::to_uint8(value))) { return false; }
2627 0 : label = static_cast<ACE_CDR::Long>(value);
2628 0 : return true;
2629 : }
2630 0 : case TK_INT16:
2631 : {
2632 : ACE_CDR::Short value;
2633 0 : if (!(strm_ >> value)) { return false; }
2634 0 : label = static_cast<ACE_CDR::Long>(value);
2635 0 : return true;
2636 : }
2637 0 : case TK_UINT16:
2638 : {
2639 : ACE_CDR::UShort value;
2640 0 : if (!(strm_ >> value)) { return false; }
2641 0 : label = static_cast<ACE_CDR::Long>(value);
2642 0 : return true;
2643 : }
2644 0 : case TK_INT32:
2645 0 : return strm_ >> label;
2646 0 : case TK_UINT32:
2647 : {
2648 : ACE_CDR::ULong value;
2649 0 : if (!(strm_ >> value)) { return false; }
2650 0 : label = static_cast<ACE_CDR::Long>(value);
2651 0 : return true;
2652 : }
2653 0 : case TK_INT64:
2654 : {
2655 : ACE_CDR::LongLong value;
2656 0 : if (!(strm_ >> value)) { return false; }
2657 0 : label = static_cast<ACE_CDR::Long>(value);
2658 0 : return true;
2659 : }
2660 0 : case TK_UINT64:
2661 : {
2662 : ACE_CDR::ULongLong value;
2663 0 : if (!(strm_ >> value)) { return false; }
2664 0 : label = static_cast<ACE_CDR::Long>(value);
2665 0 : return true;
2666 : }
2667 142 : case TK_ENUM:
2668 : {
2669 142 : DDS::TypeDescriptor_var disc_td;
2670 142 : if (disc_type->get_descriptor(disc_td) != DDS::RETCODE_OK) {
2671 0 : return false;
2672 : }
2673 142 : const ACE_CDR::ULong bit_bound = disc_td->bound()[0];
2674 142 : if (bit_bound >= 1 && bit_bound <= 8) {
2675 : ACE_CDR::Int8 value;
2676 0 : if (!(strm_ >> ACE_InputCDR::to_int8(value))) { return false; }
2677 0 : label = static_cast<ACE_CDR::Long>(value);
2678 142 : } else if (bit_bound >= 9 && bit_bound <= 16) {
2679 : ACE_CDR::Short value;
2680 0 : if (!(strm_ >> value)) { return false; }
2681 0 : label = static_cast<ACE_CDR::Long>(value);
2682 0 : } else {
2683 142 : return strm_ >> label;
2684 : }
2685 0 : return true;
2686 142 : }
2687 0 : default:
2688 0 : if (DCPS::DCPS_debug_level >= 1) {
2689 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::read_discriminator - Union has")
2690 : ACE_TEXT(" unsupported discriminator type (%C)\n"), typekind_to_string(disc_tk)));
2691 : }
2692 0 : return false;
2693 : }
2694 : }
2695 :
2696 56 : bool DynamicDataXcdrReadImpl::skip_all()
2697 : {
2698 56 : DDS::TypeDescriptor_var descriptor;
2699 56 : if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2700 0 : return false;
2701 : }
2702 :
2703 56 : const TypeKind tk = type_->get_kind();
2704 56 : if (tk != TK_STRUCTURE && tk != TK_UNION) {
2705 0 : return false;
2706 : }
2707 :
2708 56 : const DDS::ExtensibilityKind extensibility = descriptor->extensibility_kind();
2709 56 : if (strm_.encoding().kind() == DCPS::Encoding::KIND_XCDR2 && (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE)) {
2710 : size_t dheader;
2711 12 : if (!strm_.read_delimiter(dheader)) {
2712 0 : if (DCPS::DCPS_debug_level >= 1) {
2713 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_all - Failed to read")
2714 : ACE_TEXT(" DHEADER of the DynamicData object\n")));
2715 : }
2716 0 : return false;
2717 : }
2718 12 : return skip("skip_all", "Failed to skip the whole DynamicData object\n", dheader);
2719 : } else {
2720 44 : if (tk == TK_STRUCTURE) {
2721 42 : const ACE_CDR::ULong member_count = type_->get_member_count();
2722 42 : bool good = true;
2723 96 : for (ACE_CDR::ULong i = 0; i < member_count; ++i) {
2724 : ACE_CDR::ULong num_skipped;
2725 54 : if (!skip_struct_member_at_index(i, num_skipped)) {
2726 0 : good = false;
2727 0 : break;
2728 : }
2729 : }
2730 42 : return good;
2731 : } else { // Union
2732 2 : const DDS::DynamicType_var disc_type = get_base_type(descriptor->discriminator_type());
2733 : ACE_CDR::Long label;
2734 2 : if (!read_discriminator(disc_type, extensibility, label)) {
2735 0 : return false;
2736 : }
2737 :
2738 2 : DDS::DynamicTypeMembersById_var members;
2739 2 : if (type_->get_all_members(members) != DDS::RETCODE_OK) {
2740 0 : return false;
2741 : }
2742 2 : DynamicTypeMembersByIdImpl* members_impl = dynamic_cast<DynamicTypeMembersByIdImpl*>(members.in());
2743 2 : if (!members_impl) {
2744 0 : return false;
2745 : }
2746 :
2747 2 : bool has_default = false;
2748 2 : DDS::MemberDescriptor_var default_member;
2749 4 : for (DynamicTypeMembersByIdImpl::const_iterator it = members_impl->begin(); it != members_impl->end(); ++it) {
2750 4 : DDS::MemberDescriptor_var md;
2751 4 : if (it->second->get_descriptor(md) != DDS::RETCODE_OK) {
2752 0 : return false;
2753 : }
2754 4 : const DDS::UnionCaseLabelSeq& labels = md->label();
2755 6 : for (ACE_CDR::ULong i = 0; i < labels.length(); ++i) {
2756 4 : if (label == labels[i]) {
2757 2 : const DDS::DynamicType_ptr selected_member = md->type();
2758 2 : bool good = selected_member && skip_member(selected_member);
2759 2 : return good;
2760 : }
2761 : }
2762 :
2763 2 : if (md->is_default_label()) {
2764 0 : has_default = true;
2765 0 : default_member = md;
2766 : }
2767 4 : }
2768 :
2769 0 : if (has_default) {
2770 0 : const DDS::DynamicType_ptr default_dt = default_member->type();
2771 0 : bool good = default_dt && skip_member(default_dt);
2772 0 : return good;
2773 : }
2774 0 : if (DCPS::DCPS_debug_level >= 1) {
2775 0 : ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_all - Skip a union with no")
2776 : ACE_TEXT(" selected member and a discriminator with value %d\n"), label));
2777 : }
2778 0 : return true;
2779 2 : }
2780 : }
2781 56 : }
2782 :
2783 2362 : bool DynamicDataXcdrReadImpl::skip(const char* func_name, const char* description, size_t n, int size)
2784 : {
2785 2362 : if (!strm_.skip(n, size)) {
2786 0 : if (DCPS::DCPS_debug_level >= 1) {
2787 0 : ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::%C - %C\n"), func_name, description));
2788 : }
2789 0 : return false;
2790 : }
2791 2362 : return true;
2792 : }
2793 :
2794 787 : bool DynamicDataXcdrReadImpl::get_primitive_size(DDS::DynamicType_ptr dt, ACE_CDR::ULong& size) const
2795 : {
2796 787 : size = 0;
2797 :
2798 787 : switch (dt->get_kind()) {
2799 180 : case TK_BOOLEAN:
2800 : case TK_BYTE:
2801 : case TK_INT8:
2802 : case TK_UINT8:
2803 : case TK_CHAR8:
2804 180 : size = 1;
2805 180 : break;
2806 120 : case TK_INT16:
2807 : case TK_UINT16:
2808 : case TK_CHAR16:
2809 120 : size = 2;
2810 120 : break;
2811 205 : case TK_INT32:
2812 : case TK_UINT32:
2813 : case TK_FLOAT32:
2814 205 : size = 4;
2815 205 : break;
2816 116 : case TK_INT64:
2817 : case TK_UINT64:
2818 : case TK_FLOAT64:
2819 116 : size = 8;
2820 116 : break;
2821 28 : case TK_FLOAT128:
2822 28 : size = 16;
2823 28 : break;
2824 138 : default:
2825 138 : return false;
2826 : }
2827 649 : return true;
2828 : }
2829 :
2830 0 : bool DynamicDataXcdrReadImpl::check_xcdr1_mutable_i(DDS::DynamicType_ptr dt, DynamicTypeNameSet& dtns)
2831 : {
2832 0 : DDS::TypeDescriptor_var descriptor;
2833 0 : if (dt->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2834 0 : return false;
2835 : }
2836 :
2837 0 : if (dtns.find(descriptor->name()) != dtns.end()) {
2838 0 : return true;
2839 : }
2840 0 : if (descriptor->extensibility_kind() == DDS::MUTABLE &&
2841 0 : encoding_.kind() == DCPS::Encoding::KIND_XCDR1) {
2842 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2843 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::check_xcdr1_mutable: "
2844 : "XCDR1 mutable is not currently supported in OpenDDS\n"));
2845 : }
2846 0 : return false;
2847 : }
2848 0 : dtns.insert(descriptor->name());
2849 0 : for (ACE_CDR::ULong i = 0; i < dt->get_member_count(); ++i) {
2850 0 : DDS::DynamicTypeMember_var dtm;
2851 0 : if (dt->get_member_by_index(dtm, i) != DDS::RETCODE_OK) {
2852 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2853 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::check_xcdr1_mutable: "
2854 : "Failed to get member from DynamicType\n"));
2855 : }
2856 0 : return false;
2857 : }
2858 0 : DDS::MemberDescriptor_var descriptor;
2859 0 : if (dtm->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2860 0 : return false;
2861 : }
2862 0 : if (!check_xcdr1_mutable_i(descriptor->type(), dtns)) {
2863 0 : return false;
2864 : }
2865 0 : }
2866 0 : return true;
2867 0 : }
2868 :
2869 : #ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE
2870 : namespace {
2871 : template <typename T>
2872 0 : DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DynamicDataXcdrReadImpl& dyn,
2873 : DDS::ReturnCode_t (DynamicDataXcdrReadImpl::* pmf)(T&, DDS::MemberId))
2874 : {
2875 : T v;
2876 0 : const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id);
2877 0 : if (ret == DDS::RETCODE_OK) {
2878 0 : value = v;
2879 : }
2880 0 : return ret;
2881 : }
2882 :
2883 0 : DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DynamicDataXcdrReadImpl& dyn,
2884 : DDS::ReturnCode_t (DynamicDataXcdrReadImpl::* pmf)(char*&, DDS::MemberId))
2885 : {
2886 0 : CORBA::String_var v;
2887 0 : const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id);
2888 0 : if (ret == DDS::RETCODE_OK) {
2889 0 : value = v.in();
2890 : }
2891 0 : return ret;
2892 0 : }
2893 :
2894 0 : DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DynamicDataXcdrReadImpl& dyn,
2895 : DDS::ReturnCode_t (DynamicDataXcdrReadImpl::* pmf)(ACE_CDR::WChar*&, DDS::MemberId))
2896 : {
2897 0 : CORBA::WString_var v;
2898 0 : const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id);
2899 0 : if (ret == DDS::RETCODE_OK) {
2900 0 : value = v.in();
2901 : }
2902 0 : return ret;
2903 0 : }
2904 : }
2905 :
2906 0 : DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_simple_value(DCPS::Value& value, DDS::MemberId id)
2907 : {
2908 0 : DDS::DynamicTypeMember_var dtm;
2909 0 : if (type_->get_member(dtm, id) != DDS::RETCODE_OK) {
2910 0 : return DDS::RETCODE_ERROR;
2911 : }
2912 0 : DDS::MemberDescriptor_var md;
2913 0 : if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
2914 0 : return DDS::RETCODE_ERROR;
2915 : }
2916 0 : DDS::DynamicType_var member_type = get_base_type(md->type());
2917 0 : const TypeKind member_kind = member_type->get_kind();
2918 0 : switch (member_kind) {
2919 0 : case TK_BOOLEAN:
2920 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_boolean_value);
2921 0 : case TK_BYTE:
2922 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_byte_value);
2923 0 : case TK_INT8:
2924 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int8_value);
2925 0 : case TK_INT16:
2926 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int16_value);
2927 0 : case TK_INT32:
2928 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int32_value);
2929 0 : case TK_INT64:
2930 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int64_value_impl);
2931 0 : case TK_UINT8:
2932 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint8_value);
2933 0 : case TK_UINT16:
2934 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint16_value);
2935 0 : case TK_UINT32:
2936 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint32_value);
2937 0 : case TK_UINT64:
2938 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint64_value_impl);
2939 0 : case TK_FLOAT32:
2940 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_float32_value);
2941 0 : case TK_FLOAT64:
2942 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_float64_value);
2943 0 : case TK_FLOAT128:
2944 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_float128_value);
2945 0 : case TK_CHAR8:
2946 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_char8_value);
2947 0 : case TK_CHAR16:
2948 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_char16_value);
2949 0 : case TK_ENUM:
2950 : case TK_STRING8:
2951 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_string_value);
2952 0 : case TK_STRING16:
2953 0 : return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_wstring_value);
2954 0 : default:
2955 0 : return DDS::RETCODE_UNSUPPORTED;
2956 : }
2957 0 : }
2958 : #endif
2959 :
2960 : #ifndef OPENDDS_SAFETY_PROFILE
2961 : bool print_member(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS::String& indent,
2962 : MemberId member_id);
2963 :
2964 0 : bool print_members(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS::String& indent, bool print_name)
2965 : {
2966 0 : DCPS::String temp_indent = indent;
2967 0 : indent += " ";
2968 0 : const DDS::DynamicType_var type = dd->type();
2969 0 : const DDS::DynamicType_var base_type = get_base_type(type);
2970 0 : const char* const kind = base_type->get_kind() == TK_STRUCTURE ? "struct" : "union";
2971 0 : if (print_name) {
2972 0 : CORBA::String_var type_name = type->get_name();
2973 0 : type_string += DCPS::String(kind) + " " + DCPS::String(type_name);
2974 0 : }
2975 0 : type_string += "\n";
2976 :
2977 0 : const ACE_CDR::ULong item_count = dd->get_item_count();
2978 0 : for (ACE_CDR::ULong idx = 0; idx != item_count; ++idx) {
2979 : // Translate the item number into a MemberId.
2980 0 : const MemberId member_id = dd->get_member_id_at_index(idx);
2981 0 : if (member_id == MEMBER_ID_INVALID) {
2982 0 : if (log_level >= LogLevel::Notice) {
2983 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_members: "
2984 : "failed to get %C member at index %u\n", kind, idx));
2985 : }
2986 0 : return false;
2987 : }
2988 :
2989 0 : if (!print_member(dd, type_string, indent, member_id)) {
2990 0 : if (log_level >= LogLevel::Notice) {
2991 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_members: "
2992 : "failed to print %C member with id %u\n", kind, member_id));
2993 : }
2994 0 : return false;
2995 : }
2996 : }
2997 :
2998 0 : indent = temp_indent;
2999 0 : return true;
3000 0 : }
3001 :
3002 0 : bool print_member(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS::String& indent,
3003 : MemberId member_id)
3004 : {
3005 : DDS::DynamicType_ptr member_type;
3006 0 : DDS::MemberDescriptor_var member_descriptor;
3007 0 : const DDS::DynamicType_var container_type = dd->type();
3008 0 : const DDS::TypeKind container_kind = container_type->get_kind();
3009 0 : const bool sequence_like = is_sequence_like(container_kind);
3010 0 : if (sequence_like) {
3011 0 : DDS::TypeDescriptor_var td;
3012 0 : if (container_type->get_descriptor(td) != DDS::RETCODE_OK) {
3013 0 : return false;
3014 : }
3015 0 : member_type = td->element_type();
3016 :
3017 0 : } else {
3018 0 : DDS::DynamicTypeMember_var dtm;
3019 0 : if (container_type->get_member(dtm, member_id) != DDS::RETCODE_OK) {
3020 0 : return false;
3021 : }
3022 0 : if (dtm->get_descriptor(member_descriptor) != DDS::RETCODE_OK) {
3023 0 : return false;
3024 : }
3025 0 : member_type = member_descriptor->type();
3026 0 : }
3027 :
3028 0 : const DDS::DynamicType_var member_base_type = get_base_type(member_type);
3029 0 : const DDS::TypeKind tk = member_base_type->get_kind();
3030 0 : DDS::TypeDescriptor_var member_type_descriptor;
3031 0 : if (member_base_type->get_descriptor(member_type_descriptor) != DDS::RETCODE_OK) {
3032 0 : return false;
3033 : }
3034 :
3035 0 : if (member_descriptor) {
3036 0 : type_string += indent;
3037 0 : const bool struct_or_union = tk == TK_STRUCTURE || tk == TK_UNION;
3038 0 : if (struct_or_union) {
3039 0 : type_string += (tk == TK_STRUCTURE ? "struct " : "union ");
3040 : }
3041 0 : const CORBA::String_var member_type_name = member_type->get_name();
3042 0 : const DCPS::String member_name = member_descriptor->name();
3043 0 : type_string += DCPS::String(member_type_name.in()) + " " + member_name;
3044 0 : if (!struct_or_union) {
3045 0 : type_string += " ";
3046 : }
3047 0 : if (tk == TK_ARRAY || tk == TK_SEQUENCE) {
3048 0 : DDS::TypeDescriptor_var td;
3049 0 : const DDS::DynamicType_var elem_type = get_base_type(member_type_descriptor->element_type());
3050 0 : if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
3051 0 : return false;
3052 : }
3053 0 : DCPS::String ele_type_name = td->name();
3054 0 : type_string += ele_type_name;
3055 0 : }
3056 0 : }
3057 :
3058 0 : if (!is_complex(tk)) {
3059 0 : type_string += "= ";
3060 : }
3061 :
3062 0 : switch (tk) {
3063 0 : case TK_ENUM: {
3064 : DDS::Int32 value;
3065 0 : if (get_enum_value(value, member_base_type, dd, member_id) != DDS::RETCODE_OK) {
3066 0 : return false;
3067 : }
3068 0 : DDS::String8_var name;
3069 0 : if (get_enumerator_name(name, value, member_base_type) == DDS::RETCODE_OK) {
3070 0 : type_string += name.in();
3071 : } else {
3072 0 : type_string += DCPS::to_dds_string(value);
3073 : }
3074 0 : type_string += "\n";
3075 0 : break;
3076 0 : }
3077 0 : case TK_INT8:
3078 : case TK_INT16:
3079 : case TK_INT32:
3080 : case TK_INT64: {
3081 : DDS::Int64 value;
3082 0 : if (get_int_value(value, dd, member_id, tk) != DDS::RETCODE_OK) {
3083 0 : return false;
3084 : }
3085 0 : type_string += DCPS::to_dds_string(value) + "\n";
3086 0 : break;
3087 : }
3088 0 : case TK_UINT8:
3089 : case TK_UINT16:
3090 : case TK_UINT32:
3091 : case TK_UINT64: {
3092 : DDS::UInt64 value;
3093 0 : if (get_uint_value(value, dd, member_id, tk) != DDS::RETCODE_OK) {
3094 0 : return false;
3095 : }
3096 0 : type_string += DCPS::to_dds_string(value) + "\n";
3097 0 : break;
3098 : }
3099 0 : case TK_BOOLEAN: {
3100 : ACE_CDR::Boolean my_bool;
3101 0 : if (dd->get_boolean_value(my_bool, member_id) != DDS::RETCODE_OK) {
3102 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3103 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_boolean_value\n"));
3104 : }
3105 0 : return false;
3106 : }
3107 0 : DCPS::String bool_string = my_bool ? "true" : "false";
3108 0 : type_string += bool_string + "\n";
3109 0 : break;
3110 0 : }
3111 0 : case TK_BYTE: {
3112 : ACE_CDR::Octet my_byte;
3113 0 : if (dd->get_byte_value(my_byte, member_id) != DDS::RETCODE_OK) {
3114 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3115 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_byte_value\n"));
3116 : }
3117 0 : return false;
3118 : }
3119 0 : std::stringstream os;
3120 0 : os << std::hex << std::setfill('0') << std::setw(2) << int(my_byte);
3121 0 : type_string += "0x" + os.str() + "\n";
3122 0 : break;
3123 0 : }
3124 0 : case TK_CHAR8: {
3125 : ACE_CDR::Char my_char;
3126 0 : if (dd->get_char8_value(my_char, member_id) != DDS::RETCODE_OK) {
3127 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3128 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_char8_value\n"));
3129 : }
3130 0 : return false;
3131 : }
3132 0 : std::stringstream os;
3133 0 : DCPS::char_helper<ACE_CDR::Char>(os, my_char);
3134 0 : type_string += "'" + os.str() + "'\n";
3135 0 : break;
3136 0 : }
3137 : #ifdef DDS_HAS_WCHAR
3138 0 : case TK_CHAR16: {
3139 : ACE_CDR::WChar my_wchar;
3140 0 : if (dd->get_char16_value(my_wchar, member_id) != DDS::RETCODE_OK) {
3141 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3142 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_char16_value\n"));
3143 : }
3144 0 : return false;
3145 : }
3146 0 : std::stringstream os;
3147 0 : DCPS::char_helper<ACE_CDR::WChar>(os, my_wchar);
3148 0 : type_string += "L'" + os.str() + "'\n";
3149 0 : break;
3150 0 : }
3151 : #endif
3152 0 : case TK_FLOAT32: {
3153 : ACE_CDR::Float my_float;
3154 0 : if (dd->get_float32_value(my_float, member_id) != DDS::RETCODE_OK) {
3155 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3156 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_float32_value\n"));
3157 : }
3158 0 : return false;
3159 : }
3160 0 : std::stringstream os;
3161 0 : os << my_float;
3162 0 : type_string += os.str() + "\n";
3163 0 : break;
3164 0 : }
3165 0 : case TK_FLOAT64: {
3166 : ACE_CDR::Double my_double;
3167 0 : if (dd->get_float64_value(my_double, member_id) != DDS::RETCODE_OK) {
3168 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3169 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_float64_value\n"));
3170 : }
3171 0 : return false;
3172 : }
3173 0 : std::stringstream os;
3174 0 : os << my_double;
3175 0 : type_string += os.str() + "\n";
3176 0 : break;
3177 0 : }
3178 0 : case TK_FLOAT128: {
3179 : ACE_CDR::LongDouble my_longdouble;
3180 0 : if (dd->get_float128_value(my_longdouble, member_id) != DDS::RETCODE_OK) {
3181 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3182 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_float128_value\n"));
3183 : }
3184 0 : return false;
3185 : }
3186 0 : std::stringstream os;
3187 0 : os << my_longdouble;
3188 0 : type_string += os.str() + "\n";
3189 0 : break;
3190 0 : }
3191 0 : case TK_STRING8: {
3192 0 : CORBA::String_var my_string;
3193 0 : if (dd->get_string_value(my_string, member_id) != DDS::RETCODE_OK) {
3194 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3195 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_string_value\n"));
3196 : }
3197 0 : return false;
3198 : }
3199 0 : std::stringstream os;
3200 0 : DCPS::string_helper(os, my_string.inout());
3201 0 : type_string += DCPS::String("\"") + os.str() + "\"\n";
3202 0 : break;
3203 0 : }
3204 : #ifdef DDS_HAS_WCHAR
3205 0 : case TK_STRING16: {
3206 0 : CORBA::WString_var my_wstring;
3207 0 : if (dd->get_wstring_value(my_wstring, member_id) != DDS::RETCODE_OK) {
3208 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3209 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_wstring_value\n"));
3210 : }
3211 0 : return false;
3212 : }
3213 0 : std::stringstream os;
3214 0 : DCPS::string_helper(os, my_wstring.inout());
3215 0 : type_string += "L\"" + os.str() + "\"\n";
3216 0 : break;
3217 0 : }
3218 : #endif
3219 0 : case TK_BITMASK:
3220 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3221 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: Bitmask is an unsupported type in OpenDDS\n"));
3222 : }
3223 0 : break;
3224 0 : case TK_BITSET:
3225 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3226 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: Bitset is an unsupported type in OpenDDS\n"));
3227 : }
3228 0 : break;
3229 0 : case TK_ARRAY:
3230 : case TK_SEQUENCE: {
3231 0 : DCPS::String temp_indent = indent;
3232 0 : indent += " ";
3233 0 : DDS::DynamicData_var temp_dd;
3234 0 : if (dd->get_complex_value(temp_dd, member_id) != DDS::RETCODE_OK) {
3235 0 : return false;
3236 : }
3237 0 : const ACE_CDR::ULong count = temp_dd->get_item_count();
3238 0 : type_string += "[" + DCPS::to_dds_string(count) + "] =\n";
3239 0 : for (ACE_CDR::ULong i = 0; i < count; ++i) {
3240 0 : type_string += indent + "[" + DCPS::to_dds_string(i) + "] ";
3241 0 : if (!print_member(temp_dd, type_string, indent, temp_dd->get_member_id_at_index(i))) {
3242 0 : if (log_level >= LogLevel::Notice) {
3243 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: "
3244 : "failed to read array/sequence member\n"));
3245 : }
3246 0 : return false;
3247 : }
3248 : }
3249 0 : indent = temp_indent;
3250 0 : break;
3251 0 : }
3252 0 : case TK_UNION:
3253 : case TK_STRUCTURE: {
3254 0 : DDS::DynamicData_var temp_dd;
3255 0 : if (dd->get_complex_value(temp_dd, member_id) != DDS::RETCODE_OK) {
3256 0 : return false;
3257 : }
3258 0 : if (!print_members(temp_dd, type_string, indent, sequence_like)) {
3259 0 : return false;
3260 : }
3261 0 : break;
3262 0 : }
3263 : }
3264 :
3265 0 : return true;
3266 0 : }
3267 :
3268 0 : bool print_dynamic_data(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS::String& indent)
3269 : {
3270 0 : const DDS::DynamicType_var type = dd->type();
3271 0 : const DDS::DynamicType_var base_type = get_base_type(type);
3272 :
3273 : bool result;
3274 0 : switch (base_type->get_kind()) {
3275 0 : case TK_STRUCTURE:
3276 : case TK_UNION:
3277 0 : result = print_members(dd, type_string, indent, true);
3278 0 : break;
3279 0 : default:
3280 0 : result = false;
3281 : }
3282 0 : return result;
3283 0 : }
3284 : #endif
3285 :
3286 : } // namespace XTypes
3287 : } // namespace OpenDDS
3288 :
3289 : OPENDDS_END_VERSIONED_NAMESPACE_DECL
3290 :
3291 : #endif // OPENDDS_SAFETY_PROFILE
|