1 // -*- Mode: C++; -*-
2 //                            Package   : omniORB
3 // any.cc                     Created on: 31/07/97
4 //                            Author1   : Eoin Carroll (ewc)
5 //                            Author2   : James Weatherall (jnw)
6 //                            Author3   : Duncan Grisby (dgrisby)
7 //
8 //    Copyright (C) 2004-2011 Apasphere Ltd.
9 //    Copyright (C) 1996-1999 AT&T Laboratories Cambridge
10 //
11 //    This file is part of the omniORB library
12 //
13 //    The omniORB library is free software; you can redistribute it and/or
14 //    modify it under the terms of the GNU Lesser General Public
15 //    License as published by the Free Software Foundation; either
16 //    version 2.1 of the License, or (at your option) any later version.
17 //
18 //    This library is distributed in the hope that it will be useful,
19 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
20 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 //    Lesser General Public License for more details.
22 //
23 //    You should have received a copy of the GNU Lesser General Public
24 //    License along with this library. If not, see http://www.gnu.org/licenses/
25 //
26 //
27 // Description:
28 //      Implementation of type any
29 
30 #include <omniORB4/CORBA.h>
31 
32 #ifdef HAS_pch
33 #pragma hdrstop
34 #endif
35 
36 #include <typecode.h>
37 #include <tcParser.h>
38 #include <orbParameters.h>
39 #include <omniORB4/linkHacks.h>
40 #include <omniORB4/anyStream.h>
41 
42 OMNI_FORCE_LINK(dynamicLib);
43 
44 OMNI_USING_NAMESPACE(omni)
45 
46 // Mutex to protect Any pointers against modification by multiple threads.
47 static omni_tracedmutex anyLock("anyLock");
48 
49 
50 // This code is slightly unsafe by default, in that there is a small
51 // risk that compiler optimisations or CPU instruction re-ordering
52 // could lead to a race condition resulting in use of uninitialised
53 // memory if multiple threads try to read from a particular Any at the
54 // same time. To avoid that risk, but incur a small performance
55 // penalty, uncomment the SNAP_LOCK define below.
56 
57 //#define SNAP_LOCK omni_tracedmutex_lock snap_lock(anyLock)
58 #define SNAP_LOCK do{}while(0)
59 
60 
61 // Extract possibly zero typecode.
62 static inline
63 CORBA::TypeCode_ptr
get(CORBA::TypeCode_ptr tc)64 get(CORBA::TypeCode_ptr tc)
65 {
66   return tc ? tc : CORBA::_tc_null;
67 }
68 
69 // Set typecode, possibly releasing existing one. Takes ownership of new_tc.
70 static inline
71 void
grabTC(CORBA::TypeCode_ptr & tc,CORBA::TypeCode_ptr new_tc)72 grabTC(CORBA::TypeCode_ptr& tc, CORBA::TypeCode_ptr new_tc)
73 {
74   if (tc)
75     CORBA::release(tc);
76 
77   tc = new_tc;
78 }
79 
80 // Set typecode, possibly releasing existing one. Duplicates new_tc.
81 static inline
82 void
dupTC(CORBA::TypeCode_ptr & tc,CORBA::TypeCode_ptr new_tc)83 dupTC(CORBA::TypeCode_ptr& tc, CORBA::TypeCode_ptr new_tc)
84 {
85   if (tc)
86     CORBA::release(tc);
87 
88   tc = new_tc ? CORBA::TypeCode::_duplicate(new_tc) : 0;
89 }
90 
91 
92 //////////////////////////////////////////////////////////////////////
93 ////////////////// Constructors / destructor /////////////////////////
94 //////////////////////////////////////////////////////////////////////
95 
Any()96 CORBA::Any::Any()
97   : pd_tc(0), pd_mbuf(0), pd_data(0), pd_marshal(0), pd_destructor(0)
98 {
99 }
100 
101 
~Any()102 CORBA::Any::~Any()
103 {
104   if (pd_mbuf)
105     pd_mbuf->remove_ref();
106 
107   if (pd_data) {
108     OMNIORB_ASSERT(pd_destructor);
109     pd_destructor(pd_data);
110   }
111 
112   if (pd_tc)
113     CORBA::release(pd_tc);
114 }
115 
116 void
PR_clearData()117 CORBA::Any::PR_clearData()
118 {
119   if (pd_mbuf)
120     pd_mbuf->remove_ref();
121 
122   if (pd_data) {
123     OMNIORB_ASSERT(pd_destructor);
124     pd_destructor(pd_data);
125   }
126   pd_mbuf = 0;
127   pd_data = 0;
128   pd_marshal = 0;
129   pd_destructor = 0;
130 }
131 
132 
Any(const Any & a)133 CORBA::Any::Any(const Any& a)
134   : pd_tc(0), pd_data(0), pd_marshal(0), pd_destructor(0)
135 {
136   dupTC(pd_tc, a.pd_tc);
137 
138   cdrAnyMemoryStream* snap_mbuf;
139   void*               snap_data;
140   pr_marshal_fn       snap_marshal;
141 
142   {
143     SNAP_LOCK;
144     snap_mbuf	 = a.pd_mbuf;
145     snap_data	 = a.pd_data;
146     snap_marshal = a.pd_marshal;
147   }
148 
149   if (snap_mbuf) {
150     pd_mbuf = snap_mbuf;
151     pd_mbuf->add_ref();
152   }
153   else if (snap_data) {
154     // Existing Any has data in its void* pointer. Rather than trying
155     // to copy that (which would require a copy function to be
156     // registered along with the marshal and destructor functions), we
157     // marshal the data into a memory buffer.
158     pd_mbuf = new cdrAnyMemoryStream;
159     snap_marshal(*pd_mbuf, snap_data);
160   }
161   else {
162     // The Any has just a TypeCode and no data yet.
163     pd_mbuf = 0;
164   }
165 }
166 
167 
168 CORBA::Any&
operator =(const CORBA::Any & a)169 CORBA::Any::operator=(const CORBA::Any& a)
170 {
171   if (&a != this) {
172     PR_clearData();
173     dupTC(pd_tc, a.pd_tc);
174 
175     cdrAnyMemoryStream* snap_mbuf;
176     void*               snap_data;
177     pr_marshal_fn       snap_marshal;
178 
179     {
180       SNAP_LOCK;
181       snap_mbuf	   = a.pd_mbuf;
182       snap_data	   = a.pd_data;
183       snap_marshal = a.pd_marshal;
184     }
185 
186     if (snap_mbuf) {
187       pd_mbuf = snap_mbuf;
188       pd_mbuf->add_ref();
189     }
190     else if (snap_data) {
191       pd_mbuf = new cdrAnyMemoryStream;
192       snap_marshal(*pd_mbuf, snap_data);
193     }
194   }
195   return *this;
196 }
197 
198 
199 //
200 // Nasty deprecated constructor and replace() taking a void* buffer
201 //
202 
203 CORBA::
Any(TypeCode_ptr tc,void * value,Boolean release)204 Any::Any(TypeCode_ptr tc, void* value, Boolean release)
205   : pd_tc(0)
206 {
207   dupTC(pd_tc, tc);
208 
209   if (value == 0) {
210     // No value yet.
211     pd_mbuf = 0;
212     pd_data = 0;
213     pd_marshal = 0;
214     pd_destructor = 0;
215   }
216   else {
217     // Create a cdrAnyMemoryStream referencing the data.
218     pd_mbuf = new cdrAnyMemoryStream(value, release);
219     pd_data = 0;
220     pd_marshal = 0;
221     pd_destructor = 0;
222   }
223 }
224 
225 void
replace(TypeCode_ptr tc,void * value,Boolean release)226 CORBA::Any::replace(TypeCode_ptr tc, void* value, Boolean release)
227 {
228   dupTC(pd_tc, tc);
229 
230   PR_clearData();
231 
232   if (value == 0) {
233     // No value yet.
234     pd_mbuf = 0;
235     pd_data = 0;
236     pd_marshal = 0;
237     pd_destructor = 0;
238   }
239   else {
240     // Create a cdrAnyMemoryStream referencing the data.
241     pd_mbuf = new cdrAnyMemoryStream(value, release);
242     pd_data = 0;
243     pd_marshal = 0;
244     pd_destructor = 0;
245   }
246 }
247 
248 //////////////////////////////////////////////////////////////////////
249 ////////////////// Marshalling operators /////////////////////////////
250 //////////////////////////////////////////////////////////////////////
251 
252 void
operator >>=(cdrStream & s) const253 CORBA::Any::operator>>= (cdrStream& s) const
254 {
255   if (orbParameters::tcAliasExpand) {
256     CORBA::TypeCode_var tc = TypeCode_base::aliasExpand(ToTcBase(get(pd_tc)));
257     CORBA::TypeCode::marshalTypeCode(tc, s);
258   }
259   else
260     CORBA::TypeCode::marshalTypeCode(get(pd_tc), s);
261 
262   cdrAnyMemoryStream* snap_mbuf;
263   void*               snap_data;
264   pr_marshal_fn       snap_marshal;
265 
266   {
267     SNAP_LOCK;
268     snap_mbuf	 = pd_mbuf;
269     snap_data	 = pd_data;
270     snap_marshal = pd_marshal;
271   }
272 
273   if (snap_data) {
274     OMNIORB_ASSERT(snap_marshal);
275     snap_marshal(s, snap_data);
276   }
277   else if (snap_mbuf) {
278     tcParser::copyMemStreamToStream_rdonly(get(pd_tc), *snap_mbuf, s);
279   }
280   else {
281     CORBA::TCKind kind = get(pd_tc)->kind();
282     if (kind == CORBA::tk_objref ||
283         kind == CORBA::tk_value ||
284 	kind == CORBA::tk_value_box ||
285 	kind == CORBA::tk_abstract_interface) {
286 
287       // Nil objref / value
288       OMNIORB_ASSERT(snap_marshal);
289       snap_marshal(s, snap_data);
290     }
291     else {
292       // No data
293       OMNIORB_ASSERT(kind == CORBA::tk_void || kind == CORBA::tk_null);
294     }
295   }
296 }
297 
298 void
operator <<=(cdrStream & s)299 CORBA::Any::operator<<= (cdrStream& s)
300 {
301   PR_clearData();
302 
303   grabTC(pd_tc, CORBA::TypeCode::unmarshalTypeCode(s));
304   pd_mbuf = new cdrAnyMemoryStream;
305   tcParser::copyStreamToStream(get(pd_tc), s, *pd_mbuf);
306 }
307 
308 // omniORB data-only marshalling functions
309 void
NP_marshalDataOnly(cdrStream & s) const310 CORBA::Any::NP_marshalDataOnly(cdrStream& s) const
311 {
312   cdrAnyMemoryStream* snap_mbuf;
313   void*               snap_data;
314   pr_marshal_fn       snap_marshal;
315 
316   {
317     SNAP_LOCK;
318     snap_mbuf	 = pd_mbuf;
319     snap_data	 = pd_data;
320     snap_marshal = pd_marshal;
321   }
322 
323   if (snap_data) {
324     OMNIORB_ASSERT(snap_marshal);
325     snap_marshal(s, snap_data);
326   }
327   else if (snap_mbuf) {
328     tcParser::copyMemStreamToStream_rdonly(get(pd_tc), *snap_mbuf, s);
329   }
330   else {
331     CORBA::TCKind kind = get(pd_tc)->kind();
332     if (kind == CORBA::tk_objref ||
333         kind == CORBA::tk_value ||
334 	kind == CORBA::tk_value_box ||
335 	kind == CORBA::tk_abstract_interface) {
336 
337       // Nil objref / value
338       OMNIORB_ASSERT(snap_marshal);
339       snap_marshal(s, snap_data);
340     }
341     else {
342       // No data
343       OMNIORB_ASSERT(kind == CORBA::tk_void || kind == CORBA::tk_null);
344     }
345   }
346 }
347 
348 void
NP_unmarshalDataOnly(cdrStream & s)349 CORBA::Any::NP_unmarshalDataOnly(cdrStream& s)
350 {
351   PR_clearData();
352   pd_mbuf = new cdrAnyMemoryStream;
353   tcParser::copyStreamToMemStream_flush(get(pd_tc), s, *pd_mbuf);
354 }
355 
356 
357 //////////////////////////////////////////////////////////////////////
358 ////////////////// Insertion / extraction functions //////////////////
359 //////////////////////////////////////////////////////////////////////
360 
361 void
362 CORBA::Any::
PR_insert(CORBA::TypeCode_ptr newtc,pr_marshal_fn marshal,void * data)363 PR_insert(CORBA::TypeCode_ptr newtc, pr_marshal_fn marshal, void* data)
364 {
365   PR_clearData();
366   dupTC(pd_tc, newtc);
367   pd_mbuf = new cdrAnyMemoryStream();
368   marshal(*pd_mbuf, data);
369 }
370 
371 void
372 CORBA::Any::
PR_insert(CORBA::TypeCode_ptr newtc,pr_marshal_fn marshal,pr_destructor_fn destructor,void * data)373 PR_insert(CORBA::TypeCode_ptr newtc, pr_marshal_fn marshal,
374 	  pr_destructor_fn destructor, void* data)
375 {
376   PR_clearData();
377   dupTC(pd_tc, newtc);
378   pd_data = data;
379   pd_marshal = marshal;
380   pd_destructor = destructor;
381 }
382 
383 
384 CORBA::Boolean
385 CORBA::Any::
PR_extract(CORBA::TypeCode_ptr tc,pr_unmarshal_fn unmarshal,void * data) const386 PR_extract(CORBA::TypeCode_ptr tc,
387 	   pr_unmarshal_fn     unmarshal,
388 	   void*               data) const
389 {
390   if (!tc->equivalent(get(pd_tc)))
391     return 0;
392 
393   if (pd_mbuf) {
394     // Make a temporary stream wrapper around memory buffer.
395     cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
396 
397     // Extract the data
398     unmarshal(tbuf, data);
399     return 1;
400   }
401   else {
402     OMNIORB_ASSERT(!pd_data);
403     return 0;
404   }
405 }
406 
407 
408 CORBA::Boolean
409 CORBA::Any::
PR_extract(CORBA::TypeCode_ptr tc,pr_unmarshal_fn unmarshal,pr_marshal_fn marshal,pr_destructor_fn destructor,void * & data) const410 PR_extract(CORBA::TypeCode_ptr     tc,
411 	   pr_unmarshal_fn  	   unmarshal,
412 	   pr_marshal_fn    	   marshal,
413 	   pr_destructor_fn 	   destructor,
414 	   void*&                  data) const
415 {
416   if (!tc->equivalent(get(pd_tc)))
417     return 0;
418 
419   void*               snap_data;
420   cdrAnyMemoryStream* snap_mbuf;
421 
422   {
423     SNAP_LOCK;
424     snap_data = pd_data;
425     snap_mbuf = pd_mbuf;
426   }
427 
428   if (snap_data) {
429     data = snap_data;
430     return 1;
431   }
432   else if (snap_mbuf) {
433     {
434       // Make a temporary stream wrapper around memory buffer.
435       cdrAnyMemoryStream tbuf(*snap_mbuf, 1);
436 
437       // Extract the data
438       data = 0;
439       unmarshal(tbuf, data);
440     }
441 
442     // Now set the data pointer
443     CORBA::Boolean race = 0;
444     {
445       omni_tracedmutex_lock l(anyLock);
446 
447       if (!pd_data) {
448 	CORBA::Any* me = OMNI_CONST_CAST(CORBA::Any*, this);
449 
450 	me->pd_data = data;
451 	me->pd_marshal = marshal;
452 	me->pd_destructor = destructor;
453       }
454       else {
455 	// Another thread got there first. We destroy the data we just
456 	// extracted, and return what the other thread made.
457 	race = 1;
458 	snap_data = pd_data;
459       }
460     }
461     if (race) {
462       destructor(data);
463       data = snap_data;
464     }
465     return 1;
466   }
467   else {
468     return 0;
469   }
470 }
471 
472 cdrAnyMemoryStream&
PR_streamToRead() const473 CORBA::Any::PR_streamToRead() const
474 {
475   cdrAnyMemoryStream* snap_mbuf;
476 
477   {
478     SNAP_LOCK;
479     snap_mbuf = pd_mbuf;
480   }
481 
482   if (!snap_mbuf) {
483 
484     if (pd_marshal) {
485       snap_mbuf = new cdrAnyMemoryStream;
486       pd_marshal(*snap_mbuf, pd_data);
487     }
488     else {
489       CORBA::TCKind kind = get(pd_tc)->kind();
490       if (kind == CORBA::tk_void || kind == CORBA::tk_null) {
491         snap_mbuf = cdrAnyMemoryStream::_empty;
492         snap_mbuf->add_ref();
493       }
494       else {
495 	OMNIORB_THROW(BAD_PARAM, BAD_PARAM_InvalidAny, CORBA::COMPLETED_NO);
496       }
497     }
498 
499     {
500       omni_tracedmutex_lock l(anyLock);
501 
502       if (pd_mbuf) {
503 	// Another thread beat us to it
504         snap_mbuf->remove_ref();
505 	snap_mbuf = pd_mbuf;
506       }
507       else {
508 	CORBA::Any* me = OMNI_CONST_CAST(CORBA::Any*, this);
509 	me->pd_mbuf = snap_mbuf;
510       }
511     }
512   }
513   return *snap_mbuf;
514 }
515 
516 cdrAnyMemoryStream&
PR_streamToWrite()517 CORBA::Any::PR_streamToWrite()
518 {
519   PR_clearData();
520   pd_mbuf = new cdrAnyMemoryStream;
521   return *pd_mbuf;
522 }
523 
524 
525 //////////////////////////////////////////////////////////////////////
526 ////////////////// Simple insertion operators ////////////////////////
527 //////////////////////////////////////////////////////////////////////
528 
529 // Simple types always go in the memory buffer.
530 
531 void
operator <<=(Short s)532 CORBA::Any::operator<<=(Short s)
533 {
534   PR_clearData();
535   dupTC(pd_tc, CORBA::_tc_short);
536   pd_mbuf = new cdrAnyMemoryStream();
537   s >>= *pd_mbuf;
538 }
539 
540 
operator <<=(UShort u)541 void CORBA::Any::operator<<=(UShort u)
542 {
543   PR_clearData();
544   dupTC(pd_tc, CORBA::_tc_ushort);
545   pd_mbuf = new cdrAnyMemoryStream();
546   u >>= *pd_mbuf;
547 }
548 
549 
550 void
operator <<=(Long l)551 CORBA::Any::operator<<=(Long l)
552 {
553   PR_clearData();
554   dupTC(pd_tc, CORBA::_tc_long);
555   pd_mbuf = new cdrAnyMemoryStream();
556   l >>= *pd_mbuf;
557 }
558 
559 
560 void
operator <<=(ULong u)561 CORBA::Any::operator<<=(ULong u)
562 {
563   PR_clearData();
564   dupTC(pd_tc, CORBA::_tc_ulong);
565   pd_mbuf = new cdrAnyMemoryStream();
566   u >>= *pd_mbuf;
567 }
568 
569 #ifdef HAS_LongLong
570 void
operator <<=(LongLong l)571 CORBA::Any::operator<<=(LongLong l)
572 {
573   PR_clearData();
574   dupTC(pd_tc, CORBA::_tc_longlong);
575   pd_mbuf = new cdrAnyMemoryStream();
576   l >>= *pd_mbuf;
577 }
578 
579 void
operator <<=(ULongLong u)580 CORBA::Any::operator<<=(ULongLong u)
581 {
582   PR_clearData();
583   dupTC(pd_tc, CORBA::_tc_ulonglong);
584   pd_mbuf = new cdrAnyMemoryStream();
585   u >>= *pd_mbuf;
586 }
587 #endif
588 
589 
590 #if !defined(NO_FLOAT)
591 void
operator <<=(Float f)592 CORBA::Any::operator<<=(Float f)
593 {
594   PR_clearData();
595   dupTC(pd_tc, CORBA::_tc_float);
596   pd_mbuf = new cdrAnyMemoryStream();
597   f >>= *pd_mbuf;
598 }
599 
600 void
operator <<=(Double d)601 CORBA::Any::operator<<=(Double d)
602 {
603   PR_clearData();
604   dupTC(pd_tc, CORBA::_tc_double);
605   pd_mbuf = new cdrAnyMemoryStream();
606   d >>= *pd_mbuf;
607 }
608 
609 #ifdef HAS_LongDouble
610 void
operator <<=(LongDouble d)611 CORBA::Any::operator<<=(LongDouble d)
612 {
613   PR_clearData();
614   dupTC(pd_tc, CORBA::_tc_longdouble);
615   pd_mbuf = new cdrAnyMemoryStream();
616   d >>= *pd_mbuf;
617 }
618 #endif
619 
620 #endif
621 
622 
623 void
operator <<=(from_boolean b)624 CORBA::Any::operator<<=(from_boolean b)
625 {
626   PR_clearData();
627   dupTC(pd_tc, CORBA::_tc_boolean);
628   pd_mbuf = new cdrAnyMemoryStream();
629   pd_mbuf->marshalBoolean(b.val);
630 }
631 
632 void
operator <<=(from_char c)633 CORBA::Any::operator<<=(from_char c)
634 {
635   PR_clearData();
636   dupTC(pd_tc, CORBA::_tc_char);
637   pd_mbuf = new cdrAnyMemoryStream();
638   pd_mbuf->marshalChar(c.val);
639 }
640 
641 void
operator <<=(from_wchar c)642 CORBA::Any::operator<<=(from_wchar c)
643 {
644   PR_clearData();
645   dupTC(pd_tc, CORBA::_tc_wchar);
646   pd_mbuf = new cdrAnyMemoryStream();
647   pd_mbuf->marshalWChar(c.val);
648 }
649 
650 void
operator <<=(from_octet o)651 CORBA::Any::operator<<=(from_octet o)
652 {
653   PR_clearData();
654   dupTC(pd_tc, CORBA::_tc_octet);
655   pd_mbuf = new cdrAnyMemoryStream();
656   pd_mbuf->marshalOctet(o.val);
657 }
658 
659 void
operator <<=(from_fixed f)660 CORBA::Any::operator<<=(from_fixed f)
661 {
662   PR_clearData();
663   CORBA::Fixed g(f.val);
664   g.PR_setLimits(f.digits, f.scale);
665   pd_tc = CORBA::TypeCode::NP_fixed_tc(f.digits,f.scale);
666   pd_mbuf = new cdrAnyMemoryStream();
667   g >>= *pd_mbuf;
668 }
669 
670 
671 //////////////////////////////////////////////////////////////////////
672 ////////////////// Simple extraction operators ///////////////////////
673 //////////////////////////////////////////////////////////////////////
674 
675 
676 CORBA::Boolean
operator >>=(Short & s) const677 CORBA::Any::operator>>=(Short& s) const
678 {
679   if (!get(pd_tc)->equivalent(CORBA::_tc_short)) return 0;
680   OMNIORB_ASSERT(pd_mbuf);
681   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
682   s <<= tbuf;
683   return 1;
684 }
685 
686 CORBA::Boolean
operator >>=(UShort & u) const687 CORBA::Any::operator>>=(UShort& u) const
688 {
689   if (!get(pd_tc)->equivalent(CORBA::_tc_ushort)) return 0;
690   OMNIORB_ASSERT(pd_mbuf);
691   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
692   u <<= tbuf;
693   return 1;
694 }
695 
696 CORBA::Boolean
operator >>=(Long & l) const697 CORBA::Any::operator>>=(Long& l) const
698 {
699   if (!get(pd_tc)->equivalent(CORBA::_tc_long)) return 0;
700   OMNIORB_ASSERT(pd_mbuf);
701   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
702   l <<= tbuf;
703   return 1;
704 }
705 
706 
707 CORBA::Boolean
operator >>=(ULong & u) const708 CORBA::Any::operator>>=(ULong& u) const
709 {
710   if (!get(pd_tc)->equivalent(CORBA::_tc_ulong)) return 0;
711   OMNIORB_ASSERT(pd_mbuf);
712   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
713   u <<= tbuf;
714   return 1;
715 }
716 
717 
718 #ifdef HAS_LongLong
719 CORBA::Boolean
operator >>=(LongLong & l) const720 CORBA::Any::operator>>=(LongLong& l) const
721 {
722   if (!get(pd_tc)->equivalent(CORBA::_tc_longlong)) return 0;
723   OMNIORB_ASSERT(pd_mbuf);
724   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
725   l <<= tbuf;
726   return 1;
727 }
728 
729 
730 CORBA::Boolean
operator >>=(ULongLong & u) const731 CORBA::Any::operator>>=(ULongLong& u) const
732 {
733   if (!get(pd_tc)->equivalent(CORBA::_tc_ulonglong)) return 0;
734   OMNIORB_ASSERT(pd_mbuf);
735   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
736   u <<= tbuf;
737   return 1;
738 }
739 #endif
740 
741 
742 #if !defined(NO_FLOAT)
743 CORBA::Boolean
operator >>=(Float & f) const744 CORBA::Any::operator>>=(Float& f) const
745 {
746   if (!get(pd_tc)->equivalent(CORBA::_tc_float)) return 0;
747   OMNIORB_ASSERT(pd_mbuf);
748   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
749   f <<= tbuf;
750   return 1;
751 }
752 
753 
754 CORBA::Boolean
operator >>=(Double & d) const755 CORBA::Any::operator>>=(Double& d) const
756 {
757   if (!get(pd_tc)->equivalent(CORBA::_tc_double)) return 0;
758   OMNIORB_ASSERT(pd_mbuf);
759   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
760   d <<= tbuf;
761   return 1;
762 }
763 
764 #ifdef HAS_LongDouble
765 CORBA::Boolean
operator >>=(LongDouble & d) const766 CORBA::Any::operator>>=(LongDouble& d) const
767 {
768   if (!get(pd_tc)->equivalent(CORBA::_tc_longdouble)) return 0;
769   OMNIORB_ASSERT(pd_mbuf);
770   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
771   d <<= tbuf;
772   return 1;
773 }
774 #endif
775 
776 #endif
777 
778 
779 CORBA::Boolean
operator >>=(to_boolean b) const780 CORBA::Any::operator>>=(to_boolean b) const
781 {
782   if (!get(pd_tc)->equivalent(CORBA::_tc_boolean)) return 0;
783   OMNIORB_ASSERT(pd_mbuf);
784   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
785   b.ref = tbuf.unmarshalBoolean();
786   return 1;
787 }
788 
789 
790 CORBA::Boolean
operator >>=(to_char c) const791 CORBA::Any::operator>>=(to_char c) const
792 {
793   if (!get(pd_tc)->equivalent(CORBA::_tc_char)) return 0;
794   OMNIORB_ASSERT(pd_mbuf);
795   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
796   c.ref = tbuf.unmarshalChar();
797   return 1;
798 }
799 
800 
801 CORBA::Boolean
operator >>=(to_wchar c) const802 CORBA::Any::operator>>=(to_wchar c) const
803 {
804   if (!get(pd_tc)->equivalent(CORBA::_tc_wchar)) return 0;
805   OMNIORB_ASSERT(pd_mbuf);
806   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
807   c.ref = tbuf.unmarshalWChar();
808   return 1;
809 }
810 
811 
812 CORBA::Boolean
operator >>=(to_octet o) const813 CORBA::Any::operator>>=(to_octet o) const
814 {
815   if (!get(pd_tc)->equivalent(CORBA::_tc_octet)) return 0;
816   OMNIORB_ASSERT(pd_mbuf);
817   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
818   o.ref = tbuf.unmarshalOctet();
819   return 1;
820 }
821 
822 
823 CORBA::Boolean
operator >>=(to_fixed f) const824 CORBA::Any::operator>>=(to_fixed f) const
825 {
826   CORBA::TypeCode_var tc = CORBA::TypeCode::NP_fixed_tc(f.digits,f.scale);
827 
828   if (!get(pd_tc)->equivalent(tc)) return 0;
829   OMNIORB_ASSERT(pd_mbuf);
830   cdrAnyMemoryStream tbuf(*pd_mbuf, 1);
831 
832   CORBA::Fixed g;
833   g.PR_setLimits(f.digits, f.scale);
834   g <<= tbuf;
835 
836   f.val = g;
837   return 1;
838 }
839 
840 
841 
842 //////////////////////////////////////////////////////////////////////
843 /////////////// Complex insertion/extraction operators ///////////////
844 //////////////////////////////////////////////////////////////////////
845 
846 // Any
847 
marshalAny_fn(cdrStream & s,void * d)848 static void marshalAny_fn(cdrStream& s, void* d)
849 {
850   CORBA::Any* a = (CORBA::Any*)d;
851   *a >>= s;
852 }
unmarshalAny_fn(cdrStream & s,void * & d)853 static void unmarshalAny_fn(cdrStream& s, void*& d)
854 {
855   CORBA::Any* a = new CORBA::Any;
856   *a <<= s;
857   d = a;
858 }
deleteAny_fn(void * d)859 static void deleteAny_fn(void* d)
860 {
861   CORBA::Any* a = (CORBA::Any*)d;
862   delete a;
863 }
864 
865 void
operator <<=(const Any & a)866 CORBA::Any::operator<<=(const Any& a)
867 {
868   CORBA::Any* na = new CORBA::Any(a);
869   PR_insert(CORBA::_tc_any, marshalAny_fn, deleteAny_fn, na);
870 }
871 
872 void
operator <<=(Any * a)873 CORBA::Any::operator<<=(Any* a)
874 {
875   PR_insert(CORBA::_tc_any, marshalAny_fn, deleteAny_fn, a);
876 }
877 
operator >>=(const CORBA::Any * & a) const878 CORBA::Boolean CORBA::Any::operator>>=(const CORBA::Any*& a) const
879 {
880   void* v;
881 
882   if (PR_extract(CORBA::_tc_any,
883 		 unmarshalAny_fn, marshalAny_fn, deleteAny_fn, v)) {
884 
885     a = (const CORBA::Any*)v;
886     return 1;
887   }
888   return 0;
889 }
890 
891 // Deprecated non-const version.
operator >>=(CORBA::Any * & a) const892 CORBA::Boolean CORBA::Any::operator>>=(CORBA::Any*& a) const
893 {
894   return this->operator>>=((const CORBA::Any*&) a);
895 }
896 
897 // Obsolete pre-CORBA 2.3 operator.
operator >>=(Any & a) const898 CORBA::Boolean CORBA::Any::operator>>=(Any& a) const
899 {
900   const CORBA::Any* ap;
901   if (*this >>= ap) {
902     a = *ap;
903     return 1;
904   }
905   return 0;
906 }
907 
908 
909 // TypeCode
910 
marshalTypeCode_fn(cdrStream & s,void * d)911 static void marshalTypeCode_fn(cdrStream& s, void* d)
912 {
913   CORBA::TypeCode_ptr t = (CORBA::TypeCode_ptr)d;
914   CORBA::TypeCode::marshalTypeCode(t, s);
915 }
unmarshalTypeCode_fn(cdrStream & s,void * & d)916 static void unmarshalTypeCode_fn(cdrStream& s, void*& d)
917 {
918   CORBA::TypeCode_ptr t = CORBA::TypeCode::unmarshalTypeCode(s);
919   d = t;
920 }
deleteTypeCode_fn(void * d)921 static void deleteTypeCode_fn(void* d)
922 {
923   CORBA::TypeCode_ptr t = (CORBA::TypeCode_ptr)d;
924   CORBA::release(t);
925 }
926 
927 void
operator <<=(TypeCode_ptr tc)928 CORBA::Any::operator<<=(TypeCode_ptr tc)
929 {
930   if (!CORBA::TypeCode::PR_is_valid(tc)) {
931     OMNIORB_THROW(BAD_PARAM,BAD_PARAM_InvalidTypeCode,CORBA::COMPLETED_NO);
932   }
933   CORBA::TypeCode_ptr ntc = CORBA::TypeCode::_duplicate(tc);
934   PR_insert(CORBA::_tc_TypeCode, marshalTypeCode_fn, deleteTypeCode_fn, ntc);
935 }
936 void
operator <<=(TypeCode_ptr * tcp)937 CORBA::Any::operator<<=(TypeCode_ptr* tcp)
938 {
939   if (!CORBA::TypeCode::PR_is_valid(*tcp)) {
940     OMNIORB_THROW(BAD_PARAM,BAD_PARAM_InvalidTypeCode,CORBA::COMPLETED_NO);
941   }
942   PR_insert(CORBA::_tc_TypeCode, marshalTypeCode_fn, deleteTypeCode_fn, *tcp);
943   *tcp = CORBA::TypeCode::_nil();
944 }
945 CORBA::Boolean
operator >>=(CORBA::TypeCode_ptr & tc) const946 CORBA::Any::operator>>=(CORBA::TypeCode_ptr& tc) const
947 {
948   void* v;
949   if (PR_extract(CORBA::_tc_TypeCode,
950 		 unmarshalTypeCode_fn, marshalTypeCode_fn, deleteTypeCode_fn,
951 		 v)) {
952     tc = (CORBA::TypeCode_ptr)v;
953     return 1;
954   }
955   return 0;
956 }
957 
958 
959 // Object
960 
marshalObject_fn(cdrStream & s,void * v)961 static void marshalObject_fn(cdrStream& s, void* v)
962 {
963   omniObjRef* o = (omniObjRef*)v;
964   omniObjRef::_marshal(o, s);
965 }
unmarshalObject_fn(cdrStream & s,void * & v)966 static void unmarshalObject_fn(cdrStream& s, void*& v)
967 {
968   omniObjRef* o = omniObjRef::_unMarshal(CORBA::Object::_PD_repoId, s);
969   v = o;
970 }
deleteObject_fn(void * v)971 static void deleteObject_fn(void* v)
972 {
973   omniObjRef* o = (omniObjRef*)v;
974   if (o)
975     omni::releaseObjRef(o);
976 }
977 
978 void
operator <<=(Object_ptr obj)979 CORBA::Any::operator<<=(Object_ptr obj)
980 {
981   if (!CORBA::Object::_PR_is_valid(obj)) {
982     OMNIORB_THROW(BAD_PARAM,BAD_PARAM_InvalidObjectRef,CORBA::COMPLETED_NO);
983   }
984 #if 1
985   // Use the most derived interface for the TypeCode, not base CORBA::Object
986   // *** Is this right?  The C++ mapping is silent on the issue.
987   const char* repoid = CORBA::Object::_PD_repoId;
988   const char* name   = "";
989   if (!CORBA::is_nil(obj))
990     repoid = obj->_PR_getobj()->_mostDerivedRepoId();
991   CORBA::TypeCode_var tc = CORBA::TypeCode::NP_interface_tc(repoid,name);
992 #else
993   CORBA::TypeCode_ptr tc = CORBA::_tc_Object;
994 #endif
995 
996   CORBA::Object_ptr no = CORBA::Object::_duplicate(obj);
997   PR_insert(tc, marshalObject_fn, deleteObject_fn, no->_PR_getobj());
998 }
999 
1000 void
operator <<=(Object_ptr * objp)1001 CORBA::Any::operator<<=(Object_ptr* objp)
1002 {
1003   if (!CORBA::Object::_PR_is_valid(*objp)) {
1004     OMNIORB_THROW(BAD_PARAM,BAD_PARAM_InvalidObjectRef,CORBA::COMPLETED_NO);
1005   }
1006 #if 1
1007   const char* repoid = CORBA::Object::_PD_repoId;
1008   const char* name   = "";
1009   if (!CORBA::is_nil(*objp))
1010     repoid = (*objp)->_PR_getobj()->_mostDerivedRepoId();
1011   CORBA::TypeCode_var tc = CORBA::TypeCode::NP_interface_tc(repoid,name);
1012 #else
1013   CORBA::TypeCode_ptr tc = CORBA::_tc_Object;
1014 #endif
1015 
1016   PR_insert(tc, marshalObject_fn, deleteObject_fn, (*objp)->_PR_getobj());
1017   *objp = CORBA::Object::_nil();
1018 }
1019 
1020 CORBA::Boolean
operator >>=(CORBA::Object_ptr & obj) const1021 CORBA::Any::operator>>=(CORBA::Object_ptr& obj) const
1022 {
1023   void* v;
1024   if (PR_extract(CORBA::_tc_Object,
1025 		 unmarshalObject_fn, marshalObject_fn, deleteObject_fn,
1026 		 v)) {
1027     omniObjRef* r = (omniObjRef*)v;
1028     if (r)
1029       obj = (CORBA::Object_ptr)r->_ptrToObjRef(CORBA::Object::_PD_repoId);
1030     else
1031       obj = CORBA::Object::_nil();
1032     return 1;
1033   }
1034   return 0;
1035 }
1036 
1037 
1038 // Abstract Interface
1039 
marshalAbstractInterface_fn(cdrStream & s,void * v)1040 static void marshalAbstractInterface_fn(cdrStream& s, void* v)
1041 {
1042   CORBA::AbstractBase* a = (CORBA::AbstractBase*)v;
1043   if (v) {
1044     CORBA::ValueBase* b = a->_NP_to_value();
1045     if (b) {
1046       s.marshalBoolean(0);
1047       CORBA::ValueBase::_NP_marshal(b,s);
1048       return;
1049     }
1050     CORBA::Object_ptr o = a->_NP_to_object();
1051     if (o) {
1052       s.marshalBoolean(1);
1053       omniObjRef::_marshal(o->_PR_getobj(),s);
1054       return;
1055     }
1056   }
1057   s.marshalBoolean(0);
1058   CORBA::ValueBase::_NP_marshal(0,s);
1059 }
unmarshalAbstractInterface_fn(cdrStream & s,void * & v)1060 static void unmarshalAbstractInterface_fn(cdrStream& s, void*& v)
1061 {
1062   CORBA::AbstractBase* a;
1063   CORBA::Boolean c = s.unmarshalBoolean();
1064   if (c) {
1065     omniObjRef* o = omniObjRef::_unMarshal(CORBA::Object::_PD_repoId,s);
1066     if (o) {
1067       a = (CORBA::AbstractBase*)o->_ptrToObjRef(CORBA::AbstractBase::_PD_repoId);
1068       if (!a)
1069 	OMNIORB_THROW(BAD_PARAM,
1070 		      BAD_PARAM_IncorrectAbstractIntfType,
1071 		      (CORBA::CompletionStatus)s.completion());
1072     }
1073     else
1074       a = 0;
1075   }
1076   else {
1077     CORBA::ValueBase* b = CORBA::ValueBase::_NP_unmarshal(s);
1078     if (b) {
1079       a = (CORBA::AbstractBase*)b->_ptrToValue(CORBA::AbstractBase::_PD_repoId);
1080       if (!a)
1081 	OMNIORB_THROW(BAD_PARAM,
1082 		      BAD_PARAM_IncorrectAbstractIntfType,
1083 		      (CORBA::CompletionStatus)s.completion());
1084     }
1085     else
1086       a = 0;
1087   }
1088   v = a;
1089 }
deleteAbstractInterface_fn(void * v)1090 static void deleteAbstractInterface_fn(void* v)
1091 {
1092   CORBA::AbstractBase_ptr a = (CORBA::AbstractBase_ptr)v;
1093   if (a)
1094     CORBA::release(a);
1095 }
1096 
1097 
1098 // to_object, to_abstract_base, to_value
1099 
1100 CORBA::Boolean
operator >>=(to_object o) const1101 CORBA::Any::operator>>=(to_object o) const
1102 {
1103   void* v;
1104 
1105   CORBA::TCKind kind = get(pd_tc)->kind();
1106 
1107   if (kind == CORBA::tk_objref) {
1108     // We call PR_extract giving it our own TypeCode, so its type check
1109     // always succeeds, whatever specific object reference type we
1110     // contain.
1111     //
1112     // Unlike other extraction operators, the caller takes ownership
1113     // of the returned reference here.
1114 
1115     if (PR_extract(get(pd_tc),
1116 		   unmarshalObject_fn, marshalObject_fn, deleteObject_fn,
1117 		   v)) {
1118 
1119       omniObjRef* r = (omniObjRef*)v;
1120       if (r)
1121 	o.ref = CORBA::Object::_duplicate(
1122 	        (CORBA::Object_ptr)r->_ptrToObjRef(CORBA::Object::_PD_repoId));
1123       else
1124 	o.ref = CORBA::Object::_nil();
1125 
1126       return 1;
1127     }
1128   }
1129   else if (kind == CORBA::tk_abstract_interface) {
1130     if (PR_extract(get(pd_tc),
1131 		   unmarshalAbstractInterface_fn,
1132 		   marshalAbstractInterface_fn,
1133 		   deleteAbstractInterface_fn,
1134 		   v)) {
1135       CORBA::AbstractBase* a = (CORBA::AbstractBase*)v;
1136       if (a) {
1137 	if (a->_NP_to_value())
1138 	  return 0;
1139 	o.ref = a->_to_object();
1140       }
1141       else
1142 	o.ref = CORBA::Object::_nil();
1143       return 1;
1144     }
1145   }
1146   return 0;
1147 }
1148 
1149 CORBA::Boolean
operator >>=(to_abstract_base a) const1150 CORBA::Any::operator>>=(to_abstract_base a) const
1151 {
1152   void* v;
1153 
1154   if (get(pd_tc)->kind() != CORBA::tk_abstract_interface)
1155     return 0;
1156 
1157   if (PR_extract(get(pd_tc),
1158 		 unmarshalAbstractInterface_fn,
1159 		 marshalAbstractInterface_fn,
1160 		 deleteAbstractInterface_fn,
1161 		 v)) {
1162     a.ref = CORBA::AbstractBase::_duplicate((CORBA::AbstractBase*)v);
1163     return 1;
1164   }
1165   return 0;
1166 }
1167 
1168 CORBA::Boolean
operator >>=(to_value o) const1169 CORBA::Any::operator>>=(to_value o) const
1170 {
1171   void* v;
1172 
1173   CORBA::TCKind kind = get(pd_tc)->kind();
1174 
1175   if (kind == CORBA::tk_value || kind == CORBA::tk_value_box) {
1176     // When values are stored by pointer in pd_data, they are stored
1177     // as the most derived type. That means we can't use the pointer
1178     // as ValueBase here. Instead, we use a temporary memory buffer.
1179     // That's not as inefficient as it might seem, because the
1180     // cdrAnyMemoryStream stores valuetypes by pointer anyway.
1181     if (pd_mbuf) {
1182       o.ref = CORBA::ValueBase::_NP_unmarshal(*pd_mbuf);
1183       return 1;
1184     }
1185     else {
1186       OMNIORB_ASSERT(pd_data);
1187       OMNIORB_ASSERT(pd_marshal);
1188       cdrAnyMemoryStream tmp;
1189       pd_marshal(tmp, pd_data);
1190       o.ref = CORBA::ValueBase::_NP_unmarshal(tmp);
1191       return 1;
1192     }
1193   }
1194   else if (kind == CORBA::tk_abstract_interface) {
1195     if (PR_extract(get(pd_tc),
1196 		   unmarshalAbstractInterface_fn,
1197 		   marshalAbstractInterface_fn,
1198 		   deleteAbstractInterface_fn,
1199 		   v)) {
1200       CORBA::AbstractBase* a = (CORBA::AbstractBase*)v;
1201       if (a) {
1202 	o.ref = a->_to_value();
1203 	if (o.ref == 0)
1204 	  return 0;
1205       }
1206       else
1207 	o.ref = 0;
1208       return 1;
1209     }
1210   }
1211   return 0;
1212 }
1213 
1214 
1215 // String
1216 
marshalString_fn(cdrStream & s,void * d)1217 static void marshalString_fn(cdrStream& s, void* d)
1218 {
1219   s.marshalString((const char*)d);
1220 }
unmarshalString_fn(cdrStream & s,void * & d)1221 static void unmarshalString_fn(cdrStream& s, void*& d)
1222 {
1223   char* c = s.unmarshalString();
1224   d = c;
1225 }
deleteString_fn(void * d)1226 static void deleteString_fn(void* d)
1227 {
1228   CORBA::string_free((char*)d);
1229 }
1230 
1231 void
operator <<=(const char * s)1232 CORBA::Any::operator<<=(const char* s)
1233 {
1234   PR_clearData();
1235   dupTC(pd_tc, CORBA::_tc_string);
1236 
1237   char* ns = CORBA::string_dup(s);
1238   PR_insert(CORBA::_tc_string, marshalString_fn, deleteString_fn, ns);
1239 }
1240 
1241 void
operator <<=(from_string s)1242 CORBA::Any::operator<<=(from_string s)
1243 {
1244   CORBA::TypeCode_ptr tc;
1245 
1246   if (s.bound)
1247     tc = CORBA::TypeCode::NP_string_tc(s.bound);
1248   else
1249     tc = CORBA::TypeCode::_duplicate(CORBA::_tc_string);
1250 
1251   PR_clearData();
1252   grabTC(pd_tc, tc);
1253 
1254   pd_data       = s.nc ? s.val : CORBA::string_dup(s.val);
1255   pd_marshal    = marshalString_fn;
1256   pd_destructor = deleteString_fn;
1257 }
1258 
1259 CORBA::Boolean
operator >>=(const char * & s) const1260 CORBA::Any::operator>>=(const char*& s) const
1261 {
1262   void* v;
1263   if (PR_extract(CORBA::_tc_string,
1264 		 unmarshalString_fn, marshalString_fn, deleteString_fn,
1265 		 v)) {
1266     s = (const char*)v;
1267     return 1;
1268   }
1269   return 0;
1270 }
1271 
1272 CORBA::Boolean
operator >>=(to_string s) const1273 CORBA::Any::operator>>=(to_string s) const
1274 {
1275   CORBA::TypeCode_var newtc = CORBA::TypeCode::NP_string_tc(s.bound);
1276 
1277   void* v;
1278   if (PR_extract(newtc,
1279 		 unmarshalString_fn, marshalString_fn, deleteString_fn,
1280 		 v)) {
1281     s.val = (char*)v;
1282     return 1;
1283   }
1284   return 0;
1285 }
1286 
1287 
1288 // Wstring
1289 
marshalWString_fn(cdrStream & s,void * d)1290 static void marshalWString_fn(cdrStream& s, void* d)
1291 {
1292   s.marshalWString((const CORBA::WChar*)d);
1293 }
unmarshalWString_fn(cdrStream & s,void * & d)1294 static void unmarshalWString_fn(cdrStream& s, void*& d)
1295 {
1296   CORBA::WChar* c = s.unmarshalWString();
1297   d = c;
1298 }
deleteWString_fn(void * d)1299 static void deleteWString_fn(void* d)
1300 {
1301   CORBA::wstring_free((CORBA::WChar*)d);
1302 }
1303 
1304 void
operator <<=(const CORBA::WChar * s)1305 CORBA::Any::operator<<=(const CORBA::WChar* s)
1306 {
1307   PR_clearData();
1308   dupTC(pd_tc, CORBA::_tc_string);
1309 
1310   CORBA::WChar* ns = CORBA::wstring_dup(s);
1311   PR_insert(CORBA::_tc_wstring, marshalWString_fn, deleteWString_fn, ns);
1312 }
1313 
1314 void
operator <<=(from_wstring s)1315 CORBA::Any::operator<<=(from_wstring s)
1316 {
1317   CORBA::TypeCode_ptr tc;
1318 
1319   if (s.bound)
1320     tc = CORBA::TypeCode::NP_wstring_tc(s.bound);
1321   else
1322     tc = CORBA::TypeCode::_duplicate(CORBA::_tc_wstring);
1323 
1324   PR_clearData();
1325   grabTC(pd_tc, tc);
1326 
1327   pd_data       = s.nc ? s.val : CORBA::wstring_dup(s.val);
1328   pd_marshal    = marshalWString_fn;
1329   pd_destructor = deleteWString_fn;
1330 }
1331 
1332 CORBA::Boolean
operator >>=(const CORBA::WChar * & s) const1333 CORBA::Any::operator>>=(const CORBA::WChar*& s) const
1334 {
1335   void* v;
1336   if (PR_extract(CORBA::_tc_wstring,
1337 		 unmarshalWString_fn, marshalWString_fn, deleteWString_fn,
1338 		 v)) {
1339     s = (const CORBA::WChar*)v;
1340     return 1;
1341   }
1342   return 0;
1343 }
1344 
1345 CORBA::Boolean
operator >>=(to_wstring s) const1346 CORBA::Any::operator>>=(to_wstring s) const
1347 {
1348   CORBA::TypeCode_var newtc = CORBA::TypeCode::NP_wstring_tc(s.bound);
1349 
1350   void* v;
1351   if (PR_extract(newtc,
1352 		 unmarshalWString_fn, marshalWString_fn, deleteWString_fn,
1353 		 v)) {
1354     s.val = (CORBA::WChar*)v;
1355     return 1;
1356   }
1357   return 0;
1358 }
1359 
1360 
1361 CORBA::Boolean
operator >>=(const CORBA::SystemException * & e) const1362 CORBA::Any::operator>>=(const CORBA::SystemException*& e) const
1363 {
1364   CORBA::Boolean r;
1365 #define EXTRACT_IF_MATCH(name) \
1366   if (get(pd_tc)->equivalent(CORBA::_tc_##name)) {	\
1367     const CORBA::name* ex; \
1368     r = *this >>= ex; \
1369     e = ex; \
1370     return r; \
1371   }
1372   OMNIORB_FOR_EACH_SYS_EXCEPTION(EXTRACT_IF_MATCH)
1373 #undef EXTRACT_IF_MATCH
1374 
1375   return 0;
1376 }
1377 
1378 
1379 CORBA::TypeCode_ptr
type() const1380 CORBA::Any::type() const
1381 {
1382   return CORBA::TypeCode::_duplicate(get(pd_tc));
1383 }
1384 
1385 CORBA::TypeCode_ptr
NP_type() const1386 CORBA::Any::NP_type() const
1387 {
1388   return get(pd_tc);
1389 }
1390 
1391 void
type(CORBA::TypeCode_ptr tc)1392 CORBA::Any::type(CORBA::TypeCode_ptr tc)
1393 {
1394   if (!get(pd_tc)->equivalent(tc))
1395     OMNIORB_THROW(BAD_TYPECODE,
1396 		  BAD_TYPECODE_NotEquivalent,
1397 		  CORBA::COMPLETED_NO);
1398 
1399   dupTC(pd_tc, tc);
1400 }
1401 
1402 const void*
value() const1403 CORBA::Any::value() const
1404 {
1405   if (get(pd_tc)->kind() == CORBA::tk_null ||
1406       get(pd_tc)->kind() == CORBA::tk_void)
1407     return 0;
1408 
1409   cdrAnyMemoryStream* snap_mbuf;
1410 
1411   {
1412     SNAP_LOCK;
1413     snap_mbuf = pd_mbuf;
1414   }
1415 
1416   if (!snap_mbuf) {
1417     OMNIORB_ASSERT(pd_marshal);
1418 
1419     // We create a memory buffer and marshal our value into it. Note
1420     // that this will result in invalid data if we contain a
1421     // valuetype, since valuetypes do not get marshalled into the
1422     // memory buffer like other types. This value() method was
1423     // deprecated before valuetypes were specifified, so we consider
1424     // this an acceptable limitation.
1425     cdrAnyMemoryStream* mbuf = new cdrAnyMemoryStream;
1426 
1427     pd_marshal(*mbuf, pd_data);
1428 
1429     {
1430       omni_tracedmutex_lock l(anyLock);
1431 
1432       if (pd_mbuf) {
1433 	// Another thread beat us to it
1434 	delete mbuf;
1435 	snap_mbuf = pd_mbuf;
1436       }
1437       else {
1438 	CORBA::Any* me = OMNI_CONST_CAST(CORBA::Any*, this);
1439 	snap_mbuf = me->pd_mbuf = mbuf;
1440       }
1441     }
1442   }
1443   return snap_mbuf->bufPtr();
1444 }
1445