RCFProto

- Main Page
- Classes
- Files

- File List

All Classes Functions Typedefs
Marshal.hpp
1
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18
19 #ifndef INCLUDE_RCF_MARSHAL_HPP
20 #define INCLUDE_RCF_MARSHAL_HPP
21
22 #include <RCF/AmiThreadPool.hpp>
23 #include <RCF/ClientStub.hpp>
24 #include <RCF/CurrentSerializationProtocol.hpp>
25 #include <RCF/ObjectPool.hpp>
26 #include <RCF/PublishingService.hpp>
27 #include <RCF/RcfServer.hpp>
28 #include <RCF/RcfSession.hpp>
29 #include <RCF/SerializationProtocol.hpp>
30 #include <RCF/ThreadLocalData.hpp>
31 #include <RCF/Tools.hpp>
32 #include <RCF/TypeTraits.hpp>
33 #include <RCF/Version.hpp>
34
35 #include <boost/mpl/and.hpp>
36 #include <boost/mpl/assert.hpp>
37 #include <boost/mpl/and.hpp>
38 #include <boost/mpl/if.hpp>
39 #include <boost/mpl/not.hpp>
40 #include <boost/mpl/or.hpp>
41 #include <boost/scoped_ptr.hpp>
42 #include <boost/static_assert.hpp>
43 #include <boost/type_traits.hpp>
44
45 #ifdef RCF_USE_SF_SERIALIZATION
46 #include <SF/memory.hpp>
47 #endif
48
49 #ifdef RCF_USE_BOOST_SERIALIZATION
50 #include <RCF/BsAutoPtr.hpp>
51 #include <boost/serialization/binary_object.hpp>
52 #endif
53
54 #include <SF/Tools.hpp>
55
56 namespace RCF {
57
58 // The following macro hacks are necessitated by Boost.Serialization, which
59 // , apparently on principle, refuses to serialize pointers to (1) fundamental
60 // types, and (2) std::string, while happily serializing pointers to everything
61 // else...
62
63 #define RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION(type) \
64 inline void serializeImpl( \
65 SerializationProtocolOut &out, \
66 const type *pt, \
67 long int) \
68 { \
69 serializeImpl(out, *pt, 0); \
70 } \
71 \
72 inline void serializeImpl( \
73 SerializationProtocolOut &out, \
74 type *const pt, \
75 long int) \
76 { \
77 serializeImpl(out, *pt, 0); \
78 } \
79 \
80 inline void deserializeImpl( \
81 SerializationProtocolIn &in, \
82 type *&pt, \
83 long int) \
84 { \
85 RCF_ASSERT(pt==NULL); \
86 pt = new type(); \
87 deserializeImpl(in, *pt, 0); \
88 }
89
90 SF_FOR_EACH_FUNDAMENTAL_TYPE( RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION )
91
92 #define RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION_T3(type) \
93 template<typename T1, typename T2, typename T3> \
94 inline void serializeImpl( \
95 SerializationProtocolOut &out, \
96 const type<T1,T2,T3> *pt, \
97 int) \
98 { \
99 serializeImpl(out, *pt, 0); \
100 } \
101 \
102 template<typename T1, typename T2, typename T3> \
103 inline void serializeImpl( \
104 SerializationProtocolOut &out, \
105 type<T1,T2,T3> *const pt, \
106 int) \
107 { \
108 serializeImpl(out, *pt, 0); \
109 } \
110 \
111 template<typename T1, typename T2, typename T3> \
112 inline void deserializeImpl( \
113 SerializationProtocolIn &in, \
114 type<T1,T2,T3> *&pt, \
115 int) \
116 { \
117 RCF_ASSERT(pt==NULL); \
118 pt = new type<T1,T2,T3>(); \
119 deserializeImpl(in, *pt, 0); \
120 }
121
122 #ifdef RCF_USE_BOOST_SERIALIZATION
123
124 RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION_T3(std::basic_string)
125
126 #endif
127
128 #undef RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION
129
130 #undef RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION_T3
131
132 // Boost.Serialization handles smart pointers very clumsily, so we do those ourselves
133
134 #define RefCountSmartPtr boost::shared_ptr
135
136 template<typename T>
137 inline void serializeImpl(
138 SerializationProtocolOut &out,
139 const RefCountSmartPtr<T> *spt,
140 int)
141 {
142 serialize(out, *spt);
143 }
144
145 template<typename T>
146 inline void serializeImpl(
147 SerializationProtocolOut &out,
148 RefCountSmartPtr<T> *const spt,
149 int)
150 {
151 serialize(out, *spt);
152 }
153
154 template<typename T>
155 inline void deserializeImpl(
156 SerializationProtocolIn &in,
157 RefCountSmartPtr<T> *&spt,
158 int)
159 {
160 spt = new RefCountSmartPtr<T>();
161 deserialize(in, *spt);
162 }
163
164 template<typename T>
165 inline void serializeImpl(
166 SerializationProtocolOut &out,
167 const RefCountSmartPtr<T> &spt,
168 int)
169 {
170 serialize(out, spt.get());
171 }
172
173 template<typename T>
174 inline void deserializeImpl(
175 SerializationProtocolIn &in,
176 RefCountSmartPtr<T> &spt,
177 int)
178 {
179 T *pt = NULL;
180 deserialize(in, pt);
181 spt = RefCountSmartPtr<T>(pt);
182 }
183
184 #undef RefCountSmartPtr
185
186 #ifdef RCF_USE_BOOST_SERIALIZATION
187 } // namespace RCF
188
189 namespace boost { namespace serialization {
190
191 template<class Archive>
192 void save(Archive & ar, const RCF::ByteBuffer &byteBuffer, unsigned int)
193 {
194 // We have to copy the buffer - can't do efficient zero-copy transmission
195 // of ByteBuffer, with B.Ser.
196
197 boost::uint32_t len = byteBuffer.getLength();
198 ar & len;
199 ar & make_binary_object(byteBuffer.getPtr(), len);
200
201 }
202
203 template<class Archive>
204 void load(Archive &ar, RCF::ByteBuffer &byteBuffer, unsigned int)
205 {
206 // We have to copy the buffer - can't do efficient zero-copy transmission
207 // of ByteBuffer, with B.Ser.
208
209 boost::uint32_t len = 0;
210 ar & len;
211
212 RCF::ReallocBufferPtr bufferPtr = RCF::getObjectPool().getReallocBufferPtr();
213 bufferPtr->resize(len);
214 byteBuffer = RCF::ByteBuffer(bufferPtr);
215
216 ar & make_binary_object(byteBuffer.getPtr(), byteBuffer.getLength());
217 }
218
219 }} // namespace boost namespace serialization
220
221 BOOST_SERIALIZATION_SPLIT_FREE(RCF::ByteBuffer);
222
223 namespace RCF {
224 #endif // RCF_USE_BOOST_SERIALIZATION
225
226 // serializeOverride() and deserializeOverride() are used to implement
227 // a backwards compatibility workaround, for ByteBuffer interoperability
228 // with RCF runtime version <= 3.
229
230 template<typename U>
231 bool serializeOverride(SerializationProtocolOut &, U &)
232 {
233 return false;
234 }
235
236 template<typename U>
237 bool serializeOverride(SerializationProtocolOut &, U *)
238 {
239 return false;
240 }
241
242 template<typename U>
243 bool deserializeOverride(SerializationProtocolIn &, U &)
244 {
245 return false;
246 }
247
248 RCF_EXPORT bool serializeOverride(SerializationProtocolOut &out, ByteBuffer & u);
249
250 RCF_EXPORT bool serializeOverride(SerializationProtocolOut &out, ByteBuffer * pu);
251
252 RCF_EXPORT bool deserializeOverride(SerializationProtocolIn &in, ByteBuffer & u);
253
254 // For vc6, manual zero-initialization of integral types.
255
256 template<typename T> void vc6DefaultInit(T *) {}
257
258 // -------------------------------------------------------------------------
259 // Parameter store.
260
261 template<typename T>
262 class ParmStore
263 {
264 public:
265 ParmStore() : mptPtr(), mpT(NULL)
266 {
267 }
268
269 ParmStore(std::vector<char> & vec) : mptPtr(), mpT(NULL)
270 {
271 allocate(vec);
272 }
273
274 void allocate(std::vector<char> & vec)
275 {
276 RCF_ASSERT(mpT == NULL);
277
278 getObjectPool().getObj(mptPtr, false);
279
280 if (mptPtr)
281 {
282 mpT = mptPtr.get();
283 }
284 else
285 {
286 // If we didn't get it from the pool, use placement new to construct
287 // it in the given vector.
288
289 vec.resize(sizeof(T));
290 mpT = (T *) & vec[0];
291
292 #ifdef _MSC_VER
293 #pragma warning( push )
294 #pragma warning( disable : 4345 ) // warning C4345: behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
295 #endif
296
297 new (mpT) T();
298
299 vc6DefaultInit(mpT);
300
301 #ifdef _MSC_VER
302 #pragma warning( pop )
303 #endif
304 }
305
306 }
307
308 void assign(T * pt)
309 {
310 RCF_ASSERT(mpT == NULL);
311
312 mptPtr.reset(pt);
313 mpT = mptPtr.get();
314 }
315
316 ~ParmStore()
317 {
318 if (!mptPtr)
319 {
320 if (mpT)
321 {
322 mpT->~T();
323 }
324 }
325 }
326
327 T & operator*()
328 {
329 return *mpT;
330 }
331
332 T * get()
333 {
334 return mpT;
335 }
336
337 boost::shared_ptr<T> mptPtr;
338 T * mpT;
339 };
340
341
342 // -------------------------------------------------------------------------
343 // Server marshaling.
344
345 template<typename T>
346 class Sm_Value
347 {
348 public:
349
350 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
351 BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));
352
353 Sm_Value(std::vector<char> & vec) : mPs(vec)
354 {
355 }
356
357 T &get()
358 {
359 return *mPs;
360 }
361
362 void set(bool assign, const T &t)
363 {
364 if (assign)
365 {
366 *mPs = t;
367 }
368 }
369
370 void set(const T &t)
371 {
372 *mPs = t;
373 }
374
375 void read(SerializationProtocolIn &in)
376 {
377 if (in.getRemainingArchiveLength() != 0)
378 {
379 if (!deserializeOverride(in, *mPs))
380 {
381 deserialize(in, *mPs);
382 }
383 }
384 }
385
386 void write(SerializationProtocolOut &)
387 {
388 RCF_ASSERT(0);
389 }
390
391 private:
392 ParmStore<T> mPs;
393 };
394
395 template<>
396 class Sm_Value<Void>
397 {
398 public:
399
400 Sm_Value(std::vector<char> &)
401 {
402 }
403
404 ~Sm_Value()
405 {
406 }
407
408 Void &get()
409 {
410 RCF_ASSERT(0);
411 static Void v;
412 return v;
413 }
414
415 void set(bool , const Void &)
416 {
417 RCF_ASSERT(0);
418 }
419
420 void set(const Void &)
421 {
422 RCF_ASSERT(0);
423 }
424
425 void read(SerializationProtocolIn &)
426 {
427 RCF_ASSERT(0);
428 }
429
430 void write(SerializationProtocolOut &)
431 {
432 RCF_ASSERT(0);
433 }
434 };
435
436 template<typename T>
437 class Sm_Ret
438 {
439 public:
440
441 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
442 BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));
443
444 Sm_Ret(std::vector<char> & vec) : mPs(vec)
445 {
446 }
447
448 T &get()
449 {
450 return *mPs;
451 }
452
453 void set(bool assign, const T &t)
454 {
455 if (assign)
456 {
457 *mPs = t;
458 }
459 }
460
461 void set(const T &t)
462 {
463 *mPs = t;
464 }
465
466 void read(SerializationProtocolIn &)
467 {
468 RCF_ASSERT(0);
469 }
470
471 void write(SerializationProtocolOut &out)
472 {
473 if (!serializeOverride(out, *mPs))
474 {
475 serialize(out, *mPs);
476 }
477 }
478
479 private:
480 ParmStore<T> mPs;
481 };
482
483 template<typename CRefT>
484 class Sm_CRef
485 {
486 public:
487
488 typedef typename RemoveReference<CRefT>::type CT;
489 typedef typename RemoveCv<CT>::type T;
490 BOOST_MPL_ASSERT(( IsReference<CRefT> ));
491
492 BOOST_MPL_ASSERT(( IsConst<CT> ));
493
494 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
495
496 Sm_CRef(std::vector<char> & vec) : mPs(), mVec(vec)
497 {}
498
499 T &get()
500 {
501 return *mPs;
502 }
503
504 void set(bool assign, const T &t)
505 {
506 if (assign)
507 {
508 *mPs = t;
509 }
510 }
511
512 void set(const T &t)
513 {
514 *mPs = t;
515 }
516
517 void read(SerializationProtocolIn &in)
518 {
519 if (in.getRemainingArchiveLength() != 0)
520 {
521 int ver = in.getRuntimeVersion();
522 if (ver < 8)
523 {
524 // Deserialize as pointer, which means we may get
525 // polymorphic serialization happening.
526
527 T *pt = NULL;
528 deserialize(in, pt);
529 mPs.assign(pt);
530 }
531 else if (ver == 8)
532 {
533 // Deserialize as value.
534 mPs.allocate(mVec);
535 deserialize(in, *mPs);
536 }
537 else if (ver >= 9)
538 {
539 // If BSer, deserialize through pointer.
540 // If SF and caching disabled, deserialize through pointer.
541 // If SF and caching enabled, use object cache and deserialize through value.
542
543 int sp = in.getSerializationProtocol();
544 if ( (sp == Sp_SfBinary || sp == Sp_SfText)
545 && getObjectPool().isCachingEnabled( (T *) NULL ))
546 {
547 mPs.allocate(mVec);
548 deserialize(in, *mPs);
549 }
550 else
551 {
552 T *pt = NULL;
553 deserialize(in, pt);
554 if (!pt)
555 {
556 RCF::Exception e(RCF::_RcfError_DeserializationNullPointer());
557 RCF_THROW(e);
558 }
559 mPs.assign(pt);
560 }
561 }
562 }
563 else
564 {
565 mPs.allocate(mVec);
566 }
567 }
568
569 void write(SerializationProtocolOut &)
570 {
571 RCF_ASSERT(0);
572 }
573
574 private:
575 ParmStore<T> mPs;
576 std::vector<char> & mVec;
577 };
578
579 template<typename RefT>
580 class Sm_Ref
581 {
582 public:
583
584 typedef typename RemoveReference<RefT>::type T;
585 typedef typename RemoveCv<T>::type U;
586 BOOST_MPL_ASSERT(( IsReference<RefT> ));
587 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
588
589 Sm_Ref(std::vector<char> & vec) : mVec(vec)
590 {}
591
592 T &get()
593 {
594 return *mPs;
595 }
596
597 void set(bool assign, const T &t)
598 {
599 if (assign)
600 {
601 *mPs = t;
602 }
603 }
604
605 void set(const T &t)
606 {
607 *mPs = t;
608 }
609
610 void read(SerializationProtocolIn &in)
611 {
612 if (in.getRemainingArchiveLength() != 0)
613 {
614 int ver = in.getRuntimeVersion();
615 if (ver < 8)
616 {
617 // Deserialize as pointer, which means we may get
618 // polymorphic serialization happening.
619
620 T * pt = NULL;
621 deserialize(in, pt);
622 mPs.assign(pt);
623 }
624 else if (ver == 8)
625 {
626 // Deserialize as value.
627
628 mPs.allocate(mVec);
629 deserialize(in, *mPs);
630 }
631 else if (ver >= 9)
632 {
633 // If BSer, deserialize through pointer.
634 // If SF and caching disabled, deserialize through pointer.
635 // If SF and caching enabled, use object cache and deserialize through value.
636
637 int sp = in.getSerializationProtocol();
638 if ( (sp == Sp_SfBinary || sp == Sp_SfText)
639 && getObjectPool().isCachingEnabled( (T *) NULL ))
640 {
641 mPs.allocate(mVec);
642 deserialize(in, *mPs);
643 }
644 else
645 {
646 T *pt = NULL;
647 deserialize(in, pt);
648 if (!pt)
649 {
650 RCF::Exception e(RCF::_RcfError_DeserializationNullPointer());
651 RCF_THROW(e);
652 }
653 mPs.assign(pt);
654 }
655 }
656 }
657 else
658 {
659 mPs.allocate(mVec);
660 }
661 }
662
663 void write(SerializationProtocolOut &out)
664 {
665 RCF_ASSERT(mPs.get());
666
667 if (!serializeOverride(out, *mPs))
668 {
669 // B.Ser. issues - because the client side proxy for a T& has to
670 // deserialize itself as a value, here we have to serialize as a
671 // value.
672
673 serialize(out, *mPs);
674 }
675 }
676
677 private:
678 ParmStore<T> mPs;
679 std::vector<char> & mVec;
680 };
681
682 template<typename OutRefT>
683 class Sm_OutRef
684 {
685 public:
686
687 typedef typename RemoveOut<OutRefT>::type RefT;
688 typedef typename RemoveReference<RefT>::type T;
689 typedef typename RemoveCv<T>::type U;
690 BOOST_MPL_ASSERT(( IsReference<RefT> ));
691 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
692
693 Sm_OutRef(std::vector<char> & vec) : mPs(vec)
694 {
695 }
696
697 T &get()
698 {
699 return *mPs;
700 }
701
702 void set(bool assign, const T &t)
703 {
704 if (assign)
705 {
706 *mPs = t;
707 }
708 }
709
710 void set(const T &t)
711 {
712 *mPs = t;
713 }
714
715 void read(SerializationProtocolIn &)
716 {
717 RCF_ASSERT(0);
718 }
719
720 void write(SerializationProtocolOut &out)
721 {
722 if (!serializeOverride(out, *mPs))
723 {
724 // B.Ser. issues - because the client side proxy for a T& has to
725 // deserialize itself as a value, here we have to serialize as a
726 // value.
727
728 serialize(out, *mPs);
729 }
730 }
731
732 private:
733 ParmStore<T> mPs;
734 };
735
736 template<typename PtrT>
737 class Sm_Ptr
738 {
739 public:
740
741 typedef typename RemovePointer<PtrT>::type T;
742 typedef typename RemoveCv<T>::type U;
743 BOOST_MPL_ASSERT(( IsPointer<PtrT> ));
744 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
745
746 Sm_Ptr(std::vector<char> &)
747 {}
748
749 T *get()
750 {
751 return mPs.get();
752 }
753
754 void set(bool assign, const T &t)
755 {
756 if (assign)
757 {
758 *mPs = t;
759 }
760 }
761
762 void set(const T &t)
763 {
764 *mPs = t;
765 }
766
767 void read(SerializationProtocolIn &in)
768 {
769 if (in.getRemainingArchiveLength() != 0)
770 {
771 T *pt = NULL;
772 deserialize(in, pt);
773 mPs.assign(pt);
774 }
775 }
776
777 void write(SerializationProtocolOut &)
778 {
779 RCF_ASSERT(0);
780 }
781
782 private:
783 ParmStore<T> mPs;
784 };
785
786 // -------------------------------------------------------------------------
787 // Client marshaling.
788
789 template<typename T>
790 class Cm_Ret
791 {
792 public:
793
794 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
795 BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));
796
797 Cm_Ret()
798 {
799 RCF::ClientStub * pClientStub = getTlsClientStubPtr();
800 std::vector<char> & vec = pClientStub->getRetValVec();
801 mPs.allocate(vec);
802 }
803
804 T &get()
805 {
806 return *mPs;
807 }
808
809 void set(bool assign, const T &t)
810 {
811 if (assign)
812 {
813 *mPs = t;
814 }
815 }
816
817 void set(const T &t)
818 {
819 *mPs = t;
820 }
821
822 void read(SerializationProtocolIn &in)
823 {
824 if (in.getRemainingArchiveLength() != 0)
825 {
826 if (!deserializeOverride(in, *mPs))
827 {
828 deserialize(in, *mPs);
829 }
830 }
831 }
832
833 void write(SerializationProtocolOut &)
834 {
835 RCF_ASSERT(0);
836 }
837
838 private:
839 ParmStore<T> mPs;
840 };
841
842 template<typename T>
843 class Cm_Value
844 {
845 public:
846
847 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
848 BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));
849
850 // We use const_cast here, in case T's copy constructor is non-const.
851 // E.g. if T is a std::auto_ptr.
852 Cm_Value(const T &t) : mT( const_cast<T &>(t) )
853 {
854 }
855
856 const T &get()
857 {
858 return mT;
859 }
860
861 void read(SerializationProtocolIn &in)
862 {
863 RCF_UNUSED_VARIABLE(in);
864 }
865
866 void write(SerializationProtocolOut &out)
867 {
868 if (!serializeOverride(out, mT))
869 {
870 serialize(out, mT);
871 }
872 }
873
874 private:
875 T mT;
876 };
877
878 template<typename PtrT>
879 class Cm_Ptr
880 {
881 public:
882
883 typedef typename RemovePointer<PtrT>::type T;
884
885 BOOST_MPL_ASSERT(( IsPointer<PtrT> ));
886
887 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
888
889 // We use const_cast here, in case T's copy constructor is non-const.
890 // E.g. if T is a std::auto_ptr.
891 //Proxy_Ptr(const T &t) : mT( const_cast<T &>(t) )
892 Cm_Ptr(T * pt) : mpT(pt)
893 {
894 }
895
896 T *& get()
897 {
898 return mpT;
899 }
900
901 void read(SerializationProtocolIn &in)
902 {
903 RCF_UNUSED_VARIABLE(in);
904 }
905
906 void write(SerializationProtocolOut &out)
907 {
908 serialize(out, mpT);
909 }
910
911 private:
912 T * mpT;
913 };
914
915 template<typename CRefT>
916 class Cm_CRef
917 {
918 public:
919
920 typedef typename RemoveReference<CRefT>::type CT;
921 typedef typename RemoveCv<CT>::type T;
922 BOOST_MPL_ASSERT(( IsReference<CRefT> ));
923
924 BOOST_MPL_ASSERT(( IsConst<CT> ));
925
926 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
927
928 Cm_CRef(const T &t) : mT(t)
929 {}
930
931 const T &get()
932 {
933 return mT;
934 }
935
936 void read(SerializationProtocolIn &in)
937 {
938 RCF_UNUSED_VARIABLE(in);
939 }
940
941 void write(SerializationProtocolOut &out)
942 {
943 int ver = out.getRuntimeVersion();
944 if (ver < 8)
945 {
946 serialize(out, &mT);
947 }
948 else if (ver == 8)
949 {
950 serialize(out, mT);
951 }
952 else if (ver >= 9)
953 {
954 serialize(out, &mT);
955 }
956 }
957
958 private:
959 const T &mT;
960 };
961
962 template<typename RefT>
963 class Cm_Ref
964 {
965 public:
966
967 typedef typename RemoveReference<RefT>::type T;
968 BOOST_MPL_ASSERT(( IsReference<RefT> ));
969 BOOST_MPL_ASSERT(( boost::mpl::not_< IsConst<RefT> > ));
970 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
971
972 Cm_Ref(T &t) : mT(t)
973 {}
974
975 T &get()
976 {
977 return mT;
978 }
979
980 void read(SerializationProtocolIn &in)
981 {
982 if (in.getRemainingArchiveLength() != 0)
983 {
984 if (!deserializeOverride(in, mT))
985 {
986 deserialize(in, mT);
987 }
988 }
989 }
990
991 void write(SerializationProtocolOut &out)
992 {
993 int ver = out.getRuntimeVersion();
994 if (ver < 8)
995 {
996 serialize(out, &mT);
997 }
998 else if (ver == 8)
999 {
1000 serialize(out, mT);
1001 }
1002 else if (ver >= 9)
1003 {
1004 serialize(out, &mT);
1005 }
1006 }
1007
1008 private:
1009 T & mT;
1010 };
1011
1012 template<typename OutRefT>
1013 class Cm_OutRef
1014 {
1015 public:
1016
1017 typedef typename RemoveOut<OutRefT>::type RefT;
1018 typedef typename RemoveReference<RefT>::type T;
1019 BOOST_MPL_ASSERT(( IsReference<RefT> ));
1020 BOOST_MPL_ASSERT(( boost::mpl::not_< IsConst<RefT> > ));
1021 BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
1022
1023 Cm_OutRef(T &t) : mT(t)
1024 {}
1025
1026 T &get()
1027 {
1028 return mT;
1029 }
1030
1031 void read(SerializationProtocolIn &in)
1032 {
1033 if (in.getRemainingArchiveLength() != 0)
1034 {
1035 if (!deserializeOverride(in, mT))
1036 {
1037 deserialize(in, mT);
1038 }
1039 }
1040 }
1041
1042 void write(SerializationProtocolOut &)
1043 {
1044 RCF_ASSERT(0);
1045 }
1046
1047 private:
1048 T &mT;
1049 };
1050
1051 template<typename T>
1052 struct IsConstReference
1053 {
1054 typedef typename
1055 boost::mpl::and_<
1056 IsReference<T>,
1057 IsConst< typename RemoveReference<T>::type >
1058 >::type type;
1059
1060 enum { value = type::value };
1061 };
1062
1063 template<typename T>
1064 struct ServerMarshalRet
1065 {
1066 typedef typename
1067 boost::mpl::if_<
1068 boost::is_same<void, T>,
1069 Sm_Ret<Void>,
1070 Sm_Ret<T> >::type type;
1071 };
1072
1073 template<typename T>
1074 struct ServerMarshal
1075 {
1076 typedef typename
1077 boost::mpl::if_<
1078 IsPointer<T>,
1079 Sm_Ptr<T>,
1080 typename boost::mpl::if_<
1081 IsConstReference<T>,
1082 Sm_CRef<T>,
1083 typename boost::mpl::if_<
1084 IsReference<T>,
1085 Sm_Ref<T>,
1086 typename boost::mpl::if_<
1087 IsOut<T>,
1088 Sm_OutRef<T>,
1089 Sm_Value<T>
1090 >::type
1091
1092
1093
1094 >::type
1095 >::type
1096 >::type type;
1097 };
1098
1099 template<typename T>
1100 struct ClientMarshal
1101 {
1102 typedef typename
1103 boost::mpl::if_<
1104 IsPointer<T>,
1105 Cm_Ptr<T>,
1106 typename boost::mpl::if_<
1107 IsConstReference<T>,
1108 Cm_CRef<T>,
1109 typename boost::mpl::if_<
1110 IsReference<T>,
1111 Cm_Ref<T>,
1112 typename boost::mpl::if_<
1113 IsOut<T>,
1114 Cm_OutRef<T>,
1115 Cm_Value<T>
1116 >::type
1117 >::type
1118 >::type
1119 >::type type;
1120 };
1121
1122
1123 // ReferenceTo:
1124 // For generic T, return const T &.
1125 // For T &, return T &.
1126 // For const T &, return const T &
1127
1128 template<typename T>
1129 struct ReferenceTo
1130 {
1131 typedef typename
1132 boost::mpl::if_<
1133 IsReference<T>,
1134 T,
1135 typename boost::mpl::if_<
1136 RCF::IsConst<T>,
1137 typename boost::add_reference<T>::type,
1138 typename boost::add_reference<
1139 typename boost::add_const<T>::type
1140 >::type
1141 >::type
1142 >::type type;
1143 };
1144
1145 class I_Parameters
1146 {
1147 public:
1148 virtual ~I_Parameters() {}
1149 virtual void read(SerializationProtocolIn &in) = 0;
1150 virtual void write(SerializationProtocolOut &out) = 0;
1151 virtual bool enrolFutures(RCF::ClientStub *pClientStub) = 0;
1152 };
1153
1154 template<typename T>
1155 struct IsInParameter
1156 {
1157 typedef typename boost::mpl::not_< boost::is_same<T,Void> >::type NotVoid;
1158 typedef typename boost::mpl::not_< IsOut<T> >::type NotExplicitOutParameter;
1159
1160 typedef typename boost::mpl::and_<
1161 NotVoid,
1162 NotExplicitOutParameter
1163 >::type type;
1164
1165 enum { value = type::value };
1166 };
1167
1168 template<typename T>
1169 struct IsOutParameter
1170 {
1171 typedef typename
1172 boost::mpl::and_<
1173 IsReference<T>,
1174 boost::mpl::not_<
1175 boost::is_const<
1176 typename RemoveReference<T>::type
1177 >
1178 >
1179 >::type NonConstRef_;
1180
1181 typedef typename IsOut<T>::type ExplicitOutParameter;
1182
1183 // Following construction doesn't compile with VC6 for some reason.
1184
1185 //typedef typename boost::mpl::or_<
1186 // NonConstRef,
1187 // ExplicitOutParameter
1188 //>::type type;
1189
1190 enum { value = NonConstRef_::value || ExplicitOutParameter::value };
1191 };
1192
1193 template<typename T>
1194 struct IsReturnValue
1195 {
1196 typedef typename boost::mpl::not_< boost::is_same<T, Void> >::type type;
1197 enum { value = type::value };
1198 };
1199
1200 class Candidates
1201 {
1202 public:
1203 I_Future * find(const void * pv)
1204 {
1205 I_Future * pFuture = NULL;
1206 for (std::size_t i=0; i<mCandidateList.size(); ++i)
1207 {
1208 if (mCandidateList[i].first == pv)
1209 {
1210 RCF_ASSERT(!pFuture);
1211 pFuture = mCandidateList[i].second;
1212 }
1213 }
1214 return pFuture;
1215 }
1216
1217 void erase(const void * pv)
1218 {
1219 for (std::size_t i=0; i<mCandidateList.size(); ++i)
1220 {
1221 if (mCandidateList[i].first == pv)
1222 {
1223 mCandidateList.erase( mCandidateList.begin() + i );
1224 return;
1225 }
1226 }
1227 RCF_ASSERT(0);
1228 }
1229
1230 void add(const void * pv, I_Future * pFuture)
1231 {
1232 for (std::size_t i=0; i<mCandidateList.size(); ++i)
1233 {
1234 if (mCandidateList[i].first == pv)
1235 {
1236 mCandidateList[i].second = pFuture;
1237 return;
1238 }
1239 }
1240 mCandidateList.push_back( std::make_pair(pv, pFuture) );
1241 }
1242
1243 private:
1244
1245 typedef std::vector< std::pair<const void *, I_Future *> > CandidateList;
1246 CandidateList mCandidateList;
1247 };
1248
1249 //typedef std::vector< std::pair<const void *, I_Future *> > Candidates;
1250
1251 RCF_EXPORT Mutex & gCandidatesMutex();
1252 RCF_EXPORT Candidates & gCandidates();
1253
1254 template<
1255 typename R,
1256 typename A1,
1257 typename A2,
1258 typename A3,
1259 typename A4,
1260 typename A5,
1261 typename A6,
1262 typename A7,
1263 typename A8,
1264 typename A9,
1265 typename A10,
1266 typename A11,
1267 typename A12,
1268 typename A13,
1269 typename A14,
1270 typename A15>
1271 class ClientParameters : public I_Parameters
1272 {
1273 public:
1274
1275 typedef typename RemoveOut<A1 >::type A1_;
1276 typedef typename RemoveOut<A2 >::type A2_;
1277 typedef typename RemoveOut<A3 >::type A3_;
1278 typedef typename RemoveOut<A4 >::type A4_;
1279 typedef typename RemoveOut<A5 >::type A5_;
1280 typedef typename RemoveOut<A6 >::type A6_;
1281 typedef typename RemoveOut<A7 >::type A7_;
1282 typedef typename RemoveOut<A8 >::type A8_;
1283 typedef typename RemoveOut<A9 >::type A9_;
1284 typedef typename RemoveOut<A10>::type A10_;
1285 typedef typename RemoveOut<A11>::type A11_;
1286 typedef typename RemoveOut<A12>::type A12_;
1287 typedef typename RemoveOut<A13>::type A13_;
1288 typedef typename RemoveOut<A14>::type A14_;
1289 typedef typename RemoveOut<A15>::type A15_;
1290
1291 typedef typename ReferenceTo<A1_ >::type A1Ref;
1292 typedef typename ReferenceTo<A2_ >::type A2Ref;
1293 typedef typename ReferenceTo<A3_ >::type A3Ref;
1294 typedef typename ReferenceTo<A4_ >::type A4Ref;
1295 typedef typename ReferenceTo<A5_ >::type A5Ref;
1296 typedef typename ReferenceTo<A6_ >::type A6Ref;
1297 typedef typename ReferenceTo<A7_ >::type A7Ref;
1298 typedef typename ReferenceTo<A8_ >::type A8Ref;
1299 typedef typename ReferenceTo<A9_ >::type A9Ref;
1300 typedef typename ReferenceTo<A10_>::type A10Ref;
1301 typedef typename ReferenceTo<A11_>::type A11Ref;
1302 typedef typename ReferenceTo<A12_>::type A12Ref;
1303 typedef typename ReferenceTo<A13_>::type A13Ref;
1304 typedef typename ReferenceTo<A14_>::type A14Ref;
1305 typedef typename ReferenceTo<A15_>::type A15Ref;
1306
1307 ClientParameters(
1308 A1Ref a1, A2Ref a2, A3Ref a3, A4Ref a4, A5Ref a5, A6Ref a6,
1309 A7Ref a7, A8Ref a8, A9Ref a9, A10Ref a10, A11Ref a11, A12Ref a12,
1310 A13Ref a13, A14Ref a14, A15Ref a15) :
1311 a1(a1), a2(a2), a3(a3), a4(a4), a5(a5), a6(a6), a7(a7), a8(a8),
1312 a9(a9), a10(a10), a11(a11), a12(a12), a13(a13), a14(a14), a15(a15)
1313 {
1314 }
1315
1316 void read(SerializationProtocolIn &in)
1317 {
1318 if (IsReturnValue<R>::value) r.read(in);
1319 if (IsOutParameter<A1 >::value) a1.read(in);
1320 if (IsOutParameter<A2 >::value) a2.read(in);
1321 if (IsOutParameter<A3 >::value) a3.read(in);
1322 if (IsOutParameter<A4 >::value) a4.read(in);
1323 if (IsOutParameter<A5 >::value) a5.read(in);
1324 if (IsOutParameter<A6 >::value) a6.read(in);
1325 if (IsOutParameter<A7 >::value) a7.read(in);
1326 if (IsOutParameter<A8 >::value) a8.read(in);
1327 if (IsOutParameter<A9 >::value) a9.read(in);
1328 if (IsOutParameter<A10>::value) a10.read(in);
1329 if (IsOutParameter<A11>::value) a11.read(in);
1330 if (IsOutParameter<A12>::value) a12.read(in);
1331 if (IsOutParameter<A13>::value) a13.read(in);
1332 if (IsOutParameter<A14>::value) a14.read(in);
1333 if (IsOutParameter<A15>::value) a15.read(in);
1334 }
1335
1336 void write(SerializationProtocolOut &out)
1337 {
1338 if (IsInParameter<A1 >::value) a1.write(out);
1339 if (IsInParameter<A2 >::value) a2.write(out);
1340 if (IsInParameter<A3 >::value) a3.write(out);
1341 if (IsInParameter<A4 >::value) a4.write(out);
1342 if (IsInParameter<A5 >::value) a5.write(out);
1343 if (IsInParameter<A6 >::value) a6.write(out);
1344 if (IsInParameter<A7 >::value) a7.write(out);
1345 if (IsInParameter<A8 >::value) a8.write(out);
1346 if (IsInParameter<A9 >::value) a9.write(out);
1347 if (IsInParameter<A10>::value) a10.write(out);
1348 if (IsInParameter<A11>::value) a11.write(out);
1349 if (IsInParameter<A12>::value) a12.write(out);
1350 if (IsInParameter<A13>::value) a13.write(out);
1351 if (IsInParameter<A14>::value) a14.write(out);
1352 if (IsInParameter<A15>::value) a15.write(out);
1353 }
1354
1355 bool enrolFutures(RCF::ClientStub *pClientStub)
1356 {
1357 bool enrolled = false;
1358
1359 const void * pva[] = {
1360 &a1.get(),
1361 &a2.get(),
1362 &a3.get(),
1363 &a4.get(),
1364 &a5.get(),
1365 &a6.get(),
1366 &a7.get(),
1367 &a8.get(),
1368 &a9.get(),
1369 &a10.get(),
1370 &a11.get(),
1371 &a12.get(),
1372 &a13.get(),
1373 &a14.get(),
1374 &a15.get()
1375 };
1376
1377 for (std::size_t i=0; i<sizeof(pva)/sizeof(pva[0]); ++i)
1378 {
1379 const void *pv = pva[i];
1380 I_Future * pFuture = NULL;
1381
1382 {
1383 Lock lock(gCandidatesMutex());
1384 pFuture = gCandidates().find(pv);
1385 if (pFuture)
1386 {
1387 gCandidates().erase(pv);
1388 }
1389 }
1390
1391 if (pFuture)
1392 {
1393 pClientStub->enrol( pFuture );
1394 enrolled = true;
1395 }
1396 }
1397
1398 return enrolled;
1399 }
1400
1401 Cm_Ret<R> r;
1402 typename ClientMarshal<A1>::type a1;
1403 typename ClientMarshal<A2>::type a2;
1404 typename ClientMarshal<A3>::type a3;
1405 typename ClientMarshal<A4>::type a4;
1406 typename ClientMarshal<A5>::type a5;
1407 typename ClientMarshal<A6>::type a6;
1408 typename ClientMarshal<A7>::type a7;
1409 typename ClientMarshal<A8>::type a8;
1410 typename ClientMarshal<A9>::type a9;
1411 typename ClientMarshal<A10>::type a10;
1412 typename ClientMarshal<A11>::type a11;
1413 typename ClientMarshal<A12>::type a12;
1414 typename ClientMarshal<A13>::type a13;
1415 typename ClientMarshal<A14>::type a14;
1416 typename ClientMarshal<A15>::type a15;
1417 };
1418
1419 template<
1420 typename R,
1421 typename A1,
1422 typename A2,
1423 typename A3,
1424 typename A4,
1425 typename A5,
1426 typename A6,
1427 typename A7,
1428 typename A8,
1429 typename A9,
1430 typename A10,
1431 typename A11,
1432 typename A12,
1433 typename A13,
1434 typename A14,
1435 typename A15>
1436 class AllocateClientParameters
1437 {
1438 public:
1439
1440 typedef typename RemoveOut<A1 >::type A1_;
1441 typedef typename RemoveOut<A2 >::type A2_;
1442 typedef typename RemoveOut<A3 >::type A3_;
1443 typedef typename RemoveOut<A4 >::type A4_;
1444 typedef typename RemoveOut<A5 >::type A5_;
1445 typedef typename RemoveOut<A6 >::type A6_;
1446 typedef typename RemoveOut<A7 >::type A7_;
1447 typedef typename RemoveOut<A8 >::type A8_;
1448 typedef typename RemoveOut<A9 >::type A9_;
1449 typedef typename RemoveOut<A10>::type A10_;
1450 typedef typename RemoveOut<A11>::type A11_;
1451 typedef typename RemoveOut<A12>::type A12_;
1452 typedef typename RemoveOut<A13>::type A13_;
1453 typedef typename RemoveOut<A14>::type A14_;
1454 typedef typename RemoveOut<A15>::type A15_;
1455
1456 typedef typename ReferenceTo<A1_ >::type A1Ref;
1457 typedef typename ReferenceTo<A2_ >::type A2Ref;
1458 typedef typename ReferenceTo<A3_ >::type A3Ref;
1459 typedef typename ReferenceTo<A4_ >::type A4Ref;
1460 typedef typename ReferenceTo<A5_ >::type A5Ref;
1461 typedef typename ReferenceTo<A6_ >::type A6Ref;
1462 typedef typename ReferenceTo<A7_ >::type A7Ref;
1463 typedef typename ReferenceTo<A8_ >::type A8Ref;
1464 typedef typename ReferenceTo<A9_ >::type A9Ref;
1465 typedef typename ReferenceTo<A10_>::type A10Ref;
1466 typedef typename ReferenceTo<A11_>::type A11Ref;
1467 typedef typename ReferenceTo<A12_>::type A12Ref;
1468 typedef typename ReferenceTo<A13_>::type A13Ref;
1469 typedef typename ReferenceTo<A14_>::type A14Ref;
1470 typedef typename ReferenceTo<A15_>::type A15Ref;
1471
1472 typedef ClientParameters<
1473 R,
1474 A1, A2, A3, A4, A5, A6, A7, A8,
1475 A9, A10, A11, A12, A13, A14, A15> ParametersT;
1476
1477 // TODO: unnecessary copy of a* here, if A* is not a reference
1478 ParametersT &operator()(
1479 ClientStub &clientStub,
1480 A1Ref a1,
1481 A2Ref a2,
1482 A3Ref a3,
1483 A4Ref a4,
1484 A5Ref a5,
1485 A6Ref a6,
1486 A7Ref a7,
1487 A8Ref a8,
1488 A9Ref a9,
1489 A10Ref a10,
1490 A11Ref a11,
1491 A12Ref a12,
1492 A13Ref a13,
1493 A14Ref a14,
1494 A15Ref a15) const
1495 {
1496 CurrentClientStubSentry sentry(clientStub);
1497
1498 clientStub.clearParameters();
1499
1500 clientStub.mParametersVec.resize(sizeof(ParametersT));
1501
1502 clientStub.mpParameters = new ( &clientStub.mParametersVec[0] )
1503 ParametersT(
1504 a1,a2,a3,a4,a5,a6,a7,a8,
1505 a9,a10,a11,a12,a13,a14,a15);
1506
1507 return static_cast<ParametersT &>(*clientStub.mpParameters);
1508 }
1509 };
1510
1511 template<
1512 typename R,
1513 typename A1 = Void,
1514 typename A2 = Void,
1515 typename A3 = Void,
1516 typename A4 = Void,
1517 typename A5 = Void,
1518 typename A6 = Void,
1519 typename A7 = Void,
1520 typename A8 = Void,
1521 typename A9 = Void,
1522 typename A10 = Void,
1523 typename A11 = Void,
1524 typename A12 = Void,
1525 typename A13 = Void,
1526 typename A14 = Void,
1527 typename A15 = Void>
1528 class ServerParameters : public I_Parameters
1529 {
1530 public:
1531
1532 ServerParameters(RcfSession &session) :
1533 r(session.mParmsVec[0]),
1534 a1(session.mParmsVec[1]),
1535 a2(session.mParmsVec[2]),
1536 a3(session.mParmsVec[3]),
1537 a4(session.mParmsVec[4]),
1538 a5(session.mParmsVec[5]),
1539 a6(session.mParmsVec[6]),
1540 a7(session.mParmsVec[7]),
1541 a8(session.mParmsVec[8]),
1542 a9(session.mParmsVec[9]),
1543 a10(session.mParmsVec[10]),
1544 a11(session.mParmsVec[11]),
1545 a12(session.mParmsVec[12]),
1546 a13(session.mParmsVec[13]),
1547 a14(session.mParmsVec[14]),
1548 a15(session.mParmsVec[15])
1549 {
1550 read(session.mIn);
1551 }
1552
1553 void read(SerializationProtocolIn &in)
1554 {
1555 if (IsInParameter<A1 >::value) a1.read(in);
1556 if (IsInParameter<A2 >::value) a2.read(in);
1557 if (IsInParameter<A3 >::value) a3.read(in);
1558 if (IsInParameter<A4 >::value) a4.read(in);
1559 if (IsInParameter<A5 >::value) a5.read(in);
1560 if (IsInParameter<A6 >::value) a6.read(in);
1561 if (IsInParameter<A7 >::value) a7.read(in);
1562 if (IsInParameter<A8 >::value) a8.read(in);
1563 if (IsInParameter<A9 >::value) a9.read(in);
1564 if (IsInParameter<A10>::value) a10.read(in);
1565 if (IsInParameter<A11>::value) a11.read(in);
1566 if (IsInParameter<A12>::value) a12.read(in);
1567 if (IsInParameter<A13>::value) a13.read(in);
1568 if (IsInParameter<A14>::value) a14.read(in);
1569 if (IsInParameter<A15>::value) a15.read(in);
1570 }
1571
1572 void write(SerializationProtocolOut &out)
1573 {
1574 if (IsReturnValue<R>::value) r.write(out);
1575 if (IsOutParameter<A1>::value) a1.write(out);
1576 if (IsOutParameter<A2>::value) a2.write(out);
1577 if (IsOutParameter<A3>::value) a3.write(out);
1578 if (IsOutParameter<A4>::value) a4.write(out);
1579 if (IsOutParameter<A5>::value) a5.write(out);
1580 if (IsOutParameter<A6>::value) a6.write(out);
1581 if (IsOutParameter<A7>::value) a7.write(out);
1582 if (IsOutParameter<A8>::value) a8.write(out);
1583 if (IsOutParameter<A9>::value) a9.write(out);
1584 if (IsOutParameter<A10>::value) a10.write(out);
1585 if (IsOutParameter<A11>::value) a11.write(out);
1586 if (IsOutParameter<A12>::value) a12.write(out);
1587 if (IsOutParameter<A13>::value) a13.write(out);
1588 if (IsOutParameter<A14>::value) a14.write(out);
1589 if (IsOutParameter<A15>::value) a15.write(out);
1590 }
1591
1592 // TODO: we shouldn't need this here
1593 bool enrolFutures(RCF::ClientStub *)
1594 {
1595 RCF_ASSERT(0);
1596 return false;
1597 }
1598
1599 typename ServerMarshalRet<R>::type r;
1600 typename ServerMarshal<A1>::type a1;
1601 typename ServerMarshal<A2>::type a2;
1602 typename ServerMarshal<A3>::type a3;
1603 typename ServerMarshal<A4>::type a4;
1604 typename ServerMarshal<A5>::type a5;
1605 typename ServerMarshal<A6>::type a6;
1606 typename ServerMarshal<A7>::type a7;
1607 typename ServerMarshal<A8>::type a8;
1608 typename ServerMarshal<A9>::type a9;
1609 typename ServerMarshal<A10>::type a10;
1610 typename ServerMarshal<A11>::type a11;
1611 typename ServerMarshal<A12>::type a12;
1612 typename ServerMarshal<A13>::type a13;
1613 typename ServerMarshal<A14>::type a14;
1614 typename ServerMarshal<A15>::type a15;
1615 };
1616
1617 typedef boost::shared_ptr<I_Parameters> ParametersPtr;
1618
1619 template<
1620 typename R,
1621 typename A1 = Void,
1622 typename A2 = Void,
1623 typename A3 = Void,
1624 typename A4 = Void,
1625 typename A5 = Void,
1626 typename A6 = Void,
1627 typename A7 = Void,
1628 typename A8 = Void,
1629 typename A9 = Void,
1630 typename A10 = Void,
1631 typename A11 = Void,
1632 typename A12 = Void,
1633 typename A13 = Void,
1634 typename A14 = Void,
1635 typename A15 = Void>
1636 class AllocateServerParameters
1637 {
1638 public:
1639 typedef ServerParameters<
1640 R,
1641 A1, A2, A3, A4, A5, A6, A7, A8,
1642 A9, A10, A11, A12, A13, A14, A15> ParametersT;
1643
1644 ParametersT &operator()(RcfSession &session) const
1645 {
1646 session.clearParameters();
1647
1648 session.mParametersVec.resize(sizeof(ParametersT));
1649
1650 session.mpParameters = new
1651 ( &session.mParametersVec[0] )
1652 ParametersT(session);
1653
1654 return static_cast<ParametersT &>(*session.mpParameters);
1655 }
1656 };
1657
1658 // Bidirectional connections - converting between RcfClient and RcfSession.
1659
1660 RCF_EXPORT void convertRcfSessionToRcfClient(
1661 OnCallbackConnectionCreated func,
1662 RemoteCallSemantics rcs = RCF::Twoway);
1663
1664
1665 RCF_EXPORT RcfSessionPtr convertRcfClientToRcfSession(
1666 ClientStub & clientStub,
1667 ServerTransport & serverTransport,
1668 bool keepClientConnection = false);
1669
1670 RCF_EXPORT RcfSessionPtr convertRcfClientToRcfSession(
1671 ClientStub & clientStub,
1672 RcfServer & server,
1673 bool keepClientConnection = false);
1674
1675
1676 template<typename RcfClientT>
1677 inline RcfSessionPtr convertRcfClientToRcfSession(
1678 RcfClientT & client,
1679 RcfServer & server,
1680 bool keepClientConnection = false)
1681 {
1682 return convertRcfClientToRcfSession(
1683 client.getClientStub(),
1684 server,
1685 keepClientConnection);
1686 }
1687
1688 template<typename RcfClientT>
1689 inline RcfSessionPtr convertRcfClientToRcfSession(
1690 RcfClientT & client,
1691 ServerTransport & serverTransport,
1692 bool keepClientConnection = false)
1693 {
1694 return convertRcfClientToRcfSession(
1695 client.getClientStub(),
1696 serverTransport,
1697 keepClientConnection);
1698 }
1699
1700
1701
1702 RCF_EXPORT void createCallbackConnectionImpl(
1703 ClientStub & client,
1704 ServerTransport & callbackServer);
1705
1706 RCF_EXPORT void createCallbackConnectionImpl(
1707 ClientStub & client,
1708 RcfServer & callbackServer);
1709
1710
1711
1712 template<typename RcfClientT>
1713 void createCallbackConnection(
1714 RcfClientT & client,
1715 RcfServer & callbackServer)
1716 {
1717 createCallbackConnectionImpl(
1718 client.getClientStub(),
1719 callbackServer);
1720 }
1721
1722 template<typename RcfClientT>
1723 void createCallbackConnectionImpl(
1724 RcfClientT & client,
1725 ServerTransport & callbackServer)
1726 {
1727 createCallbackConnection(
1728 client.getClientStub(),
1729 callbackServer);
1730 }
1731
1732 } // namespace RCF
1733
1734 #endif // ! INCLUDE_RCF_MARSHAL_HPP