RCFProto
 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