1 // -*- Mode: C++; -*-
2 // Package : omniORB
3 // typecode.cc Created on: 03/09/98
4 // Author1 : James Weatherall (jnw)
5 // Author2 : Duncan Grisby (dgrisby)
6 //
7 // Copyright (C) 2002-2012 Apasphere Ltd.
8 // Copyright (C) 1996-1999 AT&T Laboratories Cambridge
9 //
10 // This file is part of the omniORB library
11 //
12 // The omniORB library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library. If not, see http://www.gnu.org/licenses/
24 //
25 //
26 // Description:
27 // Implementation of the CORBA::TypeCode psuedo object
28 //
29
30 #include <omniORB4/CORBA.h>
31 #include <omniORB4/objTracker.h>
32
33 #ifdef HAS_pch
34 #pragma hdrstop
35 #endif
36
37 #include <typecode.h>
38 #include <tcParser.h>
39 #include <orbParameters.h>
40 #include <omniORB4/linkHacks.h>
41
42 OMNI_FORCE_LINK(dynamicLib);
43
OMNI_USING_NAMESPACE(omni)44 OMNI_USING_NAMESPACE(omni)
45
46 // CORBA::TypeCode - core class function implementation
47 //
48 // NOTE : internally, the TypeCode implementation implicitly assumes that no
49 // content typecode is _ever_ CORBA::TypeCode::_nil().
50 // To support this assumption cleanly, the visible CORBA::TypeCode()
51 // interface must check any typecodes passed to it and raise
52 // CORBA::BAD_TYPECODE if a _nil() value is encountered.
53
54
55 //////////////////////////////////////////////////////////////////////
56 /////////////////////////// CORBA::TypeCode //////////////////////////
57 //////////////////////////////////////////////////////////////////////
58
59 CORBA::TypeCode::~TypeCode() {
60 pd_magic = 0;
61 }
62
63 CORBA::TCKind
kind() const64 CORBA::TypeCode::kind() const
65 {
66 return TypeCode_indirect::strip(ToConstTcBase_Checked(this))->NP_kind();
67 }
68
69 CORBA::Boolean
equal(CORBA::TypeCode_ptr TCp) const70 CORBA::TypeCode::equal(CORBA::TypeCode_ptr TCp) const
71 {
72 if (!PR_is_valid(TCp)) OMNIORB_THROW(BAD_PARAM,
73 BAD_PARAM_InvalidTypeCode,
74 CORBA::COMPLETED_NO);
75 return ToConstTcBase_Checked(this)
76 ->NP_equal(ToTcBase_Checked(TCp),0,0);
77 }
78
79 CORBA::Boolean
equivalent(CORBA::TypeCode_ptr TCp) const80 CORBA::TypeCode::equivalent(CORBA::TypeCode_ptr TCp) const
81 {
82 if (!PR_is_valid(TCp)) OMNIORB_THROW(BAD_PARAM,
83 BAD_PARAM_InvalidTypeCode,
84 CORBA::COMPLETED_NO);
85 return ToConstTcBase_Checked(this)
86 ->NP_equal(ToTcBase_Checked(TCp),1,0);
87 }
88
89 CORBA::TypeCode_ptr
get_compact_typecode() const90 CORBA::TypeCode::get_compact_typecode() const
91 {
92 TypeCode_base* tp = (TypeCode_base*)ToConstTcBase_Checked(this);
93 return tp->NP_compactTc();
94 }
95
96 const char*
id() const97 CORBA::TypeCode::id() const
98 {
99 return ToConstTcBase_Checked(this)->NP_id();
100 }
101
102 const char*
name() const103 CORBA::TypeCode::name() const
104 {
105 return ToConstTcBase_Checked(this)->NP_name();
106 }
107
108 CORBA::ULong
member_count() const109 CORBA::TypeCode::member_count() const
110 {
111 return ToConstTcBase_Checked(this)->NP_member_count();
112 }
113
114 const char*
member_name(CORBA::ULong index) const115 CORBA::TypeCode::member_name(CORBA::ULong index) const
116 {
117 return ToConstTcBase_Checked(this)->NP_member_name(index);
118 }
119
120 CORBA::TypeCode_ptr
member_type(CORBA::ULong i) const121 CORBA::TypeCode::member_type(CORBA::ULong i) const
122 {
123 return TypeCode_collector::duplicateRef(ToConstTcBase_Checked(this)
124 ->NP_member_type(i));
125 }
126
127 CORBA::Any*
member_label(CORBA::ULong i) const128 CORBA::TypeCode::member_label(CORBA::ULong i) const
129 {
130 return ToConstTcBase_Checked(this)->NP_member_label(i);
131 }
132
133 CORBA::TypeCode_ptr
discriminator_type() const134 CORBA::TypeCode::discriminator_type() const
135 {
136 return TypeCode_collector::duplicateRef(ToConstTcBase_Checked(this)
137 ->NP_discriminator_type());
138 }
139
140 CORBA::Long
default_index() const141 CORBA::TypeCode::default_index() const
142 {
143 return ToConstTcBase_Checked(this)->NP_default_index();
144 }
145
146 CORBA::ULong
length() const147 CORBA::TypeCode::length() const
148 {
149 return ToConstTcBase_Checked(this)->NP_length();
150 }
151
152 CORBA::TypeCode_ptr
content_type() const153 CORBA::TypeCode::content_type() const
154 {
155 return TypeCode_collector::duplicateRef(ToConstTcBase_Checked(this)
156 ->NP_content_type());
157 }
158
159 CORBA::UShort
fixed_digits() const160 CORBA::TypeCode::fixed_digits() const
161 {
162 return ToConstTcBase_Checked(this)->NP_fixed_digits();
163 }
164
165 CORBA::Short
fixed_scale() const166 CORBA::TypeCode::fixed_scale() const
167 {
168 return ToConstTcBase_Checked(this)->NP_fixed_scale();
169 }
170
171 CORBA::Long
param_count() const172 CORBA::TypeCode::param_count() const
173 {
174 return ToConstTcBase_Checked(this)->NP_param_count();
175 }
176
177 CORBA::Any*
parameter(Long index) const178 CORBA::TypeCode::parameter(Long index) const
179 {
180 return ToConstTcBase_Checked(this)->NP_parameter(index);
181 }
182
183 CORBA::Short
member_visibility(CORBA::ULong index) const184 CORBA::TypeCode::member_visibility(CORBA::ULong index) const
185 {
186 return ToConstTcBase_Checked(this)->NP_member_visibility(index);
187 }
188
189 CORBA::ValueModifier
type_modifier() const190 CORBA::TypeCode::type_modifier() const
191 {
192 return ToConstTcBase_Checked(this)->NP_type_modifier();
193 }
194
195 CORBA::TypeCode_ptr
concrete_base_type() const196 CORBA::TypeCode::concrete_base_type() const
197 {
198 return TypeCode_collector::duplicateRef(ToConstTcBase_Checked(this)
199 ->NP_concrete_base_type());
200 }
201
202
203 // Static TypeCode member functions
204
205 CORBA::TypeCode_ptr
_duplicate(CORBA::TypeCode_ptr t)206 CORBA::TypeCode::_duplicate(CORBA::TypeCode_ptr t)
207 {
208 if (!PR_is_valid(t))
209 OMNIORB_THROW(BAD_PARAM,BAD_PARAM_InvalidTypeCode,CORBA::COMPLETED_NO);
210 if (CORBA::is_nil(t)) return t;
211 return TypeCode_collector::duplicateRef(ToTcBase(t));
212 }
213
214 OMNI_NAMESPACE_BEGIN(omni)
215
216 //
217 // The nil TypeCode is derived from neither CORBA::Object or
218 // omniTrackedObject. We use a holder object to ensure it is deleted
219 // on exit.
220 //
221 class omniNilTypeCodeHolder : public omniTrackedObject {
222 public:
omniNilTypeCodeHolder(CORBA::TypeCode_ptr nil)223 inline omniNilTypeCodeHolder(CORBA::TypeCode_ptr nil) : pd_nil(nil) {}
~omniNilTypeCodeHolder()224 virtual ~omniNilTypeCodeHolder() { delete pd_nil; }
225 private:
226 CORBA::TypeCode_ptr pd_nil;
227 };
228
OMNI_NAMESPACE_END(omni)229 OMNI_NAMESPACE_END(omni)
230
231
232 CORBA::TypeCode_ptr
233 CORBA::TypeCode::_nil()
234 {
235 static TypeCode* _the_nil_ptr = 0;
236 if( !_the_nil_ptr ) {
237 omni::nilRefLock().lock();
238 if( !_the_nil_ptr ) {
239 _the_nil_ptr = new TypeCode;
240 registerTrackedObject(new omniNilTypeCodeHolder(_the_nil_ptr));
241 }
242 omni::nilRefLock().unlock();
243 }
244 return _the_nil_ptr;
245 }
246
247 // omniORB marshalling routines
248 void
marshalTypeCode(TypeCode_ptr obj,cdrStream & s)249 CORBA::TypeCode::marshalTypeCode(TypeCode_ptr obj,cdrStream &s)
250 {
251 TypeCode_offsetTable otbl;
252
253 TypeCode_marshaller::marshal(ToTcBase_Checked(obj), s, &otbl);
254 }
255
256
257 CORBA::TypeCode_ptr
unmarshalTypeCode(cdrStream & s)258 CORBA::TypeCode::unmarshalTypeCode(cdrStream &s)
259 {
260 TypeCode_offsetTable otbl;
261
262 TypeCode_base* tc = TypeCode_marshaller::unmarshal(s, &otbl);
263 TypeCode_collector::markLoopMembers(tc);
264
265 return tc;
266 }
267
268 CORBA::Boolean
NP_is_nil() const269 CORBA::TypeCode::NP_is_nil() const
270 {
271 return 1;
272 }
273
274
275 // Complex TypeCode constructors
276 // These routines are the omniORB-specific constructors for complex typecodes.
277 // CORBA-compliant applications should only ever access these through the ORB
278 // interface. These functions are for the use of omniORB stubs & libraries.
279 // NB: The reference count of the returned TypeCode_ptr is always 1, unless
280 // the TypeCode structure contains recursive references.
281
282 #if 0
283 CORBA::TypeCode_ptr
284 CORBA::TypeCode::NP_struct_tc(const char* id, const char* name,
285 const CORBA::StructMemberSeq& members)
286 {
287 const CORBA::ULong memberCount = members.length();
288 for( CORBA::ULong i = 0; i < memberCount; i++ )
289 if ( !PR_is_valid(members[i].type) || CORBA::is_nil(members[i].type))
290 OMNIORB_THROW(BAD_TYPECODE,
291 BAD_TYPECODE_TypeCodeIsNil,
292 CORBA::COMPLETED_NO);
293
294 return new TypeCode_struct(id, name, members);
295 }
296
297
298 CORBA::TypeCode_ptr
299 CORBA::TypeCode::NP_union_tc(const char* id, const char* name,
300 CORBA::TypeCode_ptr discriminator_type,
301 const CORBA::UnionMemberSeq& members)
302 {
303 const CORBA::ULong memberCount = members.length();
304 for( CORBA::ULong i = 0; i < memberCount; i++ )
305 if( !PR_is_valid(members[i].type) || CORBA::is_nil(members[i].type) )
306 OMNIORB_THROW(BAD_TYPECODE,
307 BAD_TYPECODE_TypeCodeIsNil,
308 CORBA::COMPLETED_NO);
309
310 return new TypeCode_union(id, name, ToTcBase_Checked(discriminator_type),
311 members);
312 }
313 #endif
314
315
316 CORBA::TypeCode_ptr
NP_enum_tc(const char * id,const char * name,const CORBA::EnumMemberSeq & members)317 CORBA::TypeCode::NP_enum_tc(const char* id, const char* name,
318 const CORBA::EnumMemberSeq& members)
319 {
320 return new TypeCode_enum(id, name, members);
321 }
322
323 CORBA::TypeCode_ptr
NP_alias_tc(const char * id,const char * name,CORBA::TypeCode_ptr original_type)324 CORBA::TypeCode::NP_alias_tc(const char* id, const char* name,
325 CORBA::TypeCode_ptr original_type)
326 {
327 return new TypeCode_alias(id, name, ToTcBase_Checked(original_type));
328 }
329
330 #if 0
331 CORBA::TypeCode_ptr
332 CORBA::TypeCode::NP_exception_tc(const char* id, const char* name,
333 const CORBA::StructMemberSeq& members)
334 {
335 const CORBA::ULong memberCount = members.length();
336 for( CORBA::ULong i = 0; i < memberCount; i++ )
337 if ( !PR_is_valid(members[i].type) || CORBA::is_nil(members[i].type))
338 OMNIORB_THROW(BAD_TYPECODE,
339 BAD_TYPECODE_TypeCodeIsNil,
340 CORBA::COMPLETED_NO);
341
342 return new TypeCode_except(id, name, members);
343 }
344 #endif
345
346 CORBA::TypeCode_ptr
NP_interface_tc(const char * id,const char * name)347 CORBA::TypeCode::NP_interface_tc(const char* id, const char* name)
348 {
349 return new TypeCode_objref(id, name);
350 }
351
352 CORBA::TypeCode_ptr
NP_string_tc(CORBA::ULong bound)353 CORBA::TypeCode::NP_string_tc(CORBA::ULong bound)
354 {
355 return new TypeCode_string(bound);
356 }
357
358 CORBA::TypeCode_ptr
NP_wstring_tc(CORBA::ULong bound)359 CORBA::TypeCode::NP_wstring_tc(CORBA::ULong bound)
360 {
361 return new TypeCode_wstring(bound);
362 }
363
364 CORBA::TypeCode_ptr
NP_fixed_tc(CORBA::UShort digits,CORBA::Short scale)365 CORBA::TypeCode::NP_fixed_tc(CORBA::UShort digits, CORBA::Short scale)
366 {
367 return new TypeCode_fixed(digits, scale);
368 }
369
370 CORBA::TypeCode_ptr
NP_sequence_tc(CORBA::ULong bound,CORBA::TypeCode_ptr element_type)371 CORBA::TypeCode::NP_sequence_tc(CORBA::ULong bound,
372 CORBA::TypeCode_ptr element_type)
373 {
374 return new TypeCode_sequence(bound, ToTcBase_Checked(element_type));
375 }
376
377 CORBA::TypeCode_ptr
NP_array_tc(CORBA::ULong length,CORBA::TypeCode_ptr element_type)378 CORBA::TypeCode::NP_array_tc(CORBA::ULong length,
379 CORBA::TypeCode_ptr element_type)
380 {
381 return new TypeCode_array(length, ToTcBase_Checked(element_type));
382 }
383
384 CORBA::TypeCode_ptr
NP_value_tc(const char * id,const char * name,CORBA::ValueModifier type_modifier,CORBA::TypeCode_ptr concrete_base,const ValueMemberSeq & members)385 CORBA::TypeCode::NP_value_tc(const char* id, const char* name,
386 CORBA::ValueModifier type_modifier,
387 CORBA::TypeCode_ptr concrete_base,
388 const ValueMemberSeq& members)
389 {
390 CORBA::ULong memberCount = members.length();
391 CORBA::ULong i;
392
393 TypeCode_value::Member* new_members =
394 new TypeCode_value::Member[memberCount];
395
396 for (i=0; i < memberCount; i++) {
397 new_members[i].name = CORBA::string_dup(members[i].name);
398 new_members[i].type =
399 TypeCode_collector::duplicateRef(ToTcBase(members[i].type));
400 new_members[i].access = members[i].access;
401 }
402
403 return new TypeCode_value(id, name, type_modifier, ToTcBase(concrete_base),
404 new_members, memberCount);
405 }
406
407 CORBA::TypeCode_ptr
NP_value_box_tc(const char * id,const char * name,CORBA::TypeCode_ptr boxed_type)408 CORBA::TypeCode::NP_value_box_tc(const char* id, const char* name,
409 CORBA::TypeCode_ptr boxed_type)
410 {
411 return new TypeCode_value_box(id, name, ToTcBase_Checked(boxed_type));
412 }
413
414
415 CORBA::TypeCode_ptr
NP_recursive_sequence_tc(CORBA::ULong bound,CORBA::ULong offset)416 CORBA::TypeCode::NP_recursive_sequence_tc(CORBA::ULong bound,
417 CORBA::ULong offset)
418 {
419 return new TypeCode_sequence(bound, offset);
420 }
421
422 CORBA::TypeCode_ptr
NP_recursive_tc(const char * id)423 CORBA::TypeCode::NP_recursive_tc(const char* id)
424 {
425 return new TypeCode_indirect(id);
426 }
427
428 //////////////////////////////////////////////////////////////////////
429 /////////////////////// Stub TypeCode Accessors //////////////////////
430 //////////////////////////////////////////////////////////////////////
431
432 // These are needed by the stubs to generate static typecodes
433 // for user-defined types. Before constructing or using any
434 // of the typecode functionnality it is important to ensure
435 // that any statically initialised data is properly constructed.
436
437 OMNI_NAMESPACE_BEGIN(omni)
438
439 static void check_static_data_is_initialised();
440
441
442 // The omniTypeCodeCollection singleton is used to track internal
443 // TypeCodes created in this file, and holds a hash table of TypeCodes
444 // created elsewhere.
445
446 static CORBA::ULong tc_tablesize = 131;
447
448 class omniTypeCodeCollection : public omniTrackedObject {
449 public:
omniTypeCodeCollection()450 omniTypeCodeCollection() {
451 pd_tracker = new CORBA::TypeCode::_Tracker(__FILE__);
452 pd_table = new Entry*[tc_tablesize];
453 memset((void*)pd_table, 0, tc_tablesize * sizeof(Entry*));
454 }
455 virtual ~omniTypeCodeCollection();
456
track(CORBA::TypeCode_ptr tc)457 inline void track(CORBA::TypeCode_ptr tc) {
458 pd_tracker->add(tc);
459 }
460
461 void add(const char* id, CORBA::TypeCode_ptr tc);
462 // Register TypeCode in the table
463
464 CORBA::TypeCode_ptr find(const char* id);
465 // Find TypeCode
466
467 void remove(const char* id, CORBA::TypeCode_ptr tc);
468 // Remove TypeCode if present; do nothing if not
469
470 private:
471 // Entry in the hash table
472 struct Entry {
473 CORBA::String_var repoId;
474 CORBA::TypeCode_ptr typecode;
475 Entry* next;
476
EntryomniTypeCodeCollection::Entry477 inline Entry(const char* id, CORBA::TypeCode_ptr tc)
478 : repoId(id), typecode(tc), next(0) {}
479 };
480
hash_id(const char * id)481 inline CORBA::ULong hash_id(const char* id)
482 {
483 CORBA::ULong n = 0;
484 while (*id) n = ((n << 5) ^ (n >> 27)) ^ *id++;
485 return n;
486 }
487
488 CORBA::TypeCode::_Tracker* pd_tracker;
489 Entry** pd_table;
490 friend void check_static_data_is_initialised();
491 };
492
493 static omniTypeCodeCollection* the_typecodes = 0;
494
495
OMNI_NAMESPACE_END(omni)496 OMNI_NAMESPACE_END(omni)
497
498
499 CORBA::TypeCode_ptr
500 CORBA::TypeCode::PR_struct_tc(const char* id, const char* name,
501 const PR_structMember* members,
502 ULong memberCount,
503 CORBA::TypeCode::_Tracker* tracker)
504 {
505 check_static_data_is_initialised();
506
507 TypeCode_base* indirect = 0;
508
509 CORBA::TypeCode_ptr r = the_typecodes->find(id);
510 if (r) {
511 indirect = ToTcBase(r);
512 if (indirect->NP_kind() == CORBA::_np_tk_indirect) {
513 // Resolving a forward struct. We create the struct then
514 // complete the indirection below.
515 }
516 else {
517 OMNIORB_ASSERT(indirect->NP_kind() == CORBA::tk_struct);
518 return r;
519 }
520 }
521
522 TypeCode_struct::Member* new_members
523 = new TypeCode_struct::Member[memberCount];
524
525 for( ULong i = 0; i < memberCount; i++ ) {
526 // We duplicate the name and type.
527 new_members[i].name = CORBA::string_dup(members[i].name);
528 new_members[i].type = CORBA::TypeCode::_duplicate(members[i].type);
529 }
530
531 r = new TypeCode_struct(CORBA::string_dup(id),
532 CORBA::string_dup(name),
533 new_members, memberCount);
534 tracker->add(r);
535 the_typecodes->add(id, r);
536 if (indirect)
537 indirect->NP_complete_recursive(ToTcBase(r), id);
538
539 return r;
540 }
541
542
543 CORBA::TypeCode_ptr
PR_union_tc(const char * id,const char * name,TypeCode_ptr discriminator_type,const PR_unionMember * members,ULong memberCount,Long deflt,CORBA::TypeCode::_Tracker * tracker)544 CORBA::TypeCode::PR_union_tc(const char* id, const char* name,
545 TypeCode_ptr discriminator_type,
546 const PR_unionMember* members,
547 ULong memberCount, Long deflt,
548 CORBA::TypeCode::_Tracker* tracker)
549 {
550 check_static_data_is_initialised();
551
552 TypeCode_base* indirect = 0;
553
554 CORBA::TypeCode_ptr r = the_typecodes->find(id);
555 if (r) {
556 indirect = ToTcBase(r);
557 if (indirect->NP_kind() == CORBA::_np_tk_indirect) {
558 // Resolving a forward struct. We create the union then
559 // complete the indirection below.
560 }
561 else {
562 OMNIORB_ASSERT(indirect->NP_kind() == CORBA::tk_union);
563 return r;
564 }
565 }
566
567 r = new TypeCode_union(id, name,
568 ToTcBase(discriminator_type),
569 members, memberCount, deflt);
570 tracker->add(r);
571 the_typecodes->add(id, r);
572 if (indirect)
573 indirect->NP_complete_recursive(ToTcBase(r), id);
574
575 return r;
576 }
577
578
579 CORBA::TypeCode_ptr
PR_enum_tc(const char * id,const char * name,const char ** members,ULong memberCount,CORBA::TypeCode::_Tracker * tracker)580 CORBA::TypeCode::PR_enum_tc(const char* id, const char* name,
581 const char** members, ULong memberCount,
582 CORBA::TypeCode::_Tracker* tracker)
583 {
584 check_static_data_is_initialised();
585
586 CORBA::TypeCode_ptr r = the_typecodes->find(id);
587 if (r) return r;
588
589 CORBA::EnumMemberSeq memberSeq;
590
591 memberSeq.length(memberCount);
592 for( ULong i = 0; i < memberCount; i++ )
593 memberSeq[i] = members[i];
594
595 r = NP_enum_tc(id, name, memberSeq);
596 tracker->add(r);
597 the_typecodes->add(id, r);
598 return r;
599 }
600
601
602 CORBA::TypeCode_ptr
PR_alias_tc(const char * id,const char * name,CORBA::TypeCode_ptr original_type,CORBA::TypeCode::_Tracker * tracker)603 CORBA::TypeCode::PR_alias_tc(const char* id, const char* name,
604 CORBA::TypeCode_ptr original_type,
605 CORBA::TypeCode::_Tracker* tracker)
606 {
607 check_static_data_is_initialised();
608
609 CORBA::TypeCode_ptr r = the_typecodes->find(id);
610 if (r) return r;
611
612 r = new TypeCode_alias(id, name, ToTcBase(original_type));
613 tracker->add(r);
614 the_typecodes->add(id, r);
615 return r;
616 }
617
618
619 CORBA::TypeCode_ptr
PR_exception_tc(const char * id,const char * name,const PR_structMember * members,ULong memberCount,CORBA::TypeCode::_Tracker * tracker)620 CORBA::TypeCode::PR_exception_tc(const char* id, const char* name,
621 const PR_structMember* members,
622 ULong memberCount,
623 CORBA::TypeCode::_Tracker* tracker)
624 {
625 check_static_data_is_initialised();
626
627 CORBA::TypeCode_ptr r = the_typecodes->find(id);
628 if (r) return r;
629
630 TypeCode_struct::Member* new_members =
631 new TypeCode_struct::Member[memberCount];
632
633 for( ULong i = 0; i < memberCount; i++ ) {
634 // We duplicate the name and type.
635 new_members[i].name = CORBA::string_dup(members[i].name);
636 new_members[i].type = CORBA::TypeCode::_duplicate(members[i].type);
637 }
638
639 r = new TypeCode_except(CORBA::string_dup(id),
640 CORBA::string_dup(name),
641 new_members, memberCount);
642 tracker->add(r);
643 the_typecodes->add(id, r);
644 return r;
645 }
646
647
648 CORBA::TypeCode_ptr
PR_interface_tc(const char * id,const char * name,CORBA::TypeCode::_Tracker * tracker)649 CORBA::TypeCode::PR_interface_tc(const char* id, const char* name,
650 CORBA::TypeCode::_Tracker* tracker)
651 {
652 check_static_data_is_initialised();
653
654 CORBA::TypeCode_ptr r = the_typecodes->find(id);
655 if (r) return r;
656
657 r = new TypeCode_objref(id, name);
658 tracker->add(r);
659 the_typecodes->add(id, r);
660 return r;
661 }
662
663 CORBA::TypeCode_ptr
PR_value_tc(const char * id,const char * name,CORBA::ValueModifier type_modifier,CORBA::TypeCode_ptr concrete_base,const PR_valueMember * members,CORBA::ULong memberCount,CORBA::TypeCode::_Tracker * tracker)664 CORBA::TypeCode::PR_value_tc(const char* id, const char* name,
665 CORBA::ValueModifier type_modifier,
666 CORBA::TypeCode_ptr concrete_base,
667 const PR_valueMember* members,
668 CORBA::ULong memberCount,
669 CORBA::TypeCode::_Tracker* tracker)
670 {
671 check_static_data_is_initialised();
672
673 TypeCode_base* indirect = 0;
674
675 CORBA::TypeCode_ptr r = the_typecodes->find(id);
676 if (r) {
677 indirect = ToTcBase(r);
678 if (indirect->NP_kind() == CORBA::_np_tk_indirect) {
679 // Resolving a forward value. We create the value then
680 // complete the indirection below.
681 }
682 else {
683 OMNIORB_ASSERT(indirect->NP_kind() == CORBA::tk_value);
684 return r;
685 }
686 }
687
688 TypeCode_value::Member* new_members
689 = new TypeCode_value::Member[memberCount];
690
691 for( ULong i = 0; i < memberCount; i++ ) {
692 // We duplicate the name and type.
693 new_members[i].name = CORBA::string_dup(members[i].name);
694 new_members[i].type = CORBA::TypeCode::_duplicate(members[i].type);
695 new_members[i].access = members[i].access;
696 }
697
698 r = new TypeCode_value(id, name, type_modifier, ToTcBase(concrete_base),
699 new_members, memberCount);
700 tracker->add(r);
701 the_typecodes->add(id, r);
702 if (indirect)
703 indirect->NP_complete_recursive(ToTcBase(r), id);
704
705 return r;
706 }
707
708 CORBA::TypeCode_ptr
PR_value_box_tc(const char * id,const char * name,CORBA::TypeCode_ptr boxed_type,CORBA::TypeCode::_Tracker * tracker)709 CORBA::TypeCode::PR_value_box_tc(const char* id, const char* name,
710 CORBA::TypeCode_ptr boxed_type,
711 CORBA::TypeCode::_Tracker* tracker)
712 {
713 check_static_data_is_initialised();
714
715 CORBA::TypeCode_ptr r = the_typecodes->find(id);
716 if (r) return r;
717
718 r = new TypeCode_value_box(id, name, ToTcBase(boxed_type));
719 tracker->add(r);
720 the_typecodes->add(id, r);
721 return r;
722 }
723
724 CORBA::TypeCode_ptr
PR_abstract_interface_tc(const char * id,const char * name,CORBA::TypeCode::_Tracker * tracker)725 CORBA::TypeCode::PR_abstract_interface_tc(const char* id, const char* name,
726 CORBA::TypeCode::_Tracker* tracker)
727 {
728 check_static_data_is_initialised();
729
730 CORBA::TypeCode_ptr r = the_typecodes->find(id);
731 if (r) return r;
732
733 r = new TypeCode_abstract_interface(id, name);
734 tracker->add(r);
735 the_typecodes->add(id, r);
736 return r;
737 }
738
739 CORBA::TypeCode_ptr
PR_local_interface_tc(const char * id,const char * name,CORBA::TypeCode::_Tracker * tracker)740 CORBA::TypeCode::PR_local_interface_tc(const char* id, const char* name,
741 CORBA::TypeCode::_Tracker* tracker)
742 {
743 check_static_data_is_initialised();
744
745 CORBA::TypeCode_ptr r = the_typecodes->find(id);
746 if (r) return r;
747
748 r = new TypeCode_local_interface(id, name);
749 tracker->add(r);
750 the_typecodes->add(id, r);
751 return r;
752 }
753
754
755
756 CORBA::TypeCode_ptr
PR_string_tc(CORBA::ULong bound,CORBA::TypeCode::_Tracker * tracker)757 CORBA::TypeCode::PR_string_tc(CORBA::ULong bound,
758 CORBA::TypeCode::_Tracker* tracker)
759 {
760 if( bound == 0 ) return PR_string_tc();
761 check_static_data_is_initialised();
762 CORBA::TypeCode_ptr r = new TypeCode_string(bound);
763 tracker->add(r);
764 return r;
765 }
766
767 CORBA::TypeCode_ptr
PR_wstring_tc(CORBA::ULong bound,CORBA::TypeCode::_Tracker * tracker)768 CORBA::TypeCode::PR_wstring_tc(CORBA::ULong bound,
769 CORBA::TypeCode::_Tracker* tracker)
770 {
771 if( bound == 0 ) return PR_wstring_tc();
772 check_static_data_is_initialised();
773 CORBA::TypeCode_ptr r = new TypeCode_wstring(bound);
774 tracker->add(r);
775 return r;
776 }
777
778 CORBA::TypeCode_ptr
PR_fixed_tc(CORBA::UShort digits,CORBA::UShort scale,CORBA::TypeCode::_Tracker * tracker)779 CORBA::TypeCode::PR_fixed_tc(CORBA::UShort digits, CORBA::UShort scale,
780 CORBA::TypeCode::_Tracker* tracker)
781 {
782 check_static_data_is_initialised();
783 CORBA::TypeCode_ptr r = new TypeCode_fixed(digits, scale);
784 tracker->add(r);
785 return r;
786 }
787
788 CORBA::TypeCode_ptr
PR_sequence_tc(CORBA::ULong bound,CORBA::TypeCode_ptr element_type,CORBA::TypeCode::_Tracker * tracker)789 CORBA::TypeCode::PR_sequence_tc(CORBA::ULong bound,
790 CORBA::TypeCode_ptr element_type,
791 CORBA::TypeCode::_Tracker* tracker)
792 {
793 check_static_data_is_initialised();
794 CORBA::TypeCode_ptr r = new TypeCode_sequence(bound, ToTcBase(element_type));
795 tracker->add(r);
796 return r;
797 }
798
799
800 CORBA::TypeCode_ptr
PR_array_tc(CORBA::ULong length,CORBA::TypeCode_ptr element_type,CORBA::TypeCode::_Tracker * tracker)801 CORBA::TypeCode::PR_array_tc(CORBA::ULong length,
802 CORBA::TypeCode_ptr element_type,
803 CORBA::TypeCode::_Tracker* tracker)
804 {
805 check_static_data_is_initialised();
806 CORBA::TypeCode_ptr r = new TypeCode_array(length, ToTcBase(element_type));
807 tracker->add(r);
808 return r;
809 }
810
811
812 CORBA::TypeCode_ptr
PR_recursive_sequence_tc(CORBA::ULong bound,CORBA::ULong offset,CORBA::TypeCode::_Tracker * tracker)813 CORBA::TypeCode::PR_recursive_sequence_tc(CORBA::ULong bound,
814 CORBA::ULong offset,
815 CORBA::TypeCode::_Tracker* tracker)
816 {
817 check_static_data_is_initialised();
818 CORBA::TypeCode_ptr r = new TypeCode_sequence(bound, offset);
819 tracker->add(r);
820 return r;
821 }
822
823
824 CORBA::TypeCode_ptr
PR_forward_tc(const char * id,CORBA::TypeCode::_Tracker * tracker)825 CORBA::TypeCode::PR_forward_tc(const char* id,
826 CORBA::TypeCode::_Tracker* tracker)
827 {
828 check_static_data_is_initialised();
829
830 CORBA::TypeCode_ptr r = the_typecodes->find(id);
831 if (!r) {
832 r = new TypeCode_indirect(id);
833 tracker->add(r);
834 the_typecodes->add(id, r);
835 }
836 return r;
837 }
838
839
840
PR_null_tc()841 CORBA::TypeCode_ptr CORBA::TypeCode::PR_null_tc() {
842 check_static_data_is_initialised();
843 return CORBA::_tc_null;
844 }
PR_void_tc()845 CORBA::TypeCode_ptr CORBA::TypeCode::PR_void_tc() {
846 check_static_data_is_initialised();
847 return CORBA::_tc_void;
848 }
PR_short_tc()849 CORBA::TypeCode_ptr CORBA::TypeCode::PR_short_tc() {
850 check_static_data_is_initialised();
851 return CORBA::_tc_short;
852 }
PR_long_tc()853 CORBA::TypeCode_ptr CORBA::TypeCode::PR_long_tc() {
854 check_static_data_is_initialised();
855 return CORBA::_tc_long;
856 }
PR_ushort_tc()857 CORBA::TypeCode_ptr CORBA::TypeCode::PR_ushort_tc() {
858 check_static_data_is_initialised();
859 return CORBA::_tc_ushort;
860 }
PR_ulong_tc()861 CORBA::TypeCode_ptr CORBA::TypeCode::PR_ulong_tc() {
862 check_static_data_is_initialised();
863 return CORBA::_tc_ulong;
864 }
PR_float_tc()865 CORBA::TypeCode_ptr CORBA::TypeCode::PR_float_tc() {
866 check_static_data_is_initialised();
867 return CORBA::_tc_float;
868 }
PR_double_tc()869 CORBA::TypeCode_ptr CORBA::TypeCode::PR_double_tc() {
870 check_static_data_is_initialised();
871 return CORBA::_tc_double;
872 }
PR_boolean_tc()873 CORBA::TypeCode_ptr CORBA::TypeCode::PR_boolean_tc() {
874 check_static_data_is_initialised();
875 return CORBA::_tc_boolean;
876 }
PR_char_tc()877 CORBA::TypeCode_ptr CORBA::TypeCode::PR_char_tc() {
878 check_static_data_is_initialised();
879 return CORBA::_tc_char;
880 }
PR_wchar_tc()881 CORBA::TypeCode_ptr CORBA::TypeCode::PR_wchar_tc() {
882 check_static_data_is_initialised();
883 return CORBA::_tc_wchar;
884 }
PR_octet_tc()885 CORBA::TypeCode_ptr CORBA::TypeCode::PR_octet_tc() {
886 check_static_data_is_initialised();
887 return CORBA::_tc_octet;
888 }
PR_any_tc()889 CORBA::TypeCode_ptr CORBA::TypeCode::PR_any_tc() {
890 check_static_data_is_initialised();
891 return CORBA::_tc_any;
892 }
PR_TypeCode_tc()893 CORBA::TypeCode_ptr CORBA::TypeCode::PR_TypeCode_tc() {
894 check_static_data_is_initialised();
895 return CORBA::_tc_TypeCode;
896 }
PR_Principal_tc()897 CORBA::TypeCode_ptr CORBA::TypeCode::PR_Principal_tc() {
898 check_static_data_is_initialised();
899 return CORBA::_tc_Principal;
900 }
PR_Object_tc()901 CORBA::TypeCode_ptr CORBA::TypeCode::PR_Object_tc() {
902 check_static_data_is_initialised();
903 return CORBA::_tc_Object;
904 }
PR_string_tc()905 CORBA::TypeCode_ptr CORBA::TypeCode::PR_string_tc() {
906 check_static_data_is_initialised();
907 return CORBA::_tc_string;
908 }
PR_wstring_tc()909 CORBA::TypeCode_ptr CORBA::TypeCode::PR_wstring_tc() {
910 check_static_data_is_initialised();
911 return CORBA::_tc_wstring;
912 }
913 #ifdef HAS_LongLong
PR_longlong_tc()914 CORBA::TypeCode_ptr CORBA::TypeCode::PR_longlong_tc() {
915 check_static_data_is_initialised();
916 return CORBA::_tc_longlong;
917 }
PR_ulonglong_tc()918 CORBA::TypeCode_ptr CORBA::TypeCode::PR_ulonglong_tc() {
919 check_static_data_is_initialised();
920 return CORBA::_tc_ulonglong;
921 }
922 #endif
923 #ifdef HAS_LongDouble
PR_longdouble_tc()924 CORBA::TypeCode_ptr CORBA::TypeCode::PR_longdouble_tc() {
925 check_static_data_is_initialised();
926 return CORBA::_tc_longdouble;
927 }
928 #endif
929
930
931 // OMG TypeCode release function
932
933 void
release(TypeCode_ptr o)934 CORBA::release(TypeCode_ptr o)
935 {
936 OMNIORB_ASSERT(CORBA::TypeCode::PR_is_valid(o));
937
938 if( CORBA::TypeCode::PR_is_valid(o) && !CORBA::is_nil(o) )
939 TypeCode_collector::releaseRef(ToTcBase(o));
940 }
941
942
OMNI_NAMESPACE_BEGIN(omni)943 OMNI_NAMESPACE_BEGIN(omni)
944
945 //////////////////////////////////////////////////////////////////////
946 //////////////////////////// TypeCode_base ///////////////////////////
947 //////////////////////////////////////////////////////////////////////
948
949 TypeCode_base::TypeCode_base(CORBA::TCKind tck)
950 : pd_complete(1), pd_mark(0), pd_ref_count(1),
951 pd_loop_member(0), pd_internal_ref_count(0),
952 pd_aliasExpandedTc(0), pd_compactTc(0), pd_tck(tck),
953 pd_next(0)
954 {
955 switch( tck ) {
956
957 case CORBA::tk_null:
958 case CORBA::tk_void:
959 pd_alignmentTable.setNumEntries(1);
960 pd_alignmentTable.addSimple(omni::ALIGN_1, 0);
961 pd_aliasExpandedTc = pd_compactTc = this;
962 break;
963
964 case CORBA::tk_boolean:
965 case CORBA::tk_octet:
966 pd_alignmentTable.setNumEntries(1);
967 pd_alignmentTable.addSimple(omni::ALIGN_1, 1);
968 pd_aliasExpandedTc = pd_compactTc = this;
969 break;
970
971 case CORBA::tk_short:
972 case CORBA::tk_ushort:
973 pd_alignmentTable.setNumEntries(1);
974 pd_alignmentTable.addSimple(omni::ALIGN_2, 2);
975 pd_aliasExpandedTc = pd_compactTc = this;
976 break;
977
978 case CORBA::tk_long:
979 case CORBA::tk_ulong:
980 case CORBA::tk_float:
981 pd_alignmentTable.setNumEntries(1);
982 pd_alignmentTable.addSimple(omni::ALIGN_4, 4);
983 pd_aliasExpandedTc = pd_compactTc = this;
984 break;
985
986 case CORBA::tk_double:
987 #ifdef HAS_LongLong
988 case CORBA::tk_longlong:
989 case CORBA::tk_ulonglong:
990 #endif
991 pd_alignmentTable.setNumEntries(1);
992 pd_alignmentTable.addSimple(omni::ALIGN_8, 8);
993 pd_aliasExpandedTc = pd_compactTc = this;
994 break;
995
996 #ifdef HAS_LongDouble
997 case CORBA::tk_longdouble:
998 pd_alignmentTable.setNumEntries(1);
999 pd_alignmentTable.addSimple(omni::ALIGN_8, 16);
1000 pd_aliasExpandedTc = pd_compactTc = this;
1001 break;
1002 #endif
1003
1004 case CORBA::tk_char:
1005 case CORBA::tk_wchar:
1006 pd_alignmentTable.setNumEntries(1);
1007 pd_alignmentTable.addNasty(this);
1008 pd_aliasExpandedTc = pd_compactTc = this;
1009 break;
1010
1011 case CORBA::tk_any:
1012 case CORBA::tk_TypeCode:
1013 case CORBA::tk_Principal:
1014 pd_alignmentTable.setNumEntries(1);
1015 pd_alignmentTable.addNasty(this);
1016 pd_aliasExpandedTc = pd_compactTc = this;
1017 break;
1018
1019 case CORBA::tk_string:
1020 pd_compactTc = this;
1021 break;
1022
1023 case CORBA::tk_wstring:
1024 pd_compactTc = this;
1025 break;
1026
1027 case CORBA::tk_fixed:
1028 pd_aliasExpandedTc = pd_compactTc = this;
1029 break;
1030
1031 default:
1032 pd_complete = 0;
1033 break;
1034 }
1035 }
1036
1037
~TypeCode_base()1038 TypeCode_base::~TypeCode_base()
1039 {
1040 if( pd_aliasExpandedTc && pd_aliasExpandedTc != this )
1041 TypeCode_collector::releaseRef(pd_aliasExpandedTc);
1042 if( pd_compactTc && pd_compactTc != this )
1043 TypeCode_collector::releaseRef(pd_compactTc);
1044 }
1045
1046
1047 void
NP_marshalSimpleParams(cdrStream &,TypeCode_offsetTable *) const1048 TypeCode_base::NP_marshalSimpleParams(cdrStream &,
1049 TypeCode_offsetTable* ) const
1050 {
1051 OMNIORB_THROW(BAD_TYPECODE,
1052 BAD_TYPECODE_InvalidOperation,
1053 CORBA::COMPLETED_NO);
1054 }
1055
1056 void
NP_marshalComplexParams(cdrStream &,TypeCode_offsetTable *) const1057 TypeCode_base::NP_marshalComplexParams(cdrStream &,
1058 TypeCode_offsetTable* ) const
1059 {
1060 OMNIORB_THROW(BAD_TYPECODE,
1061 BAD_TYPECODE_InvalidOperation,
1062 CORBA::COMPLETED_NO);
1063 }
1064
1065 const TypeCode_base*
NP_expand(const TypeCode_base * tc)1066 TypeCode_base::NP_expand(const TypeCode_base* tc)
1067 {
1068 while (1) {
1069 if (tc->NP_kind() == CORBA::tk_alias)
1070 tc = tc->NP_content_type();
1071 else if (tc->NP_kind() == CORBA::_np_tk_indirect)
1072 tc = ((TypeCode_indirect*)tc)->NP_resolved();
1073 else
1074 break;
1075 }
1076 return tc;
1077 }
1078
1079 CORBA::Boolean
NP_equal(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist * tcpl) const1080 TypeCode_base::NP_equal(const TypeCode_base* TCp,
1081 CORBA::Boolean is_equivalent,
1082 const TypeCode_pairlist* tcpl) const
1083 {
1084 if (NP_kind() == CORBA::_np_tk_indirect)
1085 return TypeCode_indirect::strip(this)->NP_equal(TCp, is_equivalent, tcpl);
1086
1087 TCp = TypeCode_indirect::strip(TCp);
1088
1089 // Check for trivial pointer-based equality
1090 if (this == TCp) return 1;
1091
1092 // Check the pairlist for a match, for recursive typecodes
1093 if( TypeCode_pairlist::contains(tcpl, this, TCp) )
1094 return 1;
1095
1096 // No match, so create a pair for these two codes, to avoid loops
1097 TypeCode_pairlist tcpl_tmp(tcpl, this, TCp);
1098
1099 // Should we expand the aliases?
1100 if (is_equivalent)
1101 {
1102 const TypeCode_base* tc1_tmp = NP_expand(this);
1103 const TypeCode_base* tc2_tmp = NP_expand(TCp);
1104
1105 return tc1_tmp->NP_extendedEqual(tc2_tmp, 1, &tcpl_tmp);
1106 }
1107 else
1108 return NP_extendedEqual(TCp, 0, &tcpl_tmp);
1109 }
1110
1111
1112 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean,const TypeCode_pairlist *) const1113 TypeCode_base::NP_extendedEqual(const TypeCode_base* TCp,
1114 CORBA::Boolean,
1115 const TypeCode_pairlist*) const
1116 {
1117 // Base types are equivalent if their Kinds match
1118 return NP_kind() == TCp->NP_kind();
1119 }
1120
1121
1122 const char*
NP_id() const1123 TypeCode_base::NP_id() const
1124 {
1125 throw CORBA::TypeCode::BadKind();
1126 #ifdef NEED_DUMMY_RETURN
1127 return 0;
1128 #endif
1129 }
1130
1131 const char*
NP_name() const1132 TypeCode_base::NP_name() const
1133 {
1134 throw CORBA::TypeCode::BadKind();
1135 #ifdef NEED_DUMMY_RETURN
1136 return 0;
1137 #endif
1138 }
1139
1140 CORBA::ULong
NP_member_count() const1141 TypeCode_base::NP_member_count() const
1142 {
1143 throw CORBA::TypeCode::BadKind();
1144 #ifdef NEED_DUMMY_RETURN
1145 return 0;
1146 #endif
1147 }
1148
1149 const char*
NP_member_name(CORBA::ULong index) const1150 TypeCode_base::NP_member_name(CORBA::ULong index) const
1151 {
1152 throw CORBA::TypeCode::BadKind();
1153 #ifdef NEED_DUMMY_RETURN
1154 return 0;
1155 #endif
1156 }
1157
1158 TypeCode_base*
NP_member_type(CORBA::ULong index) const1159 TypeCode_base::NP_member_type(CORBA::ULong index) const
1160 {
1161 throw CORBA::TypeCode::BadKind();
1162 #ifdef NEED_DUMMY_RETURN
1163 return 0;
1164 #endif
1165 }
1166
1167 CORBA::Any*
NP_member_label(CORBA::ULong index) const1168 TypeCode_base::NP_member_label(CORBA::ULong index) const
1169 {
1170 throw CORBA::TypeCode::BadKind();
1171 #ifdef NEED_DUMMY_RETURN
1172 return 0;
1173 #endif
1174 }
1175
1176 TypeCode_base*
NP_discriminator_type() const1177 TypeCode_base::NP_discriminator_type() const
1178 {
1179 throw CORBA::TypeCode::BadKind();
1180 #ifdef NEED_DUMMY_RETURN
1181 return 0;
1182 #endif
1183 }
1184
1185 CORBA::Long
NP_default_index() const1186 TypeCode_base::NP_default_index() const
1187 {
1188 throw CORBA::TypeCode::BadKind();
1189 #ifdef NEED_DUMMY_RETURN
1190 return 0;
1191 #endif
1192 }
1193
1194 CORBA::ULong
NP_length() const1195 TypeCode_base::NP_length() const
1196 {
1197 throw CORBA::TypeCode::BadKind();
1198 #ifdef NEED_DUMMY_RETURN
1199 return 0;
1200 #endif
1201 }
1202
1203
1204 TypeCode_base*
NP_content_type() const1205 TypeCode_base::NP_content_type() const
1206 {
1207 throw CORBA::TypeCode::BadKind();
1208 #ifdef NEED_DUMMY_RETURN
1209 return 0;
1210 #endif
1211 }
1212
1213 CORBA::UShort
NP_fixed_digits() const1214 TypeCode_base::NP_fixed_digits() const
1215 {
1216 throw CORBA::TypeCode::BadKind();
1217 #ifdef NEED_DUMMY_RETURN
1218 return 0;
1219 #endif
1220 }
1221
1222 CORBA::Short
NP_fixed_scale() const1223 TypeCode_base::NP_fixed_scale() const
1224 {
1225 throw CORBA::TypeCode::BadKind();
1226 #ifdef NEED_DUMMY_RETURN
1227 return 0;
1228 #endif
1229 }
1230
1231 CORBA::Long
NP_param_count() const1232 TypeCode_base::NP_param_count() const
1233 {
1234 return 0;
1235 }
1236
1237
1238 CORBA::Any*
NP_parameter(CORBA::Long) const1239 TypeCode_base::NP_parameter(CORBA::Long) const
1240 {
1241 throw CORBA::TypeCode::Bounds();
1242 #ifdef NEED_DUMMY_RETURN
1243 return 0;
1244 #endif
1245 }
1246
1247 CORBA::Short
NP_member_visibility(CORBA::ULong) const1248 TypeCode_base::NP_member_visibility(CORBA::ULong) const
1249 {
1250 throw CORBA::TypeCode::Bounds();
1251 #ifdef NEED_DUMMY_RETURN
1252 return 0;
1253 #endif
1254 }
1255
1256 CORBA::ValueModifier
NP_type_modifier() const1257 TypeCode_base::NP_type_modifier() const
1258 {
1259 throw CORBA::TypeCode::Bounds();
1260 #ifdef NEED_DUMMY_RETURN
1261 return 0;
1262 #endif
1263 }
1264
1265 TypeCode_base*
NP_concrete_base_type() const1266 TypeCode_base::NP_concrete_base_type() const
1267 {
1268 throw CORBA::TypeCode::BadKind();
1269 #ifdef NEED_DUMMY_RETURN
1270 return 0;
1271 #endif
1272 }
1273
1274
1275 CORBA::Boolean
NP_is_nil() const1276 TypeCode_base::NP_is_nil() const
1277 {
1278 return 0;
1279 }
1280
1281
1282 CORBA::Boolean
NP_containsAnAlias()1283 TypeCode_base::NP_containsAnAlias()
1284 {
1285 return 0;
1286 }
1287
1288
1289 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist *)1290 TypeCode_base::NP_aliasExpand(TypeCode_pairlist*)
1291 {
1292 throw omniORB::fatalException(__FILE__,__LINE__,
1293 "TypeCode_base::NP_aliasExpand() - should not have been called");
1294 #ifdef NEED_DUMMY_RETURN
1295 return 0;
1296 #endif
1297 }
1298
1299
1300 static omni_tracedmutex* aliasExpandedTc_lock = 0;
1301
1302
1303 TypeCode_base*
aliasExpand(TypeCode_base * tc)1304 TypeCode_base::aliasExpand(TypeCode_base* tc)
1305 {
1306 TypeCode_base* exp_tc;
1307 {
1308 omni_tracedmutex_lock l(*aliasExpandedTc_lock);
1309 exp_tc = tc->pd_aliasExpandedTc;
1310 }
1311
1312 if (!exp_tc) {
1313 TypeCode_base* aetc = tc->NP_containsAnAlias() ? tc->NP_aliasExpand(0) : tc;
1314
1315 {
1316 omni_tracedmutex_lock l(*aliasExpandedTc_lock);
1317 if (!tc->pd_aliasExpandedTc) {
1318 exp_tc = tc->pd_aliasExpandedTc = aetc;
1319 }
1320 else {
1321 exp_tc = tc->pd_aliasExpandedTc;
1322 if (aetc != tc)
1323 TypeCode_collector::releaseRef(aetc);
1324 }
1325 }
1326 }
1327 return TypeCode_collector::duplicateRef(exp_tc);
1328 }
1329
1330 TypeCode_base*
NP_compactTc()1331 TypeCode_base::NP_compactTc()
1332 {
1333 if ( !pd_compactTc ) {
1334 // Bounce this typecode off a cdrMemorystream.
1335 // This ensures that any recursive members are duplicated correctly.
1336 cdrMemoryStream s;
1337 CORBA::TypeCode::marshalTypeCode(this,s);
1338 pd_compactTc = ToTcBase(CORBA::TypeCode::unmarshalTypeCode(s));
1339 // Now remove all names and member_names from the typecode
1340 pd_compactTc->removeOptionalNames();
1341 }
1342 return TypeCode_collector::duplicateRef(pd_compactTc);
1343 }
1344
1345 void
removeOptionalNames()1346 TypeCode_base::removeOptionalNames()
1347 {
1348 return;
1349 }
1350
1351 void
NP_releaseChildren()1352 TypeCode_base::NP_releaseChildren()
1353 {
1354 return;
1355 }
1356
1357 //////////////////////////////////////////////////////////////////////
1358 /////////////////////////// TypeCode_string //////////////////////////
1359 //////////////////////////////////////////////////////////////////////
1360
1361 // Notes:
1362 // String typecodes have SIMPLE parameter lists (i.e. ones NOT enclosed in an
1363 // octet sequence encapsualtion)
1364
TypeCode_string(CORBA::ULong maxLen)1365 TypeCode_string::TypeCode_string(CORBA::ULong maxLen)
1366 : TypeCode_base(CORBA::tk_string)
1367 {
1368 pd_length = maxLen;
1369
1370 pd_alignmentTable.setNumEntries(1);
1371 pd_alignmentTable.addNasty(this);
1372 }
1373
1374
TypeCode_string()1375 TypeCode_string::TypeCode_string()
1376 : TypeCode_base(CORBA::tk_string)
1377 {
1378 pd_alignmentTable.setNumEntries(1);
1379 pd_alignmentTable.addNasty(this);
1380 }
1381
1382
~TypeCode_string()1383 TypeCode_string::~TypeCode_string() {}
1384
1385
1386 void
NP_marshalSimpleParams(cdrStream & s,TypeCode_offsetTable *) const1387 TypeCode_string::NP_marshalSimpleParams(cdrStream &s,
1388 TypeCode_offsetTable* ) const
1389 {
1390 pd_length >>= s;
1391 }
1392
1393 TypeCode_base*
NP_unmarshalSimpleParams(cdrStream & s,TypeCode_offsetTable * otbl)1394 TypeCode_string::NP_unmarshalSimpleParams(cdrStream &s,
1395 TypeCode_offsetTable* otbl)
1396 {
1397 TypeCode_string* _ptr = new TypeCode_string;
1398
1399 otbl->addEntry(otbl->currentOffset(), _ptr);
1400
1401 _ptr->pd_length <<= s;
1402
1403 return _ptr;
1404 }
1405
1406
1407 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean,const TypeCode_pairlist *) const1408 TypeCode_string::NP_extendedEqual(const TypeCode_base* TCp,
1409 CORBA::Boolean,
1410 const TypeCode_pairlist*) const
1411 {
1412 return ((NP_kind() == TCp->NP_kind()) && (NP_length() == TCp->NP_length()));
1413 }
1414
1415
1416 CORBA::ULong
NP_length() const1417 TypeCode_string::NP_length() const
1418 {
1419 return pd_length;
1420 }
1421
1422
1423 CORBA::Long
NP_param_count() const1424 TypeCode_string::NP_param_count() const
1425 {
1426 return 1;
1427 }
1428
1429
1430 CORBA::Any*
NP_parameter(CORBA::Long index) const1431 TypeCode_string::NP_parameter(CORBA::Long index) const
1432 {
1433 CORBA::Any* rv = new CORBA::Any;
1434
1435 try {
1436 switch (index) {
1437 case 0:
1438 *rv <<= pd_length;
1439 break;
1440 default:
1441 throw CORBA::TypeCode::Bounds();
1442 };
1443 }
1444 catch (...) {
1445 delete rv;
1446 throw;
1447 }
1448
1449 return rv;
1450 }
1451
1452 //////////////////////////////////////////////////////////////////////
1453 /////////////////////////// TypeCode_wstring /////////////////////////
1454 //////////////////////////////////////////////////////////////////////
1455
1456 // Notes:
1457 // WString typecodes have SIMPLE parameter lists (i.e. ones NOT enclosed in an
1458 // octet sequence encapsualtion)
1459
TypeCode_wstring(CORBA::ULong maxLen)1460 TypeCode_wstring::TypeCode_wstring(CORBA::ULong maxLen)
1461 : TypeCode_base(CORBA::tk_wstring)
1462 {
1463 pd_length = maxLen;
1464
1465 pd_alignmentTable.setNumEntries(1);
1466 pd_alignmentTable.addNasty(this);
1467 }
1468
1469
TypeCode_wstring()1470 TypeCode_wstring::TypeCode_wstring()
1471 : TypeCode_base(CORBA::tk_wstring)
1472 {
1473 pd_alignmentTable.setNumEntries(1);
1474 pd_alignmentTable.addNasty(this);
1475 }
1476
1477
~TypeCode_wstring()1478 TypeCode_wstring::~TypeCode_wstring() {}
1479
1480
1481 void
NP_marshalSimpleParams(cdrStream & s,TypeCode_offsetTable *) const1482 TypeCode_wstring::NP_marshalSimpleParams(cdrStream &s,
1483 TypeCode_offsetTable* ) const
1484 {
1485 pd_length >>= s;
1486 }
1487
1488 TypeCode_base*
NP_unmarshalSimpleParams(cdrStream & s,TypeCode_offsetTable * otbl)1489 TypeCode_wstring::NP_unmarshalSimpleParams(cdrStream &s,
1490 TypeCode_offsetTable* otbl)
1491 {
1492 TypeCode_wstring* _ptr = new TypeCode_wstring;
1493
1494 otbl->addEntry(otbl->currentOffset(), _ptr);
1495
1496 _ptr->pd_length <<= s;
1497
1498 return _ptr;
1499 }
1500
1501
1502 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean,const TypeCode_pairlist *) const1503 TypeCode_wstring::NP_extendedEqual(const TypeCode_base* TCp,
1504 CORBA::Boolean,
1505 const TypeCode_pairlist*) const
1506 {
1507 return ((NP_kind() == TCp->NP_kind()) && (NP_length() == TCp->NP_length()));
1508 }
1509
1510
1511 CORBA::ULong
NP_length() const1512 TypeCode_wstring::NP_length() const
1513 {
1514 return pd_length;
1515 }
1516
1517
1518 CORBA::Long
NP_param_count() const1519 TypeCode_wstring::NP_param_count() const
1520 {
1521 return 1;
1522 }
1523
1524
1525 CORBA::Any*
NP_parameter(CORBA::Long index) const1526 TypeCode_wstring::NP_parameter(CORBA::Long index) const
1527 {
1528 CORBA::Any* rv = new CORBA::Any;
1529
1530 try {
1531 switch (index) {
1532 case 0:
1533 *rv <<= pd_length;
1534 break;
1535 default:
1536 throw CORBA::TypeCode::Bounds();
1537 };
1538 }
1539 catch (...) {
1540 delete rv;
1541 throw;
1542 }
1543
1544 return rv;
1545 }
1546
1547
1548 //////////////////////////////////////////////////////////////////////
1549 /////////////////////////// TypeCode_fixed ///////////////////////////
1550 //////////////////////////////////////////////////////////////////////
1551
1552 // Notes:
1553 // Fixed typecodes have SIMPLE parameter lists (i.e. ones NOT enclosed in an
1554 // octet sequence encapsualtion)
1555
TypeCode_fixed(CORBA::UShort digits,CORBA::Short scale)1556 TypeCode_fixed::TypeCode_fixed(CORBA::UShort digits, CORBA::Short scale)
1557 : TypeCode_base(CORBA::tk_fixed)
1558 {
1559 if (digits < 1 || digits > OMNI_FIXED_DIGITS || scale > digits)
1560 OMNIORB_THROW(BAD_PARAM,
1561 BAD_PARAM_InvalidFixedPointLimits,
1562 CORBA::COMPLETED_NO);
1563
1564 pd_digits = digits;
1565 pd_scale = scale;
1566
1567 pd_alignmentTable.setNumEntries(1);
1568 pd_alignmentTable.addNasty(this);
1569 }
1570
TypeCode_fixed()1571 TypeCode_fixed::TypeCode_fixed()
1572 : TypeCode_base(CORBA::tk_fixed)
1573 {
1574 pd_alignmentTable.setNumEntries(1);
1575 pd_alignmentTable.addNasty(this);
1576 }
1577
~TypeCode_fixed()1578 TypeCode_fixed::~TypeCode_fixed() {}
1579
1580 void
NP_marshalSimpleParams(cdrStream & s,TypeCode_offsetTable *) const1581 TypeCode_fixed::NP_marshalSimpleParams(cdrStream &s,
1582 TypeCode_offsetTable* ) const
1583 {
1584 pd_digits >>= s;
1585 pd_scale >>= s;
1586 }
1587
1588 TypeCode_base*
NP_unmarshalSimpleParams(cdrStream & s,TypeCode_offsetTable * otbl)1589 TypeCode_fixed::NP_unmarshalSimpleParams(cdrStream &s,
1590 TypeCode_offsetTable* otbl)
1591 {
1592 TypeCode_fixed* _ptr = new TypeCode_fixed;
1593
1594 otbl->addEntry(otbl->currentOffset(), _ptr);
1595
1596 _ptr->pd_digits <<= s;
1597 _ptr->pd_scale <<= s;
1598
1599 return _ptr;
1600 }
1601
1602
1603 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean,const TypeCode_pairlist *) const1604 TypeCode_fixed::NP_extendedEqual(const TypeCode_base* TCp,
1605 CORBA::Boolean,
1606 const TypeCode_pairlist*) const
1607 {
1608 return ((NP_kind() == TCp->NP_kind()) &&
1609 (NP_fixed_digits() == TCp->NP_fixed_digits()) &&
1610 (NP_fixed_scale() == TCp->NP_fixed_scale()));
1611 }
1612
1613
1614 CORBA::UShort
NP_fixed_digits() const1615 TypeCode_fixed::NP_fixed_digits() const
1616 {
1617 return pd_digits;
1618 }
1619
1620 CORBA::Short
NP_fixed_scale() const1621 TypeCode_fixed::NP_fixed_scale() const
1622 {
1623 return pd_scale;
1624 }
1625
1626
1627
1628 //////////////////////////////////////////////////////////////////////
1629 /////////////////////////// TypeCode_objref //////////////////////////
1630 //////////////////////////////////////////////////////////////////////
1631
1632 // Notes:
1633 // The object reference typecode has a COMPLEX parameter list, which must
1634 // be encoded as an encapsulated octet sequence. This makes things
1635 // horrendously difficult, because of the way Indirection typecodes work.
1636
TypeCode_objref(const char * repositoryId,const char * name,CORBA::TCKind tck)1637 TypeCode_objref::TypeCode_objref(const char* repositoryId, const char* name,
1638 CORBA::TCKind tck)
1639 : TypeCode_base(tck)
1640 {
1641 pd_repoId = repositoryId;
1642 pd_name = name;
1643 pd_alignmentTable.setNumEntries(1);
1644 pd_alignmentTable.addNasty(this);
1645 pd_complete = 1;
1646 }
1647
1648
TypeCode_objref(CORBA::TCKind tck)1649 TypeCode_objref::TypeCode_objref(CORBA::TCKind tck)
1650 : TypeCode_base(tck)
1651 {
1652 pd_alignmentTable.setNumEntries(1);
1653 pd_alignmentTable.addNasty(this);
1654 }
1655
1656
~TypeCode_objref()1657 TypeCode_objref::~TypeCode_objref()
1658 {
1659 the_typecodes->remove(pd_repoId, this);
1660 }
1661
1662
1663 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable *) const1664 TypeCode_objref::NP_marshalComplexParams(cdrStream &s,
1665 TypeCode_offsetTable* ) const
1666 {
1667 s.marshalRawString(pd_repoId);
1668 s.marshalRawString(pd_name);
1669 }
1670
1671 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)1672 TypeCode_objref::NP_unmarshalComplexParams(cdrStream &s,
1673 TypeCode_offsetTable* otbl)
1674 {
1675 TypeCode_objref* _ptr = new TypeCode_objref;
1676
1677 otbl->addEntry(otbl->currentOffset(), _ptr);
1678
1679 _ptr->pd_repoId = s.unmarshalRawString();
1680 _ptr->pd_name = s.unmarshalRawString();
1681 _ptr->pd_complete = 1;
1682
1683 return _ptr;
1684 }
1685
1686
1687 TypeCode_paramListType
NP_paramListType() const1688 TypeCode_objref::NP_paramListType() const
1689 {
1690 return plt_Complex;
1691 }
1692
1693
1694 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist *) const1695 TypeCode_objref::NP_extendedEqual(const TypeCode_base* TCp,
1696 CORBA::Boolean is_equivalent,
1697 const TypeCode_pairlist* ) const
1698 {
1699 if (NP_kind() != TCp->NP_kind())
1700 return 0;
1701
1702 if (!omni::ptrStrMatch(NP_id(), TCp->NP_id())) {
1703 if (is_equivalent) {
1704 // Empty string is equivalent to CORBA::Object repoId
1705
1706 if (NP_id()[0] == '\0' &&
1707 omni::ptrStrMatch(TCp->NP_id(), CORBA::Object::_PD_repoId))
1708 return 1;
1709
1710 if (TCp->NP_id()[0] == '\0' &&
1711 omni::ptrStrMatch(NP_id(), CORBA::Object::_PD_repoId))
1712 return 1;
1713
1714 return 0;
1715 }
1716 }
1717 if (!is_equivalent)
1718 return NP_namesEqual(NP_name(), TCp->NP_name());
1719 else
1720 return 1;
1721 }
1722
1723
1724 const char*
NP_id() const1725 TypeCode_objref::NP_id() const
1726 {
1727 return pd_repoId;
1728 }
1729
1730
1731 const char*
NP_name() const1732 TypeCode_objref::NP_name() const
1733 {
1734 return pd_name;
1735 }
1736
1737
1738 CORBA::Long
NP_param_count() const1739 TypeCode_objref::NP_param_count() const
1740 {
1741 return 1;
1742 }
1743
1744
1745 CORBA::Any*
NP_parameter(CORBA::Long index) const1746 TypeCode_objref::NP_parameter(CORBA::Long index) const
1747 {
1748 CORBA::Any* rv = new CORBA::Any;
1749
1750 try {
1751 switch (index) {
1752 case 0:
1753 *rv <<= (const char* )pd_name;
1754 break;
1755 default:
1756 throw CORBA::TypeCode::Bounds();
1757 };
1758 }
1759 catch (...) {
1760 delete rv;
1761 throw;
1762 }
1763
1764 return rv;
1765 }
1766
1767 void
removeOptionalNames()1768 TypeCode_objref::removeOptionalNames()
1769 {
1770 if (!pd_compactTc) {
1771 pd_name = (const char*)"";
1772 pd_compactTc = this;
1773 }
1774 }
1775
1776 //////////////////////////////////////////////////////////////////////
1777 /////////////////////////// TypeCode_alias ///////////////////////////
1778 //////////////////////////////////////////////////////////////////////
1779
TypeCode_alias(const char * repositoryId,const char * name,TypeCode_base * real_type)1780 TypeCode_alias::TypeCode_alias(const char* repositoryId,
1781 const char* name,
1782 TypeCode_base* real_type)
1783 : TypeCode_base(CORBA::tk_alias)
1784 {
1785 // Initialise
1786 pd_repoId = repositoryId;
1787 pd_name = name;
1788 pd_content = TypeCode_collector::duplicateRef(real_type);
1789
1790 pd_alignmentTable.set(real_type->alignmentTable());
1791
1792 if( real_type->aliasExpandedTc() )
1793 pd_aliasExpandedTc =
1794 TypeCode_collector::duplicateRef(real_type->aliasExpandedTc());
1795
1796 pd_complete = NP_complete_recursive(this, repositoryId);
1797 }
1798
1799
~TypeCode_alias()1800 TypeCode_alias::~TypeCode_alias() {
1801 the_typecodes->remove(pd_repoId, this);
1802 }
1803
1804
1805 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl) const1806 TypeCode_alias::NP_marshalComplexParams(cdrStream &s,
1807 TypeCode_offsetTable* otbl) const
1808 {
1809 s.marshalRawString(pd_repoId);
1810 s.marshalRawString(pd_name);
1811 TypeCode_marshaller::marshal(ToTcBase(pd_content), s, otbl);
1812 }
1813
1814 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)1815 TypeCode_alias::NP_unmarshalComplexParams(cdrStream &s,
1816 TypeCode_offsetTable* otbl)
1817 {
1818 TypeCode_alias* _ptr = new TypeCode_alias;
1819
1820 otbl->addEntry(otbl->currentOffset(), _ptr);
1821
1822 _ptr->pd_repoId = s.unmarshalRawString();
1823 _ptr->pd_name = s.unmarshalRawString();
1824 _ptr->pd_content = TypeCode_marshaller::unmarshal(s, otbl);
1825 _ptr->pd_complete = 1;
1826 _ptr->pd_alignmentTable.set(ToTcBase(_ptr->pd_content)->alignmentTable());
1827
1828 return _ptr;
1829 }
1830
1831
1832 CORBA::Boolean
NP_complete_recursive_sequences(TypeCode_base * tc,CORBA::ULong offset)1833 TypeCode_alias::NP_complete_recursive_sequences(TypeCode_base* tc,
1834 CORBA::ULong offset)
1835 {
1836 // *** omniORB-specific - I assume here that the 'offset' parameter
1837 // ignores intermediate tk_alias typecodes between the recursive sequence
1838 // and it's content type, so I don't increase the offset here:
1839 if (!pd_complete)
1840 pd_complete =
1841 ToTcBase(pd_content)->NP_complete_recursive_sequences(tc, offset);
1842 return pd_complete;
1843 }
1844
1845 CORBA::Boolean
NP_complete_recursive(TypeCode_base * tc,const char * repoId)1846 TypeCode_alias::NP_complete_recursive(TypeCode_base* tc, const char* repoId)
1847 {
1848 if (!pd_complete)
1849 pd_complete = ToTcBase(pd_content)->NP_complete_recursive(tc, repoId);
1850 return pd_complete;
1851 }
1852
1853
1854 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist * tcpl) const1855 TypeCode_alias::NP_extendedEqual(const TypeCode_base* TCp,
1856 CORBA::Boolean is_equivalent,
1857 const TypeCode_pairlist* tcpl) const
1858 {
1859 if (NP_kind() != TCp->NP_kind())
1860 return 0;
1861
1862 if (is_equivalent) {
1863 if (NP_id() && TCp->NP_id())
1864 return NP_namesEqual(NP_id(),TCp->NP_id());
1865 }
1866 else {
1867 if (!NP_namesEqual(NP_id(),TCp->NP_id()))
1868 return 0;
1869 }
1870
1871 return (NP_content_type()->NP_equal(TCp->NP_content_type(),is_equivalent,
1872 tcpl));
1873 }
1874
1875
1876 const char*
NP_id() const1877 TypeCode_alias::NP_id() const
1878 {
1879 return pd_repoId;
1880 }
1881
1882
1883 const char*
NP_name() const1884 TypeCode_alias::NP_name() const
1885 {
1886 return pd_name;
1887 }
1888
1889
1890 TypeCode_base*
NP_content_type() const1891 TypeCode_alias::NP_content_type() const
1892 {
1893 return ToTcBase(pd_content);
1894 }
1895
1896
1897 CORBA::Long
NP_param_count() const1898 TypeCode_alias::NP_param_count() const
1899 {
1900 return 2;
1901 }
1902
1903
1904 CORBA::Any*
NP_parameter(CORBA::Long index) const1905 TypeCode_alias::NP_parameter(CORBA::Long index) const
1906 {
1907 CORBA::Any* rv = new CORBA::Any;
1908
1909 try {
1910 switch (index) {
1911 case 0:
1912 *rv <<= (const char* )pd_name;
1913 break;
1914 case 1:
1915 *rv <<= pd_content;
1916 break;
1917 default:
1918 throw CORBA::TypeCode::Bounds();
1919 };
1920 }
1921 catch (...) {
1922 delete rv;
1923 throw;
1924 }
1925
1926 return rv;
1927 }
1928
1929
1930 CORBA::Boolean
NP_containsAnAlias()1931 TypeCode_alias::NP_containsAnAlias()
1932 {
1933 return 1;
1934 }
1935
1936
1937 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist * tcpl)1938 TypeCode_alias::NP_aliasExpand(TypeCode_pairlist* tcpl)
1939 {
1940 if( ToTcBase(pd_content)->NP_containsAnAlias() )
1941 return ToTcBase(pd_content)->NP_aliasExpand(tcpl);
1942 else
1943 return TypeCode_collector::duplicateRef(ToTcBase(pd_content));
1944 }
1945
1946
1947 void
removeOptionalNames()1948 TypeCode_alias::removeOptionalNames()
1949 {
1950 if (!pd_compactTc) {
1951 pd_compactTc = this;
1952 pd_name = (const char*)"";
1953 ToTcBase(pd_content)->removeOptionalNames();
1954 }
1955 }
1956
1957 void
NP_releaseChildren()1958 TypeCode_alias::NP_releaseChildren()
1959 {
1960 // We must set pd_content to void before releasing the child, in case
1961 // the release causes a recursion back to this node.
1962 CORBA::TypeCode_ptr ctc = pd_content._retn();
1963 pd_content = CORBA::TypeCode::_duplicate(CORBA::_tc_void);
1964 CORBA::release(ctc);
1965 }
1966
1967
1968 //////////////////////////////////////////////////////////////////////
1969 ////////////////////////// TypeCode_sequence /////////////////////////
1970 //////////////////////////////////////////////////////////////////////
1971
TypeCode_sequence(CORBA::ULong maxLen,TypeCode_base * elem_type)1972 TypeCode_sequence::TypeCode_sequence(CORBA::ULong maxLen,
1973 TypeCode_base* elem_type)
1974 : TypeCode_base(CORBA::tk_sequence)
1975 {
1976 // Initialise
1977 pd_length = maxLen;
1978 pd_content = TypeCode_collector::duplicateRef(elem_type);
1979 pd_offset = 0;
1980
1981 NP_complete_recursive_sequences(this, 0);
1982
1983 pd_alignmentTable.setNumEntries(1);
1984 pd_alignmentTable.addNasty(this);
1985 }
1986
1987
TypeCode_sequence(CORBA::ULong maxLen,CORBA::ULong offset)1988 TypeCode_sequence::TypeCode_sequence(CORBA::ULong maxLen,
1989 CORBA::ULong offset)
1990 : TypeCode_base(CORBA::tk_sequence)
1991 {
1992 pd_length = maxLen;
1993 pd_offset = offset;
1994
1995 pd_alignmentTable.setNumEntries(1);
1996 pd_alignmentTable.addNasty(this);
1997 }
1998
TypeCode_sequence()1999 TypeCode_sequence::TypeCode_sequence()
2000 : TypeCode_base(CORBA::tk_sequence)
2001 {
2002 pd_alignmentTable.setNumEntries(1);
2003 pd_alignmentTable.addNasty(this);
2004 }
2005
2006
~TypeCode_sequence()2007 TypeCode_sequence::~TypeCode_sequence() { }
2008
2009
2010 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl) const2011 TypeCode_sequence::NP_marshalComplexParams(cdrStream &s,
2012 TypeCode_offsetTable* otbl) const
2013 {
2014 if (!pd_complete)
2015 OMNIORB_THROW(BAD_TYPECODE,BAD_TYPECODE_Incomplete, CORBA::COMPLETED_NO);
2016 TypeCode_marshaller::marshal(ToTcBase(pd_content), s, otbl);
2017 pd_length >>= s;
2018 }
2019
2020 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)2021 TypeCode_sequence::NP_unmarshalComplexParams(cdrStream &s,
2022 TypeCode_offsetTable* otbl)
2023 {
2024 TypeCode_sequence* _ptr = new TypeCode_sequence;
2025
2026 otbl->addEntry(otbl->currentOffset(), _ptr);
2027
2028 _ptr->pd_content = TypeCode_marshaller::unmarshal(s, otbl);
2029 if( !ToTcBase(_ptr->pd_content)->complete() )
2030 // Not necassarily correct offset -- but I don't
2031 // think it matters. We only use pd_offset when
2032 // creating typecodes.
2033 _ptr->pd_offset = 1;
2034 else
2035 _ptr->pd_offset = 0;
2036
2037 _ptr->pd_length <<= s;
2038 _ptr->pd_complete = 1;
2039
2040 return _ptr;
2041 }
2042
2043 CORBA::Boolean
NP_complete_recursive_sequences(TypeCode_base * tc,CORBA::ULong offset)2044 TypeCode_sequence::NP_complete_recursive_sequences(TypeCode_base* tc,
2045 CORBA::ULong offset)
2046 {
2047 if (!pd_complete)
2048 {
2049 if (pd_offset != 0)
2050 {
2051 if (pd_offset == offset)
2052 {
2053 // The offset is the one we're looking for, so duplicate the
2054 // typecode_ptr and mark ourself as completed
2055 pd_complete = 1;
2056 pd_content = TypeCode_collector::duplicateRef(tc);
2057
2058 // Now would be a good time to mark nodes as containing loops,
2059 // since all looped typecodes MUST contain a recursive sequence.
2060 // See the TypeCode_collector and TypeCode_marshaller classes
2061 // for more detail.
2062 TypeCode_collector::markLoopMembers(tc);
2063 }
2064 }
2065 else
2066 {
2067 // Call the child typecode to complete itself
2068 if (!CORBA::is_nil(pd_content))
2069 pd_complete = ToTcBase(pd_content)->
2070 NP_complete_recursive_sequences(tc, offset+1);
2071 }
2072 }
2073
2074 return pd_complete;
2075 }
2076
2077 CORBA::Boolean
NP_complete_recursive(TypeCode_base * tc,const char * repoId)2078 TypeCode_sequence::NP_complete_recursive(TypeCode_base* tc, const char* repoId)
2079 {
2080 if (!pd_complete && !CORBA::is_nil(pd_content)) {
2081 pd_complete = ToTcBase(pd_content)->NP_complete_recursive(tc, repoId);
2082 if (pd_complete)
2083 TypeCode_collector::markLoopMembers(tc);
2084 }
2085 return pd_complete;
2086 }
2087
2088
2089 TypeCode_paramListType
NP_paramListType() const2090 TypeCode_sequence::NP_paramListType() const
2091 {
2092 return plt_Complex;
2093 }
2094
2095
2096 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist * tcpl) const2097 TypeCode_sequence::NP_extendedEqual(const TypeCode_base* TCp,
2098 CORBA::Boolean is_equivalent,
2099 const TypeCode_pairlist* tcpl) const
2100 {
2101 if ((NP_kind() != TCp->NP_kind()) || (NP_length() != TCp->NP_length()))
2102 return 0;
2103 else
2104 return (NP_content_type()->NP_equal(TCp->NP_content_type(),
2105 is_equivalent,tcpl));
2106 }
2107
2108
2109 CORBA::ULong
NP_length() const2110 TypeCode_sequence::NP_length() const
2111 {
2112 return pd_length;
2113 }
2114
2115
2116 TypeCode_base*
NP_content_type() const2117 TypeCode_sequence::NP_content_type() const
2118 {
2119 // Sanity check that recursive sequences have been properly completed
2120 OMNIORB_ASSERT(!CORBA::is_nil(pd_content));
2121 return ToTcBase(pd_content);
2122 }
2123
2124
2125 CORBA::Long
NP_param_count() const2126 TypeCode_sequence::NP_param_count() const
2127 {
2128 return 2;
2129 }
2130
2131
2132 CORBA::Any*
NP_parameter(CORBA::Long index) const2133 TypeCode_sequence::NP_parameter(CORBA::Long index) const
2134 {
2135 CORBA::Any* rv = new CORBA::Any;
2136
2137 try {
2138 switch (index) {
2139 case 0:
2140 *rv <<= pd_length;
2141 break;
2142 case 1:
2143 *rv <<= pd_content;
2144 break;
2145 default:
2146 throw CORBA::TypeCode::Bounds();
2147 };
2148 }
2149 catch (...) {
2150 delete rv;
2151 throw;
2152 }
2153
2154 return rv;
2155 }
2156
2157
2158 CORBA::Boolean
NP_containsAnAlias()2159 TypeCode_sequence::NP_containsAnAlias()
2160 {
2161 if( pd_offset ) {
2162 // If any of the nodes included in the recursive loop need
2163 // to be replaced with an expanded version, then we need to
2164 // replace all of them. So say we are a (sub) member of
2165 // a structure -- then if any of the members contains an
2166 // alias, then we need to be replaced.
2167 // It would be very difficult to detect this however, so
2168 // lets play safe and say that this is kind of like an alias,
2169 // so say yes. This just means that some recursive sequences
2170 // get duplicated needlessly.
2171
2172 return 1;
2173 }
2174 else
2175 return ToTcBase(pd_content)->NP_containsAnAlias();
2176 }
2177
2178
2179 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist * tcpl)2180 TypeCode_sequence::NP_aliasExpand(TypeCode_pairlist* tcpl)
2181 {
2182 TypeCode_sequence* tc = new TypeCode_sequence;
2183 TypeCode_pairlist pl(tcpl, tc, this);
2184
2185 TypeCode_base* rcontent =
2186 (TypeCode_base*) TypeCode_pairlist::search(tcpl, ToTcBase(pd_content));
2187
2188 if( rcontent ) {
2189 // Recursive sequence ...
2190 tc->pd_content = TypeCode_collector::duplicateRef(rcontent);
2191 // Not necassarily correct offset -- but I don't
2192 // think it matters. We only use pd_offset when
2193 // creating typecodes.
2194 tc->pd_offset = 1;
2195 }
2196 else {
2197 tc->pd_content = ToTcBase(pd_content)->NP_aliasExpand(&pl);
2198 tc->pd_offset = 0;
2199 }
2200 tc->pd_length = pd_length;
2201 tc->pd_complete = 1;
2202
2203 return tc;
2204 }
2205
2206 void
removeOptionalNames()2207 TypeCode_sequence::removeOptionalNames()
2208 {
2209 if (!pd_compactTc) {
2210 pd_compactTc = this;
2211 ToTcBase(pd_content)->removeOptionalNames();
2212 }
2213 }
2214
2215 void
NP_releaseChildren()2216 TypeCode_sequence::NP_releaseChildren()
2217 {
2218 CORBA::TypeCode_ptr ctc = pd_content._retn();
2219 pd_content = CORBA::TypeCode::_duplicate(CORBA::_tc_void);
2220 CORBA::release(ctc);
2221 }
2222
2223
2224 //////////////////////////////////////////////////////////////////////
2225 /////////////////////////// TypeCode_array ///////////////////////////
2226 //////////////////////////////////////////////////////////////////////
2227
TypeCode_array(CORBA::ULong length,TypeCode_base * elem_type)2228 TypeCode_array::TypeCode_array(CORBA::ULong length,
2229 TypeCode_base* elem_type)
2230 : TypeCode_base(CORBA::tk_array)
2231 {
2232 // Initialise
2233 pd_length = length;
2234 pd_content = TypeCode_collector::duplicateRef(elem_type);
2235
2236 NP_complete_recursive_sequences(this, 0);
2237
2238 generateAlignmentTable();
2239 }
2240
2241
~TypeCode_array()2242 TypeCode_array::~TypeCode_array() {}
2243
2244
2245 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl) const2246 TypeCode_array::NP_marshalComplexParams(cdrStream &s,
2247 TypeCode_offsetTable* otbl) const
2248 {
2249 TypeCode_marshaller::marshal(ToTcBase(pd_content), s, otbl);
2250 pd_length >>= s;
2251 }
2252
2253 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)2254 TypeCode_array::NP_unmarshalComplexParams(cdrStream &s,
2255 TypeCode_offsetTable* otbl)
2256 {
2257 TypeCode_array* _ptr = new TypeCode_array;
2258
2259 otbl->addEntry(otbl->currentOffset(), _ptr);
2260
2261 _ptr->pd_content = TypeCode_marshaller::unmarshal(s, otbl);
2262 _ptr->pd_length <<= s;
2263 _ptr->pd_complete = 1;
2264 _ptr->generateAlignmentTable();
2265
2266 return _ptr;
2267 }
2268
2269 CORBA::Boolean
NP_complete_recursive_sequences(TypeCode_base * tc,CORBA::ULong offset)2270 TypeCode_array::NP_complete_recursive_sequences(TypeCode_base* tc,
2271 CORBA::ULong offset)
2272 {
2273 if (!pd_complete)
2274 pd_complete =
2275 ToTcBase(pd_content)->NP_complete_recursive_sequences(tc, offset+1);
2276
2277 return pd_complete;
2278 }
2279
2280 CORBA::Boolean
NP_complete_recursive(TypeCode_base * tc,const char * repoId)2281 TypeCode_array::NP_complete_recursive(TypeCode_base* tc, const char* repoId)
2282 {
2283 if (!pd_complete)
2284 pd_complete = ToTcBase(pd_content)->NP_complete_recursive(tc, repoId);
2285 return pd_complete;
2286 }
2287
2288 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist * tcpl) const2289 TypeCode_array::NP_extendedEqual(const TypeCode_base* TCp,
2290 CORBA::Boolean is_equivalent,
2291 const TypeCode_pairlist* tcpl) const
2292 {
2293 if ((NP_kind() != TCp->NP_kind()) || (NP_length() != TCp->NP_length()))
2294 return 0;
2295 else
2296 return (NP_content_type()->NP_equal(TCp->NP_content_type(),is_equivalent,tcpl));
2297 }
2298
2299
2300 CORBA::ULong
NP_length() const2301 TypeCode_array::NP_length() const
2302 {
2303 return pd_length;
2304 }
2305
2306
2307 TypeCode_base*
NP_content_type() const2308 TypeCode_array::NP_content_type() const
2309 {
2310 return ToTcBase(pd_content);
2311 }
2312
2313
2314 CORBA::Long
NP_param_count() const2315 TypeCode_array::NP_param_count() const
2316 {
2317 return 2;
2318 }
2319
2320
2321 CORBA::Any*
NP_parameter(CORBA::Long index) const2322 TypeCode_array::NP_parameter(CORBA::Long index) const
2323 {
2324 CORBA::Any* rv = new CORBA::Any;
2325
2326 try {
2327 switch (index) {
2328 case 0:
2329 *rv <<= pd_length;
2330 break;
2331 case 1:
2332 *rv <<= pd_content;
2333 break;
2334 default:
2335 throw CORBA::TypeCode::Bounds();
2336 };
2337 }
2338 catch (...) {
2339 delete rv;
2340 throw;
2341 }
2342
2343 return rv;
2344 }
2345
2346
2347 void
generateAlignmentTable()2348 TypeCode_array::generateAlignmentTable()
2349 {
2350 const TypeCode_alignTable& eat = ToTcBase(pd_content)->alignmentTable();
2351
2352 if( pd_length == 1 ) {
2353 pd_alignmentTable.set(eat);
2354 }
2355 else if( eat.is_simple() ) {
2356 // We can copy the whole array as a single block.
2357 pd_alignmentTable.setNumEntries(1);
2358 CORBA::ULong size_aligned = omni::align_to(eat[0].simple.size,
2359 eat[0].simple.alignment);
2360 pd_alignmentTable.addSimple(eat[0].simple.alignment,
2361 eat[0].simple.size +
2362 (pd_length - 1) * size_aligned);
2363 }
2364 else if( eat.has_only_simple() ) {
2365 // We need to copy the first element separately, and then the
2366 // rest as a simple block. This is possible because a struct of
2367 // simple blocks will always finish with the same alignment
2368 // (modulo the max alignment requirement of the elements).
2369 pd_alignmentTable.setNumEntries(eat.entries() + 1);
2370 CORBA::ULong start = 0;
2371 for( unsigned i = 0; i < eat.entries(); i++ ) {
2372 pd_alignmentTable.add(eat, i);
2373 start = omni::align_to(start, eat[i].simple.alignment);
2374 start += eat[i].simple.size;
2375 }
2376 CORBA::ULong end = start;
2377 for( unsigned j = 0; j < eat.entries(); j++ ) {
2378 end = omni::align_to(end, eat[j].simple.alignment);
2379 end += eat[j].simple.size;
2380 }
2381 pd_alignmentTable.addSimple(omni::ALIGN_1,
2382 (pd_length - 1) * (end - start));
2383 }
2384 else {
2385 pd_alignmentTable.setNumEntries(1);
2386 pd_alignmentTable.addNasty(this);
2387 }
2388 }
2389
2390
2391 CORBA::Boolean
NP_containsAnAlias()2392 TypeCode_array::NP_containsAnAlias()
2393 {
2394 return ToTcBase(pd_content)->NP_containsAnAlias();
2395 }
2396
2397
2398 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist * tcpl)2399 TypeCode_array::NP_aliasExpand(TypeCode_pairlist* tcpl)
2400 {
2401 TypeCode_array* tc = new TypeCode_array;
2402 TypeCode_pairlist pl(tcpl, tc, this);
2403
2404 tc->pd_content = ToTcBase(pd_content)->NP_aliasExpand(&pl);
2405 tc->pd_length = pd_length;
2406 tc->pd_complete = 1;
2407 tc->generateAlignmentTable();
2408
2409 return tc;
2410 }
2411
2412
2413 void
removeOptionalNames()2414 TypeCode_array::removeOptionalNames()
2415 {
2416 if (!pd_compactTc) {
2417 pd_compactTc = this;
2418 ToTcBase(pd_content)->removeOptionalNames();
2419 }
2420 }
2421
2422 void
NP_releaseChildren()2423 TypeCode_array::NP_releaseChildren()
2424 {
2425 CORBA::TypeCode_ptr ctc = pd_content._retn();
2426 pd_content = CORBA::TypeCode::_duplicate(CORBA::_tc_void);
2427 CORBA::release(ctc);
2428 }
2429
2430 //////////////////////////////////////////////////////////////////////
2431 /////////////////////////// TypeCode_struct //////////////////////////
2432 //////////////////////////////////////////////////////////////////////
2433
TypeCode_struct(char * repositoryId,char * name,TypeCode_struct::Member * members,CORBA::ULong memberCount)2434 TypeCode_struct::TypeCode_struct(char* repositoryId, char* name,
2435 TypeCode_struct::Member* members,
2436 CORBA::ULong memberCount)
2437 : TypeCode_base(CORBA::tk_struct)
2438 {
2439 pd_repoId = repositoryId;
2440 pd_name = name;
2441 pd_nmembers = memberCount;
2442 pd_members = members;
2443 NP_complete_recursive_sequences(this, 0);
2444 NP_complete_recursive(this, repositoryId);
2445
2446 generateAlignmentTable();
2447 }
2448
2449
~TypeCode_struct()2450 TypeCode_struct::~TypeCode_struct()
2451 {
2452 the_typecodes->remove(pd_repoId, this);
2453
2454 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2455 CORBA::string_free(pd_members[i].name);
2456 if( pd_members[i].type ) CORBA::release(pd_members[i].type);
2457 }
2458 delete[] pd_members;
2459 }
2460
2461
2462 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl) const2463 TypeCode_struct::NP_marshalComplexParams(cdrStream &s,
2464 TypeCode_offsetTable* otbl) const
2465 {
2466 s.marshalRawString(pd_repoId);
2467 s.marshalRawString(pd_name);
2468 pd_nmembers >>= s;
2469
2470 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2471 s.marshalRawString(pd_members[i].name);
2472 TypeCode_marshaller::marshal(ToTcBase(pd_members[i].type), s, otbl);
2473 }
2474 }
2475
2476
2477 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)2478 TypeCode_struct::NP_unmarshalComplexParams(cdrStream& s,
2479 TypeCode_offsetTable* otbl)
2480 {
2481 TypeCode_struct* _ptr = new TypeCode_struct;
2482
2483 otbl->addEntry(otbl->currentOffset(), _ptr);
2484
2485 try {
2486 _ptr->pd_repoId = s.unmarshalRawString();
2487 _ptr->pd_name = s.unmarshalRawString();
2488 _ptr->pd_nmembers <<= s;
2489
2490 if (!s.checkInputOverrun(1, _ptr->pd_nmembers))
2491 OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
2492 (CORBA::CompletionStatus)s.completion());
2493
2494 // We need to initialised the members of <pd_members> to zero
2495 // to ensure we can destroy this properly in the case of an
2496 // exception being thrown.
2497 _ptr->pd_members = new TypeCode_struct::Member[_ptr->pd_nmembers];
2498 for( CORBA::ULong j = 0; j < _ptr->pd_nmembers; j++ ) {
2499 _ptr->pd_members[j].name = 0;
2500 _ptr->pd_members[j].type = 0;
2501 }
2502
2503 for( CORBA::ULong i = 0; i < _ptr->pd_nmembers; i++ ) {
2504 _ptr->pd_members[i].name = s.unmarshalRawString();
2505 _ptr->pd_members[i].type = TypeCode_marshaller::unmarshal(s, otbl);
2506 }
2507 }
2508 catch(...) {
2509 delete _ptr;
2510 throw;
2511 }
2512
2513 _ptr->pd_complete = 1;
2514 _ptr->generateAlignmentTable();
2515 return _ptr;
2516 }
2517
2518 CORBA::Boolean
NP_complete_recursive_sequences(TypeCode_base * tc,CORBA::ULong offset)2519 TypeCode_struct::NP_complete_recursive_sequences(TypeCode_base* tc,
2520 CORBA::ULong offset)
2521 {
2522 if (!pd_complete)
2523 {
2524 pd_complete = 1;
2525
2526 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2527 pd_complete = pd_complete && ToTcBase(pd_members[i].type)
2528 ->NP_complete_recursive_sequences(tc, offset + 1);
2529 }
2530 }
2531
2532 return pd_complete;
2533 }
2534
2535 CORBA::Boolean
NP_complete_recursive(TypeCode_base * tc,const char * repoId)2536 TypeCode_struct::NP_complete_recursive(TypeCode_base* tc, const char* repoId)
2537 {
2538 if (!pd_complete) {
2539 pd_complete = 1;
2540
2541 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2542 pd_complete = pd_complete &&
2543 ToTcBase(pd_members[i].type)->NP_complete_recursive(tc, repoId);
2544 }
2545 }
2546 return pd_complete;
2547 }
2548
2549
2550 // OMG Interface:
2551 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist * tcpl) const2552 TypeCode_struct::NP_extendedEqual(const TypeCode_base* TCp,
2553 CORBA::Boolean is_equivalent,
2554 const TypeCode_pairlist* tcpl) const
2555 {
2556 if (NP_kind() != TCp->NP_kind())
2557 return 0;
2558
2559 if (is_equivalent) {
2560 if (NP_id() && TCp->NP_id())
2561 return NP_namesEqual(NP_id(),TCp->NP_id());
2562 }
2563 else {
2564 if (!NP_namesEqual(NP_id(),TCp->NP_id()))
2565 return 0;
2566 }
2567
2568 if (pd_nmembers != TCp->NP_member_count())
2569 return 0;
2570
2571 if (!is_equivalent && !NP_namesEqual(NP_name(),TCp->NP_name()))
2572 return 0;
2573
2574 for( CORBA::ULong i=0; i < pd_nmembers; i++ ) {
2575 if (!is_equivalent && !NP_namesEqual(pd_members[i].name,
2576 TCp->NP_member_name(i)))
2577 return 0;
2578
2579 if (!ToTcBase(pd_members[i].type)->NP_equal(TCp->NP_member_type(i),
2580 is_equivalent, tcpl))
2581 return 0;
2582 }
2583 return 1;
2584 }
2585
2586
2587 const char*
NP_id() const2588 TypeCode_struct::NP_id() const
2589 {
2590 return pd_repoId;
2591 }
2592
2593
2594 const char*
NP_name() const2595 TypeCode_struct::NP_name() const
2596 {
2597 return pd_name;
2598 }
2599
2600
2601 CORBA::ULong
NP_member_count() const2602 TypeCode_struct::NP_member_count() const
2603 {
2604 return pd_nmembers;
2605 }
2606
2607
2608 const char*
NP_member_name(CORBA::ULong index) const2609 TypeCode_struct::NP_member_name(CORBA::ULong index) const
2610 {
2611 if( index >= pd_nmembers ) throw CORBA::TypeCode::Bounds();
2612 return pd_members[index].name;
2613 }
2614
2615
2616 TypeCode_base*
NP_member_type(CORBA::ULong index) const2617 TypeCode_struct::NP_member_type(CORBA::ULong index) const
2618 {
2619 if( index >= pd_nmembers ) throw CORBA::TypeCode::Bounds();
2620 return ToTcBase(pd_members[index].type);
2621 }
2622
2623
2624 CORBA::Long
NP_param_count() const2625 TypeCode_struct::NP_param_count() const
2626 {
2627 return 1 + pd_nmembers * 2;
2628 }
2629
2630
2631 CORBA::Any*
NP_parameter(CORBA::Long index) const2632 TypeCode_struct::NP_parameter(CORBA::Long index) const
2633 {
2634 CORBA::Any* rv = new CORBA::Any;
2635
2636 try {
2637 switch (index) {
2638 case 0:
2639 *rv <<= (const char*) pd_name;
2640 break;
2641
2642 default:
2643 if( (index >= 1) && ((CORBA::ULong)index < (1 + pd_nmembers * 2)) ) {
2644 const CORBA::Long tmp = (index-1)/2;
2645
2646 switch( (index - 1) % 2 ) {
2647 case 0:
2648 *rv <<= (const char*) pd_members[tmp].name;
2649 break;
2650 case 1:
2651 *rv <<= pd_members[tmp].type;
2652 break;
2653 }
2654 }
2655 else
2656 throw CORBA::TypeCode::Bounds();
2657 }
2658 }
2659 catch (...) {
2660 delete rv;
2661 throw;
2662 }
2663
2664 return rv;
2665 }
2666
2667
2668 void
generateAlignmentTable()2669 TypeCode_struct::generateAlignmentTable()
2670 {
2671 unsigned num_entries = 0;
2672 int simple_size = 0;
2673 omni::alignment_t simple_alignment = omni::ALIGN_8;
2674
2675 // Determine how many table entries we will need.
2676 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2677 TypeCode_base* mtc = ToTcBase(pd_members[i].type);
2678
2679 if (mtc->complete()) {
2680
2681 const TypeCode_alignTable& mat = mtc->alignmentTable();
2682
2683 for( unsigned j = 0; j < mat.entries(); j++ ) {
2684
2685 switch( mat[j].type ) {
2686
2687 case TypeCode_alignTable::it_simple:
2688
2689 if( simple_size % mat[j].simple.alignment == 0 &&
2690 mat[j].simple.alignment <= simple_alignment ) {
2691
2692 // If can, add onto existing simple ...
2693 if( simple_size == 0 ) simple_alignment = mat[j].simple.alignment;
2694 simple_size += mat[j].simple.size;
2695 }
2696 else {
2697 simple_size = mat[j].simple.size;
2698 simple_alignment = mat[j].simple.alignment;
2699 num_entries++;
2700 }
2701 break;
2702
2703 default:
2704 if( simple_size > 0 ) {
2705 simple_size = 0;
2706 simple_alignment = omni::ALIGN_8;
2707 num_entries++;
2708 }
2709 num_entries++;
2710 break;
2711 }
2712 }
2713 }
2714 else {
2715 // TypeCode incomplete. It must have nasty alignment.
2716 if( simple_size > 0 ) {
2717 simple_size = 0;
2718 simple_alignment = omni::ALIGN_8;
2719 num_entries++;
2720 }
2721 num_entries++;
2722 }
2723 }
2724 // And there may be an extra simple one at the end ...
2725 if( simple_size > 0 ) num_entries++;
2726
2727 // Generate the entries.
2728 if( num_entries == 0 ) {
2729 pd_alignmentTable.setNumEntries(1);
2730 pd_alignmentTable.addSimple(omni::ALIGN_1, 0);
2731 }
2732 else {
2733 pd_alignmentTable.setNumEntries(num_entries);
2734 simple_size = 0;
2735 simple_alignment = omni::ALIGN_8;
2736
2737 for( CORBA::ULong ii = 0; ii < pd_nmembers; ii++ ) {
2738
2739 TypeCode_base* mtc = ToTcBase(pd_members[ii].type);
2740
2741 if (mtc->complete()) {
2742
2743 const TypeCode_alignTable& mat = mtc->alignmentTable();
2744
2745 for( unsigned j = 0; j < mat.entries(); j++ ) {
2746
2747 switch( mat[j].type ) {
2748
2749 case TypeCode_alignTable::it_simple:
2750
2751 if( simple_size % mat[j].simple.alignment == 0 &&
2752 mat[j].simple.alignment <= simple_alignment ) {
2753
2754 // If can add onto existing simple ...
2755 if( simple_size == 0 )
2756 simple_alignment = mat[j].simple.alignment;
2757 simple_size += mat[j].simple.size;
2758 }
2759 else {
2760 pd_alignmentTable.addSimple(simple_alignment, simple_size);
2761 simple_size = mat[j].simple.size;
2762 simple_alignment = mat[j].simple.alignment;
2763 }
2764 break;
2765
2766 default:
2767 if( simple_size > 0 ) {
2768 pd_alignmentTable.addSimple(simple_alignment, simple_size);
2769 simple_size = 0;
2770 simple_alignment = omni::ALIGN_8;
2771 }
2772 pd_alignmentTable.add(mat, j);
2773 break;
2774 }
2775 }
2776 }
2777 else {
2778 // Incomplete
2779 if( simple_size > 0 ) {
2780 pd_alignmentTable.addSimple(simple_alignment, simple_size);
2781 simple_size = 0;
2782 simple_alignment = omni::ALIGN_8;
2783 }
2784 pd_alignmentTable.addNasty(mtc);
2785 }
2786 }
2787 // And there may be an extra simple one at the end ...
2788 if( simple_size > 0 ) {
2789 pd_alignmentTable.addSimple(simple_alignment, simple_size);
2790 }
2791 }
2792 }
2793
2794
2795 CORBA::Boolean
NP_containsAnAlias()2796 TypeCode_struct::NP_containsAnAlias()
2797 {
2798 for( CORBA::ULong i = 0; i < pd_nmembers; i++ )
2799 if( ToTcBase(pd_members[i].type)->NP_containsAnAlias() )
2800 return 1;
2801
2802 return 0;
2803 }
2804
2805
2806 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist * tcpl)2807 TypeCode_struct::NP_aliasExpand(TypeCode_pairlist* tcpl)
2808 {
2809 TypeCode_struct* tc = new TypeCode_struct;
2810 TypeCode_pairlist pl(tcpl, tc, this);
2811
2812 tc->pd_repoId = pd_repoId;
2813 tc->pd_name = pd_name;
2814 tc->pd_nmembers = pd_nmembers;
2815
2816 TypeCode_struct::Member* members = new TypeCode_struct::Member[pd_nmembers];
2817 tc->pd_members = members;
2818
2819 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2820 if( ToTcBase(pd_members[i].type)->NP_containsAnAlias() )
2821 members[i].type = ToTcBase(pd_members[i].type)->NP_aliasExpand(&pl);
2822 else
2823 members[i].type =
2824 TypeCode_collector::duplicateRef(ToTcBase(pd_members[i].type));
2825
2826 members[i].name = CORBA::string_dup(pd_members[i].name);
2827 }
2828
2829 tc->pd_complete = 1;
2830 tc->generateAlignmentTable();
2831
2832 return tc;
2833 }
2834
2835 void
removeOptionalNames()2836 TypeCode_struct::removeOptionalNames()
2837 {
2838 if (!pd_compactTc) {
2839 pd_compactTc = this;
2840 pd_name = (const char*)"";
2841 for (CORBA::ULong i=0; i< pd_nmembers; i++) {
2842 CORBA::string_free(pd_members[i].name);
2843 pd_members[i].name = CORBA::string_dup("");
2844 ToTcBase(pd_members[i].type)->removeOptionalNames();
2845 }
2846 }
2847 }
2848
2849 void
NP_releaseChildren()2850 TypeCode_struct::NP_releaseChildren()
2851 {
2852 // We acquire a reference to ourselves here. Otherwise, we will be
2853 // released while releasing the children, rendering the list of
2854 // TypeCodes invalid.
2855 TypeCode_collector::duplicateRef(this);
2856 pd_loop_member = 0;
2857
2858 for (CORBA::ULong i = 0; i < pd_nmembers; i++) {
2859 CORBA::TypeCode_ptr ctc = pd_members[i].type;
2860 pd_members[i].type = CORBA::TypeCode::_duplicate(CORBA::_tc_void);
2861 CORBA::release(ctc);
2862 }
2863 TypeCode_collector::releaseRef(this);
2864 }
2865
2866 //////////////////////////////////////////////////////////////////////
2867 /////////////////////////// TypeCode_except //////////////////////////
2868 //////////////////////////////////////////////////////////////////////
2869
TypeCode_except(char * repositoryId,char * name,TypeCode_struct::Member * members,CORBA::ULong memberCount)2870 TypeCode_except::TypeCode_except(char* repositoryId, char* name,
2871 TypeCode_struct::Member* members,
2872 CORBA::ULong memberCount)
2873 : TypeCode_base(CORBA::tk_except)
2874 {
2875 pd_repoId = repositoryId;
2876 pd_name = name;
2877 pd_nmembers = memberCount;
2878 pd_members = members;
2879
2880 NP_complete_recursive_sequences(this, 0);
2881 NP_complete_recursive(this, repositoryId);
2882
2883 generateAlignmentTable();
2884 }
2885
2886
~TypeCode_except()2887 TypeCode_except::~TypeCode_except()
2888 {
2889 the_typecodes->remove(pd_repoId, this);
2890
2891 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2892 CORBA::string_free(pd_members[i].name);
2893 if( pd_members[i].type ) CORBA::release(pd_members[i].type);
2894 }
2895 delete[] pd_members;
2896 }
2897
2898
2899 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl) const2900 TypeCode_except::NP_marshalComplexParams(cdrStream &s,
2901 TypeCode_offsetTable* otbl) const
2902 {
2903 s.marshalRawString(pd_repoId);
2904 s.marshalRawString(pd_name);
2905 pd_nmembers >>= s;
2906
2907 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2908 s.marshalRawString(pd_members[i].name);
2909 TypeCode_marshaller::marshal(ToTcBase(pd_members[i].type), s, otbl);
2910 }
2911 }
2912
2913 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)2914 TypeCode_except::NP_unmarshalComplexParams(cdrStream& s,
2915 TypeCode_offsetTable* otbl)
2916 {
2917 TypeCode_except* _ptr = new TypeCode_except;
2918
2919 otbl->addEntry(otbl->currentOffset(), _ptr);
2920
2921 try {
2922 _ptr->pd_repoId = s.unmarshalRawString();
2923 _ptr->pd_name = s.unmarshalRawString();
2924 _ptr->pd_nmembers <<= s;
2925
2926 if (!s.checkInputOverrun(1, _ptr->pd_nmembers))
2927 OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
2928 (CORBA::CompletionStatus)s.completion());
2929
2930 // We need to initialised the members of <pd_members> to zero
2931 // to ensure we can destroy this properly in the case of an
2932 // exception being thrown.
2933 _ptr->pd_members = new TypeCode_struct::Member[_ptr->pd_nmembers];
2934 for( CORBA::ULong j = 0; j < _ptr->pd_nmembers; j++ ) {
2935 _ptr->pd_members[j].name = 0;
2936 _ptr->pd_members[j].type = 0;
2937 }
2938
2939 for( CORBA::ULong i = 0; i < _ptr->pd_nmembers; i++ ) {
2940 _ptr->pd_members[i].name = s.unmarshalRawString();
2941 _ptr->pd_members[i].type = TypeCode_marshaller::unmarshal(s, otbl);
2942 }
2943 }
2944 catch(...) {
2945 delete _ptr;
2946 throw;
2947 }
2948
2949 _ptr->pd_complete = 1;
2950 _ptr->generateAlignmentTable();
2951 return _ptr;
2952 }
2953
2954
2955 CORBA::Boolean
NP_complete_recursive_sequences(TypeCode_base * tc,CORBA::ULong offset)2956 TypeCode_except::NP_complete_recursive_sequences(TypeCode_base* tc,
2957 CORBA::ULong offset)
2958 {
2959 if (!pd_complete)
2960 {
2961 pd_complete = 1;
2962
2963 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2964 pd_complete = pd_complete && ToTcBase(pd_members[i].type)
2965 ->NP_complete_recursive_sequences(tc, offset + 1);
2966 }
2967 }
2968
2969 return pd_complete;
2970 }
2971
2972 CORBA::Boolean
NP_complete_recursive(TypeCode_base * tc,const char * repoId)2973 TypeCode_except::NP_complete_recursive(TypeCode_base* tc, const char* repoId)
2974 {
2975 if (!pd_complete) {
2976 pd_complete = 1;
2977
2978 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
2979 pd_complete = pd_complete &&
2980 ToTcBase(pd_members[i].type)->NP_complete_recursive(tc, repoId);
2981 }
2982 }
2983 return pd_complete;
2984 }
2985
2986
2987 // OMG Interface:
2988 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist * tcpl) const2989 TypeCode_except::NP_extendedEqual(const TypeCode_base* TCp,
2990 CORBA::Boolean is_equivalent,
2991 const TypeCode_pairlist* tcpl) const
2992 {
2993 if (NP_kind() != TCp->NP_kind())
2994 return 0;
2995
2996 if (strcmp(NP_id(), TCp->NP_id()) != 0)
2997 return 0;
2998 else if (is_equivalent)
2999 return 1;
3000
3001 if (pd_nmembers != TCp->NP_member_count())
3002 return 0;
3003
3004 if (!NP_namesEqual(NP_name(),TCp->NP_name()))
3005 return 0;
3006
3007 for( CORBA::ULong i=0; i < pd_nmembers; i++ ) {
3008 if ((!NP_namesEqual(pd_members[i].name, TCp->NP_member_name(i))) ||
3009 (!ToTcBase(pd_members[i].type)->NP_equal(TCp->NP_member_type(i),
3010 0, tcpl)))
3011 return 0;
3012 }
3013
3014 return 1;
3015 }
3016
3017
3018 const char*
NP_id() const3019 TypeCode_except::NP_id() const
3020 {
3021 return pd_repoId;
3022 }
3023
3024
3025 const char*
NP_name() const3026 TypeCode_except::NP_name() const
3027 {
3028 return pd_name;
3029 }
3030
3031
3032 CORBA::ULong
NP_member_count() const3033 TypeCode_except::NP_member_count() const
3034 {
3035 return pd_nmembers;
3036 }
3037
3038
3039 const char*
NP_member_name(CORBA::ULong index) const3040 TypeCode_except::NP_member_name(CORBA::ULong index) const
3041 {
3042 if( index >= pd_nmembers ) throw CORBA::TypeCode::Bounds();
3043 return pd_members[index].name;
3044 }
3045
3046
3047 TypeCode_base*
NP_member_type(CORBA::ULong index) const3048 TypeCode_except::NP_member_type(CORBA::ULong index) const
3049 {
3050 if( index >= pd_nmembers ) throw CORBA::TypeCode::Bounds();
3051 return ToTcBase(pd_members[index].type);
3052 }
3053
3054
3055 CORBA::Long
NP_param_count() const3056 TypeCode_except::NP_param_count() const
3057 {
3058 return 1 + pd_nmembers * 2;
3059 }
3060
3061
3062 CORBA::Any*
NP_parameter(CORBA::Long index) const3063 TypeCode_except::NP_parameter(CORBA::Long index) const
3064 {
3065 CORBA::Any* rv = new CORBA::Any;
3066
3067 try {
3068 switch (index) {
3069 case 0:
3070 *rv <<= (const char*) pd_name;
3071 break;
3072
3073 default:
3074 if( (index >= 1) && ((CORBA::ULong)index < (1 + pd_nmembers * 2)) ) {
3075 const CORBA::Long tmp = (index-1)/2;
3076
3077 switch( (index - 1) % 2 ) {
3078 case 0:
3079 *rv <<= (const char*) pd_members[tmp].name;
3080 break;
3081 case 1:
3082 *rv <<= pd_members[tmp].type;
3083 break;
3084 }
3085 }
3086 else
3087 throw CORBA::TypeCode::Bounds();
3088 }
3089 }
3090 catch (...) {
3091 delete rv;
3092 throw;
3093 }
3094
3095 return rv;
3096 }
3097
3098
3099 void
generateAlignmentTable()3100 TypeCode_except::generateAlignmentTable()
3101 {
3102 unsigned num_entries = 0;
3103 int simple_size = 0;
3104 omni::alignment_t simple_alignment = omni::ALIGN_8;
3105
3106 // Determine how many table entries we will need.
3107 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
3108 TypeCode_base* mtc = ToTcBase(pd_members[i].type);
3109 const TypeCode_alignTable& mat = mtc->alignmentTable();
3110
3111 for( unsigned j = 0; j < mat.entries(); j++ ) {
3112 switch( mat[j].type ) {
3113 case TypeCode_alignTable::it_simple:
3114 if( simple_size % mat[j].simple.alignment == 0 &&
3115 mat[j].simple.alignment <= simple_alignment ) {
3116 // If can add onto existing simple ...
3117 if( simple_size == 0 ) simple_alignment = mat[j].simple.alignment;
3118 simple_size += mat[j].simple.size;
3119 }
3120 else {
3121 simple_size = mat[j].simple.size;
3122 simple_alignment = mat[j].simple.alignment;
3123 num_entries++;
3124 }
3125 break;
3126
3127 default:
3128 if( simple_size > 0 ) {
3129 simple_size = 0;
3130 simple_alignment = omni::ALIGN_8;
3131 num_entries++;
3132 }
3133 num_entries++;
3134 break;
3135 }
3136 }
3137 }
3138 // And there may be an extra simple one at the end ...
3139 if( simple_size > 0 ) num_entries++;
3140
3141 // Generate the entries.
3142 if( num_entries == 0 ) {
3143 pd_alignmentTable.setNumEntries(1);
3144 pd_alignmentTable.addSimple(omni::ALIGN_1, 0);
3145 }
3146 else {
3147 pd_alignmentTable.setNumEntries(num_entries);
3148 simple_size = 0;
3149 simple_alignment = omni::ALIGN_8;
3150
3151 for( CORBA::ULong ii = 0; ii < pd_nmembers; ii++ ) {
3152 TypeCode_base* mtc = ToTcBase(pd_members[ii].type);
3153 const TypeCode_alignTable& mat = mtc->alignmentTable();
3154
3155 for( unsigned j = 0; j < mat.entries(); j++ ) {
3156 switch( mat[j].type ) {
3157 case TypeCode_alignTable::it_simple:
3158 if( simple_size % mat[j].simple.alignment == 0 &&
3159 mat[j].simple.alignment <= simple_alignment ) {
3160 // If can add onto existing simple ...
3161 if( simple_size == 0 ) simple_alignment = mat[j].simple.alignment;
3162 simple_size += mat[j].simple.size;
3163 }
3164 else {
3165 pd_alignmentTable.addSimple(simple_alignment, simple_size);
3166 simple_size = mat[j].simple.size;
3167 simple_alignment = mat[j].simple.alignment;
3168 }
3169 break;
3170
3171 default:
3172 if( simple_size > 0 ) {
3173 pd_alignmentTable.addSimple(simple_alignment, simple_size);
3174 simple_size = 0;
3175 simple_alignment = omni::ALIGN_8;
3176 }
3177 pd_alignmentTable.add(mat, j);
3178 break;
3179 }
3180 }
3181 }
3182 // And there may be an extra simple one at the end ...
3183 if( simple_size > 0 ) {
3184 pd_alignmentTable.addSimple(simple_alignment, simple_size);
3185 }
3186 }
3187 }
3188
3189
3190 CORBA::Boolean
NP_containsAnAlias()3191 TypeCode_except::NP_containsAnAlias()
3192 {
3193 for( CORBA::ULong i = 0; i < pd_nmembers; i++ )
3194 if( ToTcBase(pd_members[i].type)->NP_containsAnAlias() )
3195 return 1;
3196
3197 return 0;
3198 }
3199
3200
3201 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist * tcpl)3202 TypeCode_except::NP_aliasExpand(TypeCode_pairlist* tcpl)
3203 {
3204 TypeCode_except* tc = new TypeCode_except;
3205 TypeCode_pairlist pl(tcpl, tc, this);
3206
3207 tc->pd_repoId = pd_repoId;
3208 tc->pd_name = pd_name;
3209 tc->pd_nmembers = pd_nmembers;
3210
3211 TypeCode_struct::Member* members = new TypeCode_struct::Member[pd_nmembers];
3212 tc->pd_members = members;
3213
3214 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
3215 if( ToTcBase(pd_members[i].type)->NP_containsAnAlias() )
3216 members[i].type = ToTcBase(pd_members[i].type)->NP_aliasExpand(&pl);
3217 else
3218 members[i].type =
3219 TypeCode_collector::duplicateRef(ToTcBase(pd_members[i].type));
3220
3221 members[i].name = CORBA::string_dup(pd_members[i].name);
3222 }
3223
3224 tc->pd_complete = 1;
3225 tc->generateAlignmentTable();
3226
3227 return tc;
3228 }
3229
3230 void
removeOptionalNames()3231 TypeCode_except::removeOptionalNames()
3232 {
3233 if (!pd_compactTc) {
3234 pd_compactTc = this;
3235 pd_name = (const char*)"";
3236 for (CORBA::ULong i=0; i< pd_nmembers; i++) {
3237 CORBA::string_free(pd_members[i].name);
3238 pd_members[i].name = CORBA::string_dup("");
3239 ToTcBase(pd_members[i].type)->removeOptionalNames();
3240 }
3241 }
3242 }
3243
3244
3245 void
NP_releaseChildren()3246 TypeCode_except::NP_releaseChildren()
3247 {
3248 // We acquire a reference to ourselves here. Otherwise, we will be
3249 // released while releasing the children, rendering the list of
3250 // TypeCodes invalid.
3251 TypeCode_collector::duplicateRef(this);
3252 pd_loop_member = 0;
3253
3254 for (CORBA::ULong i = 0; i < pd_nmembers; i++) {
3255 CORBA::TypeCode_ptr ctc = pd_members[i].type;
3256 pd_members[i].type = CORBA::TypeCode::_duplicate(CORBA::_tc_void);
3257 CORBA::release(ctc);
3258 }
3259 TypeCode_collector::releaseRef(this);
3260 }
3261
3262 //////////////////////////////////////////////////////////////////////
3263 //////////////////////////// TypeCode_enum ///////////////////////////
3264 //////////////////////////////////////////////////////////////////////
3265
TypeCode_enum(const char * repositoryId,const char * name,const CORBA::EnumMemberSeq & members)3266 TypeCode_enum::TypeCode_enum(const char* repositoryId,
3267 const char* name,
3268 const CORBA::EnumMemberSeq &members)
3269 : TypeCode_base(CORBA::tk_enum)
3270 {
3271 pd_complete = 1;
3272 pd_repoId = repositoryId;
3273 pd_name = name;
3274 pd_members = members;
3275 pd_alignmentTable.setNumEntries(1);
3276 pd_alignmentTable.addSimple(omni::ALIGN_4, 4);
3277 }
3278
3279
TypeCode_enum()3280 TypeCode_enum::TypeCode_enum()
3281 : TypeCode_base(CORBA::tk_enum)
3282 {
3283 pd_complete = 1;
3284 pd_alignmentTable.setNumEntries(1);
3285 pd_alignmentTable.addSimple(omni::ALIGN_4, 4);
3286 }
3287
3288
~TypeCode_enum()3289 TypeCode_enum::~TypeCode_enum() {
3290 the_typecodes->remove(pd_repoId, this);
3291 }
3292
3293
3294 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl) const3295 TypeCode_enum::NP_marshalComplexParams(cdrStream& s,
3296 TypeCode_offsetTable* otbl) const
3297 {
3298 s.marshalRawString(pd_repoId);
3299 s.marshalRawString(pd_name);
3300
3301 // Can't use EnumMemberSeq's insertion operator since that would do
3302 // code set conversion.
3303 CORBA::ULong len = pd_members.length();
3304 len >>= s;
3305
3306 const char* const* buffer = pd_members.get_buffer();
3307 for (CORBA::ULong i=0; i < len; i++)
3308 s.marshalRawString(buffer[i]);
3309 }
3310
3311
3312 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)3313 TypeCode_enum::NP_unmarshalComplexParams(cdrStream &s,
3314 TypeCode_offsetTable* otbl)
3315 {
3316 TypeCode_enum* _ptr = new TypeCode_enum;
3317
3318 otbl->addEntry(otbl->currentOffset(), _ptr);
3319
3320 _ptr->pd_repoId = s.unmarshalRawString();
3321 _ptr->pd_name = s.unmarshalRawString();
3322
3323 CORBA::ULong len;
3324 len <<= s;
3325
3326 if (!s.checkInputOverrun(1, len))
3327 OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
3328 (CORBA::CompletionStatus)s.completion());
3329
3330 _ptr->pd_members.length(len);
3331 char** buffer = _ptr->pd_members.get_buffer(0);
3332
3333 for (CORBA::ULong i=0; i < len; i++)
3334 buffer[i] = s.unmarshalRawString();
3335
3336 return _ptr;
3337 }
3338
3339
3340 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist *) const3341 TypeCode_enum::NP_extendedEqual(const TypeCode_base* TCp,
3342 CORBA::Boolean is_equivalent,
3343 const TypeCode_pairlist*) const
3344 {
3345 if (NP_kind() != TCp->NP_kind())
3346 return 0;
3347
3348 if (is_equivalent) {
3349 if (NP_id() && TCp->NP_id())
3350 return NP_namesEqual(NP_id(),TCp->NP_id());
3351 }
3352 else {
3353 if (!NP_namesEqual(NP_id(),TCp->NP_id()))
3354 return 0;
3355 }
3356
3357 if (pd_members.length() != TCp->NP_member_count())
3358 return 0;
3359
3360 if (!is_equivalent) {
3361 if (!NP_namesEqual(NP_name(),TCp->NP_name()))
3362 return 0;
3363
3364 CORBA::ULong memberCount = pd_members.length();
3365 TypeCode_enum* TCe = (TypeCode_enum*) TCp;
3366
3367 for( CORBA::ULong i=0; i < memberCount; i++ )
3368 if( !NP_namesEqual(pd_members[i], TCe->pd_members[i]) )
3369 return 0;
3370 }
3371
3372 return 1;
3373 }
3374
3375
3376 const char*
NP_id() const3377 TypeCode_enum::NP_id() const
3378 {
3379 return pd_repoId;
3380 }
3381
3382
3383 const char*
NP_name() const3384 TypeCode_enum::NP_name() const
3385 {
3386 return pd_name;
3387 }
3388
3389
3390 CORBA::ULong
NP_member_count() const3391 TypeCode_enum::NP_member_count() const
3392 {
3393 return pd_members.length();
3394 }
3395
3396
3397 const char*
NP_member_name(CORBA::ULong index) const3398 TypeCode_enum::NP_member_name(CORBA::ULong index) const
3399 {
3400 if (pd_members.length() <= index)
3401 throw CORBA::TypeCode::Bounds();
3402
3403 return pd_members[index];
3404 }
3405
3406
3407 CORBA::Long
NP_param_count() const3408 TypeCode_enum::NP_param_count() const
3409 {
3410 return 1 + member_count();
3411 }
3412
3413
3414 CORBA::Any*
NP_parameter(CORBA::Long index) const3415 TypeCode_enum::NP_parameter(CORBA::Long index) const
3416 {
3417 CORBA::Any* rv = new CORBA::Any;
3418
3419 try {
3420 switch (index) {
3421 case 0:
3422 *rv <<= (const char* ) pd_name;
3423 break;
3424 default:
3425 if( (index >= 1) && ((CORBA::ULong)index < (1+NP_member_count())) )
3426 *rv <<= (const char* )pd_members[index-1];
3427 else
3428 throw CORBA::TypeCode::Bounds();
3429 };
3430 }
3431 catch (...) {
3432 delete rv;
3433 throw;
3434 }
3435
3436 return rv;
3437 }
3438
3439
3440 CORBA::Long
NP_member_index(const char * name) const3441 TypeCode_enum::NP_member_index(const char* name) const
3442 {
3443 CORBA::ULong mc = pd_members.length();
3444
3445 for( CORBA::ULong i = 0; i < mc; i++ )
3446 if( !strcmp(name, pd_members[i]) )
3447 return i;
3448
3449 return -1;
3450 }
3451
3452 void
removeOptionalNames()3453 TypeCode_enum::removeOptionalNames()
3454 {
3455 if (!pd_compactTc) {
3456 pd_compactTc = this;
3457 pd_name = (const char*)"";
3458 for (CORBA::ULong i=0; i < pd_members.length(); i++) {
3459 pd_members[i] = (const char*)"";
3460 }
3461 }
3462 }
3463
3464 //////////////////////////////////////////////////////////////////////
3465 /////////////////////////// TypeCode_union ///////////////////////////
3466 //////////////////////////////////////////////////////////////////////
3467
TypeCode_union(const char * repositoryId,const char * name,TypeCode_base * discriminatorTC,const CORBA::UnionMemberSeq & members)3468 TypeCode_union::TypeCode_union(const char* repositoryId,
3469 const char* name,
3470 TypeCode_base* discriminatorTC,
3471 const CORBA::UnionMemberSeq& members)
3472 : TypeCode_base(CORBA::tk_union)
3473 {
3474 const CORBA::ULong memberCount = members.length();
3475
3476 if (memberCount == 0)
3477 OMNIORB_THROW(BAD_PARAM,BAD_PARAM_InvalidInitialSize,CORBA::COMPLETED_NO);
3478
3479 pd_repoId = CORBA::string_dup(repositoryId);
3480 pd_name = CORBA::string_dup(name);
3481 pd_discrim_tc = TypeCode_collector::duplicateRef(discriminatorTC);
3482 pd_members.length(memberCount);
3483
3484 pd_default = TYPECODE_UNION_IMPLICIT_DEFAULT;
3485
3486 // Copy <members> into pd_members, checking the members are valid,
3487 // and extracting the label values.
3488 for( CORBA::ULong i = 0; i < memberCount; i++ ) {
3489
3490 pd_members[i].aname = CORBA::string_dup(members[i].name);
3491 pd_members[i].atype =
3492 TypeCode_collector::duplicateRef(ToTcBase(members[i].type));
3493
3494 CORBA::TypeCode_var lbl_tc = members[i].label.type();
3495
3496 if( CORBA::_tc_octet->equivalent(lbl_tc) )
3497 {
3498 if( pd_default >= 0 )
3499 OMNIORB_THROW(BAD_PARAM,
3500 BAD_PARAM_IllegitimateDiscriminatorType,
3501 CORBA::COMPLETED_NO);
3502 CORBA::Octet v;
3503 members[i].label >>= CORBA::Any::to_octet(v);
3504 if( v != CORBA::Octet(0) )
3505 OMNIORB_THROW(BAD_PARAM,
3506 BAD_PARAM_IllegitimateDiscriminatorType,
3507 CORBA::COMPLETED_NO);
3508 pd_default = i;
3509 pd_members[i].alabel = Discriminator(0);
3510 }
3511 else
3512 {
3513 // This checks that:
3514 // (a) the label type is the same as pd_discrim_tc
3515 // (b) pd_discrim_tc is a legal union discriminator typecode
3516 // and throws an appropriate exception if either fails.
3517 pd_members[i].alabel =
3518 TypeCode_union_helper::extractLabel(members[i].label, pd_discrim_tc);
3519 }
3520
3521 // Check the discriminator isn't the same as one we've already
3522 // had. This makes the loop O(n^2). Oh well, n is probably
3523 // small...
3524 if ((int)i != pd_default) {
3525 for (CORBA::ULong j=0; j < i; j++) {
3526 if ((int)j == pd_default) continue;
3527 if (pd_members[j].alabel == pd_members[i].alabel)
3528 OMNIORB_THROW(BAD_PARAM,
3529 BAD_PARAM_DuplicateLabelValue,
3530 CORBA::COMPLETED_NO);
3531 }
3532 }
3533 }
3534
3535 if( pd_default == TYPECODE_UNION_IMPLICIT_DEFAULT &&
3536 !TypeCode_union_helper::has_implicit_default(this) )
3537 pd_default = TYPECODE_UNION_NO_DEFAULT;
3538
3539 NP_complete_recursive_sequences(this, 0);
3540 NP_complete_recursive(this, repositoryId);
3541
3542 pd_alignmentTable.setNumEntries(1);
3543 pd_alignmentTable.addNasty(this);
3544
3545 pd_have_calculated_default_value = 0;
3546 }
3547
3548
3549 // This constructor is used for PR_union_tc()
TypeCode_union(const char * repositoryId,const char * name,TypeCode_base * discriminatorTC,const CORBA::PR_unionMember * members,CORBA::ULong memberCount,CORBA::Long deflt)3550 TypeCode_union::TypeCode_union(const char* repositoryId,
3551 const char* name,
3552 TypeCode_base* discriminatorTC,
3553 const CORBA::PR_unionMember* members,
3554 CORBA::ULong memberCount, CORBA::Long deflt)
3555 : TypeCode_base(CORBA::tk_union)
3556 {
3557 // Fill out the union TypeCode
3558 pd_repoId = repositoryId;
3559 pd_name = name;
3560 pd_discrim_tc = TypeCode_collector::duplicateRef(discriminatorTC);
3561 pd_default = deflt < 0 ? TYPECODE_UNION_IMPLICIT_DEFAULT : deflt;
3562 pd_members.length(memberCount);
3563
3564 // Copy <members> into pd_members, checking the members are valid,
3565 // and extracting the label values.
3566 for( CORBA::ULong i = 0; i < memberCount; i++ ) {
3567
3568 pd_members[i].aname = CORBA::string_dup(members[i].name);
3569 pd_members[i].atype =
3570 TypeCode_collector::duplicateRef(ToTcBase(members[i].type));
3571 pd_members[i].alabel = members[i].label;
3572 }
3573
3574 if( pd_default == TYPECODE_UNION_IMPLICIT_DEFAULT &&
3575 !TypeCode_union_helper::has_implicit_default(this) )
3576 pd_default = TYPECODE_UNION_NO_DEFAULT;
3577
3578 NP_complete_recursive_sequences(this, 0);
3579 NP_complete_recursive(this, repositoryId);
3580
3581 pd_alignmentTable.setNumEntries(1);
3582 pd_alignmentTable.addNasty(this);
3583
3584 pd_have_calculated_default_value = 0;
3585 }
3586
3587
TypeCode_union()3588 TypeCode_union::TypeCode_union()
3589 : TypeCode_base(CORBA::tk_union)
3590 {
3591 pd_alignmentTable.setNumEntries(1);
3592 pd_alignmentTable.addNasty(this);
3593
3594 pd_have_calculated_default_value = 0;
3595 }
3596
3597
~TypeCode_union()3598 TypeCode_union::~TypeCode_union() {
3599 the_typecodes->remove(pd_repoId, this);
3600 }
3601
3602
3603 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl) const3604 TypeCode_union::NP_marshalComplexParams(cdrStream &s,
3605 TypeCode_offsetTable* otbl) const
3606 {
3607 s.marshalRawString(pd_repoId);
3608 s.marshalRawString(pd_name);
3609 TypeCode_marshaller::marshal(ToTcBase(pd_discrim_tc), s, otbl);
3610 pd_default >>= s;
3611
3612 const CORBA::ULong memberCount = pd_members.length();
3613 memberCount >>= s;
3614 for( CORBA::ULong i = 0; i < memberCount; i++ )
3615 {
3616 TypeCode_union_helper::marshalLabel(pd_members[i].alabel,
3617 pd_discrim_tc, s);
3618 s.marshalRawString(pd_members[i].aname);
3619 TypeCode_marshaller::marshal(ToTcBase(pd_members[i].atype), s, otbl);
3620 }
3621 }
3622
3623
3624 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)3625 TypeCode_union::NP_unmarshalComplexParams(cdrStream &s,
3626 TypeCode_offsetTable* otbl)
3627 {
3628 TypeCode_union* _ptr = new TypeCode_union;
3629
3630 otbl->addEntry(otbl->currentOffset(), _ptr);
3631
3632 _ptr->pd_repoId = s.unmarshalRawString();
3633 _ptr->pd_name = s.unmarshalRawString();
3634 _ptr->pd_discrim_tc = TypeCode_marshaller::unmarshal(s, otbl);
3635 _ptr->pd_default <<= s;
3636
3637 if( _ptr->pd_default < 0 ) {
3638 if( TypeCode_union_helper::has_implicit_default(_ptr) )
3639 _ptr->pd_default = TYPECODE_UNION_IMPLICIT_DEFAULT;
3640 else
3641 _ptr->pd_default = TYPECODE_UNION_NO_DEFAULT;
3642 }
3643
3644 CORBA::ULong memberCount;
3645 memberCount <<= s;
3646
3647 if (!s.checkInputOverrun(1, memberCount))
3648 OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
3649 (CORBA::CompletionStatus)s.completion());
3650
3651 _ptr->pd_members.length(memberCount);
3652
3653 // Read in the different labels, names and types
3654 for( CORBA::ULong i = 0; i < memberCount; i++ )
3655 {
3656 _ptr->pd_members[i].alabel =
3657 TypeCode_union_helper::unmarshalLabel(_ptr->pd_discrim_tc, s);
3658 _ptr->pd_members[i].aname = s.unmarshalRawString();
3659 _ptr->pd_members[i].atype = TypeCode_marshaller::unmarshal(s, otbl);
3660 }
3661
3662 _ptr->pd_complete = 1;
3663
3664 return _ptr;
3665 }
3666
3667
3668 CORBA::Boolean
NP_complete_recursive_sequences(TypeCode_base * tc,CORBA::ULong offset)3669 TypeCode_union::NP_complete_recursive_sequences(TypeCode_base* tc,
3670 CORBA::ULong offset)
3671 {
3672 if (!pd_complete)
3673 {
3674 pd_complete = 1;
3675
3676 const CORBA::ULong memberCount = pd_members.length();
3677 for( CORBA::ULong i = 0; i < memberCount; i++ )
3678 pd_complete = pd_complete &&
3679 ToTcBase(pd_members[i].atype)->
3680 NP_complete_recursive_sequences(tc, offset+1);
3681 }
3682
3683 return pd_complete;
3684 }
3685
3686 CORBA::Boolean
NP_complete_recursive(TypeCode_base * tc,const char * repoId)3687 TypeCode_union::NP_complete_recursive(TypeCode_base* tc, const char* repoId)
3688 {
3689 if (!pd_complete) {
3690 pd_complete = 1;
3691
3692 const CORBA::ULong memberCount = pd_members.length();
3693 for( CORBA::ULong i = 0; i < memberCount; i++ )
3694 pd_complete = pd_complete &&
3695 ToTcBase(pd_members[i].atype)->NP_complete_recursive(tc, repoId);
3696 }
3697 return pd_complete;
3698 }
3699
3700
3701 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist * tcpl) const3702 TypeCode_union::NP_extendedEqual(const TypeCode_base* TCp,
3703 CORBA::Boolean is_equivalent,
3704 const TypeCode_pairlist* tcpl) const
3705 {
3706 if (NP_kind() != TCp->NP_kind())
3707 return 0;
3708
3709 if (is_equivalent) {
3710 if (NP_id() && TCp->NP_id())
3711 return NP_namesEqual(NP_id(),TCp->NP_id());
3712 }
3713 else {
3714 if (!NP_namesEqual(NP_id(),TCp->NP_id()))
3715 return 0;
3716 }
3717
3718 if (!is_equivalent && !NP_namesEqual(NP_name(),TCp->NP_name()))
3719 return 0;
3720
3721 if (NP_member_count() != TCp->NP_member_count())
3722 return 0;
3723
3724 if (NP_default_index() != TCp->NP_default_index() &&
3725 (NP_default_index() >= 0 || TCp->NP_default_index() >= 0)) {
3726 return 0;
3727 }
3728
3729 if (!(NP_discriminator_type()->NP_equal(TCp->NP_discriminator_type(),
3730 is_equivalent, tcpl))) {
3731 return 0;
3732 }
3733
3734 const CORBA::ULong memberCount = pd_members.length();
3735
3736 TypeCode_union* uTCp = (TypeCode_union*)TCp;
3737
3738 for( CORBA::ULong i = 0; i < memberCount; i++ ) {
3739 if ((CORBA::Long(i) != NP_default_index() &&
3740 pd_members[i].alabel != uTCp->pd_members[i].alabel) ||
3741 !ToTcBase(pd_members[i].atype)->
3742 NP_equal(ToTcBase(uTCp->pd_members[i].atype), is_equivalent, tcpl) ) {
3743 return 0;
3744 }
3745
3746 if (!is_equivalent && !NP_namesEqual(pd_members[i].aname,
3747 uTCp->pd_members[i].aname)) {
3748 return 0;
3749 }
3750 }
3751
3752 return 1;
3753 }
3754
3755
3756 const char*
NP_id() const3757 TypeCode_union::NP_id() const
3758 {
3759 return pd_repoId;
3760 }
3761
3762
3763 const char*
NP_name() const3764 TypeCode_union::NP_name() const
3765 {
3766 return pd_name;
3767 }
3768
3769
3770 CORBA::ULong
NP_member_count() const3771 TypeCode_union::NP_member_count() const
3772 {
3773 return pd_members.length();
3774 }
3775
3776
3777 const char*
NP_member_name(CORBA::ULong index) const3778 TypeCode_union::NP_member_name(CORBA::ULong index) const
3779 {
3780 if (pd_members.length() <= index)
3781 throw CORBA::TypeCode::Bounds();
3782
3783 return pd_members[index].aname;
3784 }
3785
3786
3787 TypeCode_base*
NP_member_type(CORBA::ULong index) const3788 TypeCode_union::NP_member_type(CORBA::ULong index) const
3789 {
3790 if (pd_members.length() <= index)
3791 throw CORBA::TypeCode::Bounds();
3792
3793 return ToTcBase(pd_members[index].atype);
3794 }
3795
3796
3797 CORBA::Any*
NP_member_label(CORBA::ULong i) const3798 TypeCode_union::NP_member_label(CORBA::ULong i) const
3799 {
3800 if (pd_members.length() <= i)
3801 throw CORBA::TypeCode::Bounds();
3802
3803 CORBA::Any* a = new CORBA::Any;
3804 if( !a ) _CORBA_new_operator_return_null();
3805
3806 if (CORBA::Long(i) != pd_default) {
3807 TypeCode_union_helper::insertLabel(*a, pd_members[i].alabel, pd_discrim_tc);
3808 }
3809 else {
3810 (*a) <<= CORBA::Any::from_octet((CORBA::Octet)0);
3811 }
3812 return a;
3813 }
3814
3815
3816 TypeCode_base*
NP_discriminator_type() const3817 TypeCode_union::NP_discriminator_type() const
3818 {
3819 return ToTcBase(pd_discrim_tc);
3820 }
3821
3822
3823 CORBA::Long
NP_default_index() const3824 TypeCode_union::NP_default_index() const
3825 {
3826 return pd_default;
3827 }
3828
3829
3830 CORBA::Long
NP_param_count() const3831 TypeCode_union::NP_param_count() const
3832 {
3833 return 2 + (member_count() * 3);
3834 }
3835
3836
3837 CORBA::Any*
NP_parameter(CORBA::Long index) const3838 TypeCode_union::NP_parameter(CORBA::Long index) const
3839 {
3840 CORBA::Any* rv = new CORBA::Any;
3841 if( !rv ) _CORBA_new_operator_return_null();
3842
3843 try {
3844 switch (index) {
3845 case 0:
3846 *rv <<= (const char* ) pd_name;
3847 break;
3848 case 1:
3849 *rv <<= pd_discrim_tc;
3850 break;
3851 default:
3852 if( (index >= 2) && ((CORBA::ULong)index < (2+NP_member_count()*3)) )
3853 {
3854 const CORBA::Long tmp = (index-2)/3;
3855
3856 switch ((index-2) % 3) {
3857 case 0:
3858 {
3859 CORBA::Any* a = NP_member_label(tmp);
3860 delete rv;
3861 rv = a;
3862 }
3863 break;
3864 case 1:
3865 *rv <<= (const char* )pd_members[tmp].aname;
3866 break;
3867 case 2:
3868 *rv <<= pd_members[tmp].atype;
3869 break;
3870 };
3871 }
3872 else
3873 throw CORBA::TypeCode::Bounds();
3874 };
3875 }
3876 catch (...) {
3877 delete rv;
3878 throw;
3879 }
3880
3881 return rv;
3882 }
3883
3884
3885 CORBA::Long
NP_index_from_discriminator(Discriminator d) const3886 TypeCode_union::NP_index_from_discriminator(Discriminator d) const
3887 {
3888 //?? We could consider having a sorted version of pd_members. This
3889 // could be an array of indicies into pd_members (as we need to keep
3890 // pd_members itself in the order defined in the IDL). We could then
3891 // implement this lookup very much more efficiently (binary search).
3892
3893 CORBA::Long n = pd_members.length();
3894
3895 for( CORBA::Long i = 0; i < n; i++ )
3896 if( pd_members[i].alabel == d && i != pd_default )
3897 return i;
3898
3899 if( pd_default >= 0 ) return pd_default;
3900 else return -1;
3901 }
3902
3903
3904 TypeCode_union::Discriminator
NP_default_value()3905 TypeCode_union::NP_default_value()
3906 {
3907 if( pd_default == TYPECODE_UNION_NO_DEFAULT )
3908 throw omniORB::fatalException(__FILE__,__LINE__,
3909 "TypeCode_union::NP_default_value() - union has no default"
3910 " (not even implicit)");
3911
3912 if( !pd_have_calculated_default_value ) {
3913
3914 // We need to search for a suitable value.
3915 // Some of the following loops look like they might never terminate -
3916 // but in fact they will because we do know that there must be some
3917 // value of the given type which is not in the union.
3918
3919 switch( ToTcBase(pd_discrim_tc)->NP_kind() ) {
3920 case CORBA::tk_char:
3921 {
3922 CORBA::UShort c = 0x0;
3923 while( 1 ) {
3924 CORBA::Long i = NP_index_from_discriminator(c++);
3925 if( i < 0 || i == pd_default ) {
3926 pd_default_value = c - 1;
3927 break;
3928 }
3929 }
3930 break;
3931 }
3932 case CORBA::tk_boolean:
3933 {
3934 CORBA::Long i = NP_index_from_discriminator(0);
3935 if( i < 0 || i == pd_default )
3936 pd_default_value = 0;
3937 else
3938 pd_default_value = 1;
3939 break;
3940 }
3941 case CORBA::tk_short:
3942 {
3943 CORBA::Long c = -0x7fff;
3944 while( 1 ) {
3945 CORBA::Long i = NP_index_from_discriminator(c++);
3946 if( i < 0 || i == pd_default ) {
3947 pd_default_value = c - 1;
3948 break;
3949 }
3950 }
3951 break;
3952 }
3953 case CORBA::tk_long:
3954 {
3955 CORBA::Long c = -0x7fffffff;
3956 while( 1 ) {
3957 CORBA::Long i = NP_index_from_discriminator(c++);
3958 if( i < 0 || i == pd_default ) {
3959 pd_default_value = c - 1;
3960 break;
3961 }
3962 }
3963 break;
3964 }
3965 case CORBA::tk_ushort:
3966 case CORBA::tk_ulong:
3967 case CORBA::tk_enum:
3968 {
3969 CORBA::ULong c = 0x0;
3970 while( 1 ) {
3971 CORBA::Long i = NP_index_from_discriminator(c++);
3972 if( i < 0 || i == pd_default ) {
3973 pd_default_value = c - 1;
3974 break;
3975 }
3976 }
3977 break;
3978 }
3979 default:
3980 // Just to stop compiler warnings ...
3981 break;
3982 }
3983
3984 pd_have_calculated_default_value = 1;
3985 }
3986
3987 return pd_default_value;
3988 }
3989
3990
3991 CORBA::Boolean
NP_containsAnAlias()3992 TypeCode_union::NP_containsAnAlias()
3993 {
3994 if( ToTcBase(pd_discrim_tc)->NP_containsAnAlias() )
3995 return 1;
3996
3997 for( CORBA::ULong i = 0; i < pd_members.length(); i++ )
3998 if( ToTcBase(pd_members[i].atype)->NP_containsAnAlias() )
3999 return 1;
4000
4001 return 0;
4002 }
4003
4004 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist * tcpl)4005 TypeCode_union::NP_aliasExpand(TypeCode_pairlist* tcpl)
4006 {
4007 TypeCode_union* tc = new TypeCode_union();
4008 TypeCode_pairlist pl(tcpl, tc, this);
4009
4010 tc->pd_repoId = pd_repoId;
4011 tc->pd_name = pd_name;
4012 if( ToTcBase(pd_discrim_tc)->NP_containsAnAlias() )
4013 tc->pd_discrim_tc = ToTcBase(pd_discrim_tc)->NP_aliasExpand(&pl);
4014 else
4015 tc->pd_discrim_tc =
4016 TypeCode_collector::duplicateRef(ToTcBase(pd_discrim_tc));
4017 tc->pd_default = pd_default;
4018 tc->pd_have_calculated_default_value = pd_have_calculated_default_value;
4019 tc->pd_default_value = pd_default_value;
4020 tc->pd_members.length(pd_members.length());
4021
4022 for( CORBA::ULong i = 0; i < pd_members.length(); i++ ) {
4023 if( ToTcBase(pd_members[i].atype)->NP_containsAnAlias() )
4024 tc->pd_members[i].atype =
4025 ToTcBase(pd_members[i].atype)->NP_aliasExpand(&pl);
4026 else
4027 tc->pd_members[i].atype =
4028 TypeCode_collector::duplicateRef(ToTcBase(pd_members[i].atype));
4029 tc->pd_members[i].aname = pd_members[i].aname;
4030 tc->pd_members[i].alabel = pd_members[i].alabel;
4031 }
4032
4033 tc->pd_complete = 1;
4034
4035 return tc;
4036 }
4037
4038
4039 void
removeOptionalNames()4040 TypeCode_union::removeOptionalNames()
4041 {
4042 if (!pd_compactTc) {
4043 pd_compactTc = this;
4044 pd_name = (const char*)"";
4045 ToTcBase(pd_discrim_tc)->removeOptionalNames();
4046
4047 for (CORBA::ULong i=0; i< pd_members.length(); i++) {
4048 pd_members[i].aname = CORBA::string_dup("");
4049 ToTcBase(pd_members[i].atype)->removeOptionalNames();
4050 }
4051 }
4052 }
4053
4054 void
NP_releaseChildren()4055 TypeCode_union::NP_releaseChildren()
4056 {
4057 // We acquire a reference to ourselves here. Otherwise, we will be
4058 // released while releasing the children, rendering the list of
4059 // TypeCodes invalid.
4060 TypeCode_collector::duplicateRef(this);
4061 pd_loop_member = 0;
4062
4063 CORBA::ULong memberCount = pd_members.length();
4064
4065 for (CORBA::ULong i = 0; i < memberCount; i++) {
4066 CORBA::TypeCode_ptr ctc = pd_members[i].atype._retn();
4067 pd_members[i].atype = CORBA::TypeCode::_duplicate(CORBA::_tc_void);
4068 CORBA::release(ctc);
4069 }
4070 TypeCode_collector::releaseRef(this);
4071 }
4072
4073
4074 //////////////////////////////////////////////////////////////////////
4075 /////////////////////////// TypeCode_value ///////////////////////////
4076 //////////////////////////////////////////////////////////////////////
4077
4078
TypeCode_value(const char * repositoryId,const char * name,CORBA::ValueModifier type_modifier,TypeCode_base * concrete_base,TypeCode_value::Member * members,CORBA::ULong memberCount)4079 TypeCode_value::TypeCode_value(const char* repositoryId, const char* name,
4080 CORBA::ValueModifier type_modifier,
4081 TypeCode_base* concrete_base,
4082 TypeCode_value::Member* members,
4083 CORBA::ULong memberCount)
4084 : TypeCode_base(CORBA::tk_value)
4085 {
4086 pd_repoId = repositoryId;
4087 pd_name = name;
4088 pd_members = members;
4089 pd_nmembers = memberCount;
4090 pd_modifier = type_modifier;
4091 pd_base = TypeCode_collector::duplicateRef(concrete_base);
4092
4093 NP_complete_recursive_sequences(this, 0);
4094 NP_complete_recursive(this, repositoryId);
4095
4096 pd_alignmentTable.setNumEntries(1);
4097 pd_alignmentTable.addNasty(this);
4098 }
4099
TypeCode_value()4100 TypeCode_value::TypeCode_value()
4101 : TypeCode_base(CORBA::tk_value)
4102 {
4103 pd_alignmentTable.setNumEntries(1);
4104 pd_alignmentTable.addNasty(this);
4105 }
4106
4107
~TypeCode_value()4108 TypeCode_value::~TypeCode_value()
4109 {
4110 the_typecodes->remove(pd_repoId, this);
4111
4112 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
4113 CORBA::string_free(pd_members[i].name);
4114 if( pd_members[i].type ) CORBA::release(pd_members[i].type);
4115 }
4116 delete[] pd_members;
4117 }
4118
4119 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl) const4120 TypeCode_value::NP_marshalComplexParams(cdrStream &s,
4121 TypeCode_offsetTable* otbl) const
4122 {
4123 s.marshalRawString(pd_repoId);
4124 s.marshalRawString(pd_name);
4125 pd_modifier >>= s;
4126 TypeCode_marshaller::marshal(ToTcBase(pd_base), s, otbl);
4127
4128 pd_nmembers >>= s;
4129
4130 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
4131 s.marshalRawString(pd_members[i].name);
4132 TypeCode_marshaller::marshal(ToTcBase(pd_members[i].type), s, otbl);
4133 pd_members[i].access >>= s;
4134 }
4135 }
4136
4137
4138 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)4139 TypeCode_value::NP_unmarshalComplexParams(cdrStream& s,
4140 TypeCode_offsetTable* otbl)
4141 {
4142 TypeCode_value* _ptr = new TypeCode_value;
4143
4144 otbl->addEntry(otbl->currentOffset(), _ptr);
4145
4146 try {
4147 _ptr->pd_repoId = s.unmarshalRawString();
4148 _ptr->pd_name = s.unmarshalRawString();
4149 _ptr->pd_modifier <<= s;
4150
4151 _ptr->pd_base = TypeCode_marshaller::unmarshal(s, otbl);
4152
4153 if (!(_ptr->pd_base->kind() == CORBA::tk_value ||
4154 _ptr->pd_base->kind() == CORBA::tk_null)) {
4155 OMNIORB_THROW(MARSHAL, MARSHAL_InvalidTypeCodeKind,
4156 (CORBA::CompletionStatus)s.completion());
4157 }
4158 _ptr->pd_nmembers <<= s;
4159
4160 if (!s.checkInputOverrun(1, _ptr->pd_nmembers))
4161 OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
4162 (CORBA::CompletionStatus)s.completion());
4163
4164 // We need to initialise the members of <pd_members> to zero
4165 // to ensure we can destroy this properly in the case of an
4166 // exception being thrown.
4167 _ptr->pd_members = new Member[_ptr->pd_nmembers];
4168 for( CORBA::ULong j = 0; j < _ptr->pd_nmembers; j++ ) {
4169 _ptr->pd_members[j].name = 0;
4170 _ptr->pd_members[j].type = 0;
4171 }
4172
4173 for( CORBA::ULong i = 0; i < _ptr->pd_nmembers; i++ ) {
4174 _ptr->pd_members[i].name = s.unmarshalRawString();
4175 _ptr->pd_members[i].type = TypeCode_marshaller::unmarshal(s, otbl);
4176 _ptr->pd_members[i].access <<= s;
4177 }
4178 }
4179 catch(...) {
4180 delete _ptr;
4181 throw;
4182 }
4183
4184 _ptr->pd_complete = 1;
4185 return _ptr;
4186 }
4187
4188
4189 CORBA::Boolean
NP_complete_recursive_sequences(TypeCode_base * tc,CORBA::ULong offset)4190 TypeCode_value::NP_complete_recursive_sequences(TypeCode_base* tc,
4191 CORBA::ULong offset)
4192 {
4193 if (!pd_complete) {
4194 pd_complete = 1;
4195
4196 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
4197 pd_complete = pd_complete && ToTcBase(pd_members[i].type)
4198 ->NP_complete_recursive_sequences(tc, offset + 1);
4199 }
4200 }
4201 return pd_complete;
4202 }
4203
4204
4205 CORBA::Boolean
NP_complete_recursive(TypeCode_base * tc,const char * repoId)4206 TypeCode_value::NP_complete_recursive(TypeCode_base* tc, const char* repoId)
4207 {
4208 if (!pd_complete) {
4209 pd_complete = 1;
4210
4211 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
4212 pd_complete = pd_complete &&
4213 ToTcBase(pd_members[i].type)->NP_complete_recursive(tc, repoId);
4214 }
4215 }
4216 return pd_complete;
4217 }
4218
4219
4220 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist * tcpl) const4221 TypeCode_value::NP_extendedEqual(const TypeCode_base* TCp,
4222 CORBA::Boolean is_equivalent,
4223 const TypeCode_pairlist* tcpl) const
4224 {
4225 if (NP_kind() != TCp->NP_kind())
4226 return 0;
4227
4228 if (is_equivalent) {
4229 if (NP_id() && TCp->NP_id())
4230 return NP_namesEqual(NP_id(),TCp->NP_id());
4231 }
4232 else {
4233 if (!NP_namesEqual(NP_id(),TCp->NP_id()))
4234 return 0;
4235 }
4236
4237 if (pd_modifier != TCp->NP_type_modifier())
4238 return 0;
4239
4240 if (pd_nmembers != TCp->NP_member_count())
4241 return 0;
4242
4243 if (!is_equivalent && !NP_namesEqual(NP_name(),TCp->NP_name()))
4244 return 0;
4245
4246 for( CORBA::ULong i=0; i < pd_nmembers; i++ ) {
4247 if (pd_members[i].access != TCp->NP_member_visibility(i))
4248 return 0;
4249
4250 if (!is_equivalent && !NP_namesEqual(pd_members[i].name,
4251 TCp->NP_member_name(i)))
4252 return 0;
4253
4254 if (!ToTcBase(pd_members[i].type)->NP_equal(TCp->NP_member_type(i),
4255 is_equivalent, tcpl))
4256 return 0;
4257 }
4258
4259 if (!ToTcBase(pd_base)->NP_equal(TCp->NP_concrete_base_type(),
4260 is_equivalent, tcpl))
4261 return 0;
4262
4263 return 1;
4264 }
4265
4266
4267 const char*
NP_id() const4268 TypeCode_value::NP_id() const
4269 {
4270 return pd_repoId;
4271 }
4272
4273
4274 const char*
NP_name() const4275 TypeCode_value::NP_name() const
4276 {
4277 return pd_name;
4278 }
4279
4280
4281 CORBA::ULong
NP_member_count() const4282 TypeCode_value::NP_member_count() const
4283 {
4284 return pd_nmembers;
4285 }
4286
4287
4288 const char*
NP_member_name(CORBA::ULong index) const4289 TypeCode_value::NP_member_name(CORBA::ULong index) const
4290 {
4291 if( index >= pd_nmembers ) throw CORBA::TypeCode::Bounds();
4292 return pd_members[index].name;
4293 }
4294
4295
4296 TypeCode_base*
NP_member_type(CORBA::ULong index) const4297 TypeCode_value::NP_member_type(CORBA::ULong index) const
4298 {
4299 if( index >= pd_nmembers ) throw CORBA::TypeCode::Bounds();
4300 return ToTcBase(pd_members[index].type);
4301 }
4302
4303 CORBA::Short
NP_member_visibility(CORBA::ULong index) const4304 TypeCode_value::NP_member_visibility(CORBA::ULong index) const
4305 {
4306 if( index >= pd_nmembers ) throw CORBA::TypeCode::Bounds();
4307 return pd_members[index].access;
4308 }
4309
4310 CORBA::ValueModifier
NP_type_modifier() const4311 TypeCode_value::NP_type_modifier() const
4312 {
4313 return pd_modifier;
4314 }
4315
4316 TypeCode_base*
NP_concrete_base_type() const4317 TypeCode_value::NP_concrete_base_type() const
4318 {
4319 return ToTcBase(pd_base);
4320 }
4321
4322
4323 CORBA::Boolean
NP_containsAnAlias()4324 TypeCode_value::NP_containsAnAlias()
4325 {
4326 for( CORBA::ULong i = 0; i < pd_nmembers; i++ )
4327 if( ToTcBase(pd_members[i].type)->NP_containsAnAlias() )
4328 return 1;
4329
4330 return 0;
4331 }
4332
4333
4334 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist * tcpl)4335 TypeCode_value::NP_aliasExpand(TypeCode_pairlist* tcpl)
4336 {
4337 TypeCode_value* tc = new TypeCode_value;
4338 TypeCode_pairlist pl(tcpl, tc, this);
4339
4340 tc->pd_repoId = pd_repoId;
4341 tc->pd_name = pd_name;
4342 tc->pd_nmembers = pd_nmembers;
4343 tc->pd_modifier = pd_modifier;
4344 tc->pd_base = pd_base;
4345
4346 TypeCode_value::Member* members = new TypeCode_value::Member[pd_nmembers];
4347 tc->pd_members = members;
4348
4349 for( CORBA::ULong i = 0; i < pd_nmembers; i++ ) {
4350 if( ToTcBase(pd_members[i].type)->NP_containsAnAlias() )
4351 members[i].type = ToTcBase(pd_members[i].type)->NP_aliasExpand(&pl);
4352 else
4353 members[i].type =
4354 TypeCode_collector::duplicateRef(ToTcBase(pd_members[i].type));
4355
4356 members[i].name = CORBA::string_dup(pd_members[i].name);
4357 members[i].access = pd_members[i].access;
4358 }
4359
4360 tc->pd_complete = 1;
4361
4362 return tc;
4363 }
4364
4365 void
removeOptionalNames()4366 TypeCode_value::removeOptionalNames()
4367 {
4368 if (!pd_compactTc) {
4369 pd_compactTc = this;
4370 pd_name = (const char*)"";
4371 for (CORBA::ULong i=0; i< pd_nmembers; i++) {
4372 CORBA::string_free(pd_members[i].name);
4373 pd_members[i].name = CORBA::string_dup("");
4374 ToTcBase(pd_members[i].type)->removeOptionalNames();
4375 }
4376 }
4377 }
4378
4379 TypeCode_paramListType
NP_paramListType() const4380 TypeCode_value::NP_paramListType() const
4381 {
4382 return plt_Complex;
4383 }
4384
4385
4386 void
NP_releaseChildren()4387 TypeCode_value::NP_releaseChildren()
4388 {
4389 // We acquire a reference to ourselves here. Otherwise, we will be
4390 // released while releasing the children, rendering the list of
4391 // TypeCodes invalid.
4392 TypeCode_collector::duplicateRef(this);
4393 pd_loop_member = 0;
4394
4395 for (CORBA::ULong i = 0; i < pd_nmembers; i++) {
4396 CORBA::TypeCode_ptr ctc = pd_members[i].type;
4397 pd_members[i].type = CORBA::TypeCode::_duplicate(CORBA::_tc_void);
4398 CORBA::release(ctc);
4399 }
4400 TypeCode_collector::releaseRef(this);
4401 }
4402
4403
4404 //////////////////////////////////////////////////////////////////////
4405 /////////////////////////// TypeCode_value_box ///////////////////////
4406 //////////////////////////////////////////////////////////////////////
4407
TypeCode_value_box(const char * repositoryId,const char * name,TypeCode_base * boxed)4408 TypeCode_value_box::TypeCode_value_box(const char* repositoryId,
4409 const char* name,
4410 TypeCode_base* boxed)
4411 : TypeCode_base(CORBA::tk_value_box)
4412 {
4413 pd_repoId = repositoryId;
4414 pd_name = name;
4415 pd_boxed = TypeCode_collector::duplicateRef(boxed);
4416
4417 pd_alignmentTable.setNumEntries(1);
4418 pd_alignmentTable.addNasty(this);
4419 pd_complete = 1;
4420 }
4421
TypeCode_value_box()4422 TypeCode_value_box::TypeCode_value_box()
4423 : TypeCode_base(CORBA::tk_value_box)
4424 {
4425 pd_alignmentTable.setNumEntries(1);
4426 pd_alignmentTable.addNasty(this);
4427 }
4428
~TypeCode_value_box()4429 TypeCode_value_box::~TypeCode_value_box()
4430 {
4431 the_typecodes->remove(pd_repoId, this);
4432 }
4433
4434 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl) const4435 TypeCode_value_box::NP_marshalComplexParams(cdrStream &s,
4436 TypeCode_offsetTable* otbl) const
4437 {
4438 s.marshalRawString(pd_repoId);
4439 s.marshalRawString(pd_name);
4440 TypeCode_marshaller::marshal(ToTcBase(pd_boxed), s, otbl);
4441 }
4442
4443 TypeCode_base*
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)4444 TypeCode_value_box::NP_unmarshalComplexParams(cdrStream& s,
4445 TypeCode_offsetTable* otbl)
4446 {
4447 TypeCode_value_box* _ptr = new TypeCode_value_box;
4448
4449 otbl->addEntry(otbl->currentOffset(), _ptr);
4450
4451 try {
4452 _ptr->pd_repoId = s.unmarshalRawString();
4453 _ptr->pd_name = s.unmarshalRawString();
4454 _ptr->pd_boxed = TypeCode_marshaller::unmarshal(s, otbl);
4455 }
4456 catch(...) {
4457 delete _ptr;
4458 throw;
4459 }
4460
4461 _ptr->pd_complete = 1;
4462 return _ptr;
4463 }
4464
4465 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean is_equivalent,const TypeCode_pairlist * tcpl) const4466 TypeCode_value_box::NP_extendedEqual(const TypeCode_base* TCp,
4467 CORBA::Boolean is_equivalent,
4468 const TypeCode_pairlist* tcpl) const
4469 {
4470 if (NP_kind() != TCp->NP_kind())
4471 return 0;
4472
4473 if (is_equivalent) {
4474 if (NP_id() && TCp->NP_id())
4475 return NP_namesEqual(NP_id(),TCp->NP_id());
4476 }
4477 else {
4478 if (!NP_namesEqual(NP_id(),TCp->NP_id()))
4479 return 0;
4480 }
4481
4482 if (!ToTcBase(pd_boxed)->NP_equal(TCp->NP_content_type(),
4483 is_equivalent, tcpl))
4484 return 0;
4485
4486 return 1;
4487 }
4488
4489 const char*
NP_id() const4490 TypeCode_value_box::NP_id() const
4491 {
4492 return pd_repoId;
4493 }
4494
4495
4496 const char*
NP_name() const4497 TypeCode_value_box::NP_name() const
4498 {
4499 return pd_name;
4500 }
4501
4502 TypeCode_base*
NP_content_type() const4503 TypeCode_value_box::NP_content_type() const
4504 {
4505 return ToTcBase(pd_boxed);
4506 }
4507
4508 CORBA::Boolean
NP_containsAnAlias()4509 TypeCode_value_box::NP_containsAnAlias()
4510 {
4511 return ToTcBase(pd_boxed)->NP_containsAnAlias();
4512 }
4513
4514 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist * tcpl)4515 TypeCode_value_box::NP_aliasExpand(TypeCode_pairlist* tcpl)
4516 {
4517 TypeCode_value_box* tc = new TypeCode_value_box;
4518 TypeCode_pairlist pl(tcpl, tc, this);
4519
4520 tc->pd_repoId = pd_repoId;
4521 tc->pd_name = pd_name;
4522
4523 if (ToTcBase(pd_boxed)->NP_containsAnAlias())
4524 tc->pd_boxed = ToTcBase(pd_boxed)->NP_aliasExpand(&pl);
4525 else
4526 tc->pd_boxed = TypeCode_collector::duplicateRef(ToTcBase(pd_boxed));
4527
4528 tc->pd_complete = 1;
4529 return tc;
4530 }
4531
4532 void
removeOptionalNames()4533 TypeCode_value_box::removeOptionalNames()
4534 {
4535 if (!pd_compactTc) {
4536 pd_compactTc = this;
4537 pd_name = (const char*)"";
4538 }
4539 }
4540
4541 TypeCode_paramListType
NP_paramListType() const4542 TypeCode_value_box::NP_paramListType() const
4543 {
4544 return plt_Complex;
4545 }
4546
4547 void
NP_releaseChildren()4548 TypeCode_value_box::NP_releaseChildren()
4549 {
4550 CORBA::TypeCode_ptr ctc = pd_boxed._retn();
4551 pd_boxed = CORBA::TypeCode::_duplicate(CORBA::_tc_void);
4552 CORBA::release(ctc);
4553 }
4554
4555
4556 //////////////////////////////////////////////////////////////////////
4557 /////////////////////////// TypeCode_abstract_interface //////////////
4558 //////////////////////////////////////////////////////////////////////
4559
4560 TypeCode_abstract_interface::
TypeCode_abstract_interface(const char * repositoryId,const char * name)4561 TypeCode_abstract_interface(const char* repositoryId, const char* name)
4562 : TypeCode_objref(repositoryId, name, CORBA::tk_abstract_interface)
4563 {
4564 }
4565
4566
TypeCode_abstract_interface()4567 TypeCode_abstract_interface::TypeCode_abstract_interface()
4568 : TypeCode_objref(CORBA::tk_abstract_interface)
4569 {
4570 }
4571
4572
~TypeCode_abstract_interface()4573 TypeCode_abstract_interface::~TypeCode_abstract_interface() {
4574 the_typecodes->remove(pd_repoId, this);
4575 }
4576
4577
4578 TypeCode_base*
4579 TypeCode_abstract_interface::
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)4580 NP_unmarshalComplexParams(cdrStream &s,
4581 TypeCode_offsetTable* otbl)
4582 {
4583 TypeCode_abstract_interface* _ptr = new TypeCode_abstract_interface;
4584
4585 otbl->addEntry(otbl->currentOffset(), _ptr);
4586
4587 _ptr->pd_repoId = s.unmarshalRawString();
4588 _ptr->pd_name = s.unmarshalRawString();
4589 _ptr->pd_complete = 1;
4590
4591 return _ptr;
4592 }
4593
4594 //////////////////////////////////////////////////////////////////////
4595 /////////////////////////// TypeCode_local_interface /////////////////
4596 //////////////////////////////////////////////////////////////////////
4597
4598 TypeCode_local_interface::
TypeCode_local_interface(const char * repositoryId,const char * name)4599 TypeCode_local_interface(const char* repositoryId, const char* name)
4600 : TypeCode_objref(repositoryId, name, CORBA::tk_local_interface)
4601 {
4602 }
4603
4604
TypeCode_local_interface()4605 TypeCode_local_interface::TypeCode_local_interface()
4606 : TypeCode_objref(CORBA::tk_local_interface)
4607 {
4608 }
4609
4610
~TypeCode_local_interface()4611 TypeCode_local_interface::~TypeCode_local_interface() {
4612 the_typecodes->remove(pd_repoId, this);
4613 }
4614
4615
4616 TypeCode_base*
4617 TypeCode_local_interface::
NP_unmarshalComplexParams(cdrStream & s,TypeCode_offsetTable * otbl)4618 NP_unmarshalComplexParams(cdrStream &s,
4619 TypeCode_offsetTable* otbl)
4620 {
4621 TypeCode_local_interface* _ptr = new TypeCode_local_interface;
4622
4623 otbl->addEntry(otbl->currentOffset(), _ptr);
4624
4625 _ptr->pd_repoId = s.unmarshalRawString();
4626 _ptr->pd_name = s.unmarshalRawString();
4627 _ptr->pd_complete = 1;
4628
4629 return _ptr;
4630 }
4631
4632
4633 //////////////////////////////////////////////////////////////////////
4634 //////////////////////// TypeCode_indirect ///////////////////////////
4635 //////////////////////////////////////////////////////////////////////
4636
TypeCode_indirect(const char * repoId)4637 TypeCode_indirect::TypeCode_indirect(const char* repoId)
4638 : TypeCode_base(CORBA::_np_tk_indirect), pd_repoId(repoId), pd_resolved(0)
4639 { }
4640
~TypeCode_indirect()4641 TypeCode_indirect::~TypeCode_indirect()
4642 {
4643 if (pd_resolved) TypeCode_collector::releaseRef(pd_resolved);
4644 the_typecodes->remove(pd_repoId, this);
4645 }
4646
4647 void
NP_marshalSimpleParams(cdrStream & s,TypeCode_offsetTable * tbl) const4648 TypeCode_indirect::NP_marshalSimpleParams(cdrStream& s,
4649 TypeCode_offsetTable* tbl) const
4650 {
4651 OMNIORB_ASSERT(pd_resolved);
4652 pd_resolved->NP_marshalSimpleParams(s, tbl);
4653 }
4654
4655 void
NP_marshalComplexParams(cdrStream & s,TypeCode_offsetTable * tbl) const4656 TypeCode_indirect::NP_marshalComplexParams(cdrStream& s,
4657 TypeCode_offsetTable* tbl) const
4658 {
4659 OMNIORB_ASSERT(pd_resolved);
4660 pd_resolved->NP_marshalComplexParams(s, tbl);
4661 }
4662
4663 CORBA::Boolean
NP_complete_recursive_sequences(TypeCode_base * tc,CORBA::ULong offset)4664 TypeCode_indirect::NP_complete_recursive_sequences(TypeCode_base* tc,
4665 CORBA::ULong offset)
4666 {
4667 return 0;
4668 }
4669
4670 CORBA::Boolean
NP_complete_recursive(TypeCode_base * tc,const char * repoId)4671 TypeCode_indirect::NP_complete_recursive(TypeCode_base* tc,
4672 const char* repoId)
4673 {
4674 if (!pd_complete) {
4675 if (omni::strMatch(repoId, pd_repoId)) {
4676 OMNIORB_ASSERT(!pd_resolved);
4677 pd_complete = 1;
4678 pd_resolved = TypeCode_collector::duplicateRef(tc);
4679 TypeCode_collector::markLoopMembers(tc);
4680 return 1;
4681 }
4682 }
4683 return 0;
4684 }
4685
4686 #define CHECK_RESOLVED do { \
4687 if (!pd_resolved) \
4688 OMNIORB_THROW(BAD_TYPECODE, \
4689 BAD_TYPECODE_UnresolvedRecursiveTC, \
4690 CORBA::COMPLETED_NO); \
4691 } while(0)
4692
4693 CORBA::Boolean
NP_extendedEqual(const TypeCode_base * TCp,CORBA::Boolean equivalent,const TypeCode_pairlist * pl) const4694 TypeCode_indirect::NP_extendedEqual(const TypeCode_base* TCp,
4695 CORBA::Boolean equivalent,
4696 const TypeCode_pairlist* pl) const
4697 {
4698 CHECK_RESOLVED;
4699 return pd_resolved->NP_extendedEqual(TCp, equivalent, pl);
4700 }
4701
4702 const char*
NP_id() const4703 TypeCode_indirect::NP_id() const
4704 {
4705 CHECK_RESOLVED;
4706 return pd_resolved->NP_id();
4707 }
4708
4709 const char*
NP_name() const4710 TypeCode_indirect::NP_name() const
4711 {
4712 CHECK_RESOLVED;
4713 return pd_resolved->NP_name();
4714 }
4715
4716 CORBA::ULong
NP_member_count() const4717 TypeCode_indirect::NP_member_count() const
4718 {
4719 CHECK_RESOLVED;
4720 return pd_resolved->NP_member_count();
4721 }
4722
4723 const char*
NP_member_name(CORBA::ULong index) const4724 TypeCode_indirect::NP_member_name(CORBA::ULong index) const
4725 {
4726 CHECK_RESOLVED;
4727 return pd_resolved->NP_member_name(index);
4728 }
4729
4730 TypeCode_base*
NP_member_type(CORBA::ULong index) const4731 TypeCode_indirect::NP_member_type(CORBA::ULong index) const
4732 {
4733 CHECK_RESOLVED;
4734 return pd_resolved->NP_member_type(index);
4735 }
4736
4737 CORBA::Any*
NP_member_label(CORBA::ULong index) const4738 TypeCode_indirect::NP_member_label(CORBA::ULong index) const
4739 {
4740 CHECK_RESOLVED;
4741 return pd_resolved->NP_member_label(index);
4742 }
4743
4744 TypeCode_base*
NP_discriminator_type() const4745 TypeCode_indirect::NP_discriminator_type() const
4746 {
4747 CHECK_RESOLVED;
4748 return pd_resolved->NP_discriminator_type();
4749 }
4750
4751 CORBA::Long
NP_default_index() const4752 TypeCode_indirect::NP_default_index() const
4753 {
4754 CHECK_RESOLVED;
4755 return pd_resolved->NP_default_index();
4756 }
4757
4758 CORBA::ULong
NP_length() const4759 TypeCode_indirect::NP_length() const
4760 {
4761 CHECK_RESOLVED;
4762 return pd_resolved->NP_length();
4763 }
4764
4765 TypeCode_base*
NP_content_type() const4766 TypeCode_indirect::NP_content_type() const
4767 {
4768 CHECK_RESOLVED;
4769 return pd_resolved->NP_content_type();
4770 }
4771
4772 CORBA::UShort
NP_fixed_digits() const4773 TypeCode_indirect::NP_fixed_digits() const
4774 {
4775 CHECK_RESOLVED;
4776 return pd_resolved->NP_fixed_digits();
4777 }
4778
4779 CORBA::Short
NP_fixed_scale() const4780 TypeCode_indirect::NP_fixed_scale() const
4781 {
4782 CHECK_RESOLVED;
4783 return pd_resolved->NP_fixed_scale();
4784 }
4785
4786 CORBA::Long
NP_param_count() const4787 TypeCode_indirect::NP_param_count() const
4788 {
4789 CHECK_RESOLVED;
4790 return pd_resolved->NP_param_count();
4791 }
4792
4793 CORBA::Any*
NP_parameter(CORBA::Long p) const4794 TypeCode_indirect::NP_parameter(CORBA::Long p) const
4795 {
4796 CHECK_RESOLVED;
4797 return pd_resolved->NP_parameter(p);
4798 }
4799
4800 CORBA::Short
NP_member_visibility(CORBA::ULong m) const4801 TypeCode_indirect::NP_member_visibility(CORBA::ULong m) const
4802 {
4803 CHECK_RESOLVED;
4804 return pd_resolved->NP_member_visibility(m);
4805 }
4806
4807 CORBA::ValueModifier
NP_type_modifier() const4808 TypeCode_indirect::NP_type_modifier() const
4809 {
4810 CHECK_RESOLVED;
4811 return pd_resolved->NP_type_modifier();
4812 }
4813
4814 TypeCode_base*
NP_concrete_base_type() const4815 TypeCode_indirect::NP_concrete_base_type() const
4816 {
4817 CHECK_RESOLVED;
4818 return pd_resolved->NP_concrete_base_type();
4819 }
4820
4821 CORBA::Boolean
NP_containsAnAlias()4822 TypeCode_indirect::NP_containsAnAlias()
4823 {
4824 CHECK_RESOLVED;
4825 return pd_resolved->NP_containsAnAlias();
4826 }
4827
4828 TypeCode_base*
NP_aliasExpand(TypeCode_pairlist * pl)4829 TypeCode_indirect::NP_aliasExpand(TypeCode_pairlist* pl)
4830 {
4831 CHECK_RESOLVED;
4832 return pd_resolved->NP_aliasExpand(pl);
4833 }
4834
4835 void
removeOptionalNames()4836 TypeCode_indirect::removeOptionalNames()
4837 {
4838 CHECK_RESOLVED;
4839 pd_resolved->removeOptionalNames();
4840 }
4841
4842
4843 void
NP_releaseChildren()4844 TypeCode_indirect::NP_releaseChildren()
4845 {
4846 if (pd_resolved) {
4847 TypeCode_base* rtc = pd_resolved;
4848 pd_resolved = ToTcBase(CORBA::TypeCode::_duplicate(CORBA::_tc_void));
4849 TypeCode_collector::releaseRef(rtc);
4850 }
4851 }
4852
4853
4854
4855 #undef CHECK_RESOLVED
4856
4857
4858 //////////////////////////////////////////////////////////////////////
4859 //////////////////////// TypeCode_offsetTable ////////////////////////
4860 //////////////////////////////////////////////////////////////////////
4861
TypeCode_offsetTable()4862 TypeCode_offsetTable::TypeCode_offsetTable()
4863 : pd_table(0), pd_curr_offset(0), pd_parent_table(0),
4864 pd_parent_base_offset(0)
4865 {
4866 }
4867
4868
~TypeCode_offsetTable()4869 TypeCode_offsetTable::~TypeCode_offsetTable()
4870 {
4871 TypeCode_offsetEntry* entry = pd_table;
4872
4873 while (entry != 0)
4874 {
4875 TypeCode_offsetEntry* next_entry = entry->pd_next;
4876
4877 delete entry;
4878 entry = next_entry;
4879 }
4880 }
4881
4882
4883 // Routine to create a child, encapsulating offsetTable
TypeCode_offsetTable(TypeCode_offsetTable * parent,CORBA::Long base_offset)4884 TypeCode_offsetTable::TypeCode_offsetTable(TypeCode_offsetTable* parent,
4885 CORBA::Long base_offset)
4886 : pd_table(0), pd_curr_offset(base_offset),
4887 pd_parent_table(parent),
4888 pd_parent_base_offset(parent->currentOffset() - base_offset)
4889 {
4890 }
4891
4892
4893 // Routine to add an offset->typecode mapping
4894 void
addEntry(CORBA::Long offset,TypeCode_base * typecode)4895 TypeCode_offsetTable::addEntry(CORBA::Long offset, TypeCode_base* typecode)
4896 {
4897 // If this table is a wrapper round another then correct the offset and
4898 // pass on the request
4899 if (pd_parent_table != 0)
4900 pd_parent_table->addEntry(offset + pd_parent_base_offset, typecode);
4901 else
4902 {
4903 // Otherwise, just look in this table directly
4904 TypeCode_offsetEntry* new_entry = new TypeCode_offsetEntry;
4905
4906 new_entry->pd_next = pd_table;
4907 new_entry->pd_offset = offset;
4908 new_entry->pd_typecode = typecode;
4909
4910 pd_table = new_entry;
4911 }
4912 }
4913
4914
4915 // Routines to retrieve typecode by offset or vica versa
4916 TypeCode_base*
lookupOffset(CORBA::Long offset)4917 TypeCode_offsetTable::lookupOffset(CORBA::Long offset)
4918 {
4919 // If this table is a wrapper round another then correct
4920 // the offset and pass on the request
4921 if (pd_parent_table != 0)
4922 return pd_parent_table->lookupOffset(offset + pd_parent_base_offset);
4923
4924 // Visibroker's Java ORB gives out TypeCode indirections which are not
4925 // a multiple of 4. Rounding them up seems to solve the problem ...
4926
4927 if (orbParameters::acceptMisalignedTcIndirections && (offset & 0x3)) {
4928 omniORB::logs(1, "Warning: received TypeCode with "
4929 "mis-aligned indirection.");
4930 offset = (offset + 3) & 0xfffffffc;
4931 }
4932
4933 // Otherwise, just look in this table directly
4934 TypeCode_offsetEntry* entry = pd_table;
4935
4936 while (entry != 0) {
4937 if ((CORBA::Long)entry->pd_offset == offset)
4938 return entry->pd_typecode;
4939
4940 entry = entry->pd_next;
4941 }
4942
4943 return 0;
4944 }
4945
4946
4947 CORBA::Boolean
lookupTypeCode(const TypeCode_base * tc,CORBA::Long & offset)4948 TypeCode_offsetTable::lookupTypeCode(const TypeCode_base* tc,
4949 CORBA::Long &offset)
4950 {
4951 // If this table is a wrapper round another then correct
4952 // the offset and pass on the request
4953 if (pd_parent_table != 0)
4954 {
4955 if (pd_parent_table->lookupTypeCode(tc, offset))
4956 {
4957 offset = offset - pd_parent_base_offset;
4958 return 1;
4959 }
4960 return 0;
4961 }
4962
4963 // Otherwise, just look in this table directly
4964 TypeCode_offsetEntry* entry = pd_table;
4965
4966 while (entry != 0) {
4967 if (entry->pd_typecode == tc) {
4968 offset = entry->pd_offset;
4969 return 1;
4970 }
4971 entry = entry->pd_next;
4972 }
4973
4974 return 0;
4975 }
4976
4977 //////////////////////////////////////////////////////////////////////
4978 ////////////////////////// TypeCode_pairlist /////////////////////////
4979 //////////////////////////////////////////////////////////////////////
4980
4981 int
contains(const TypeCode_pairlist * pl,const TypeCode_base * t1,const TypeCode_base * t2)4982 TypeCode_pairlist::contains(const TypeCode_pairlist* pl,
4983 const TypeCode_base* t1, const TypeCode_base* t2)
4984 {
4985 while( pl ) {
4986
4987 if( t1 == pl->d_tc1 && t2 == pl->d_tc2 )
4988 return 1;
4989
4990 pl = pl->d_next;
4991 }
4992 return 0;
4993 }
4994
4995
4996 const TypeCode_base*
search(const TypeCode_pairlist * pl,const TypeCode_base * tc)4997 TypeCode_pairlist::search(const TypeCode_pairlist* pl, const TypeCode_base* tc)
4998 {
4999 while( pl ) {
5000
5001 if( tc == pl->d_tc2 )
5002 return pl->d_tc1;
5003
5004 pl = pl->d_next;
5005 }
5006 return 0;
5007 }
5008
5009 //////////////////////////////////////////////////////////////////////
5010 ///////////////////////// TypeCode_marshaller ////////////////////////
5011 //////////////////////////////////////////////////////////////////////
5012
5013
5014 void
marshal(TypeCode_base * tc,cdrStream & s,TypeCode_offsetTable * otbl)5015 TypeCode_marshaller::marshal(TypeCode_base* tc,
5016 cdrStream& s,
5017 TypeCode_offsetTable* otbl)
5018 {
5019 CORBA::ULong tck = tc->NP_kind();
5020
5021 // Follow any TypeCode_indirect objects created by
5022 // ORB::create_recursive_tc().
5023 while (tck == 0xffffffff)
5024 {
5025 tc = ((TypeCode_indirect*)tc)->NP_resolved();
5026 tck = tc->NP_kind();
5027 }
5028
5029 // If this _exact_ typecode has already been marshalled into the stream
5030 // then just put in an indirection
5031 CORBA::Long tc_offset;
5032 if( orbParameters::useTypeCodeIndirections &&
5033 otbl->lookupTypeCode(tc, tc_offset) )
5034 {
5035 // The desired typecode was found, so write out an indirection
5036 CORBA::ULong tck_indirect = 0xffffffff;
5037 tck_indirect >>= s;
5038
5039 // Now write out the offset
5040 CORBA::Long offset = tc_offset - (s.currentOutputPtr());
5041 offset >>= s;
5042 }
5043 else
5044 {
5045 // Write out the Kind
5046 tck >>= s;
5047
5048 // Set the current offset of the offset table
5049 otbl->setOffset(s.currentOutputPtr() - 4);
5050
5051 // Establish whether there are parameters to marshal
5052 switch( paramListType(tck) ) {
5053
5054 case plt_None:
5055 // No parameters
5056 break;
5057
5058 case plt_Simple:
5059 // Simple parameter list
5060 tc->NP_marshalSimpleParams(s, otbl);
5061 break;
5062
5063 case plt_Complex:
5064 // Complex parameter list
5065 {
5066 // The typecode is complex and wasn't found, so add it to the table
5067 otbl->addEntry(otbl->currentOffset(), tc);
5068
5069 // Build the parameter list
5070 cdrEncapsulationStream paramlist;
5071
5072 // Create a child TypeCode_offsetTable with the correct base
5073 // offset.
5074 // NB: When the offsetTable is passed to us, the currentOffset
5075 // value will indicate the START of the typecode we're
5076 // marshalling. Relative to the start of the encapsulated
5077 // data, this location has offset -8, allowing four bytes for
5078 // the TypeCode Kind and four for the encapsulation size.
5079 TypeCode_offsetTable offsetTbl(otbl, -8);
5080
5081 // Call the supplied typecode object to marshal its complex
5082 // parameter data into the temporary stream.
5083 tc->NP_marshalComplexParams(paramlist, &offsetTbl);
5084
5085 // Now write the size of the encapsulation out to the main stream
5086 CORBA::ULong bufsize = paramlist.bufSize();
5087 bufsize >>= s;
5088
5089 // And copy the data out to the main stream
5090 s.put_octet_array((CORBA::Char*) paramlist.bufPtr(), bufsize);
5091
5092 break;
5093 }
5094 } // switch( paramListType(tck) ) {
5095 }
5096 }
5097
5098
5099 TypeCode_base*
unmarshal(cdrStream & s,TypeCode_offsetTable * otbl)5100 TypeCode_marshaller::unmarshal(cdrStream& s,
5101 TypeCode_offsetTable* otbl)
5102 {
5103 // Read the kind from the stream
5104 CORBA::ULong tck;
5105 tck <<= s;
5106
5107 // Set the current position value in the offsetTable
5108 otbl->setOffset(s.currentInputPtr()-4);
5109
5110 // Depending on the kind, create the correct type of TypeCode class
5111
5112 // Each simple typecode class provides a NP_unmarshalSimpleParams
5113 // static function which reads the parameters in from a stream &
5114 // constructs a typecode of that type. NP_unmarshalSimpleParams is
5115 // passed the current TypeCode_offsetTable, in order that indirection
5116 // typecodes can be correctly interpreted.
5117
5118 // Each complex typecode class provides a NP_unmarshalComplexParams
5119 // static function which reads the parameters in from a stream &
5120 // constructs a typecode of that type. NP_unmarshalComplexParams is
5121 // passed a child TypeCode_offsetTable and MemBufferedStream, in order
5122 // that indirection typecodes can be correctly interpreted.
5123
5124 switch( paramListType(tck) ) {
5125
5126 // TypeCode Kinds with no parameters
5127 case plt_None:
5128 switch (tck) {
5129
5130 // Indirection typecode
5131 case 0xffffffff:
5132 {
5133 CORBA::Long currpos = s.currentInputPtr();
5134 CORBA::Long offset;
5135
5136 // Read in the offset within the GIOP message
5137 offset <<= s;
5138
5139 // Now look it up in the table
5140 TypeCode_base* tc = otbl->lookupOffset(offset+currpos);
5141 if (tc == 0)
5142 OMNIORB_THROW(MARSHAL,
5143 MARSHAL_InvalidIndirection,
5144 CORBA::COMPLETED_NO);
5145
5146 return TypeCode_collector::duplicateRef(tc);
5147 }
5148
5149 // Simple types with no parameters
5150 case CORBA::tk_null:
5151 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_null));
5152 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_null));
5153 case CORBA::tk_void:
5154 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_void));
5155 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_void));
5156 case CORBA::tk_short:
5157 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_short));
5158 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_short));
5159 case CORBA::tk_ushort:
5160 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_ushort));
5161 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_ushort));
5162 case CORBA::tk_long:
5163 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_long));
5164 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_long));
5165 case CORBA::tk_ulong:
5166 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_ulong));
5167 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_ulong));
5168 case CORBA::tk_float:
5169 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_float));
5170 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_float));
5171 case CORBA::tk_double:
5172 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_double));
5173 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_double));
5174 case CORBA::tk_boolean:
5175 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_boolean));
5176 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_boolean));
5177 case CORBA::tk_char:
5178 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_char));
5179 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_char));
5180 case CORBA::tk_wchar:
5181 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_wchar));
5182 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_wchar));
5183 case CORBA::tk_octet:
5184 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_octet));
5185 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_octet));
5186 case CORBA::tk_any:
5187 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_any));
5188 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_any));
5189 case CORBA::tk_TypeCode:
5190 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_TypeCode));
5191 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_TypeCode));
5192 case CORBA::tk_Principal:
5193 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_Principal));
5194 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_Principal));
5195 #ifdef HAS_LongLong
5196 case CORBA::tk_longlong:
5197 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_longlong));
5198 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_longlong));
5199 case CORBA::tk_ulonglong:
5200 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_ulonglong));
5201 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_ulonglong));
5202 #endif
5203 #ifdef HAS_LongDouble
5204 case CORBA::tk_longdouble:
5205 otbl->addEntry(otbl->currentOffset(), ToTcBase(CORBA::_tc_longdouble));
5206 return TypeCode_collector::duplicateRef(ToTcBase(CORBA::_tc_longdouble));
5207 #endif
5208
5209 default:
5210 OMNIORB_THROW(MARSHAL, MARSHAL_InvalidTypeCodeKind, CORBA::COMPLETED_NO);
5211 };
5212 // Never reach here
5213
5214 // TypeCode Kinds with simple parameter lists
5215 case plt_Simple:
5216
5217 switch (tck) {
5218
5219 case CORBA::tk_string:
5220 return TypeCode_string::NP_unmarshalSimpleParams(s, otbl);
5221
5222 case CORBA::tk_wstring:
5223 return TypeCode_wstring::NP_unmarshalSimpleParams(s, otbl);
5224
5225 case CORBA::tk_fixed:
5226 return TypeCode_fixed::NP_unmarshalSimpleParams(s, otbl);
5227
5228 default:
5229 OMNIORB_THROW(MARSHAL,MARSHAL_InvalidTypeCodeKind, CORBA::COMPLETED_NO);
5230 };
5231 // Never reach here
5232
5233 // TypeCode Kinds with complex parameter lists
5234 case plt_Complex:
5235 {
5236 // Create a child TypeCode_offsetTable with the correct base offset.
5237 // NB: When the offsetTable is passed to us, the currentOffset value
5238 // will indicate the START of the typecode we're unmarshalling.
5239 // Relative to the start of the encapsulated data, this location has
5240 // offset -8, allowing four bytes for the TypeCode Kind and four for
5241 // the encapsulation size.
5242 TypeCode_offsetTable tbl(otbl, -8);
5243
5244 // Read the size of the encapsulation
5245 CORBA::ULong size;
5246 size <<= s;
5247
5248 // Create a buffered stream to handle the encapsulation
5249 // and read the data in.
5250 //?? Can we do this without lots of copying? Is it worth it?
5251 cdrMemoryStream mbs(size);
5252 s.copy_to(mbs, size);
5253
5254 // Get the byte order
5255 CORBA::Boolean byteorder = mbs.unmarshalBoolean();
5256 mbs.setByteSwapFlag(byteorder);
5257
5258 // Now switch on the Kind to call the appropriate
5259 // unmarshalComplexParams fn.
5260 switch (tck) {
5261
5262 case CORBA::tk_objref:
5263 return TypeCode_objref::NP_unmarshalComplexParams(mbs, &tbl);
5264
5265 case CORBA::tk_alias:
5266 return TypeCode_alias::NP_unmarshalComplexParams(mbs, &tbl);
5267
5268 case CORBA::tk_sequence:
5269 return TypeCode_sequence::NP_unmarshalComplexParams(mbs, &tbl);
5270
5271 case CORBA::tk_array:
5272 return TypeCode_array::NP_unmarshalComplexParams(mbs, &tbl);
5273
5274 case CORBA::tk_struct:
5275 return TypeCode_struct::NP_unmarshalComplexParams(mbs, &tbl);
5276
5277 case CORBA::tk_except:
5278 return TypeCode_except::NP_unmarshalComplexParams(mbs, &tbl);
5279
5280 case CORBA::tk_enum:
5281 return TypeCode_enum::NP_unmarshalComplexParams(mbs, &tbl);
5282
5283 case CORBA::tk_union:
5284 return TypeCode_union::NP_unmarshalComplexParams(mbs, &tbl);
5285
5286 case CORBA::tk_value:
5287 return TypeCode_value::NP_unmarshalComplexParams(mbs, &tbl);
5288
5289 case CORBA::tk_value_box:
5290 return TypeCode_value_box::NP_unmarshalComplexParams(mbs, &tbl);
5291
5292 case CORBA::tk_abstract_interface:
5293 return TypeCode_abstract_interface::NP_unmarshalComplexParams(mbs, &tbl);
5294
5295 case CORBA::tk_local_interface:
5296 return TypeCode_local_interface::NP_unmarshalComplexParams(mbs, &tbl);
5297
5298 default:
5299 OMNIORB_THROW(MARSHAL,
5300 MARSHAL_InvalidTypeCodeKind,
5301 CORBA::COMPLETED_NO);
5302 };
5303 // Never reach here
5304 }
5305
5306 default:
5307 OMNIORB_THROW(MARSHAL, MARSHAL_InvalidTypeCodeKind, CORBA::COMPLETED_NO);
5308 // Never reach here
5309 };
5310
5311 #ifdef NEED_DUMMY_RETURN
5312 return 0;
5313 #endif
5314 }
5315
5316 // Function used to establish whether a particular typecode Kind
5317 // has no parameters, simple parameters, or complex parameters
5318 TypeCode_paramListType
paramListType(CORBA::ULong kind)5319 TypeCode_marshaller::paramListType(CORBA::ULong kind)
5320 {
5321 static TypeCode_paramListType plt[] = {
5322 plt_None, // null
5323 plt_None, // void
5324 plt_None, // short
5325 plt_None, // long
5326 plt_None, // ushort
5327 plt_None, // ulong
5328 plt_None, // float
5329 plt_None, // double
5330 plt_None, // boolean
5331 plt_None, // char
5332 plt_None, // octet
5333 plt_None, // any
5334 plt_None, // typecode
5335 plt_None, // principal
5336 plt_Complex, // objref
5337 plt_Complex, // struct
5338 plt_Complex, // union
5339 plt_Complex, // enum
5340 plt_Simple, // string
5341 plt_Complex, // sequence
5342 plt_Complex, // array
5343 plt_Complex, // alias
5344 plt_Complex, // except
5345 plt_None, // longlong
5346 plt_None, // ulonglong
5347 plt_None, // long double
5348 plt_None, // wchar
5349 plt_Simple, // wstring
5350 plt_Simple, // fixed
5351 plt_Complex, // value
5352 plt_Complex, // value_box
5353 plt_Complex, // native
5354 plt_Complex, // abstract_interface
5355 plt_Complex // local_interface
5356 };
5357
5358 if( kind == 0xffffffff ) return plt_None;
5359
5360 if( kind < sizeof(plt) / sizeof(TypeCode_paramListType) )
5361 return plt[kind];
5362
5363 OMNIORB_THROW(MARSHAL, MARSHAL_InvalidTypeCodeKind, CORBA::COMPLETED_NO);
5364 #ifdef NEED_DUMMY_RETURN
5365 return plt_None;
5366 #endif
5367 }
5368
5369 //////////////////////////////////////////////////////////////////////
5370 ///////////////////////// TypeCode_collector /////////////////////////
5371 //////////////////////////////////////////////////////////////////////
5372
5373 // Global typecode lock. This lock guarantees only one duplicate/release is
5374 // in progress at any one time.
5375
5376 // Initialised in check_static_data_is_initialised().
5377 static omni_tracedmutex* refcount_lock = 0;
5378
5379
5380 // Duplicating typecodes
5381
5382 TypeCode_base*
duplicateRef(TypeCode_base * tc)5383 TypeCode_collector::duplicateRef(TypeCode_base* tc)
5384 {
5385 omni_tracedmutex_lock l(*refcount_lock);
5386
5387 tc->pd_ref_count++;
5388
5389 return tc;
5390 }
5391
5392 // Releasing typecodes
5393
5394 void
releaseRef(TypeCode_base * tc)5395 TypeCode_collector::releaseRef(TypeCode_base* tc)
5396 {
5397 CORBA::Boolean node_can_be_freed = 0;
5398 CORBA::Boolean children_can_be_freed = 0;
5399
5400 {
5401 omni_tracedmutex_lock l(*refcount_lock);
5402
5403 // If the reference count is already zero then this node is already
5404 // being deleted
5405 if (tc->pd_ref_count == 0) {
5406 return;
5407 }
5408 // If the reference count has hit 1 then we can delete the node
5409 if (tc->pd_ref_count == 1) {
5410 node_can_be_freed = 1;
5411 }
5412 else {
5413 // Is this typecode part of a loop?
5414 if (tc->pd_loop_member) {
5415 // Yes, so are the references to it real or because of the loop?
5416 countInternalRefs(tc);
5417
5418 if (checkInternalRefs(tc, 0)) {
5419 children_can_be_freed = 1;
5420 }
5421 }
5422 }
5423 tc->pd_ref_count--;
5424 }
5425
5426 // Now delete the node's storage, if possible
5427 if (node_can_be_freed) {
5428 delete tc;
5429 }
5430
5431 if (children_can_be_freed) {
5432 tc->NP_releaseChildren();
5433 }
5434 }
5435
5436 // Marking typecodes that are part of one or more loops
5437
5438 void
markLoopMembers(TypeCode_base * tc)5439 TypeCode_collector::markLoopMembers(TypeCode_base* tc)
5440 {
5441 // Lock the typecode space before doing this
5442 omni_tracedmutex_lock l(*refcount_lock);
5443
5444 markLoops(tc, 0);
5445 }
5446
5447 // -- - Internal reference counting fns
5448
5449 // These functions could be split up and distributed amongs the typecode
5450 // classes they affect but instead I've used switch statements to keep
5451 // the functions in one piece, for clarity.
5452
5453 // NB : It is required that refcount_lock be held for these to operate
5454 // as desired.
5455
5456 // -- markLoops
5457 // Given a typecode and an initial depth count (usually zero), markloops will
5458 // follow the TypeCode tree to establish where it contains loops.
5459
_minimum(CORBA::ULong a,CORBA::ULong b)5460 static inline CORBA::ULong _minimum(CORBA::ULong a, CORBA::ULong b)
5461 {
5462 return a < b ? a : b;
5463 }
5464
5465 CORBA::ULong
markLoops(TypeCode_base * tc,CORBA::ULong depth)5466 TypeCode_collector::markLoops(TypeCode_base* tc, CORBA::ULong depth)
5467 {
5468 // Have we visited this node before?
5469 if (tc->pd_mark)
5470 {
5471 return tc->pd_internal_depth - 1;
5472 }
5473 else
5474 {
5475 // No, so mark that we have and set an initial value for the depth count
5476 tc->pd_mark = 1;
5477 tc->pd_internal_depth = depth+1;
5478
5479 // Now enumerate the child nodes, if any, to find out what the
5480 // lowest-depth node they can access is.
5481 switch (tc->NP_kind()) {
5482
5483 case CORBA::tk_alias:
5484 case CORBA::tk_array:
5485 case CORBA::tk_value_box:
5486 tc->pd_internal_depth = markLoops(tc->NP_content_type(), depth+1);
5487 break;
5488
5489 case CORBA::tk_sequence:
5490 if (((TypeCode_sequence*)tc)->PR_content_is_assigned())
5491 tc->pd_internal_depth = markLoops(tc->NP_content_type(), depth+1);
5492 break;
5493
5494 case CORBA::tk_struct:
5495 case CORBA::tk_except:
5496 case CORBA::tk_union:
5497 case CORBA::tk_value:
5498 {
5499 CORBA::ULong memberCount = tc->NP_member_count();
5500
5501 // Enumerate the member typecodes
5502 for( CORBA::ULong i = 0; i < memberCount; i++ )
5503 {
5504 tc->pd_internal_depth = _minimum(tc->pd_internal_depth,
5505 markLoops(tc->NP_member_type(i),
5506 depth+1));
5507 }
5508
5509 break;
5510 }
5511
5512 case CORBA::_np_tk_indirect:
5513 {
5514 if (tc->pd_complete) {
5515 tc->pd_internal_depth =
5516 markLoops(((TypeCode_indirect*)tc)->NP_resolved(), depth+1);
5517 }
5518 break;
5519 }
5520
5521 default:
5522 break;
5523 };
5524
5525 // Now check whether or not we're part of a loop
5526 if (tc->pd_internal_depth <= depth) {
5527 tc->pd_loop_member = 1;
5528 }
5529 else
5530 tc->pd_loop_member = 0;
5531
5532 // Clear the mark
5533 tc->pd_mark = 0;
5534 }
5535
5536 // Return the least-deep accessible node
5537 return tc->pd_internal_depth;
5538 }
5539
5540 // -- countInternalRefs
5541 // Follows the typecode tree round, marking the nodes with the number of
5542 // references to them that are actually just internal ones.
5543 // If all the nodes in a loop have the same number of references as internal
5544 // references then this indicates that the loop is, in fact, 'floating'.
5545
5546 void
countInternalRefs(TypeCode_base * tc)5547 TypeCode_collector::countInternalRefs(TypeCode_base* tc)
5548 {
5549 // Increase the internal reference count to this node
5550 tc->pd_internal_ref_count++;
5551
5552 // If this node is already marked then don't check its children
5553 if (!tc->pd_mark)
5554 {
5555 tc->pd_mark = 1;
5556
5557 // Now *think* of the children!
5558 switch (tc->NP_kind()) {
5559
5560 case CORBA::tk_alias:
5561 case CORBA::tk_array:
5562 case CORBA::tk_sequence:
5563 case CORBA::tk_value_box:
5564 countInternalRefs(tc->NP_content_type());
5565 break;
5566
5567 case CORBA::tk_struct:
5568 case CORBA::tk_except:
5569 case CORBA::tk_union:
5570 case CORBA::tk_value:
5571 {
5572 CORBA::ULong memberCount = tc->NP_member_count();
5573
5574 // Enumerate the member typecodes
5575 for( CORBA::ULong i = 0; i < memberCount; i++ )
5576 countInternalRefs(tc->NP_member_type(i));
5577
5578 break;
5579 }
5580
5581 case CORBA::_np_tk_indirect:
5582 {
5583 countInternalRefs(((TypeCode_indirect*)tc)->NP_resolved());
5584 break;
5585 }
5586
5587 default:
5588 break;
5589 }
5590 }
5591 }
5592
5593 // -- checkInternalRefs
5594 // Follows the typecode tree, reading back the internal reference count
5595 // values and checking them against the external reference counts if
5596 // necessary.
5597 // The depth counting system used to mark looped typecodes is used here
5598 // to avoid checking the internal reference counts of nodes that aren't
5599 // in the loop(s) we're interested in.
5600 // If the depth count returned by a child node exceeds the parent's depth
5601 // then we know that that particular child node is not in a loop with
5602 // the parent node and so isn't relevant to the test.
5603 // This function returns FALSE if the node is part of a loop in which another
5604 // member is referenced, or returns TRUE if the node is not part of a loop
5605 // or the loop is not externally referenced at all.
5606
5607 CORBA::Boolean
checkInternalRefs(TypeCode_base * tc,CORBA::ULong depth)5608 TypeCode_collector::checkInternalRefs(TypeCode_base* tc, CORBA::ULong depth)
5609 {
5610 CORBA::Boolean loop_can_be_freed = 1;
5611
5612 // If this node's mark has already been cleared then don't check its children
5613 if (tc->pd_mark)
5614 {
5615 CORBA::ULong internal_ref_count = tc->pd_internal_ref_count;
5616
5617 // Clear the mark & internal ref count & set the depth value
5618 tc->pd_mark = 0;
5619 tc->pd_internal_depth = depth;
5620 tc->pd_internal_ref_count = 0;
5621
5622 // Now *think* of the children!
5623 switch (tc->NP_kind()) {
5624
5625 case CORBA::tk_alias:
5626 case CORBA::tk_array:
5627 case CORBA::tk_sequence:
5628 case CORBA::tk_value_box:
5629 {
5630 TypeCode_base* child = tc->NP_content_type();
5631 CORBA::Boolean child_can_be_freed =
5632 checkInternalRefs(child, depth+1);
5633
5634 tc->pd_internal_depth = child->pd_internal_depth;
5635
5636 // Is this node part of a loop involving the child node?
5637 if (child->pd_internal_depth <= depth)
5638 {
5639 // Yes, so if the child node can't be freed then neither can we
5640 if (!child_can_be_freed)
5641 loop_can_be_freed = 0;
5642 else
5643 {
5644 // Child can be freed, so we should check our internal
5645 // references to see if we can be, too.
5646 if (internal_ref_count < tc->pd_ref_count)
5647 loop_can_be_freed = 0;
5648 }
5649 }
5650
5651 break;
5652 }
5653
5654 case CORBA::tk_struct:
5655 case CORBA::tk_except:
5656 case CORBA::tk_union:
5657 case CORBA::tk_value:
5658 {
5659 CORBA::Boolean can_be_freed = 1;
5660 CORBA::ULong memberCount = tc->NP_member_count();
5661
5662 // Enumerate the member typecodes
5663 for( CORBA::ULong i = 0; i < memberCount; i++ )
5664 {
5665 TypeCode_base* child = tc->NP_member_type(i);
5666 CORBA::Boolean child_can_be_freed =
5667 checkInternalRefs(child, depth+1);
5668
5669 tc->pd_internal_depth = _minimum(tc->pd_internal_depth,
5670 child->pd_internal_depth);
5671
5672 // Is this node part of a loop involving the child node?
5673 if (child->pd_internal_depth <= depth)
5674 {
5675 // Yes, so if the child node can't be freed then
5676 // neither can we.
5677 if (!child_can_be_freed)
5678 loop_can_be_freed = 0;
5679 else
5680 {
5681 // Child can be freed, so we should check our internal
5682 // references to see if we can be, too.
5683 if (internal_ref_count < tc->pd_ref_count)
5684 loop_can_be_freed = 0;
5685 }
5686 }
5687 }
5688
5689 break;
5690 }
5691
5692 case CORBA::_np_tk_indirect:
5693 {
5694 TypeCode_base* child = ((TypeCode_indirect*)tc)->NP_resolved();
5695 CORBA::Boolean child_can_be_freed =
5696 checkInternalRefs(child, depth+1);
5697
5698 tc->pd_internal_depth = child->pd_internal_depth;
5699
5700 // Is this node part of a loop involving the child node?
5701 if (child->pd_internal_depth <= depth)
5702 {
5703 // Yes, so if the child node can't be freed then neither can we
5704 if (!child_can_be_freed)
5705 loop_can_be_freed = 0;
5706 else
5707 {
5708 // Child can be freed, so we should check our internal
5709 // references to see if we can be, too.
5710 if (internal_ref_count < tc->pd_ref_count)
5711 loop_can_be_freed = 0;
5712 }
5713 }
5714
5715 break;
5716 }
5717
5718 default:
5719 break;
5720 }
5721 }
5722
5723 // We ONLY return true if this node is part of a loop AND can be freed
5724 if (tc->pd_internal_depth <= depth)
5725 return loop_can_be_freed;
5726 else
5727 return 0;
5728 }
5729
5730 //////////////////////////////////////////////////////////////////////
5731 //////////////////////// TypeCode_union_helper ///////////////////////
5732 //////////////////////////////////////////////////////////////////////
5733
5734 TypeCode_union::Discriminator
extractLabel(const CORBA::Any & label,CORBA::TypeCode_ptr dtc)5735 TypeCode_union_helper::extractLabel(const CORBA::Any& label,
5736 CORBA::TypeCode_ptr dtc)
5737 {
5738 // When the discriminator is a long, short, unsigned short or unsigned long,
5739 // we have to cast the label value from any of these kinds and check
5740 // if it is within the integer range of the discriminator.
5741 CORBA::TCKind lbl_kind;
5742 TypeCode_union::Discriminator lbl_value;
5743 CORBA::Boolean sign = 0; // 1 == signed.
5744 CORBA::TypeCode_var aetc = TypeCode_base::aliasExpand(ToTcBase(dtc));
5745
5746 {
5747 CORBA::TypeCode_var lbl_tc = label.type();
5748 CORBA::TypeCode_var ae_lbl_tc=TypeCode_base::aliasExpand(ToTcBase(lbl_tc));
5749 lbl_kind = ToTcBase(ae_lbl_tc)->NP_kind();
5750
5751 switch (lbl_kind) {
5752 case CORBA::tk_char:
5753 {
5754 CORBA::Char c;
5755 label >>= CORBA::Any::to_char(c);
5756 lbl_value = c;
5757 break;
5758 }
5759 case CORBA::tk_boolean:
5760 {
5761 CORBA::Boolean c;
5762 label >>= CORBA::Any::to_boolean(c);
5763 lbl_value = ((c)? 1 : 0);
5764 break;
5765 }
5766 case CORBA::tk_octet:
5767 {
5768 CORBA::Octet c;
5769 label >>= CORBA::Any::to_octet(c);
5770 lbl_value = c;
5771 break;
5772 }
5773 case CORBA::tk_short:
5774 {
5775 CORBA::Short c;
5776 label >>= c;
5777 lbl_value = c;
5778 sign = 1;
5779 break;
5780 }
5781 case CORBA::tk_ushort:
5782 {
5783 CORBA::UShort c;
5784 label >>= c;
5785 lbl_value = c;
5786 break;
5787 }
5788 case CORBA::tk_long:
5789 {
5790 CORBA::Long c;
5791 label >>= c;
5792 lbl_value = c;
5793 sign = 1;
5794 break;
5795 }
5796 case CORBA::tk_ulong:
5797 {
5798 CORBA::ULong c;
5799 label >>= c;
5800 lbl_value = c;
5801 break;
5802 }
5803 #ifdef HAS_LongLong
5804 case CORBA::tk_longlong:
5805 {
5806 CORBA::LongLong c;
5807 label >>= c;
5808 lbl_value = c;
5809 sign = 1;
5810 break;
5811 }
5812 case CORBA::tk_ulonglong:
5813 {
5814 CORBA::ULongLong c;
5815 label >>= c;
5816 lbl_value = c;
5817 break;
5818 }
5819 #endif
5820 case CORBA::tk_enum:
5821 {
5822 // check that <label> is of the correct type
5823 if( !dtc->equivalent(lbl_tc) )
5824 OMNIORB_THROW(BAD_PARAM,
5825 BAD_PARAM_IncompatibleDiscriminatorType,
5826 CORBA::COMPLETED_NO);
5827 CORBA::ULong c;
5828 cdrAnyMemoryStream ms(label.PR_streamToRead(), 1);
5829 c <<= ms;
5830 lbl_value = c;
5831 break;
5832 }
5833 default:
5834 OMNIORB_THROW(BAD_PARAM,
5835 BAD_PARAM_IllegitimateDiscriminatorType,
5836 CORBA::COMPLETED_NO);
5837 }
5838 }
5839
5840 switch( aetc->kind() ) {
5841 case CORBA::tk_char:
5842 if (lbl_kind != CORBA::tk_char)
5843 OMNIORB_THROW(BAD_PARAM,
5844 BAD_PARAM_IncompatibleDiscriminatorType,
5845 CORBA::COMPLETED_NO);
5846 break;
5847 case CORBA::tk_boolean:
5848 if (lbl_kind != CORBA::tk_boolean)
5849 OMNIORB_THROW(BAD_PARAM,
5850 BAD_PARAM_IncompatibleDiscriminatorType,
5851 CORBA::COMPLETED_NO);
5852 break;
5853 case CORBA::tk_short:
5854 if ((sign && ((TypeCode_union::DiscriminatorSigned) lbl_value < -32768) )
5855 || (lbl_value > 32767) )
5856 OMNIORB_THROW(BAD_PARAM,
5857 BAD_PARAM_IllegitimateDiscriminatorType,
5858 CORBA::COMPLETED_NO);
5859 break;
5860 case CORBA::tk_ushort:
5861 if ((sign && ((TypeCode_union::DiscriminatorSigned) lbl_value < 0) ) ||
5862 (lbl_value > 65536) )
5863 OMNIORB_THROW(BAD_PARAM,
5864 BAD_PARAM_IllegitimateDiscriminatorType,
5865 CORBA::COMPLETED_NO);
5866 break;
5867 case CORBA::tk_long:
5868 // XXX if TypeCode_union::Discriminator is bigger than
5869 // CORBA::Long, we test for the negative limit as well.
5870 if (!sign && (lbl_value > 2147483647) )
5871 OMNIORB_THROW(BAD_PARAM,
5872 BAD_PARAM_IllegitimateDiscriminatorType,
5873 CORBA::COMPLETED_NO);
5874 #ifdef HAS_LongLong
5875 // The unlikely looking constant -1 is to work around a bug in MSVC
5876 // that incorrectly deals with large negative literals :-( .
5877 if (sign &&
5878 ((TypeCode_union::DiscriminatorSigned)lbl_value <
5879 _CORBA_LONGLONG_CONST(-2147483647) - 1))
5880 OMNIORB_THROW(BAD_PARAM,
5881 BAD_PARAM_IllegitimateDiscriminatorType,
5882 CORBA::COMPLETED_NO);
5883 #endif
5884 break;
5885 case CORBA::tk_ulong:
5886 // XXX if TypeCode_union::Discriminator is bigger than
5887 // CORBA::ULong, we test for the positive limit as well.
5888 if (sign && ((TypeCode_union::DiscriminatorSigned) lbl_value < 0))
5889 OMNIORB_THROW(BAD_PARAM,
5890 BAD_PARAM_IllegitimateDiscriminatorType,
5891 CORBA::COMPLETED_NO);
5892 #ifdef HAS_LongLong
5893 if (lbl_value > 0xffffffff)
5894 OMNIORB_THROW(BAD_PARAM,
5895 BAD_PARAM_IllegitimateDiscriminatorType,
5896 CORBA::COMPLETED_NO);
5897 #endif
5898 break;
5899
5900 #ifdef HAS_LongLong
5901 case CORBA::tk_longlong:
5902 if (!sign && (lbl_value > _CORBA_LONGLONG_CONST(0x7fffffffffffffff)))
5903 OMNIORB_THROW(BAD_PARAM,
5904 BAD_PARAM_IllegitimateDiscriminatorType,
5905 CORBA::COMPLETED_NO);
5906 break;
5907 case CORBA::tk_ulonglong:
5908 if (sign && ((TypeCode_union::DiscriminatorSigned)lbl_value < 0))
5909 OMNIORB_THROW(BAD_PARAM,
5910 BAD_PARAM_IllegitimateDiscriminatorType,
5911 CORBA::COMPLETED_NO);
5912 break;
5913 #endif
5914
5915 case CORBA::tk_enum:
5916 {
5917 if (lbl_value >= aetc->member_count()) {
5918 OMNIORB_THROW(MARSHAL,
5919 MARSHAL_InvalidEnumValue,
5920 CORBA::COMPLETED_NO);
5921 }
5922 break;
5923 }
5924 // case CORBA::tk_wchar:
5925 case CORBA::tk_octet:
5926 default:
5927 OMNIORB_THROW(BAD_TYPECODE,
5928 BAD_PARAM_IllegitimateDiscriminatorType,
5929 CORBA::COMPLETED_NO);
5930 }
5931
5932 return lbl_value;
5933 }
5934
5935
5936 void
insertLabel(CORBA::Any & label,TypeCode_union::Discriminator c,CORBA::TypeCode_ptr tc)5937 TypeCode_union_helper::insertLabel(CORBA::Any& label,
5938 TypeCode_union::Discriminator c,
5939 CORBA::TypeCode_ptr tc)
5940 {
5941 const TypeCode_base* aetc = TypeCode_base::NP_expand(ToTcBase(tc));
5942
5943 switch( aetc->NP_kind() ) {
5944 case CORBA::tk_char:
5945 label <<= CORBA::Any::from_char((CORBA::Char)c);
5946 break;
5947 case CORBA::tk_boolean:
5948 label <<= CORBA::Any::from_boolean((CORBA::Boolean)c);
5949 break;
5950 case CORBA::tk_octet:
5951 label <<= CORBA::Any::from_octet((CORBA::Octet)c);
5952 break;
5953 case CORBA::tk_short:
5954 label <<= CORBA::Short(c);
5955 break;
5956 case CORBA::tk_ushort:
5957 label <<= CORBA::UShort(c);
5958 break;
5959 case CORBA::tk_long:
5960 label <<= CORBA::Long(c);
5961 break;
5962 case CORBA::tk_ulong:
5963 label <<= CORBA::ULong(c);
5964 break;
5965 #ifdef HAS_LongLong
5966 case CORBA::tk_longlong:
5967 label <<= CORBA::LongLong(c);
5968 break;
5969 case CORBA::tk_ulonglong:
5970 label <<= CORBA::ULongLong(c);
5971 break;
5972 #endif
5973
5974 case CORBA::tk_enum:
5975 {
5976 CORBA::ULong val = c;
5977 if (val >= aetc->member_count()) {
5978 OMNIORB_THROW(MARSHAL,
5979 MARSHAL_InvalidEnumValue,
5980 CORBA::COMPLETED_NO);
5981 }
5982 label.replace((CORBA::TypeCode_ptr)aetc, 0, 0);
5983 cdrAnyMemoryStream& ms = label.PR_streamToWrite();
5984 val >>= ms;
5985 break;
5986 }
5987 // case CORBA::tk_wchar:
5988 default:
5989 throw omniORB::fatalException(__FILE__,__LINE__,
5990 "TypeCode_union_helper::insertLabel() - illegal disciminator type");
5991 }
5992 }
5993
5994
5995 void
marshalLabel(TypeCode_union::Discriminator l,CORBA::TypeCode_ptr tc,cdrStream & s)5996 TypeCode_union_helper::marshalLabel(TypeCode_union::Discriminator l,
5997 CORBA::TypeCode_ptr tc,
5998 cdrStream &s)
5999 {
6000 const TypeCode_base* aetc = TypeCode_base::NP_expand(ToTcBase(tc));
6001
6002 switch( aetc->NP_kind() ) {
6003 case CORBA::tk_char:
6004 {
6005 CORBA::Char c = CORBA::Char(l);
6006 s.marshalChar(c);
6007 break;
6008 }
6009 case CORBA::tk_boolean:
6010 {
6011 CORBA::Boolean c = CORBA::Boolean(l);
6012 s.marshalBoolean(c);
6013 break;
6014 }
6015 case CORBA::tk_octet:
6016 {
6017 CORBA::Octet c = CORBA::Octet(l);
6018 s.marshalOctet(c);
6019 break;
6020 }
6021 case CORBA::tk_short:
6022 {
6023 CORBA::Short c = CORBA::Short(l);
6024 c >>= s;
6025 break;
6026 }
6027 case CORBA::tk_ushort:
6028 {
6029 CORBA::UShort c = CORBA::UShort(l);
6030 c >>= s;
6031 break;
6032 }
6033 case CORBA::tk_long:
6034 {
6035 CORBA::Long c = CORBA::Long(l);
6036 c >>= s;
6037 break;
6038 }
6039 case CORBA::tk_ulong:
6040 case CORBA::tk_enum:
6041 {
6042 CORBA::ULong c = CORBA::ULong(l);
6043 c >>= s;
6044 break;
6045 }
6046 #ifdef HAS_LongLong
6047 case CORBA::tk_longlong:
6048 {
6049 CORBA::LongLong c = CORBA::LongLong(l);
6050 c >>= s;
6051 break;
6052 }
6053 case CORBA::tk_ulonglong:
6054 {
6055 CORBA::ULongLong c = CORBA::ULongLong(l);
6056 c >>= s;
6057 break;
6058 }
6059 #endif
6060
6061 // case CORBA::tk_wchar:
6062 default:
6063 throw omniORB::fatalException(__FILE__,__LINE__,
6064 "TypeCode_union_helper::marshalLabel() - illegal disciminator type");
6065 }
6066 }
6067
6068
6069 TypeCode_union::Discriminator
unmarshalLabel(CORBA::TypeCode_ptr tc,cdrStream & s)6070 TypeCode_union_helper::unmarshalLabel(CORBA::TypeCode_ptr tc,
6071 cdrStream& s)
6072 {
6073 const TypeCode_base* aetc = TypeCode_base::NP_expand(ToTcBase(tc));
6074
6075 switch( aetc->NP_kind() ) {
6076 case CORBA::tk_char:
6077 {
6078 CORBA::Char c = s.unmarshalChar();
6079 return TypeCode_union::Discriminator(c);
6080 }
6081 case CORBA::tk_boolean:
6082 {
6083 CORBA::Boolean c = s.unmarshalBoolean();
6084 return TypeCode_union::Discriminator(c);
6085 }
6086 case CORBA::tk_octet:
6087 {
6088 CORBA::Octet c = s.unmarshalOctet();
6089 return TypeCode_union::Discriminator(c);
6090 }
6091 case CORBA::tk_short:
6092 {
6093 CORBA::Short c;
6094 c <<= s;
6095 return TypeCode_union::Discriminator(c);
6096 }
6097 case CORBA::tk_ushort:
6098 {
6099 CORBA::UShort c;
6100 c <<= s;
6101 return TypeCode_union::Discriminator(c);
6102 }
6103 case CORBA::tk_long:
6104 {
6105 CORBA::Long c;
6106 c <<= s;
6107 return TypeCode_union::Discriminator(c);
6108 }
6109 case CORBA::tk_ulong:
6110 case CORBA::tk_enum:
6111 {
6112 CORBA::ULong c;
6113 c <<= s;
6114 return TypeCode_union::Discriminator(c);
6115 }
6116 #ifdef HAS_LongLong
6117 case CORBA::tk_longlong:
6118 {
6119 CORBA::LongLong c;
6120 c <<= s;
6121 return TypeCode_union::Discriminator(c);
6122 }
6123 case CORBA::tk_ulonglong:
6124 {
6125 CORBA::ULongLong c;
6126 c <<= s;
6127 return TypeCode_union::Discriminator(c);
6128 }
6129 #endif
6130
6131 // case CORBA::tk_wchar:
6132 default:
6133 throw omniORB::fatalException(__FILE__,__LINE__,
6134 "TypeCode_union_helper::unmarshalLabel() - illegal disciminator type");
6135 }
6136
6137 #ifdef NEED_DUMMY_RETURN
6138 return 0;
6139 #endif
6140 }
6141
6142
6143 CORBA::Boolean
has_implicit_default(TypeCode_base * tc)6144 TypeCode_union_helper::has_implicit_default(TypeCode_base* tc)
6145 {
6146 if( tc->NP_default_index() >= 0 ) return 0;
6147
6148 TypeCode_base* dtc = tc->NP_discriminator_type();
6149 CORBA::TypeCode_var aedtc = TypeCode_base::aliasExpand(dtc);
6150 TypeCode_union::Discriminator npossible = 0;
6151
6152 switch( ToTcBase(aedtc)->NP_kind() ) {
6153
6154 case CORBA::tk_short:
6155 case CORBA::tk_ushort:
6156 npossible = 65536;
6157 break;
6158 case CORBA::tk_long:
6159 case CORBA::tk_ulong:
6160 npossible = 0xffffffff;
6161 break;
6162 case CORBA::tk_boolean:
6163 npossible = 2;
6164 break;
6165 case CORBA::tk_char:
6166 case CORBA::tk_octet:
6167 npossible = 256;
6168 break;
6169 #ifdef HAS_LongLong
6170 case CORBA::tk_longlong:
6171 case CORBA::tk_ulonglong:
6172 // Not likely to have this many cases!
6173 npossible = _CORBA_LONGLONG_CONST(0xffffffffffffffff);
6174 break;
6175 #endif
6176 case CORBA::tk_enum:
6177 npossible = ToTcBase(aedtc)->NP_member_count();
6178 break;
6179 default:
6180 OMNIORB_THROW(BAD_TYPECODE, BAD_TYPECODE_UnknownKind, CORBA::COMPLETED_NO);
6181 }
6182
6183 return npossible > tc->NP_member_count();
6184 }
6185
OMNI_NAMESPACE_END(omni)6186 OMNI_NAMESPACE_END(omni)
6187
6188 //////////////////////////////////////////////////////////////////////
6189 /////////////////////// CORBA::TypeCode_member ///////////////////////
6190 //////////////////////////////////////////////////////////////////////
6191
6192 CORBA::TypeCode_member::TypeCode_member()
6193 {
6194 _ptr = CORBA::TypeCode::_nil();
6195 }
6196
TypeCode_member(const CORBA::TypeCode_member & p)6197 CORBA::TypeCode_member::TypeCode_member(const CORBA::TypeCode_member& p)
6198 {
6199 _ptr = CORBA::TypeCode::_duplicate(p._ptr);
6200 }
6201
~TypeCode_member()6202 CORBA::TypeCode_member::~TypeCode_member()
6203 {
6204 CORBA::release(_ptr);
6205 }
6206
6207
6208 CORBA::TypeCode_member&
operator =(CORBA::TypeCode_ptr p)6209 CORBA::TypeCode_member::operator=(CORBA::TypeCode_ptr p)
6210 {
6211 CORBA::release(_ptr);
6212 _ptr = p;
6213 return *this;
6214 }
6215
6216
6217 CORBA::TypeCode_member&
operator =(const CORBA::TypeCode_member & p)6218 CORBA::TypeCode_member::operator=(const CORBA::TypeCode_member& p)
6219 {
6220 if (this != &p) {
6221 CORBA::release(_ptr);
6222 _ptr = CORBA::TypeCode::_duplicate(p._ptr);
6223 }
6224 return *this;
6225 }
6226
6227 CORBA::TypeCode_member&
operator =(const CORBA::TypeCode_var & p)6228 CORBA::TypeCode_member::operator=(const CORBA::TypeCode_var& p)
6229 {
6230 CORBA::release(_ptr);
6231 _ptr = CORBA::TypeCode::_duplicate(p.pd_ref);
6232 return *this;
6233 }
6234
6235 CORBA::TypeCode_ptr&
out()6236 CORBA::TypeCode_member::out()
6237 {
6238 CORBA::release(_ptr);
6239 _ptr = CORBA::TypeCode::_nil();
6240 return _ptr;
6241 }
6242
6243 CORBA::TypeCode_ptr
_retn()6244 CORBA::TypeCode_member::_retn()
6245 {
6246 CORBA::TypeCode_ptr tmp = _ptr;
6247 _ptr = CORBA::TypeCode::_nil();
6248 return tmp;
6249 }
6250
6251 void
operator >>=(cdrStream & s) const6252 CORBA::TypeCode_member::operator>>=(cdrStream& s) const
6253 {
6254 CORBA::TypeCode::marshalTypeCode(_ptr, s);
6255 }
6256
6257 void
operator <<=(cdrStream & s)6258 CORBA::TypeCode_member::operator<<=(cdrStream& s)
6259 {
6260 CORBA::TypeCode_ptr _result = CORBA::TypeCode::unmarshalTypeCode(s);
6261 CORBA::release(_ptr);
6262 _ptr = _result;
6263 }
6264
6265 //////////////////////////////////////////////////////////////////////
6266 ///////////////////////////// CORBA::ORB /////////////////////////////
6267 //////////////////////////////////////////////////////////////////////
6268
validFirstChar(char c)6269 static inline int validFirstChar(char c)
6270 {
6271 return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
6272 }
6273
validOtherChar(char c)6274 static inline int validOtherChar(char c)
6275 {
6276 return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
6277 (c >= '0' && c <= '9') || (c == '_'));
6278 }
6279
6280 static void
checkValidName(const char * name)6281 checkValidName(const char* name)
6282 {
6283 int ok = 1;
6284
6285 if (*name) {
6286 if (!validFirstChar(*name++)) ok = 0;
6287
6288 for(; ok && *name; name++) {
6289 if (!validOtherChar(*name)) ok = 0;
6290 }
6291 }
6292 if (!ok)
6293 OMNIORB_THROW(BAD_PARAM,BAD_PARAM_InvalidName,CORBA::COMPLETED_NO);
6294 }
6295
6296 static void
checkValidMemberName(const char * name)6297 checkValidMemberName(const char* name)
6298 {
6299 int ok = 1;
6300
6301 if (*name) {
6302 if (!validFirstChar(*name++)) ok = 0;
6303
6304 for(; ok && *name; name++) {
6305 if (!validOtherChar(*name)) ok = 0;
6306 }
6307 }
6308 if (!ok)
6309 OMNIORB_THROW(BAD_PARAM,BAD_PARAM_InvalidMemberName,CORBA::COMPLETED_NO);
6310 }
6311
6312 static void
checkValidRepoId(const char * id)6313 checkValidRepoId(const char* id)
6314 {
6315 if (*id) {
6316 for (; *id && *id != ':'; id++);
6317 if (!*id)
6318 OMNIORB_THROW(BAD_PARAM,
6319 BAD_PARAM_InvalidRepositoryId,
6320 CORBA::COMPLETED_NO);
6321 }
6322 }
6323
6324 static void
checkValidTypeCode(const CORBA::TypeCode_ptr tc)6325 checkValidTypeCode(const CORBA::TypeCode_ptr tc)
6326 {
6327 if (!CORBA::TypeCode::PR_is_valid(tc))
6328 OMNIORB_THROW(BAD_PARAM, BAD_PARAM_InvalidTypeCode, CORBA::COMPLETED_NO);
6329
6330 CORBA::TCKind k = ToConstTcBase_Checked(tc)->NP_kind();
6331 if (k == CORBA::tk_null || k == CORBA::tk_void || k == CORBA::tk_except)
6332 OMNIORB_THROW(BAD_TYPECODE,
6333 BAD_TYPECODE_IllegitimateMember,
6334 CORBA::COMPLETED_NO);
6335 }
6336
6337 CORBA::TypeCode_ptr
create_struct_tc(const char * id,const char * name,const CORBA::StructMemberSeq & members)6338 CORBA::ORB::create_struct_tc(const char* id, const char* name,
6339 const CORBA::StructMemberSeq& members)
6340 {
6341 CORBA::ULong memberCount = members.length();
6342 CORBA::ULong i;
6343
6344 checkValidName(name);
6345 checkValidRepoId(id);
6346
6347 for( i = 0; i < memberCount; i++ ) {
6348 if (!CORBA::TypeCode::PR_is_valid(members[i].type))
6349 OMNIORB_THROW(BAD_PARAM, BAD_PARAM_InvalidTypeCode, CORBA::COMPLETED_NO);
6350
6351 checkValidMemberName(members[i].name);
6352 checkValidTypeCode(members[i].type);
6353 }
6354
6355 TypeCode_struct::Member* new_members =
6356 new TypeCode_struct::Member[memberCount];
6357
6358 for( i = 0; i < memberCount; i++ ) {
6359 // We duplicate the name and the type.
6360 new_members[i].name = CORBA::string_dup(members[i].name);
6361 new_members[i].type =
6362 TypeCode_collector::duplicateRef(ToTcBase(members[i].type));
6363 }
6364
6365 return new TypeCode_struct(CORBA::string_dup(id), CORBA::string_dup(name),
6366 new_members, memberCount);
6367 }
6368
6369
6370 CORBA::TypeCode_ptr
create_union_tc(const char * id,const char * name,CORBA::TypeCode_ptr discriminator_type,const CORBA::UnionMemberSeq & members)6371 CORBA::ORB::create_union_tc(const char* id, const char* name,
6372 CORBA::TypeCode_ptr discriminator_type,
6373 const CORBA::UnionMemberSeq& members)
6374 {
6375 const CORBA::ULong memberCount = members.length();
6376 CORBA::ULong i;
6377
6378 checkValidName(name);
6379 checkValidRepoId(id);
6380
6381 for( i = 0; i < memberCount; i++ ) {
6382 if( !CORBA::TypeCode::PR_is_valid(members[i].type) ||
6383 CORBA::is_nil(members[i].type) )
6384 OMNIORB_THROW(BAD_PARAM, BAD_PARAM_InvalidTypeCode, CORBA::COMPLETED_NO);
6385
6386 checkValidMemberName(members[i].name);
6387 checkValidTypeCode(members[i].type);
6388 }
6389
6390 return new TypeCode_union(id, name, ToTcBase_Checked(discriminator_type),
6391 members);
6392 }
6393
6394 CORBA::TypeCode_ptr
create_enum_tc(const char * id,const char * name,const CORBA::EnumMemberSeq & members)6395 CORBA::ORB::create_enum_tc(const char* id, const char* name,
6396 const CORBA::EnumMemberSeq& members)
6397 {
6398 checkValidName(name);
6399 checkValidRepoId(id);
6400
6401 for (CORBA::ULong i=0; i < members.length(); i++)
6402 checkValidMemberName(members[i]);
6403
6404 return CORBA::TypeCode::NP_enum_tc(id, name, members);
6405 }
6406
6407 CORBA::TypeCode_ptr
create_alias_tc(const char * id,const char * name,CORBA::TypeCode_ptr original_type)6408 CORBA::ORB::create_alias_tc(const char* id, const char* name,
6409 CORBA::TypeCode_ptr original_type)
6410 {
6411 checkValidName(name);
6412 checkValidRepoId(id);
6413 checkValidTypeCode(original_type);
6414 return CORBA::TypeCode::NP_alias_tc(id, name, original_type);
6415 }
6416
6417 CORBA::TypeCode_ptr
create_exception_tc(const char * id,const char * name,const CORBA::StructMemberSeq & members)6418 CORBA::ORB::create_exception_tc(const char* id, const char* name,
6419 const CORBA::StructMemberSeq& members)
6420 {
6421 CORBA::ULong memberCount = members.length();
6422 CORBA::ULong i;
6423
6424 checkValidName(name);
6425 checkValidRepoId(id);
6426
6427 for( i = 0; i < memberCount; i++ ) {
6428 if (!CORBA::TypeCode::PR_is_valid(members[i].type))
6429 OMNIORB_THROW(BAD_PARAM, BAD_PARAM_InvalidTypeCode, CORBA::COMPLETED_NO);
6430
6431 checkValidMemberName(members[i].name);
6432 checkValidTypeCode(members[i].type);
6433 }
6434
6435 TypeCode_struct::Member* new_members =
6436 new TypeCode_struct::Member[memberCount];
6437
6438 for( i = 0; i < memberCount; i++ ) {
6439 // We duplicate the name and the type.
6440 new_members[i].name = CORBA::string_dup(members[i].name);
6441 new_members[i].type =
6442 TypeCode_collector::duplicateRef(ToTcBase(members[i].type));
6443 }
6444
6445 return new TypeCode_except(CORBA::string_dup(id), CORBA::string_dup(name),
6446 new_members, memberCount);
6447 }
6448
6449 CORBA::TypeCode_ptr
create_interface_tc(const char * id,const char * name)6450 CORBA::ORB::create_interface_tc(const char* id, const char* name)
6451 {
6452 checkValidName(name);
6453 checkValidRepoId(id);
6454 return CORBA::TypeCode::NP_interface_tc(id, name);
6455 }
6456
6457 CORBA::TypeCode_ptr
create_string_tc(CORBA::ULong bound)6458 CORBA::ORB::create_string_tc(CORBA::ULong bound)
6459 {
6460 return CORBA::TypeCode::NP_string_tc(bound);
6461 }
6462
6463 CORBA::TypeCode_ptr
create_wstring_tc(CORBA::ULong bound)6464 CORBA::ORB::create_wstring_tc(CORBA::ULong bound)
6465 {
6466 return CORBA::TypeCode::NP_wstring_tc(bound);
6467 }
6468
6469 CORBA::TypeCode_ptr
create_fixed_tc(CORBA::UShort digits,CORBA::Short scale)6470 CORBA::ORB::create_fixed_tc(CORBA::UShort digits, CORBA::Short scale)
6471 {
6472 return CORBA::TypeCode::NP_fixed_tc(digits, scale);
6473 }
6474
6475 CORBA::TypeCode_ptr
create_sequence_tc(CORBA::ULong bound,CORBA::TypeCode_ptr element_type)6476 CORBA::ORB::create_sequence_tc(CORBA::ULong bound,
6477 CORBA::TypeCode_ptr element_type)
6478 {
6479 if (!CORBA::TypeCode::PR_is_valid(element_type))
6480 OMNIORB_THROW(BAD_PARAM, BAD_PARAM_InvalidTypeCode, CORBA::COMPLETED_NO);
6481
6482 checkValidTypeCode(element_type);
6483
6484 return CORBA::TypeCode::NP_sequence_tc(bound, element_type);
6485 }
6486
6487 CORBA::TypeCode_ptr
create_array_tc(CORBA::ULong length,CORBA::TypeCode_ptr element_type)6488 CORBA::ORB::create_array_tc(CORBA::ULong length,
6489 CORBA::TypeCode_ptr element_type)
6490 {
6491 if (!CORBA::TypeCode::PR_is_valid(element_type))
6492 OMNIORB_THROW(BAD_PARAM, BAD_PARAM_InvalidTypeCode, CORBA::COMPLETED_NO);
6493
6494 checkValidTypeCode(element_type);
6495
6496 return CORBA::TypeCode::NP_array_tc(length, element_type);
6497 }
6498
6499 CORBA::TypeCode_ptr
create_value_tc(const char * id,const char * name,CORBA::ValueModifier type_modifier,CORBA::TypeCode_ptr concrete_base,const CORBA::ValueMemberSeq & members)6500 CORBA::ORB::create_value_tc(const char* id, const char* name,
6501 CORBA::ValueModifier type_modifier,
6502 CORBA::TypeCode_ptr concrete_base,
6503 const CORBA::ValueMemberSeq& members)
6504 {
6505 CORBA::ULong memberCount = members.length();
6506 CORBA::ULong i;
6507
6508 checkValidName(name);
6509 checkValidRepoId(id);
6510
6511 CORBA::TCKind k = ToConstTcBase_Checked(concrete_base)->NP_kind();
6512 if (!(k == CORBA::tk_null || k == CORBA::tk_value))
6513 OMNIORB_THROW(BAD_TYPECODE,
6514 BAD_TYPECODE_IllegitimateMember,
6515 CORBA::COMPLETED_NO);
6516
6517 for( i = 0; i < memberCount; i++ ) {
6518 if (!CORBA::TypeCode::PR_is_valid(members[i].type))
6519 OMNIORB_THROW(BAD_PARAM, BAD_PARAM_InvalidTypeCode, CORBA::COMPLETED_NO);
6520
6521 checkValidMemberName(members[i].name);
6522 checkValidTypeCode(members[i].type);
6523 }
6524
6525 TypeCode_value::Member* new_members =
6526 new TypeCode_value::Member[memberCount];
6527
6528 for( i = 0; i < memberCount; i++ ) {
6529 // We duplicate the name and the type.
6530 new_members[i].name = CORBA::string_dup(members[i].name);
6531 new_members[i].type =
6532 TypeCode_collector::duplicateRef(ToTcBase(members[i].type));
6533 new_members[i].access = members[i].access;
6534 }
6535
6536 return new TypeCode_value(id, name, type_modifier,
6537 ToTcBase(concrete_base),
6538 new_members, memberCount);
6539 }
6540
6541 CORBA::TypeCode_ptr
create_value_box_tc(const char * id,const char * name,CORBA::TypeCode_ptr boxed_type)6542 CORBA::ORB::create_value_box_tc(const char* id, const char* name,
6543 CORBA::TypeCode_ptr boxed_type)
6544 {
6545 checkValidName(name);
6546 checkValidRepoId(id);
6547 checkValidTypeCode(boxed_type);
6548 return CORBA::TypeCode::NP_value_box_tc(id, name, boxed_type);
6549 }
6550
6551
6552 CORBA::TypeCode_ptr
create_recursive_sequence_tc(CORBA::ULong bound,CORBA::ULong offset)6553 CORBA::ORB::create_recursive_sequence_tc(CORBA::ULong bound,
6554 CORBA::ULong offset)
6555 {
6556 return CORBA::TypeCode::NP_recursive_sequence_tc(bound, offset);
6557 }
6558
6559 CORBA::TypeCode_ptr
create_recursive_tc(const char * id)6560 CORBA::ORB::create_recursive_tc(const char* id)
6561 {
6562 checkValidRepoId(id);
6563 return CORBA::TypeCode::NP_recursive_tc(id);
6564 }
6565
6566
6567 //////////////////////////////////////////////////////////////////////
6568 ///////////////////////// TypeCode constants /////////////////////////
6569 //////////////////////////////////////////////////////////////////////
6570
6571 #if defined(HAS_Cplusplus_Namespace) && defined(_MSC_VER)
6572 // MSVC++ does not give the constants external linkage otherwise. Its a bug.
6573 namespace CORBA {
6574 TypeCode_ptr _tc_null;
6575 TypeCode_ptr _tc_void;
6576 TypeCode_ptr _tc_short;
6577 TypeCode_ptr _tc_long;
6578 TypeCode_ptr _tc_ushort;
6579 TypeCode_ptr _tc_ulong;
6580 TypeCode_ptr _tc_float;
6581 TypeCode_ptr _tc_double;
6582 TypeCode_ptr _tc_boolean;
6583 TypeCode_ptr _tc_char;
6584 TypeCode_ptr _tc_wchar;
6585 TypeCode_ptr _tc_octet;
6586 TypeCode_ptr _tc_any;
6587 TypeCode_ptr _tc_TypeCode;
6588 TypeCode_ptr _tc_Principal;
6589 TypeCode_ptr _tc_Object;
6590 TypeCode_ptr _tc_string;
6591 TypeCode_ptr _tc_wstring;
6592 TypeCode_ptr _tc_NamedValue;
6593 #ifdef HAS_LongLong
6594 TypeCode_ptr _tc_longlong;
6595 TypeCode_ptr _tc_ulonglong;
6596 #endif
6597 #ifdef HAS_LongDouble
6598 TypeCode_ptr _tc_longdouble;
6599 #endif
6600 }
6601 #else
6602 CORBA::TypeCode_ptr CORBA::_tc_null;
6603 CORBA::TypeCode_ptr CORBA::_tc_void;
6604 CORBA::TypeCode_ptr CORBA::_tc_short;
6605 CORBA::TypeCode_ptr CORBA::_tc_long;
6606 CORBA::TypeCode_ptr CORBA::_tc_ushort;
6607 CORBA::TypeCode_ptr CORBA::_tc_ulong;
6608 CORBA::TypeCode_ptr CORBA::_tc_float;
6609 CORBA::TypeCode_ptr CORBA::_tc_double;
6610 CORBA::TypeCode_ptr CORBA::_tc_boolean;
6611 CORBA::TypeCode_ptr CORBA::_tc_char;
6612 CORBA::TypeCode_ptr CORBA::_tc_wchar;
6613 CORBA::TypeCode_ptr CORBA::_tc_octet;
6614 CORBA::TypeCode_ptr CORBA::_tc_any;
6615 CORBA::TypeCode_ptr CORBA::_tc_TypeCode;
6616 CORBA::TypeCode_ptr CORBA::_tc_Principal;
6617 CORBA::TypeCode_ptr CORBA::_tc_Object;
6618 CORBA::TypeCode_ptr CORBA::_tc_string;
6619 CORBA::TypeCode_ptr CORBA::_tc_wstring;
6620 CORBA::TypeCode_ptr CORBA::_tc_NamedValue;
6621 #ifdef HAS_LongLong
6622 CORBA::TypeCode_ptr CORBA::_tc_longlong;
6623 CORBA::TypeCode_ptr CORBA::_tc_ulonglong;
6624 #endif
6625 #ifdef HAS_LongDouble
6626 CORBA::TypeCode_ptr CORBA::_tc_longdouble;
6627 #endif
6628
6629 #endif
6630
6631 // Stub TypeCode tracker
6632
~_Tracker()6633 CORBA::TypeCode::_Tracker::~_Tracker()
6634 {
6635 TypeCode_base *current, *next;
6636 int count = 0;
6637
6638 current = ToTcBase(pd_head);
6639 while (current) {
6640 next = current->pd_next;
6641 CORBA::release(current);
6642 current = next;
6643 count++;
6644 }
6645 if (count && omniORB::trace(25)) {
6646 const char *i, *f;
6647
6648 for (i=pd_file, f=pd_file; *i; i++)
6649 if (*i == '/' || *i == '\\')
6650 f = i+1;
6651
6652 omniORB::logger l;
6653 l << "Released " << count
6654 << " stub TypeCode" << (count == 1 ? "" : "s")
6655 << " from '" << f << "'.\n";
6656 }
6657 pd_head = 0;
6658 }
6659
6660 void
add(CORBA::TypeCode_ptr tc)6661 CORBA::TypeCode::_Tracker::add(CORBA::TypeCode_ptr tc)
6662 {
6663 ToTcBase(tc)->pd_next = ToTcBase(pd_head);
6664 pd_head = tc;
6665 }
6666
6667
OMNI_NAMESPACE_BEGIN(omni)6668 OMNI_NAMESPACE_BEGIN(omni)
6669
6670 // During static initialisation of the dynamic stubs (in DynSK.cc
6671 // files), we need to access TypeCodes of pre-defined types and use
6672 // other objects that must have been correctly initialised. Since the
6673 // C++ runtime does not guarantee the execution order of static
6674 // initialisers between source files, we cannot rely on static
6675 // initialisers in this file to have run before the objects are used.
6676 // Instead, we call this function from all functions called in stub
6677 // static initialisers, to ensure everything is initialised.
6678 //
6679 static void check_static_data_is_initialised()
6680 {
6681 static int is_initialised = 0;
6682
6683 if( is_initialised ) return;
6684 is_initialised = 1;
6685
6686 the_typecodes = new omniTypeCodeCollection;
6687 registerTrackedObject(the_typecodes);
6688
6689 // Mutexes
6690 aliasExpandedTc_lock = new omni_tracedmutex("aliasExpandedTc_lock");
6691 refcount_lock = new omni_tracedmutex("TypeCode::refcount_lock");
6692
6693 // Primitive TypeCodes
6694 CORBA::_tc_null = new TypeCode_base(CORBA::tk_null);
6695 CORBA::_tc_void = new TypeCode_base(CORBA::tk_void);
6696 CORBA::_tc_short = new TypeCode_base(CORBA::tk_short);
6697 CORBA::_tc_long = new TypeCode_base(CORBA::tk_long);
6698 CORBA::_tc_ushort = new TypeCode_base(CORBA::tk_ushort);
6699 CORBA::_tc_ulong = new TypeCode_base(CORBA::tk_ulong);
6700 CORBA::_tc_float = new TypeCode_base(CORBA::tk_float);
6701 CORBA::_tc_double = new TypeCode_base(CORBA::tk_double);
6702 CORBA::_tc_boolean = new TypeCode_base(CORBA::tk_boolean);
6703 CORBA::_tc_char = new TypeCode_base(CORBA::tk_char);
6704 CORBA::_tc_wchar = new TypeCode_base(CORBA::tk_wchar);
6705 CORBA::_tc_octet = new TypeCode_base(CORBA::tk_octet);
6706 CORBA::_tc_any = new TypeCode_base(CORBA::tk_any);
6707 CORBA::_tc_TypeCode = new TypeCode_base(CORBA::tk_TypeCode);
6708 CORBA::_tc_Principal = new TypeCode_base(CORBA::tk_Principal);
6709 CORBA::_tc_Object = new TypeCode_objref("IDL:omg.org/CORBA/Object:1.0",
6710 "Object");
6711 CORBA::_tc_string = new TypeCode_string(0);
6712 CORBA::_tc_wstring = new TypeCode_wstring(0);
6713
6714 the_typecodes->track(CORBA::_tc_null);
6715 the_typecodes->track(CORBA::_tc_void);
6716 the_typecodes->track(CORBA::_tc_short);
6717 the_typecodes->track(CORBA::_tc_long);
6718 the_typecodes->track(CORBA::_tc_ushort);
6719 the_typecodes->track(CORBA::_tc_ulong);
6720 the_typecodes->track(CORBA::_tc_float);
6721 the_typecodes->track(CORBA::_tc_double);
6722 the_typecodes->track(CORBA::_tc_boolean);
6723 the_typecodes->track(CORBA::_tc_char);
6724 the_typecodes->track(CORBA::_tc_wchar);
6725 the_typecodes->track(CORBA::_tc_octet);
6726 the_typecodes->track(CORBA::_tc_any);
6727 the_typecodes->track(CORBA::_tc_TypeCode);
6728 the_typecodes->track(CORBA::_tc_Principal);
6729 the_typecodes->track(CORBA::_tc_Object);
6730 the_typecodes->track(CORBA::_tc_string);
6731 the_typecodes->track(CORBA::_tc_wstring);
6732
6733 #ifdef HAS_LongLong
6734 CORBA::_tc_longlong = new TypeCode_base(CORBA::tk_longlong);
6735 CORBA::_tc_ulonglong = new TypeCode_base(CORBA::tk_ulonglong);
6736
6737 the_typecodes->track(CORBA::_tc_longlong);
6738 the_typecodes->track(CORBA::_tc_ulonglong);
6739 #endif
6740 #ifdef HAS_LongDouble
6741 CORBA::_tc_longdouble = new TypeCode_base(CORBA::tk_longdouble);
6742 the_typecodes->track(CORBA::_tc_longdouble);
6743 #endif
6744 {
6745 CORBA::TypeCode_var tc_Flags = new TypeCode_alias("IDL:omg.org/CORBA/Flags:1.0", "Flags",ToTcBase(CORBA::_tc_ulong));
6746 CORBA::TypeCode_var tc_Identifier = new TypeCode_alias("IDL:omg.org/CORBA/Identifier:1.0", "Identifier", ToTcBase(CORBA::_tc_string));
6747
6748 CORBA::PR_structMember nvMembers[4];
6749
6750 nvMembers[0].name = "name";
6751 nvMembers[0].type = tc_Identifier;
6752 nvMembers[1].name = "argument";
6753 nvMembers[1].type = CORBA::_tc_any;
6754 nvMembers[2].name = "len";
6755 nvMembers[2].type = CORBA::_tc_long;
6756 nvMembers[3].name = "arg_modes";
6757 nvMembers[3].type = tc_Flags;
6758
6759 CORBA::_tc_NamedValue = CORBA::TypeCode::PR_struct_tc("IDL:omg.org/CORBA/NamedValue:1.0", "NamedValue",nvMembers, 4, the_typecodes->pd_tracker);
6760 }
6761 }
6762
6763 //
6764 // TypeCode collection
6765 //
6766
6767 void
6768 omniTypeCodeCollection::
add(const char * id,CORBA::TypeCode_ptr tc)6769 add(const char* id, CORBA::TypeCode_ptr tc)
6770 {
6771 CORBA::ULong hv = hash_id(id) % tc_tablesize;
6772 Entry* e = new Entry(id, tc);
6773 e->next = pd_table[hv];
6774 pd_table[hv] = e;
6775 }
6776
6777 CORBA::TypeCode_ptr
6778 omniTypeCodeCollection::
find(const char * id)6779 find(const char* id)
6780 {
6781 CORBA::ULong hv = hash_id(id) % tc_tablesize;
6782 Entry* e;
6783 for (e = pd_table[hv]; e; e = e->next) {
6784 if (omni::strMatch(id, e->repoId)) {
6785 return e->typecode;
6786 }
6787 }
6788 return 0;
6789 }
6790
6791 void
6792 omniTypeCodeCollection::
remove(const char * id,CORBA::TypeCode_ptr tc)6793 remove(const char* id, CORBA::TypeCode_ptr tc)
6794 {
6795 CORBA::ULong hv = hash_id(id) % tc_tablesize;
6796 Entry *e, **f;
6797
6798 f = &(pd_table[hv]);
6799
6800 for (e = pd_table[hv]; e; e = e->next) {
6801 if (e->typecode == tc) {
6802 *f = e->next;
6803 delete e;
6804 return;
6805 }
6806 f = &(e->next);
6807 }
6808 }
6809
~omniTypeCodeCollection()6810 omniTypeCodeCollection::~omniTypeCodeCollection()
6811 {
6812 CORBA::TypeCode_ptr t = CORBA::_tc_short;
6813
6814 delete pd_tracker;
6815
6816 if (omniORB::trace(10)) {
6817 int count = 0;
6818 for (CORBA::ULong i=0; i < tc_tablesize; i++) {
6819 for (Entry* e = pd_table[i]; e; e = e->next) {
6820 count++;
6821 if (omniORB::trace(20)) {
6822 omniORB::logger l;
6823 l << "Stub TypeCode '" << e->repoId << "' leaked.\n";
6824 }
6825 }
6826 }
6827 if (count) {
6828 omniORB::logger l;
6829 l << "Warning: " << count << " stub TypeCode" << (count == 1 ? "" : "s")
6830 << " leaked by application code.\n";
6831 }
6832 }
6833 delete[] pd_table;
6834
6835 // Delete mutexes
6836 delete aliasExpandedTc_lock;
6837 delete refcount_lock;
6838 }
6839
6840
6841 // We need a singleton here as a final check, so that if no
6842 // stub code calls into check_static_data_is_initialised()
6843 // it will still be called before main().
6844
6845 class TypeCodeInitialiser {
6846 // public just to stop brain-dead compilers complaining
6847 public:
TypeCodeInitialiser()6848 TypeCodeInitialiser() { check_static_data_is_initialised(); }
6849 static TypeCodeInitialiser typecode_initialiser;
6850 };
6851 TypeCodeInitialiser TypeCodeInitialiser::typecode_initialiser;
6852
6853 OMNI_NAMESPACE_END(omni)
6854