OpenDDS  Snapshot(2023/04/28-20:55)
TypeAssignability.cpp
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.opendds.org/license.html
4  */
5 
6 #include "DCPS/DdsDcps_pch.h"
7 #include "TypeAssignability.h"
8 
9 #include <set>
10 
12 
13 namespace OpenDDS {
14 namespace XTypes {
15 
16 /**
17  * @brief Both input type objects must be minimal
18  */
20  const TypeObject& tb) const
21 {
22  if (EK_MINIMAL == ta.kind && EK_MINIMAL == tb.kind) {
23  if (TK_ALIAS == ta.minimal.kind || TK_ALIAS == tb.minimal.kind) {
24  return assignable_alias(ta.minimal, tb.minimal);
25  }
26 
27  switch (ta.minimal.kind) {
28  case TK_ANNOTATION:
29  return assignable_annotation(ta.minimal, tb.minimal);
30  case TK_STRUCTURE:
31  return assignable_struct(ta.minimal, tb.minimal);
32  case TK_UNION:
33  return assignable_union(ta.minimal, tb.minimal);
34  case TK_BITSET:
35  return assignable_bitset(ta.minimal, tb.minimal);
36  case TK_SEQUENCE:
37  return assignable_sequence(ta.minimal, tb.minimal);
38  case TK_ARRAY:
39  return assignable_array(ta.minimal, tb.minimal);
40  case TK_MAP:
41  return assignable_map(ta.minimal, tb.minimal);
42  case TK_ENUM:
43  return assignable_enum(ta.minimal, tb.minimal);
44  case TK_BITMASK:
45  return assignable_bitmask(ta.minimal, tb.minimal);
46  default:
47  return assignable_extended(ta.minimal, tb.minimal);
48  }
49  }
50 
51  return false;
52 }
53 
54 /**
55  * @brief The first argument must be a minimal type object
56  */
58  const TypeIdentifier& tb) const
59 {
60  if (EK_MINIMAL == ta.kind) {
61  if (TK_ALIAS == ta.minimal.kind) {
62  return assignable(get_base_type(ta.minimal), tb);
63  }
64 
65  switch (ta.minimal.kind) {
66  case TK_ANNOTATION:
67  return assignable_annotation(ta.minimal, tb);
68  case TK_STRUCTURE:
69  return assignable_struct(ta.minimal, tb);
70  case TK_UNION:
71  return assignable_union(ta.minimal, tb);
72  case TK_BITSET:
73  return assignable_bitset(ta.minimal, tb);
74  case TK_SEQUENCE:
75  return assignable_sequence(ta.minimal, tb);
76  case TK_ARRAY:
77  return assignable_array(ta.minimal, tb);
78  case TK_MAP:
79  return assignable_map(ta.minimal, tb);
80  case TK_ENUM:
81  return assignable_enum(ta.minimal, tb);
82  case TK_BITMASK:
83  return assignable_bitmask(ta.minimal, tb);
84  default:
85  return false;
86  }
87  }
88 
89  return false;
90 }
91 
92 /**
93  * @brief Both input can be of any type
94  */
96  const TypeIdentifier& tb) const
97 {
98  if (ta == tb) {
99  return true;
100  }
101 
102  switch (ta.kind()) {
103  case TK_BOOLEAN:
104  case TK_BYTE:
105  case TK_INT16:
106  case TK_INT32:
107  case TK_INT64:
108  case TK_UINT16:
109  case TK_UINT32:
110  case TK_UINT64:
111  case TK_FLOAT32:
112  case TK_FLOAT64:
113  case TK_FLOAT128:
114  case TK_INT8:
115  case TK_UINT8:
116  case TK_CHAR8:
117  case TK_CHAR16:
118  return assignable_primitive(ta, tb);
119  case TI_STRING8_SMALL:
120  case TI_STRING8_LARGE:
121  case TI_STRING16_SMALL:
122  case TI_STRING16_LARGE:
123  return assignable_string(ta, tb);
126  return assignable_plain_sequence(ta, tb);
129  return assignable_plain_array(ta, tb);
130  case TI_PLAIN_MAP_SMALL:
131  case TI_PLAIN_MAP_LARGE:
132  return assignable_plain_map(ta, tb);
134  // No rule in the spec for strongly connected components
135  return false;
136  case EK_COMPLETE:
137  // Assuming only equivalence kind of EK_MINIMAL is supported
138  return false;
139  case EK_MINIMAL: {
140  const MinimalTypeObject& base_type_a = lookup_minimal(ta);
141  return assignable(TypeObject(base_type_a), tb);
142  }
143  default:
144  return false; // Future extensions
145  }
146 }
147 
148 /**
149  * @brief The second argument must be a minimal type object
150  */
152  const TypeObject& tb) const
153 {
154  if (EK_MINIMAL == tb.kind) {
155  if (TK_ALIAS == tb.minimal.kind) {
156  return assignable(ta, get_base_type(tb.minimal));
157  }
158 
159  switch (ta.kind()) {
160  case TK_BOOLEAN:
161  case TK_BYTE:
162  case TK_INT16:
163  case TK_INT32:
164  case TK_INT64:
165  case TK_UINT16:
166  case TK_UINT32:
167  case TK_UINT64:
168  case TK_FLOAT32:
169  case TK_FLOAT64:
170  case TK_FLOAT128:
171  case TK_INT8:
172  case TK_UINT8:
173  case TK_CHAR8:
174  case TK_CHAR16:
175  return assignable_primitive(ta, tb.minimal);
176  case TI_STRING8_SMALL:
177  case TI_STRING8_LARGE:
178  case TI_STRING16_SMALL:
179  case TI_STRING16_LARGE:
180  return assignable_string(ta, tb.minimal);
183  return assignable_plain_sequence(ta, tb.minimal);
186  return assignable_plain_array(ta, tb.minimal);
187  case TI_PLAIN_MAP_SMALL:
188  case TI_PLAIN_MAP_LARGE:
189  return assignable_plain_map(ta, tb.minimal);
191  return false;
192  case EK_COMPLETE:
193  return false;
194  case EK_MINIMAL: {
195  const MinimalTypeObject& tobj_a = lookup_minimal(ta);
196  return assignable(TypeObject(tobj_a), tb);
197  }
198  default:
199  return false;
200  }
201  }
202 
203  return false;
204 }
205 
206 /**
207  * @brief At least one input type object must be TK_ALIAS
208  */
210  const MinimalTypeObject& tb) const
211 {
212  if (TK_ALIAS == ta.kind && TK_ALIAS != tb.kind) {
214  switch (tia.kind()) {
215  case TK_BOOLEAN:
216  case TK_BYTE:
217  case TK_INT16:
218  case TK_INT32:
219  case TK_INT64:
220  case TK_UINT16:
221  case TK_UINT32:
222  case TK_UINT64:
223  case TK_FLOAT32:
224  case TK_FLOAT64:
225  case TK_FLOAT128:
226  case TK_INT8:
227  case TK_UINT8:
228  case TK_CHAR8:
229  case TK_CHAR16:
230  return assignable_primitive(tia, tb);
231  case TI_STRING8_SMALL:
232  case TI_STRING8_LARGE:
233  case TI_STRING16_SMALL:
234  case TI_STRING16_LARGE:
235  return assignable_string(tia, tb);
238  return assignable_plain_sequence(tia, tb);
241  return assignable_plain_array(tia, tb);
242  case TI_PLAIN_MAP_SMALL:
243  case TI_PLAIN_MAP_LARGE:
244  return assignable_plain_map(tia, tb);
246  // Does alias ever have SCC as its base type?
247  return false;
248  case EK_COMPLETE:
249  // Supporting minimal base type only
250  return false;
251  case EK_MINIMAL: {
252  const MinimalTypeObject& base_type_a = lookup_minimal(tia);
253  return assignable(TypeObject(base_type_a), TypeObject(tb));
254  }
255  default:
256  return false; // Future extensions
257  }
258  } else if (TK_ALIAS != ta.kind && TK_ALIAS == tb.kind) {
260  switch (ta.kind) {
261  case TK_ANNOTATION:
262  return assignable_annotation(ta, tib);
263  case TK_STRUCTURE:
264  return assignable_struct(ta, tib);
265  case TK_UNION:
266  return assignable_union(ta, tib);
267  case TK_BITSET:
268  return assignable_bitset(ta, tib);
269  case TK_SEQUENCE:
270  return assignable_sequence(ta, tib);
271  case TK_ARRAY:
272  return assignable_array(ta, tib);
273  case TK_MAP:
274  return assignable_map(ta, tib);
275  case TK_ENUM:
276  return assignable_enum(ta, tib);
277  case TK_BITMASK:
278  return assignable_bitmask(ta, tib);
279  default:
280  return false; // Future extensions
281  }
282  } else if (TK_ALIAS == ta.kind && TK_ALIAS == tb.kind) {
285  return assignable(tia, tib);
286  }
287 
288  return false;
289 }
290 
291 /**
292  * @brief The first type must be TK_ANNOTATION.
293  * The second type must not be TK_ALIAS.
294  */
296  const MinimalTypeObject&) const
297 {
298  // No rule for annotation in the spec
299  return false;
300 }
301 
302 /**
303  * @brief The first type must be TK_ANNOTATION.
304  * The second type can be anything.
305  */
307  const TypeIdentifier&) const
308 {
309  // No rule for annotation in the spec
310  return false;
311 }
312 
313 /**
314  * @brief The first type must be TK_STRUCTURE.
315  * The second type must not be TK_ALIAS.
316  */
318  const MinimalTypeObject& tb) const
319 {
320  if (TK_STRUCTURE != tb.kind) {
321  return false;
322  }
323 
324  // Extensibility kind must match
325  const TypeFlag extensibility_mask = IS_FINAL | IS_APPENDABLE | IS_MUTABLE;
326  const ACE_CDR::UShort a_exten = ta.struct_type.struct_flags & extensibility_mask;
327  if (a_exten != (tb.struct_type.struct_flags & extensibility_mask)) {
328  return false;
329  }
330 
331  // If T1 is appendable, then members with the same member_index have the
332  // same member ID, the same setting for the 'optional' attribute and the
333  // T1 member type is strongly assignable from the T2 member type.
334  // If T1 is final, then they meet the same condition as for T1 being
335  // appendable and in addition T1 and T2 have the same set of member IDs.
336  if (IS_FINAL == a_exten &&
338  return false;
339  }
340  if (IS_APPENDABLE == a_exten || IS_FINAL == a_exten) {
341  const unsigned num_members = (std::min)(ta.struct_type.member_seq.length(),
343  for (unsigned i = 0; i < num_members; ++i) {
344  if (ta.struct_type.member_seq[i].common.member_id !=
345  tb.struct_type.member_seq[i].common.member_id ||
346  (ta.struct_type.member_seq[i].common.member_flags & IS_OPTIONAL) !=
347  (tb.struct_type.member_seq[i].common.member_flags & IS_OPTIONAL) ||
348  !strongly_assignable(ta.struct_type.member_seq[i].common.member_type_id,
349  tb.struct_type.member_seq[i].common.member_type_id)) {
350  return false;
351  }
352  }
353  }
354 
355  // Any members in T1 and T2 that have the same name also have
356  // the same ID, and vice versa
357  MatchedSet matched_members;
358  for (unsigned i = 0; i < ta.struct_type.member_seq.length(); ++i) {
359  MemberId id_a = ta.struct_type.member_seq[i].common.member_id;
360  const NameHash& h_a = ta.struct_type.member_seq[i].detail.name_hash;
361  ACE_CDR::ULong name_a = (h_a[0] << 24) | (h_a[1] << 16) | (h_a[2] << 8) | (h_a[3]);
362  for (unsigned j = 0; j < tb.struct_type.member_seq.length(); ++j) {
363  MemberId id_b = tb.struct_type.member_seq[j].common.member_id;
364  const NameHash& h_b = tb.struct_type.member_seq[j].detail.name_hash;
365  ACE_CDR::ULong name_b = (h_b[0] << 24) | (h_b[1] << 16) | (h_b[2] << 8) | (h_b[3]);
366 
368  if ((name_a == name_b && id_a != id_b) || (id_a == id_b && name_a != name_b)) {
369  return false;
370  } else if (name_a == name_b && id_a == id_b) {
371  matched_members.push_back(std::make_pair(&ta.struct_type.member_seq[i],
372  &tb.struct_type.member_seq[j]));
373  break;
374  }
375  } else if (id_a == id_b) {
376  matched_members.push_back(std::make_pair(&ta.struct_type.member_seq[i],
377  &tb.struct_type.member_seq[j]));
378  break;
379  }
380  }
381  }
382 
383  // There is at least one member m1 of T1 and one corresponding member
384  // m2 of T2 such that m1.id == m2.id
385  if (matched_members.size() == 0) {
386  return false;
387  }
388 
389  // For any member m2 of T2, if there is a member m1 of T1 with the same
390  // ID, then the type KeyErased(m1.type) is-assignable-from the type
391  // KeyErased(m2.type).
392  // For any non-aggregated type T, we consider that KeyErased(T) = T
393  // (whereas the spec only defines KeyErased for aggregated types).
394  // Consequently, this rule applies to any pair of members m2 of T2 and
395  // m1 of T1 with the same ID.
396  for (size_t i = 0; i < matched_members.size(); ++i) {
397  const CommonStructMember& member = matched_members[i].second->common;
398  const MinimalTypeObject* toa = 0;
399  const MinimalTypeObject* tob = 0;
400  bool aggregated_type_matched = false;
401  if (get_struct_member(tob, member)) {
402  if (!get_struct_member(toa, matched_members[i].first->common)) {
403  return false;
404  }
405  aggregated_type_matched = true;
406  } else if (get_union_member(tob, member)) {
407  if (!get_union_member(toa, matched_members[i].first->common)) {
408  return false;
409  }
410  aggregated_type_matched = true;
411  }
412 
413  if (aggregated_type_matched) {
414  MinimalTypeObject key_erased_a = *toa, key_erased_b = *tob;
415  erase_key(key_erased_a);
416  erase_key(key_erased_b);
417  if (!assignable(TypeObject(key_erased_a), TypeObject(key_erased_b))) {
418  return false;
419  }
420  } else if (!assignable(matched_members[i].first->common.member_type_id,
421  matched_members[i].second->common.member_type_id)) {
422  return false;
423  }
424  }
425 
426  // Members for which both optional is false and must_understand is true in
427  // either T1 or T2 appear in both T1 and T2.
428  // Members marked as key in either T1 or T2 appear in both T1 and T2.
429  for (unsigned i = 0; i < ta.struct_type.member_seq.length(); ++i) {
430  const MemberFlag& flags = ta.struct_type.member_seq[i].common.member_flags;
431  MemberId id = ta.struct_type.member_seq[i].common.member_id;
432  bool found = false;
433  if ((flags & (IS_OPTIONAL | IS_MUST_UNDERSTAND)) == IS_MUST_UNDERSTAND) {
434  for (size_t j = 0; j < matched_members.size(); ++j) {
435  if (id == matched_members[j].first->common.member_id) {
436  found = true;
437  break;
438  }
439  }
440  if (!found) {
441  return false;
442  }
443  }
444 
445  found = false;
446  if ((flags & IS_KEY) == IS_KEY) {
447  for (size_t j = 0; j < matched_members.size(); ++j) {
448  if (id == matched_members[j].first->common.member_id) {
449  found = true;
450  break;
451  }
452  }
453  if (!found) {
454  return false;
455  }
456  }
457  }
458 
459  for (unsigned i = 0; i < tb.struct_type.member_seq.length(); ++i) {
460  const MemberFlag& flags = tb.struct_type.member_seq[i].common.member_flags;
461  MemberId id = tb.struct_type.member_seq[i].common.member_id;
462  bool found = false;
463  if ((flags & (IS_OPTIONAL | IS_MUST_UNDERSTAND)) == IS_MUST_UNDERSTAND) {
464  for (size_t j = 0; j < matched_members.size(); ++j) {
465  if (id == matched_members[j].second->common.member_id) {
466  found = true;
467  break;
468  }
469  }
470  if (!found) {
471  return false;
472  }
473  }
474 
475  found = false;
476  if ((flags & IS_KEY) == IS_KEY) {
477  for (size_t j = 0; j < matched_members.size(); ++j) {
478  if (id == matched_members[j].second->common.member_id) {
479  found = true;
480  break;
481  }
482  }
483  if (!found) {
484  return false;
485  }
486  }
487  }
488 
489  // For any string key member m2 in T2, the m1 member of T1 with the
490  // same member ID verifies m1.type.length >= m2.type.length
491  for (size_t i = 0; i < matched_members.size(); ++i) {
492  const CommonStructMember& member = matched_members[i].second->common;
493  MemberFlag flags = member.member_flags;
494  LBound bound_a, bound_b;
495  if ((flags & IS_KEY) == IS_KEY && get_string_bound(bound_b, member)) {
496  if (!get_string_bound(bound_a, matched_members[i].first->common)) {
497  return false;
498  }
499  if (bound_a < bound_b) {
500  return false;
501  }
502  }
503  }
504 
505  // For any enumerated key member m2 in T2, the m1 member of T1 with
506  // the same member ID verifies that all literals in m2.type appear as
507  // literals in m1.type
508  for (size_t i = 0; i < matched_members.size(); ++i) {
509  const CommonStructMember& member = matched_members[i].second->common;
510  MemberFlag flags = member.member_flags;
511  if ((flags & IS_KEY) == IS_KEY &&
512  EK_MINIMAL == member.member_type_id.kind()) {
513  const MinimalTypeObject& tob = lookup_minimal(member.member_type_id);
514  if (TK_ENUM == tob.kind) {
515  if (!struct_rule_enum_key(tob, matched_members[i].first->common)) {
516  return false;
517  }
518  } else if (TK_ALIAS == tob.kind) {
519  const TypeIdentifier& base_b = get_base_type(tob);
520  if (EK_MINIMAL == base_b.kind()) {
521  const MinimalTypeObject& base_obj_b = lookup_minimal(base_b);
522  if (TK_ENUM == base_obj_b.kind &&
523  !struct_rule_enum_key(base_obj_b, matched_members[i].first->common)) {
524  return false;
525  }
526  }
527  }
528  }
529  }
530 
531  // For any sequence or map key member m2 in T2, the m1 member of T1
532  // with the same member ID verifies m1.type.length >= m2.type.length
533  for (size_t i = 0; i < matched_members.size(); ++i) {
534  const CommonStructMember& member = matched_members[i].second->common;
535  MemberFlag flags = member.member_flags;
536  LBound bound_a, bound_b;
537  if ((flags & IS_KEY) == IS_KEY) {
538  if (get_sequence_bound(bound_b, member)) {
539  if (!get_sequence_bound(bound_a, matched_members[i].first->common)) {
540  return false;
541  }
542  if (bound_a < bound_b) {
543  return false;
544  }
545  } else if (get_map_bound(bound_b, member)) {
546  if (!get_map_bound(bound_a, matched_members[i].first->common)) {
547  return false;
548  }
549  if (bound_a < bound_b) {
550  return false;
551  }
552  }
553  }
554  }
555 
556  // For any structure or union key member m2 in T2, the m1 member
557  // of T1 with the same member ID verifies that KeyHolder(m1.type)
558  // is-assignable-from KeyHolder(m2.type)
559  for (size_t i = 0; i < matched_members.size(); ++i) {
560  const CommonStructMember& member = matched_members[i].second->common;
561  MemberFlag flags = member.member_flags;
562  if ((flags & IS_KEY) == IS_KEY) {
563  const MinimalTypeObject* toa = 0;
564  const MinimalTypeObject* tob = 0;
565  bool type_matched = false;
566  if (get_struct_member(tob, member)) {
567  if (!get_struct_member(toa, matched_members[i].first->common)) {
568  return false;
569  }
570  type_matched = true;
571  } else if (get_union_member(tob, member)) {
572  if (!get_union_member(toa, matched_members[i].first->common)) {
573  return false;
574  }
575  type_matched = true;
576  }
577 
578  if (type_matched) {
579  MinimalTypeObject key_holder_a = *toa, key_holder_b = *tob;
580  hold_key(key_holder_a);
581  hold_key(key_holder_b);
582  if (!assignable(TypeObject(key_holder_a), TypeObject(key_holder_b))) {
583  return false;
584  }
585 
586  // For any union key member m2 in T2, the m1 member of T1 with the
587  // same ID verifies that: for every discriminator value of m2.type
588  // that selects a member m22 in m2.type, the discriminator value
589  // selects a member m11 in m1.type that verifies KeyHolder(m11.type)
590  // is-assignable-from KeyHolder(m22.type)
591  if (TK_UNION == tob->kind) {
592  const MinimalUnionMemberSeq& mseq_a = toa->union_type.member_seq;
593  const MinimalUnionMemberSeq& mseq_b = tob->union_type.member_seq;
594  for (unsigned j = 0; j < mseq_b.length(); ++j) {
595  const UnionCaseLabelSeq& labels_b = mseq_b[j].common.label_seq;
596  for (unsigned k = 0; k < mseq_a.length(); ++k) {
597  const UnionCaseLabelSeq& labels_a = mseq_a[k].common.label_seq;
598  bool matched = false;
599  for (unsigned p = 0; p < labels_b.length(); ++p) {
600  for (unsigned q = 0; q < labels_a.length(); ++q) {
601  if (labels_b[p] == labels_a[q]) {
602  const TypeIdentifier& tib = mseq_b[j].common.type_id;
603  const TypeIdentifier& tia = mseq_a[k].common.type_id;
604  MinimalTypeObject kh_a, kh_b;
605  bool ret_b = hold_key(tib, kh_b);
606  bool ret_a = hold_key(tia, kh_a);
607  if ((ret_a && ret_b && !assignable(TypeObject(kh_a), TypeObject(kh_b))) ||
608  (ret_a && !ret_b && !assignable(TypeObject(kh_a), tib)) ||
609  (!ret_a && ret_b && !assignable(tia, TypeObject(kh_b))) ||
610  (!ret_a && !ret_b && !assignable(tia, tib))) {
611  return false;
612  }
613  matched = true;
614  break;
615  }
616  } // labels_a
617  if (matched) break;
618  } // labels_b
619  } // mseq_a
620  } // mseq_b
621  }
622  }
623  } // IS_KEY
624  }
625 
626  return true;
627 }
628 
629 /**
630  * @brief The first type must be TK_STRUCTURE.
631  * The second type can be anything.
632  */
634  const TypeIdentifier& tb) const
635 {
636  if (EK_MINIMAL == tb.kind()) {
637  const MinimalTypeObject& tob = lookup_minimal(tb);
638  if (TK_STRUCTURE == tob.kind) {
639  return assignable_struct(ta, tob);
640  } else if (TK_ALIAS == tob.kind) {
642  return assignable_struct(ta, base);
643  }
644  } else if (EK_COMPLETE == tb.kind()) {
645  // Assuming tb.kind of EK_COMPLETE is not supported
646  return false;
647  }
648 
649  return false;
650 }
651 
652 /**
653  * @brief The first type must be TK_UNION.
654  * The second type must not be TK_ALIAS.
655  */
657  const MinimalTypeObject& tb) const
658 {
659  if (TK_UNION != tb.kind) {
660  return false;
661  }
662 
663  // Extensibility kind must match
664  const TypeFlag extensibility_mask = IS_FINAL | IS_APPENDABLE | IS_MUTABLE;
665  if ((ta.union_type.union_flags & extensibility_mask) !=
666  (tb.union_type.union_flags & extensibility_mask)) {
667  return false;
668  }
669 
670  OPENDDS_SET(ACE_CDR::Long) labels_set_a;
671  for (unsigned i = 0; i < ta.union_type.member_seq.length(); ++i) {
672  const UnionCaseLabelSeq& labels_a = ta.union_type.member_seq[i].common.label_seq;
673  labels_set_a.insert(labels_a.members.begin(), labels_a.members.end());
674  }
675 
676  // If extensibility is final, then the set of labels must be identical.
677  // Assuming labels are mapped to values identically in both input types.
678  if ((ta.union_type.union_flags & extensibility_mask) == IS_FINAL) {
679  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
680  const UnionCaseLabelSeq& labels_b = tb.union_type.member_seq[i].common.label_seq;
681  for (unsigned j = 0; j < labels_b.length(); ++j) {
682  if (labels_set_a.find(labels_b.members[j]) == labels_set_a.end()) {
683  return false;
684  }
685  labels_set_a.erase(labels_b.members[j]);
686  }
687  }
688  if (labels_set_a.size() > 0) {
689  return false;
690  }
691  } else { // Must have at least one common label other than the default
692  // This implementation assumes that the default member has IS_DEFAULT
693  // flag turned on, but the label "default" does not map into a numeric
694  // value for storing on the member's UnionCaseLabelSeq. Instead, only
695  // the other labels, if any, for this default members will have their
696  // numeric values stored in its UnionCaseLabelSeq.
697  bool found = false;
698  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
699  const UnionCaseLabelSeq& labels_b = tb.union_type.member_seq[i].common.label_seq;
700  for (unsigned j = 0; j < labels_b.length(); ++j) {
701  if (labels_set_a.find(labels_b[j]) != labels_set_a.end()) {
702  found = true;
703  break;
704  }
705  }
706  if (found) break;
707  }
708  if (!found) {
709  return false;
710  }
711  }
712 
713  // Discriminator type must be one of these: (i) non-float primitive types,
714  // or (ii) enumerated types, or (iii) an alias type that resolves to
715  // one of the above two type kinds
718  if (!strongly_assignable(tia, tib)) {
719  return false;
720  }
721 
722  // Both discriminators are keys or neither are keys
725  if ((((flags_a & IS_KEY) == IS_KEY) && ((flags_b & IS_KEY) != IS_KEY)) ||
726  (((flags_a & IS_KEY) != IS_KEY) && ((flags_b & IS_KEY) == IS_KEY))) {
727  return false;
728  }
729 
730  // Members with the same ID must have the same name, and vice versa
732  OPENDDS_MAP(MemberId, ACE_CDR::ULong) id_to_name_a;
733  OPENDDS_MAP(ACE_CDR::ULong, MemberId) name_to_id_a;
734  for (unsigned i = 0; i < ta.union_type.member_seq.length(); ++i) {
735  MemberId id = ta.union_type.member_seq[i].common.member_id;
736  const NameHash& h = ta.union_type.member_seq[i].detail.name_hash;
737  ACE_CDR::ULong name = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
738  id_to_name_a[id] = name;
739  name_to_id_a[name] = id;
740  }
741 
742  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
743  MemberId id = tb.union_type.member_seq[i].common.member_id;
744  const NameHash& h = tb.union_type.member_seq[i].detail.name_hash;
745  ACE_CDR::ULong name = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
746  if (id_to_name_a.find(id) != id_to_name_a.end() &&
747  id_to_name_a[id] != name) {
748  return false;
749  }
750 
751  if (name_to_id_a.find(name) != name_to_id_a.end() &&
752  name_to_id_a[name] != id) {
753  return false;
754  }
755  }
756  }
757 
758  // For all non-default labels in T2 that select some member in T1,
759  // the type of the selected member in T1 is assignable from the
760  // type of the T2 member
761  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
762  const UnionCaseLabelSeq& label_seq_b = tb.union_type.member_seq[i].common.label_seq;
763  for (unsigned j = 0; j < ta.union_type.member_seq.length(); ++j) {
764  // Consider a case when tb has multiple labels for a member, e.g.,
765  // "LABEL1" and "LABEL2" are associated with a member of type MemberB,
766  // and ta has two members, one has label "LABEL1" and
767  // type MemberA1, and the other has label "LABEL2" and
768  // type MemberA2. There are two possible ways to check assignability:
769  // (i) check whether BOTH MemberA1 and MemberA2 are assignable from
770  // MemberB since labels for MemberB match the labels of both MemberA1
771  // and MemberA2 (i.e., all must be assignable), or (ii) check EITHER
772  // MemberA1 OR MemberA2 is assignable from MemberB (i.e., one member
773  // of ta that is assignable is sufficient). The spec does not clearly
774  // say which way we should do it. For now we are going with method (i).
775  const UnionCaseLabelSeq& label_seq_a = ta.union_type.member_seq[j].common.label_seq;
776  bool matched = false;
777  for (unsigned k = 0; k < label_seq_b.length(); ++k) {
778  for (unsigned t = 0; t < label_seq_a.length(); ++t) {
779  if (label_seq_b.members[k] == label_seq_a.members[t]) {
780  const TypeIdentifier& tia = ta.union_type.member_seq[j].common.type_id;
781  const TypeIdentifier& tib = tb.union_type.member_seq[i].common.type_id;
782  if (!assignable(tia, tib)) {
783  return false;
784  }
785  matched = true;
786  break;
787  }
788  }
789  if (matched) break;
790  }
791  }
792  }
793 
794  // If any non-default labels of T1 that select the default member of T2,
795  // the type of the member in T1 is assignable from the type of the default
796  // member in T2
797  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
798  const UnionMemberFlag& flags_b = tb.union_type.member_seq[i].common.member_flags;
799  if ((flags_b & IS_DEFAULT) == IS_DEFAULT) {
800  const UnionCaseLabelSeq& label_seq_b = tb.union_type.member_seq[i].common.label_seq;
801  for (unsigned j = 0; j < ta.union_type.member_seq.length(); ++j) {
802  const UnionCaseLabelSeq& label_seq_a = ta.union_type.member_seq[j].common.label_seq;
803  bool matched = false;
804  for (unsigned k = 0; k < label_seq_a.length(); ++k) {
805  for (unsigned t = 0; t < label_seq_b.length(); ++t) {
806  if (label_seq_a[k] == label_seq_b[t]) {
807  const TypeIdentifier& tia = ta.union_type.member_seq[j].common.type_id;
808  const TypeIdentifier& tib = tb.union_type.member_seq[i].common.type_id;
809  if (!assignable(tia, tib)) {
810  return false;
811  }
812  matched = true;
813  break;
814  }
815  }
816  if (matched) break;
817  }
818  }
819  break;
820  }
821  }
822 
823  // If T1 and T2 both have default labels, the type of T1's default member
824  // is assignable from the type of T2's default member
825  for (unsigned i = 0; i < ta.union_type.member_seq.length(); ++i) {
826  const UnionMemberFlag& flags_a = ta.union_type.member_seq[i].common.member_flags;
827  if ((flags_a & IS_DEFAULT) == IS_DEFAULT) {
828  for (unsigned j = 0; j < tb.union_type.member_seq.length(); ++j) {
829  const UnionMemberFlag& flags_b = tb.union_type.member_seq[j].common.member_flags;
830  if ((flags_b & IS_DEFAULT) == IS_DEFAULT) {
831  const TypeIdentifier& tia = ta.union_type.member_seq[i].common.type_id;
832  const TypeIdentifier& tib = tb.union_type.member_seq[j].common.type_id;
833  if (!assignable(tia, tib)) {
834  return false;
835  }
836  break;
837  }
838  }
839  break;
840  }
841  }
842 
843  return true;
844 }
845 
846 /**
847  * @brief The first type must be TK_UNION.
848  * The second type can be anything.
849  */
851  const TypeIdentifier& tb) const
852 {
853  if (EK_MINIMAL == tb.kind()) {
854  const MinimalTypeObject& tob = lookup_minimal(tb);
855  if (TK_UNION == tob.kind) {
856  return assignable_union(ta, tob);
857  } else if (TK_ALIAS == tob.kind) {
859  return assignable_union(ta, base);
860  }
861  } else if (EK_COMPLETE == tb.kind()) {
862  // Assuming tb.kind of EK_COMPLETE is not supported
863  return false;
864  }
865 
866  return false;
867 }
868 
869 /**
870  * @brief The first type must be TK_BITSET.
871  * The second type must not be TK_ALIAS.
872  */
874  const MinimalTypeObject&) const
875 {
876  // No rule for bitset in the spec
877  return false;
878 }
879 
880 /**
881  * @brief The first type must be TK_BITSET.
882  * The second type can be anything.
883  */
885  const TypeIdentifier&) const
886 {
887  // No rule for bitset in the spec
888  return false;
889 }
890 
891 /**
892  * @brief The first type must be TK_SEQUENCE.
893  * The second type must not be TK_ALIAS.
894  */
896  const MinimalTypeObject& tb) const
897 {
898  if (TK_SEQUENCE != tb.kind) {
899  return false;
900  }
903 }
904 
905 /**
906  * @brief The first type must be TK_SEQUENCE.
907  * The second type can be anything.
908  */
910  const TypeIdentifier& tb) const
911 {
912  if (TI_PLAIN_SEQUENCE_SMALL == tb.kind()) {
914  *tb.seq_sdefn().element_identifier);
915  } else if (TI_PLAIN_SEQUENCE_LARGE == tb.kind()) {
917  *tb.seq_ldefn().element_identifier);
918  } else if (EK_MINIMAL == tb.kind()) {
919  const MinimalTypeObject& tob = lookup_minimal(tb);
920  if (TK_SEQUENCE == tob.kind) {
921  return assignable_sequence(ta, tob);
922  } else if (TK_ALIAS == tob.kind) {
924  return assignable_sequence(ta, base);
925  }
926  } else if (EK_COMPLETE == tb.kind()) {
927  // Assuming tb.kind of EK_COMPLETE is not supported
928  return false;
929  }
930 
931  return false;
932 }
933 
934 /**
935  * @brief The first type must be TK_ARRAY.
936  * The second type must not be TK_ALIAS.
937  */
939  const MinimalTypeObject& tb) const
940 {
941  if (TK_ARRAY != tb.kind) {
942  return false;
943  }
944 
945  // Bounds must match
946  const LBoundSeq& bounds_a = ta.array_type.header.common.bound_seq;
947  const LBoundSeq& bounds_b = tb.array_type.header.common.bound_seq;
948  if (bounds_a.members.size() != bounds_b.members.size()) {
949  return false;
950  }
951 
952  for (unsigned i = 0; i < bounds_a.members.size(); ++i) {
953  if (bounds_a.members[i] != bounds_b.members[i]) {
954  return false;
955  }
956  }
959 }
960 
961 /**
962  * @brief The first type must be TK_ARRAY.
963  * The second type can be anything.
964  */
966  const TypeIdentifier& tb) const
967 {
968  const LBoundSeq& bounds_a = ta.array_type.header.common.bound_seq;
969  if (TI_PLAIN_ARRAY_SMALL == tb.kind()) {
970  const SBoundSeq& bounds_b = tb.array_sdefn().array_bound_seq;
971  if (bounds_a.members.size() != bounds_b.members.size()) {
972  return false;
973  }
974 
975  for (unsigned i = 0; i < bounds_a.members.size(); ++i) {
976  if (bounds_a.members[i] != static_cast<LBound>(bounds_b.members[i])) {
977  return false;
978  }
979  }
980 
982  *tb.array_sdefn().element_identifier);
983  } else if (TI_PLAIN_ARRAY_LARGE == tb.kind()) {
984  const LBoundSeq& bounds_b = tb.array_ldefn().array_bound_seq;
985  if (bounds_a.members.size() != bounds_b.members.size()) {
986  return false;
987  }
988 
989  for (unsigned i = 0; i < bounds_a.members.size(); ++i) {
990  if (bounds_a.members[i] != bounds_b.members[i]) {
991  return false;
992  }
993  }
995  *tb.array_ldefn().element_identifier);
996  } else if (EK_MINIMAL == tb.kind()) {
997  const MinimalTypeObject& tob = lookup_minimal(tb);
998  if (TK_ARRAY == tob.kind) {
999  return assignable_array(ta, tob);
1000  } else if (TK_ALIAS == tob.kind) {
1001  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1002  return assignable_array(ta, base);
1003  }
1004  } else if (EK_COMPLETE == tb.kind()) {
1005  // Assuming tb.kind of EK_COMPLETE is not supported
1006  return false;
1007  }
1008 
1009  return false;
1010 }
1011 
1012 /**
1013  * @brief The first type must be TK_MAP.
1014  * The second type must not be TK_ALIAS.
1015  */
1017  const MinimalTypeObject& tb) const
1018 {
1019  if (TK_MAP != tb.kind) {
1020  return false;
1021  }
1023  tb.map_type.key.common.type) &&
1026 }
1027 
1028 /**
1029  * @brief The first type must be TK_MAP.
1030  * The second type can be anything.
1031  */
1033  const TypeIdentifier& tb) const
1034 {
1035  if (TI_PLAIN_MAP_SMALL == tb.kind()) {
1037  *tb.map_sdefn().key_identifier) &&
1039  *tb.map_sdefn().element_identifier);
1040  } else if (TI_PLAIN_MAP_LARGE == tb.kind()) {
1042  *tb.map_ldefn().key_identifier) &&
1044  *tb.map_ldefn().element_identifier);
1045  } else if (EK_MINIMAL == tb.kind()) {
1046  const MinimalTypeObject& tob = lookup_minimal(tb);
1047  if (TK_MAP == tob.kind) {
1048  return assignable_map(ta, tob);
1049  } else if (TK_ALIAS == tob.kind) {
1050  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1051  return assignable_map(ta, base);
1052  }
1053  } else if (EK_COMPLETE == tb.kind()) {
1054  // Assuming tb.kind of EK_COMPLETE is not supported
1055  return false;
1056  }
1057 
1058  return false;
1059 }
1060 
1061 /**
1062  * @brief The first type must be TK_ENUM.
1063  * The second type must not be TK_ALIAS.
1064  */
1066  const MinimalTypeObject& tb) const
1067 {
1068  if (TK_ENUM != tb.kind) {
1069  return false;
1070  }
1071 
1072  // Assuming that EnumTypeFlag is used and contains extensibility
1073  // of the containing type.
1074  const TypeFlag extensibility_mask = IS_FINAL | IS_APPENDABLE | IS_MUTABLE;
1075  TypeFlag ta_ext = ta.enumerated_type.enum_flags & extensibility_mask;
1076  TypeFlag tb_ext = tb.enumerated_type.enum_flags & extensibility_mask;
1077  if (ta_ext != tb_ext &&
1078  // Backwards compatibility.
1079  ta_ext != 0 && tb_ext != 0) {
1080  return false;
1081  }
1082 
1083  // T1.bit_bound and T2.bit_bound must be equal (DDSXTY14-34)
1086  return false;
1087  }
1088 
1089  const size_t size_a = ta.enumerated_type.literal_seq.members.size();
1090  const size_t size_b = tb.enumerated_type.literal_seq.members.size();
1091  OPENDDS_MAP(ACE_CDR::ULong, ACE_CDR::Long) ta_name_to_value;
1092  for (size_t i = 0; i < size_a; ++i) {
1093  const NameHash& h = ta.enumerated_type.literal_seq.members[i].detail.name_hash;
1094  ACE_CDR::ULong key_a = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1095  ta_name_to_value[key_a] = ta.enumerated_type.literal_seq.members[i].common.value;
1096  }
1097 
1098  // If extensibility is FINAL, both must have the same literals.
1099  if (IS_FINAL == ta_ext) {
1100  if (size_a != size_b) {
1101  return false;
1102  }
1103 
1104  for (size_t i = 0; i < size_b; ++i) {
1105  const NameHash& h = tb.enumerated_type.literal_seq.members[i].detail.name_hash;
1106  ACE_CDR::ULong key_b = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1107 
1108  // Literals that have the same name must have the same value.
1109  if (ta_name_to_value.find(key_b) == ta_name_to_value.end() ||
1110  ta_name_to_value[key_b] != tb.enumerated_type.literal_seq.members[i].common.value) {
1111  return false;
1112  }
1113  }
1114  } else {
1115  // Any literals that have the same name also have the same value
1116  for (size_t i = 0; i < size_b; ++i) {
1117  const NameHash& h = tb.enumerated_type.literal_seq.members[i].detail.name_hash;
1118  ACE_CDR::ULong key_b = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1119  if (ta_name_to_value.find(key_b) != ta_name_to_value.end() &&
1120  ta_name_to_value[key_b] != tb.enumerated_type.literal_seq.members[i].common.value) {
1121  return false;
1122  }
1123  }
1124 
1125  OPENDDS_MAP(ACE_CDR::ULong, ACE_CDR::ULong) ta_value_to_name;
1126  for (size_t i = 0; i < size_a; ++i) {
1127  ACE_CDR::ULong value_a = ta.enumerated_type.literal_seq.members[i].common.value;
1128  const NameHash& h = ta.enumerated_type.literal_seq.members[i].detail.name_hash;
1129  ACE_CDR::ULong name_a = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1130  ta_value_to_name[value_a] = name_a;
1131  }
1132 
1133  // Any literals that have the same value also have the same name
1134  for (size_t i = 0; i < size_b; ++i) {
1135  ACE_CDR::ULong value_b = tb.enumerated_type.literal_seq.members[i].common.value;
1136  const NameHash& h = tb.enumerated_type.literal_seq.members[i].detail.name_hash;
1137  ACE_CDR::ULong name_b = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1138  if (ta_value_to_name.find(value_b) != ta_value_to_name.end() &&
1139  ta_value_to_name[value_b] != name_b) {
1140  return false;
1141  }
1142  }
1143  }
1144 
1145  return true;
1146 }
1147 
1148 /**
1149  * @brief The first type must be TK_ENUM.
1150  * The second type can be anything.
1151  */
1153  const TypeIdentifier& tb) const
1154 {
1155  if (EK_MINIMAL == tb.kind()) {
1156  const MinimalTypeObject& tob = lookup_minimal(tb);
1157  if (TK_ENUM == tob.kind) {
1158  return assignable_enum(ta, tob);
1159  } else if (TK_ALIAS == tob.kind) {
1160  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1161  return assignable_enum(ta, base);
1162  }
1163  } else if (EK_COMPLETE == tb.kind()) {
1164  // Assuming tb.kind of EK_COMPLETE is not supported
1165  return false;
1166  }
1167 
1168  return false;
1169 }
1170 
1171 /**
1172  * @brief The first type must be TK_BITMASK.
1173  * The second type must not be TK_ALIAS.
1174  */
1176  const MinimalTypeObject& tb) const
1177 {
1178  if (TK_BITMASK == tb.kind) {
1179  return ta.bitmask_type.header.common.bit_bound ==
1181  }
1182 
1183  return false;
1184 }
1185 
1186 /**
1187  * @brief The first type must be TK_BITMASK.
1188  * The second type can be anything.
1189  */
1191  const TypeIdentifier& tb) const
1192 {
1193  BitBound ta_bit_bound = ta.bitmask_type.header.common.bit_bound;
1194  if (TK_UINT8 == tb.kind()) {
1195  return 1 <= ta_bit_bound && ta_bit_bound <= 8;
1196  } else if (TK_UINT16 == tb.kind()) {
1197  return 9 <= ta_bit_bound && ta_bit_bound <= 16;
1198  } else if (TK_UINT32 == tb.kind()) {
1199  return 17 <= ta_bit_bound && ta_bit_bound <= 32;
1200  } else if (TK_UINT64 == tb.kind()) {
1201  return 33 <= ta_bit_bound && ta_bit_bound <= 64;
1202  } else if (EK_MINIMAL == tb.kind()) {
1203  const MinimalTypeObject& tob = lookup_minimal(tb);
1204  if (TK_BITMASK == tob.kind) {
1205  return assignable_bitmask(ta, tob);
1206  } else if (TK_ALIAS == tob.kind) {
1207  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1208  return assignable_bitmask(ta, base);
1209  }
1210  } else if (EK_COMPLETE == tb.kind()) {
1211  // Assuming tb.kind of EK_COMPLETE is not supported
1212  return false;
1213  }
1214 
1215  return false;
1216 }
1217 
1218 /**
1219  * @brief The first type must be a future extension type kind.
1220  * The second type must not be TK_ALIAS.
1221  */
1223  const MinimalTypeObject&) const
1224 {
1225  // Future extensions
1226  return false;
1227 }
1228 
1229 /**
1230  * @brief The first type must be a primitive type.
1231  * The second type can be anything.
1232  */
1234  const TypeIdentifier& tb) const
1235 {
1236  if (ta.kind() == tb.kind()) {
1237  return true;
1238  }
1239 
1240  if (EK_MINIMAL == tb.kind()) {
1241  const MinimalTypeObject& tob = lookup_minimal(tb);
1242  if (TK_BITMASK == tob.kind) {
1243  return assignable_primitive(ta, tob);
1244  } else if (TK_ALIAS == tob.kind) {
1245  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1246  return assignable_primitive(ta, base);
1247  }
1248  } else if (EK_COMPLETE == tb.kind()) {
1249  // Assuming tb.kind of EK_COMPLETE is not supported
1250  return false;
1251  }
1252 
1253  return false;
1254 }
1255 
1256 /**
1257  * @brief The first type must be a primitive type.
1258  * The second type must not be TK_ALIAS.
1259  */
1261  const MinimalTypeObject& tb) const
1262 {
1263  if (TK_BITMASK != tb.kind ||
1264  !(TK_UINT8 == ta.kind() || TK_UINT16 == ta.kind() ||
1265  TK_UINT32 == ta.kind() || TK_UINT64 == ta.kind())) {
1266  return false;
1267  }
1268 
1269  BitBound bit_bound = tb.bitmask_type.header.common.bit_bound;
1270  if (TK_UINT8 == ta.kind()) {
1271  return 1 <= bit_bound && bit_bound <= 8;
1272  } else if (TK_UINT16 == ta.kind()) {
1273  return 9 <= bit_bound && bit_bound <= 16;
1274  } else if (TK_UINT32 == ta.kind()) {
1275  return 17 <= bit_bound && bit_bound <= 32;
1276  } else { // TK_UINT64
1277  return 33 <= bit_bound && bit_bound <= 64;
1278  }
1279 }
1280 
1281 /**
1282  * @brief The first type must be a string type.
1283  * The second type can be anything.
1284  */
1286  const TypeIdentifier& tb) const
1287 {
1288  if (TI_STRING8_SMALL == tb.kind() || TI_STRING8_LARGE == tb.kind()) {
1289  if (TI_STRING8_SMALL == ta.kind() || TI_STRING8_LARGE == ta.kind()) {
1290  return true;
1291  }
1292  } else if (TI_STRING16_SMALL == tb.kind() || TI_STRING16_LARGE == tb.kind()) {
1293  if (TI_STRING16_SMALL == ta.kind() || TI_STRING16_LARGE == ta.kind()) {
1294  return true;
1295  }
1296  } else if (EK_MINIMAL == tb.kind()) {
1297  const MinimalTypeObject& tob = lookup_minimal(tb);
1298  if (TK_ALIAS == tob.kind) {
1299  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1300  return assignable_string(ta, base);
1301  }
1302  } else if (EK_COMPLETE == tb.kind()) {
1303  // Assuming tb.kind of EK_COMPLETE is not supported
1304  return false;
1305  }
1306 
1307  return false;
1308 }
1309 
1310 /**
1311  * @brief The first type must be a string type.
1312  * The second type must not be TK_ALIAS.
1313  */
1315  const MinimalTypeObject&) const
1316 {
1317  // The second type cannot be string since string types do not have
1318  // type object. Thus the first type is not assignable from the second type.
1319  return false;
1320 }
1321 
1322 /**
1323  * @brief The first type must be a plain sequence type.
1324  * The second type can be anything.
1325  */
1327  const TypeIdentifier& tb) const
1328 {
1329  if (TI_PLAIN_SEQUENCE_SMALL == tb.kind()) {
1330  if (TI_PLAIN_SEQUENCE_SMALL == ta.kind()) {
1331  return strongly_assignable(*ta.seq_sdefn().element_identifier,
1332  *tb.seq_sdefn().element_identifier);
1333  } else { // TI_PLAIN_SEQUENCE_LARGE
1334  return strongly_assignable(*ta.seq_ldefn().element_identifier,
1335  *tb.seq_sdefn().element_identifier);
1336  }
1337  } else if (TI_PLAIN_SEQUENCE_LARGE == tb.kind()) {
1338  if (TI_PLAIN_SEQUENCE_SMALL == ta.kind()) {
1339  return strongly_assignable(*ta.seq_sdefn().element_identifier,
1340  *tb.seq_ldefn().element_identifier);
1341  } else { // TI_PLAIN_SEQUENCE_LARGE
1342  return strongly_assignable(*ta.seq_ldefn().element_identifier,
1343  *tb.seq_ldefn().element_identifier);
1344  }
1345  } else if (EK_MINIMAL == tb.kind()) {
1346  const MinimalTypeObject& tob = lookup_minimal(tb);
1347  if (TK_SEQUENCE == tob.kind) {
1348  return assignable_plain_sequence(ta, tob);
1349  } else if (TK_ALIAS == tob.kind) {
1350  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1351  return assignable_plain_sequence(ta, base);
1352  }
1353  } else if (EK_COMPLETE == tb.kind()) {
1354  // Can tb.kind be EK_COMPLETE? More generally, can a MinimalTypeObject
1355  // depend on a TypeIdentifier that identifies a class of types which have
1356  // COMPLETE equivalence relation.
1357  // For now, assuming tb.kind of EK_COMPLETE is not supported.
1358  return false;
1359  }
1360 
1361  return false;
1362 }
1363 
1364 /**
1365  * @brief The first type must be a plain sequence type.
1366  * The second type must not be TK_ALIAS.
1367  */
1369  const MinimalTypeObject& tb) const
1370 {
1371  if (TK_SEQUENCE == tb.kind) {
1372  if (TI_PLAIN_SEQUENCE_SMALL == ta.kind()) {
1373  return strongly_assignable(*ta.seq_sdefn().element_identifier,
1375  } else { // TI_PLAIN_SEQUENCE_LARGE
1376  return strongly_assignable(*ta.seq_ldefn().element_identifier,
1378  }
1379  }
1380 
1381  return false;
1382 }
1383 
1384 /**
1385  * @brief The first type must be a plain array type.
1386  * The second type can be anything.
1387  */
1389  const TypeIdentifier& tb) const
1390 {
1391  if (TI_PLAIN_ARRAY_SMALL == tb.kind()) {
1392  const Sequence<SBound>& bounds_b = tb.array_sdefn().array_bound_seq;
1393  if (TI_PLAIN_ARRAY_SMALL == ta.kind()) {
1394  const Sequence<SBound>& bounds_a = ta.array_sdefn().array_bound_seq;
1395  if (bounds_a.members.size() != bounds_b.members.size()) {
1396  return false;
1397  }
1398 
1399  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1400  if (bounds_a.members[i] != bounds_b.members[i]) {
1401  return false;
1402  }
1403  }
1404 
1405  return strongly_assignable(*ta.array_sdefn().element_identifier,
1406  *tb.array_sdefn().element_identifier);
1407  } else { // TI_PLAIN_ARRAY_LARGE
1408  const Sequence<LBound>& bounds_a = ta.array_ldefn().array_bound_seq;
1409  if (bounds_a.members.size() != bounds_b.members.size()) {
1410  return false;
1411  }
1412 
1413  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1414  if (bounds_a.members[i] != static_cast<LBound>(bounds_b.members[i])) {
1415  return false;
1416  }
1417  }
1418 
1419  return strongly_assignable(*ta.array_ldefn().element_identifier,
1420  *tb.array_sdefn().element_identifier);
1421  }
1422  } else if (TI_PLAIN_ARRAY_LARGE == tb.kind()) {
1423  const Sequence<LBound>& bounds_b = tb.array_ldefn().array_bound_seq;
1424  if (TI_PLAIN_ARRAY_SMALL == ta.kind()) {
1425  const Sequence<SBound>& bounds_a = ta.array_sdefn().array_bound_seq;
1426  if (bounds_a.members.size() != bounds_b.members.size()) {
1427  return false;
1428  }
1429 
1430  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1431  if (static_cast<LBound>(bounds_a.members[i]) != bounds_b.members[i]) {
1432  return false;
1433  }
1434  }
1435 
1436  return strongly_assignable(*ta.array_sdefn().element_identifier,
1437  *tb.array_ldefn().element_identifier);
1438  } else { // TI_PLAIN_ARRAY_LARGE
1439  const Sequence<LBound>& bounds_a = ta.array_ldefn().array_bound_seq;
1440  if (bounds_a.members.size() != bounds_b.members.size()) {
1441  return false;
1442  }
1443 
1444  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1445  if (bounds_a.members[i] != bounds_b.members[i]) {
1446  return false;
1447  }
1448  }
1449 
1450  return strongly_assignable(*ta.array_ldefn().element_identifier,
1451  *tb.array_ldefn().element_identifier);
1452  }
1453  } else if (EK_MINIMAL == tb.kind()) {
1454  const MinimalTypeObject& tob = lookup_minimal(tb);
1455  if (TK_ARRAY == tob.kind) {
1456  return assignable_plain_array(ta, tob);
1457  } else if (TK_ALIAS == tob.kind) {
1458  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1459  return assignable_plain_array(ta, base);
1460  }
1461  } else if (EK_COMPLETE == tb.kind()) {
1462  // Assuming tb.kind of EK_COMPLETE is not supported (similar to the way
1463  // assignability for plain sequences and plain maps are being handled)
1464  return false;
1465  }
1466 
1467  return false;
1468 }
1469 
1470 /**
1471  * @brief The first type must be a plain array type.
1472  * The second type must not be TK_ALIAS.
1473  */
1475  const MinimalTypeObject& tb) const
1476 {
1477  if (TK_ARRAY == tb.kind) {
1478  const Sequence<LBound>& bounds_b = tb.array_type.header.common.bound_seq;
1479  if (TI_PLAIN_ARRAY_SMALL == ta.kind()) {
1480  const Sequence<SBound>& bounds_a = ta.array_sdefn().array_bound_seq;
1481  if (bounds_a.members.size() != bounds_b.members.size()) {
1482  return false;
1483  }
1484 
1485  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1486  if (static_cast<LBound>(bounds_a.members[i]) != bounds_b.members[i]) {
1487  return false;
1488  }
1489  }
1490 
1491  return strongly_assignable(*ta.array_sdefn().element_identifier,
1493  } else { // TI_PLAIN_ARRAY_LARGE
1494  const Sequence<LBound>& bounds_a = ta.array_ldefn().array_bound_seq;
1495  if (bounds_a.members.size() != bounds_b.members.size()) {
1496  return false;
1497  }
1498 
1499  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1500  if (bounds_a.members[i] != bounds_b.members[i]) {
1501  return false;
1502  }
1503  }
1504 
1505  return strongly_assignable(*ta.array_ldefn().element_identifier,
1507  }
1508  }
1509 
1510  return false;
1511 }
1512 
1513 /**
1514  * @brief The first type must be a plain map type.
1515  * The second type can be anything.
1516  */
1518  const TypeIdentifier& tb) const
1519 {
1520  if (TI_PLAIN_MAP_SMALL == tb.kind()) {
1521  if (TI_PLAIN_MAP_SMALL == ta.kind()) {
1522  return strongly_assignable(*ta.map_sdefn().key_identifier,
1523  *tb.map_sdefn().key_identifier) &&
1524  strongly_assignable(*ta.map_sdefn().element_identifier,
1525  *tb.map_sdefn().element_identifier);
1526  } else { // TI_PLAIN_MAP_LARGE
1527  return strongly_assignable(*ta.map_ldefn().key_identifier,
1528  *tb.map_sdefn().key_identifier) &&
1529  strongly_assignable(*ta.map_ldefn().element_identifier,
1530  *tb.map_sdefn().element_identifier);
1531  }
1532  } else if (TI_PLAIN_MAP_LARGE == tb.kind()) {
1533  if (TI_PLAIN_MAP_SMALL == ta.kind()) {
1534  return strongly_assignable(*ta.map_sdefn().key_identifier,
1535  *tb.map_ldefn().key_identifier) &&
1536  strongly_assignable(*ta.map_sdefn().element_identifier,
1537  *tb.map_ldefn().element_identifier);
1538  } else { // TI_PLAIN_MAP_LARGE
1539  return strongly_assignable(*ta.map_ldefn().key_identifier,
1540  *tb.map_ldefn().key_identifier) &&
1541  strongly_assignable(*ta.map_ldefn().element_identifier,
1542  *tb.map_ldefn().element_identifier);
1543  }
1544  } else if (EK_MINIMAL == tb.kind()) {
1545  const MinimalTypeObject& tob = lookup_minimal(tb);
1546  if (TK_MAP == tob.kind) {
1547  return assignable_plain_map(ta, tob);
1548  } else if (TK_ALIAS == tob.kind) {
1549  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1550  return assignable_plain_map(ta, base);
1551  }
1552  } else if (EK_COMPLETE == tb.kind()) {
1553  // Assuming tb.kind of EK_COMPLETE is not supported (similar to how
1554  // assignability for plain sequences and plain arrays are being handled)
1555  return false;
1556  }
1557 
1558  return false;
1559 }
1560 
1561 /**
1562  * @brief The first type must be a plain map type.
1563  * The second type must not be TK_ALIAS.
1564  */
1566  const MinimalTypeObject& tb) const
1567 {
1568  if (TK_MAP == tb.kind) {
1569  if (TI_PLAIN_MAP_SMALL == ta.kind()) {
1570  return strongly_assignable(*ta.map_sdefn().key_identifier,
1571  tb.map_type.key.common.type) &&
1572  strongly_assignable(*ta.map_sdefn().element_identifier,
1574  } else { // TI_PLAIN_MAP_LARGE
1575  return strongly_assignable(*ta.map_ldefn().key_identifier,
1576  tb.map_type.key.common.type) &&
1577  strongly_assignable(*ta.map_ldefn().element_identifier,
1579  }
1580  }
1581 
1582  return false;
1583 }
1584 
1585 /**
1586  * @brief If types T1 and T2 are equivalent using the MINIMAL relation,
1587  * or alternatively if T1 is-assignable-from T2 and T2 is a delimited type,
1588  * then T1 is said to be strongly assignable from T2
1589  */
1591  const TypeIdentifier& tib) const
1592 {
1593  if (equal_type_id(tia, tib)) {
1594  return true;
1595  }
1596 
1597  if (assignable(tia, tib) && is_delimited(tib)) {
1598  return true;
1599  }
1600  return false;
1601 }
1602 
1603 /**
1604  * @brief Check whether two type identifiers are equal
1605  */
1607  const TypeIdentifier& tib) const
1608 {
1609  switch (tia.kind()) {
1610  case TK_BOOLEAN:
1611  case TK_BYTE:
1612  case TK_INT16:
1613  case TK_INT32:
1614  case TK_INT64:
1615  case TK_UINT16:
1616  case TK_UINT32:
1617  case TK_UINT64:
1618  case TK_FLOAT32:
1619  case TK_FLOAT64:
1620  case TK_FLOAT128:
1621  case TK_INT8:
1622  case TK_UINT8:
1623  case TK_CHAR8:
1624  case TK_CHAR16: {
1625  if (tib.kind() == tia.kind()) {
1626  return true;
1627  }
1628  break;
1629  }
1630  case TI_STRING8_SMALL:
1631  case TI_STRING16_SMALL: {
1632  if (tib.kind() == tia.kind() && tib.string_sdefn().bound == tia.string_sdefn().bound) {
1633  return true;
1634  }
1635  break;
1636  }
1637  case TI_STRING8_LARGE:
1638  case TI_STRING16_LARGE: {
1639  if (tib.kind() == tia.kind() && tib.string_ldefn().bound == tia.string_ldefn().bound) {
1640  return true;
1641  }
1642  break;
1643  }
1644  case TI_PLAIN_SEQUENCE_SMALL: {
1645  if (tib.kind() == tia.kind() &&
1646  tib.seq_sdefn().bound == tia.seq_sdefn().bound &&
1647  equal_type_id(*tia.seq_sdefn().element_identifier,
1648  *tib.seq_sdefn().element_identifier)) {
1649  return true;
1650  }
1651  break;
1652  }
1653  case TI_PLAIN_SEQUENCE_LARGE: {
1654  if (tib.kind() == tia.kind() &&
1655  tib.seq_ldefn().bound == tia.seq_ldefn().bound &&
1656  equal_type_id(*tia.seq_ldefn().element_identifier,
1657  *tib.seq_ldefn().element_identifier)) {
1658  return true;
1659  }
1660  break;
1661  }
1662  case TI_PLAIN_ARRAY_SMALL: {
1663  if (tib.kind() == tia.kind()) {
1664  const SBoundSeq& bounds_a = tia.array_sdefn().array_bound_seq;
1665  const SBoundSeq& bounds_b = tia.array_sdefn().array_bound_seq;
1666  if (bounds_a.members.size() != bounds_b.members.size()) {
1667  break;
1668  }
1669  bool equal_bounds = true;
1670  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1671  if (bounds_a.members[i] != bounds_b.members[i]) {
1672  equal_bounds = false;
1673  break;
1674  }
1675  }
1676  if (!equal_bounds) {
1677  break;
1678  }
1679  if (equal_type_id(*tia.array_sdefn().element_identifier,
1680  *tib.array_sdefn().element_identifier)) {
1681  return true;
1682  }
1683  }
1684  break;
1685  }
1686  case TI_PLAIN_ARRAY_LARGE: {
1687  if (tib.kind() == tia.kind()) {
1688  const LBoundSeq& bounds_a = tia.array_ldefn().array_bound_seq;
1689  const LBoundSeq& bounds_b = tib.array_ldefn().array_bound_seq;
1690  if (bounds_a.members.size() != bounds_b.members.size()) {
1691  break;
1692  }
1693  bool equal_bounds = true;
1694  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1695  if (bounds_a.members[i] != bounds_b.members[i]) {
1696  equal_bounds = false;
1697  break;
1698  }
1699  }
1700  if (!equal_bounds) {
1701  break;
1702  }
1703  if (equal_type_id(*tia.array_ldefn().element_identifier,
1704  *tib.array_ldefn().element_identifier)) {
1705  return true;
1706  }
1707  }
1708  break;
1709  }
1710  case TI_PLAIN_MAP_SMALL: {
1711  if (tib.kind() == tia.kind() &&
1712  tib.map_sdefn().bound == tia.map_sdefn().bound &&
1713  equal_type_id(*tia.map_sdefn().key_identifier,
1714  *tib.map_sdefn().key_identifier) &&
1715  equal_type_id(*tia.map_sdefn().element_identifier,
1716  *tib.map_sdefn().element_identifier)) {
1717  return true;
1718  }
1719  break;
1720  }
1721  case TI_PLAIN_MAP_LARGE: {
1722  if (tib.kind() == tia.kind() &&
1723  tib.map_ldefn().bound == tia.map_ldefn().bound &&
1724  equal_type_id(*tia.map_ldefn().key_identifier,
1725  *tib.map_ldefn().key_identifier) &&
1726  equal_type_id(*tia.map_ldefn().element_identifier,
1727  *tib.map_ldefn().element_identifier)) {
1728  return true;
1729  }
1730  break;
1731  }
1733  if (tib.kind() == tia.kind() &&
1734  tib.sc_component_id().scc_length == tia.sc_component_id().scc_length &&
1735  tib.sc_component_id().sc_component_id.kind ==
1736  tia.sc_component_id().sc_component_id.kind) {
1737  const EquivalenceHash& ha = tia.sc_component_id().sc_component_id.hash;
1738  const EquivalenceHash& hb = tib.sc_component_id().sc_component_id.hash;
1739  bool equal_hash = true;
1740  for (size_t i = 0; i < 14; ++i) {
1741  if (ha[i] != hb[i]) {
1742  equal_hash = false;
1743  break;
1744  }
1745  }
1746  if (equal_hash) {
1747  return true;
1748  }
1749  }
1750  break;
1751  }
1752  case EK_COMPLETE:
1753  case EK_MINIMAL: {
1754  if (tib.kind() == tia.kind()) {
1755  bool equal_hash = true;
1756  for (size_t i = 0; i < 14; ++i) {
1757  if (tia.equivalence_hash()[i] != tib.equivalence_hash()[i]) {
1758  equal_hash = false;
1759  break;
1760  }
1761  }
1762  if (equal_hash) {
1763  return true;
1764  }
1765  }
1766  break;
1767  }
1768  default:
1769  return false; // Future extensions
1770  }
1771 
1772  return false;
1773 }
1774 
1775 /**
1776  * @brief Concept of delimited types (sub-clause 7.2.4.2)
1777  */
1779 {
1780  switch (ti.kind()) {
1781  case TK_BOOLEAN:
1782  case TK_BYTE:
1783  case TK_INT16:
1784  case TK_INT32:
1785  case TK_INT64:
1786  case TK_UINT16:
1787  case TK_UINT32:
1788  case TK_UINT64:
1789  case TK_FLOAT32:
1790  case TK_FLOAT64:
1791  case TK_FLOAT128:
1792  case TK_INT8:
1793  case TK_UINT8:
1794  case TK_CHAR8:
1795  case TK_CHAR16:
1796  case TI_STRING8_SMALL:
1797  case TI_STRING8_LARGE:
1798  case TI_STRING16_SMALL:
1799  case TI_STRING16_LARGE:
1800  return true;
1802  return is_delimited(*ti.seq_sdefn().element_identifier);
1804  return is_delimited(*ti.seq_ldefn().element_identifier);
1805  case TI_PLAIN_ARRAY_SMALL:
1806  return is_delimited(*ti.array_sdefn().element_identifier);
1807  case TI_PLAIN_ARRAY_LARGE:
1808  return is_delimited(*ti.array_ldefn().element_identifier);
1809  case TI_PLAIN_MAP_SMALL:
1810  return is_delimited(*ti.map_sdefn().key_identifier) &&
1811  is_delimited(*ti.map_sdefn().element_identifier);
1812  case TI_PLAIN_MAP_LARGE:
1813  return is_delimited(*ti.map_ldefn().key_identifier) &&
1814  is_delimited(*ti.map_ldefn().element_identifier);
1815  case EK_COMPLETE:
1816  case EK_MINIMAL: {
1817  const MinimalTypeObject& tobj = lookup_minimal(ti);
1818  return is_delimited(tobj);
1819  }
1820  default:
1821  // Future extensions and strongly connected components
1822  return false;
1823  }
1824 }
1825 
1826 /**
1827  * @brief Check if a type is delimited (sub-clause 7.2.4.2)
1828  */
1830 {
1831  switch (tobj.kind) {
1832  case TK_ALIAS: {
1833  const TypeIdentifier& base = get_base_type(tobj);
1834  return is_delimited(base);
1835  }
1836  case TK_ANNOTATION:
1838  case TK_STRUCTURE:
1840  case TK_UNION:
1842  case TK_BITSET:
1844  case TK_SEQUENCE:
1846  case TK_ARRAY:
1847  return is_delimited(tobj.array_type.element.common.type);
1848  case TK_MAP:
1849  return is_delimited(tobj.map_type.key.common.type) &&
1851  case TK_ENUM:
1852  case TK_BITMASK:
1853  return true;
1854  default:
1855  return false; // Future extensions
1856  }
1857 }
1858 
1860 {
1861  if ((flags & IS_FINAL) == IS_FINAL) {
1862  return false;
1863  } else if ((flags & IS_MUTABLE) == IS_MUTABLE) {
1864  // Mutable types are delimited with both encoding versions 1 and 2
1865  return true;
1866  } else { // Default extensibility is APPENDABLE (7.3.1.2.1.8)
1867  // Types with extensibility kind APPENDABLE are delimited
1868  // if serialized with encoding version 2 and are not
1869  // delimited if serialized with encoding version 1.
1870  // We are supporting XCDR2 in this iteration.
1871  return true;
1872  }
1873 }
1874 
1875 /**
1876  * @brief Key-Erased type of an aggregated type T (struct or union)
1877  * is constructed from T by removing the key designation from
1878  * any member that has it (sub-clause 7.2.2.4.6).
1879  * The input type must be either a struct or an union.
1880  */
1882 {
1883  if (TK_STRUCTURE == type.kind) {
1885  for (size_t i = 0; i < mseq.members.size(); ++i) {
1886  MemberFlag& flags = mseq.members[i].common.member_flags;
1887  if ((flags & IS_KEY) == IS_KEY) {
1888  flags &= ~IS_KEY;
1889  }
1890  }
1891  } else if (TK_UNION == type.kind) {
1893  if ((flags & IS_KEY) == IS_KEY) {
1894  flags &= ~IS_KEY;
1895  }
1896  }
1897 }
1898 
1899 /**
1900  * @brief Key-Holder type of an aggregated type T (struct or union)
1901  * is constructed from T (sub-clause 7.2.2.4.7)
1902  * The input MinimalTypeObject is modified to get the corresponding KeyHolder type.
1903  * The input must be either a struct or an union.
1904  */
1906 {
1907  if (TK_STRUCTURE == type.kind) {
1909  bool found_key = false;
1910  for (size_t i = 0; i < mseq.members.size(); ++i) {
1911  const MemberFlag& flags = mseq.members[i].common.member_flags;
1912  if ((flags & IS_KEY) == IS_KEY) {
1913  found_key = true;
1914  break;
1915  }
1916  }
1917 
1918  if (found_key) { // Remove all non-key members
1919  Sequence<MinimalStructMember> key_members;
1920  for (size_t i = 0; i < mseq.members.size(); ++i) {
1921  const MemberFlag& flags = mseq.members[i].common.member_flags;
1922  if ((flags & IS_KEY) == IS_KEY) {
1923  key_members.append(mseq.members[i]);
1924  }
1925  }
1926  mseq.members = key_members.members;
1927  } else { // Add a key designator to each member
1928  for (size_t i = 0; i < mseq.members.size(); ++i) {
1929  const MemberFlag& flags = mseq.members[i].common.member_flags;
1930  if ((flags & IS_KEY) != IS_KEY) {
1931  mseq.members[i].common.member_flags |= IS_KEY;
1932  }
1933  }
1934  }
1935  } else if (TK_UNION == type.kind) {
1937  // Remove all non-key members
1939  }
1940  }
1941 }
1942 
1943 /**
1944  * @brief Return false if the input type does not have type object; the output
1945  * MinimalTypeObject is not used in this case.
1946  * Return true if the input type has type object; the output MinimalTypeObject
1947  * contains the KeyHolder type of the corresponding type.
1948  */
1950 {
1951  if (EK_MINIMAL != ti.kind() && EK_COMPLETE != ti.kind()) {
1952  return false;
1953  }
1954 
1955  to = lookup_minimal(ti);
1956  switch (to.kind) {
1957  case TK_STRUCTURE:
1958  case TK_UNION: {
1959  hold_key(to);
1960  return true;
1961  }
1962  case TK_ALIAS: {
1963  const TypeIdentifier& base = get_base_type(to);
1964  return hold_key(base, to);
1965  }
1966  default: // KeyHolder is not defined for other types
1967  return true;
1968  }
1969 }
1970 
1971 /**
1972  * @brief The input must be of type TK_ALIAS
1973  * Return the non-alias base type identifier of the input
1974  */
1976 {
1977  const TypeIdentifier& base = type.alias_type.body.common.related_type;
1978  switch (base.kind()) {
1979  case EK_COMPLETE:
1980  case EK_MINIMAL: {
1981  const MinimalTypeObject& type_obj = lookup_minimal(base);
1982  if (TK_ALIAS == type_obj.kind) {
1983  return get_base_type(type_obj);
1984  }
1985  return base;
1986  }
1987  default:
1988  return base;
1989  }
1990 }
1991 
1992 /**
1993  * @brief The first argument must be TK_ENUM and is the type object
1994  * of a key member of the containing struct. Therefore, there must be a
1995  * member with the same ID (and name) in the other struct type.
1996  */
1998  const CommonStructMember& ma) const
1999 {
2000  if (EK_MINIMAL != ma.member_type_id.kind()) {
2001  return false;
2002  }
2003 
2006  const MinimalEnumeratedLiteralSeq* literals_a = 0;
2007  if (TK_ENUM == toa.kind) {
2008  literals_a = &toa.enumerated_type.literal_seq;
2009  } else if (TK_ALIAS == toa.kind) {
2010  const TypeIdentifier& base_a = get_base_type(toa);
2011  if (EK_MINIMAL == base_a.kind()) {
2012  const MinimalTypeObject& base_obj_a = lookup_minimal(base_a);
2013  if (TK_ENUM == base_obj_a.kind) {
2014  literals_a = &base_obj_a.enumerated_type.literal_seq;
2015  } else {
2016  return false;
2017  }
2018  } else {
2019  return false;
2020  }
2021  } else {
2022  return false;
2023  }
2024 
2025  // All literals in tb must appear as literals in toa
2026  for (size_t j = 0; j < literals_b.members.size(); ++j) {
2027  const NameHash& h_b = literals_b.members[j].detail.name_hash;
2028  ACE_CDR::ULong key_b = (h_b[0] << 24) | (h_b[1] << 16) | (h_b[2] << 8) | (h_b[3]);
2029  bool found = false;
2030  for (size_t k = 0; k < literals_a->members.size(); ++k) {
2031  const NameHash& h_a = literals_a->members[k].detail.name_hash;
2032  ACE_CDR::ULong key_a = (h_a[0] << 24) | (h_a[1] << 16) | (h_a[2] << 8) | (h_a[3]);
2033  if (key_a == key_b) {
2034  found = true;
2035  break;
2036  }
2037  }
2038  if (!found) {
2039  return false;
2040  }
2041  }
2042  return true;
2043 }
2044 
2045 /**
2046  * @brief Check whether a struct member is of sequence type and
2047  * if so compute its bound into the first argument
2048  */
2050  const CommonStructMember& member) const
2051 {
2052  ACE_CDR::Octet kind = member.member_type_id.kind();
2053  bool is_sequence = false;
2054  if (EK_MINIMAL == kind) {
2055  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2056  if (TK_SEQUENCE == tobj.kind) {
2057  bound = tobj.sequence_type.header.common.bound;
2058  is_sequence = true;
2059  } else if (TK_ALIAS == tobj.kind) {
2060  const TypeIdentifier& base = get_base_type(tobj);
2061  if (EK_MINIMAL == base.kind()) {
2062  const MinimalTypeObject& base_obj = lookup_minimal(base);
2063  if (TK_SEQUENCE == base_obj.kind) {
2064  bound = base_obj.sequence_type.header.common.bound;
2065  is_sequence = true;
2066  }
2067  } else if (TI_PLAIN_SEQUENCE_SMALL == base.kind()) {
2068  bound = static_cast<LBound>(base.seq_sdefn().bound);
2069  is_sequence = true;
2070  } else if (TI_PLAIN_SEQUENCE_LARGE == base.kind()) {
2071  bound = base.seq_ldefn().bound;
2072  is_sequence = true;
2073  }
2074  }
2075  } else if (TI_PLAIN_SEQUENCE_SMALL == kind) {
2076  bound = static_cast<LBound>(member.member_type_id.seq_sdefn().bound);
2077  is_sequence = true;
2078  } else if (TI_PLAIN_SEQUENCE_LARGE == kind) {
2079  bound = member.member_type_id.seq_ldefn().bound;
2080  is_sequence = true;
2081  }
2082  return is_sequence;
2083 }
2084 
2085 /**
2086  * @brief Check whether a struct member is of map type and if so
2087  * compute its bound into the first argument
2088  */
2090  const CommonStructMember& member) const
2091 {
2092  ACE_CDR::Octet kind = member.member_type_id.kind();
2093  bool is_map = false;
2094  if (EK_MINIMAL == kind) {
2095  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2096  if (TK_MAP == tobj.kind) {
2097  bound = tobj.map_type.header.common.bound;
2098  is_map = true;
2099  } else if (TK_ALIAS == tobj.kind) {
2100  const TypeIdentifier& base = get_base_type(tobj);
2101  if (EK_MINIMAL == base.kind()) {
2102  const MinimalTypeObject& base_obj = lookup_minimal(base);
2103  if (TK_MAP == base_obj.kind) {
2104  bound = base_obj.map_type.header.common.bound;
2105  is_map = true;
2106  }
2107  } else if (TI_PLAIN_MAP_SMALL == base.kind()) {
2108  bound = static_cast<LBound>(base.map_sdefn().bound);
2109  is_map = true;
2110  } else if (TI_PLAIN_MAP_LARGE == base.kind()) {
2111  bound = base.map_ldefn().bound;
2112  is_map = true;
2113  }
2114  }
2115  } else if (TI_PLAIN_MAP_SMALL == kind) {
2116  bound = static_cast<LBound>(member.member_type_id.map_sdefn().bound);
2117  is_map = true;
2118  } else if (TI_PLAIN_MAP_LARGE == kind) {
2119  bound = member.member_type_id.map_ldefn().bound;
2120  is_map = true;
2121  }
2122  return is_map;
2123 }
2124 
2125 /**
2126  * @brief Check whether the input struct member is of string type and
2127  * if so compute its bound into the first argument
2128  */
2130  const CommonStructMember& member) const
2131 {
2132  ACE_CDR::Octet kind = member.member_type_id.kind();
2133  bool is_string = false;
2134  if (EK_MINIMAL == kind) {
2135  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2136  if (TK_ALIAS == tobj.kind) {
2137  const TypeIdentifier& base = get_base_type(tobj);
2138  if (TI_STRING8_SMALL == base.kind() || TI_STRING16_SMALL == base.kind()) {
2139  bound = static_cast<LBound>(base.string_sdefn().bound);
2140  is_string = true;
2141  } else if (TI_STRING8_LARGE == base.kind() || TI_STRING16_LARGE == base.kind()) {
2142  bound = base.string_ldefn().bound;
2143  is_string = true;
2144  }
2145  }
2146  } else if (TI_STRING8_SMALL == kind || TI_STRING16_SMALL == kind) {
2147  bound = static_cast<LBound>(member.member_type_id.string_sdefn().bound);
2148  is_string = true;
2149  } else if (TI_STRING8_LARGE == kind || TI_STRING16_LARGE == kind) {
2150  bound = member.member_type_id.string_ldefn().bound;
2151  is_string = true;
2152  }
2153  return is_string;
2154 }
2155 
2156 /**
2157  * @brief Check if the second argument is of a struct type and if so
2158  * return its type object as the first argument
2159  */
2161  const CommonStructMember& member) const
2162 {
2163  ACE_CDR::Octet kind = member.member_type_id.kind();
2164  bool is_struct = false;
2165  if (EK_MINIMAL == kind) {
2166  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2167  if (TK_STRUCTURE == tobj.kind) {
2168  ret = &tobj;
2169  is_struct = true;
2170  } else if (TK_ALIAS == tobj.kind) {
2171  const TypeIdentifier& base = get_base_type(tobj);
2172  if (EK_MINIMAL == base.kind()) {
2173  const MinimalTypeObject& base_obj = lookup_minimal(base);
2174  if (TK_STRUCTURE == base_obj.kind) {
2175  ret = &base_obj;
2176  is_struct = true;
2177  }
2178  }
2179  }
2180  }
2181  return is_struct;
2182 }
2183 
2184 /**
2185  * @brief Check if the second argument is of a union type and if so
2186  * return its type object as the first argument
2187  */
2189  const CommonStructMember& member) const
2190 {
2191  ACE_CDR::Octet kind = member.member_type_id.kind();
2192  bool is_union = false;
2193  if (EK_MINIMAL == kind) {
2194  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2195  if (TK_UNION == tobj.kind) {
2196  ret = &tobj;
2197  is_union = true;
2198  } else if (TK_ALIAS == tobj.kind) {
2199  const TypeIdentifier& base = get_base_type(tobj);
2200  if (EK_MINIMAL == base.kind()) {
2201  const MinimalTypeObject& base_obj = lookup_minimal(base);
2202  if (TK_UNION == base_obj.kind) {
2203  ret = &base_obj;
2204  is_union = true;
2205  }
2206  }
2207  }
2208  }
2209  return is_union;
2210 }
2211 
2212 } // namespace XTypes
2213 } // namespace OpenDDS
2214 
ACE_Byte Octet
bool assignable_extended(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be a future extension type kind. The second type must not be TK_ALIAS.
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
MinimalEnumeratedType enumerated_type
Definition: TypeObject.h:3135
ACE_CDR::ULong MemberId
Definition: TypeObject.h:910
const TypeKind TK_INT32
Definition: TypeObject.h:217
MemberFlag UnionMemberFlag
Definition: TypeObject.h:380
bool is_delimited_with_flags(TypeFlag flags) const
MinimalCollectionHeader header
Definition: TypeObject.h:2283
const TypeKind TK_FLOAT128
Definition: TypeObject.h:224
const TypeIdentifierKind TI_STRING8_LARGE
Definition: TypeObject.h:256
const TypeKind TK_BYTE
Definition: TypeObject.h:215
const TypeFlag IS_MUTABLE
Definition: TypeObject.h:402
const TypeKind TK_UNION
Definition: TypeObject.h:244
bool get_sequence_bound(LBound &b, const CommonStructMember &m) const
Check whether a struct member is of sequence type and if so compute its bound into the first argument...
bool is_delimited(const TypeIdentifier &ti) const
Concept of delimited types (sub-clause 7.2.4.2)
const TypeKind TK_INT16
Definition: TypeObject.h:216
TypeConsistencyAttributes type_consistency_
bool equal_type_id(const TypeIdentifier &tia, const TypeIdentifier &tib) const
Check whether two type identifiers are equal.
const TypeIdentifierKind TI_PLAIN_SEQUENCE_LARGE
Definition: TypeObject.h:261
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool get_union_member(const MinimalTypeObject *&ret, const CommonStructMember &m) const
Check if the second argument is of a union type and if so return its type object as the first argumen...
MinimalCollectionElement element
Definition: TypeObject.h:2407
const MemberFlag IS_MUST_UNDERSTAND
Definition: TypeObject.h:374
const TypeKind TK_UINT16
Definition: TypeObject.h:219
ACE_CDR::UShort BitBound
Definition: TypeObject.h:2478
ACE_CDR::Octet kind() const
Definition: TypeObject.h:748
bool assignable_enum(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ENUM. The second type must not be TK_ALIAS.
void erase_key(MinimalTypeObject &type) const
Key-Erased type of an aggregated type T (struct or union) is constructed from T by removing the key d...
bool assignable_struct(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_STRUCTURE. The second type must not be TK_ALIAS.
MinimalEnumeratedLiteralSeq literal_seq
Definition: TypeObject.h:2667
const TypeIdentifierKind TI_STRING16_LARGE
Definition: TypeObject.h:258
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const TypeKind TK_INT8
Definition: TypeObject.h:225
const TypeIdentifierKind TI_STRING8_SMALL
Definition: TypeObject.h:255
bool assignable_array(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ARRAY. The second type must not be TK_ALIAS.
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
bool assignable_plain_array(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain array type. The second type can be anything.
bool get_struct_member(const MinimalTypeObject *&ret, const CommonStructMember &m) const
Check if the second argument is of a struct type and if so return its type object as the first argume...
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
MinimalAnnotationType annotation_type
Definition: TypeObject.h:3128
const TypeIdentifierKind TI_PLAIN_MAP_LARGE
Definition: TypeObject.h:267
ACE_CDR::UShort MemberFlag
Definition: TypeObject.h:368
bool assignable_annotation(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ANNOTATION. The second type must not be TK_ALIAS.
const MemberFlag IS_KEY
Definition: TypeObject.h:375
const TypeKind TK_BOOLEAN
Definition: TypeObject.h:214
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
const TypeIdentifierKind TI_PLAIN_ARRAY_LARGE
Definition: TypeObject.h:264
const TypeIdentifierKind TI_PLAIN_ARRAY_SMALL
Definition: TypeObject.h:263
const TypeKind TK_BITMASK
Definition: TypeObject.h:239
bool assignable_sequence(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_SEQUENCE. The second type must not be TK_ALIAS.
ACE_UINT16 UShort
const TypeFlag IS_FINAL
Definition: TypeObject.h:400
MinimalDiscriminatorMember discriminator
Definition: TypeObject.h:1777
bool get_map_bound(LBound &b, const CommonStructMember &m) const
Check whether a struct member is of map type and if so compute its bound into the first argument...
bool struct_rule_enum_key(const MinimalTypeObject &tb, const CommonStructMember &ma) const
The first argument must be TK_ENUM and is the type object of a key member of the containing struct...
MinimalUnionMemberSeq member_seq
Definition: TypeObject.h:1778
const TypeKind TK_CHAR8
Definition: TypeObject.h:227
ACE_UINT32 ULong
bool assignable_union(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_UNION. The second type must not be TK_ALIAS.
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
MinimalCollectionElement element
Definition: TypeObject.h:2460
bool assignable(const TypeObject &ta, const TypeObject &tb) const
Both input type objects must be minimal.
typedef OPENDDS_SET(DynamicTypePtrPair) DynamicTypePtrPairSeen
const char *const name
Definition: debug.cpp:60
Sequence & append(const T &member)
Definition: TypeObject.h:155
MinimalCollectionElement key
Definition: TypeObject.h:2459
const TypeKind TK_FLOAT32
Definition: TypeObject.h:222
MinimalSequenceType sequence_type
Definition: TypeObject.h:3132
ACE_CDR::Octet EquivalenceHash[14]
Definition: TypeObject.h:287
bool assignable_plain_map(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain map type. The second type can be anything.
ACE_INT32 Long
void hold_key(MinimalTypeObject &type) const
Key-Holder type of an aggregated type T (struct or union) is constructed from T (sub-clause 7...
ACE_CDR::UShort TypeFlag
Definition: TypeObject.h:399
const TypeKind TK_UINT64
Definition: TypeObject.h:221
MinimalStructMemberSeq member_seq
Definition: TypeObject.h:1505
const TypeKind TK_INT64
Definition: TypeObject.h:218
MinimalCollectionElement element
Definition: TypeObject.h:2284
bool get_string_bound(LBound &b, const CommonStructMember &m) const
Check whether the input struct member is of string type and if so compute its bound into the first ar...
const MemberFlag IS_OPTIONAL
Definition: TypeObject.h:373
const TypeKind TK_UINT32
Definition: TypeObject.h:220
MinimalCollectionHeader header
Definition: TypeObject.h:2458
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
const TypeKind TK_ANNOTATION
Definition: TypeObject.h:242
const TypeKind TK_ENUM
Definition: TypeObject.h:238
const TypeFlag IS_APPENDABLE
Definition: TypeObject.h:401
bool assignable_alias(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
At least one input type object must be TK_ALIAS.
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeIdentifierKind TI_STRING16_SMALL
Definition: TypeObject.h:257
bool assignable_bitmask(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_BITMASK. The second type must not be TK_ALIAS.
typedef OPENDDS_MAP(TypeIdentifier, TypeObject) TypeMap
const MemberFlag IS_DEFAULT
Definition: TypeObject.h:376
const TypeIdentifierKind TI_STRONGLY_CONNECTED_COMPONENT
Definition: TypeObject.h:269
const TypeKind TK_ARRAY
Definition: TypeObject.h:249
bool assignable_map(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_MAP. The second type must not be TK_ALIAS.
const TypeKind TK_UINT8
Definition: TypeObject.h:226
bool assignable_plain_sequence(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain sequence type. The second type can be anything.
bool assignable_string(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a string type. The second type can be anything.
ACE_CDR::ULong LBound
Definition: TypeObject.h:312
bool assignable_primitive(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a primitive type. The second type can be anything.
const TypeKind TK_MAP
Definition: TypeObject.h:250
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
bool assignable_bitset(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_BITSET. The second type must not be TK_ALIAS.
ACE_CDR::ULong length() const
Definition: TypeObject.h:167
const TypeKind TK_CHAR16
Definition: TypeObject.h:228
MinimalTypeObject minimal
Definition: TypeObject.h:3244
const TypeKind TK_FLOAT64
Definition: TypeObject.h:223
const TypeKind TK_BITSET
Definition: TypeObject.h:245
MinimalEnumeratedHeader header
Definition: TypeObject.h:2666
ACE_CDR::Octet NameHash[4]
Definition: TypeObject.h:296