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