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