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 #if RCF_FEATURE_SF==1
46 #include <SF/memory.hpp>
47 #endif
48 
49 #if RCF_FEATURE_BOOST_SERIALIZATION==1
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 #if RCF_FEATURE_BOOST_SERIALIZATION==1
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 #if RCF_FEATURE_BOOST_SERIALIZATION==1
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_FEATURE_BOOST_SERIALIZATION==1
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  // Helper class to ensure delete is called for pointers that we allocate as part of reference marshaling.
342  template<typename T>
343  class Deleter
344  {
345  public:
346  Deleter(T *& pt) : mpt(pt), mDismissed(false)
347  {
348  }
349  ~Deleter()
350  {
351  if ( !mDismissed && mpt )
352  {
353  delete mpt;
354  mpt = NULL;
355  }
356  }
357  void dismiss()
358  {
359  mDismissed = true;
360  }
361  private:
362  T*& mpt;
363  bool mDismissed;
364  };
365 
366 
367  // -------------------------------------------------------------------------
368  // Server marshaling.
369 
370  template<typename T>
371  class Sm_Value
372  {
373  public:
374 
375  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
376  BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));
377 
378  Sm_Value(std::vector<char> & vec) : mPs(vec)
379  {
380  }
381 
382  T &get()
383  {
384  return *mPs;
385  }
386 
387  void set(bool assign, const T &t)
388  {
389  if (assign)
390  {
391  *mPs = t;
392  }
393  }
394 
395  void set(const T &t)
396  {
397  *mPs = t;
398  }
399 
400  void read(SerializationProtocolIn &in)
401  {
402  if (in.getRemainingArchiveLength() != 0)
403  {
404  if (!deserializeOverride(in, *mPs))
405  {
406  deserialize(in, *mPs);
407  }
408  }
409  }
410 
411  void write(SerializationProtocolOut &)
412  {
413  RCF_ASSERT(0);
414  }
415 
416  private:
417  ParmStore<T> mPs;
418  };
419 
420  template<>
421  class Sm_Value<Void>
422  {
423  public:
424 
425  Sm_Value(std::vector<char> &)
426  {
427  }
428 
429  ~Sm_Value()
430  {
431  }
432 
433  Void &get()
434  {
435  RCF_ASSERT(0);
436  static Void v;
437  return v;
438  }
439 
440  void set(bool , const Void &)
441  {
442  RCF_ASSERT(0);
443  }
444 
445  void set(const Void &)
446  {
447  RCF_ASSERT(0);
448  }
449 
450  void read(SerializationProtocolIn &)
451  {
452  RCF_ASSERT(0);
453  }
454 
455  void write(SerializationProtocolOut &)
456  {
457  RCF_ASSERT(0);
458  }
459  };
460 
461  template<typename T>
462  class Sm_Ret
463  {
464  public:
465 
466  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
467  BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));
468 
469  Sm_Ret(std::vector<char> & vec) : mPs(vec)
470  {
471  }
472 
473  T &get()
474  {
475  return *mPs;
476  }
477 
478  void set(bool assign, const T &t)
479  {
480  if (assign)
481  {
482  *mPs = t;
483  }
484  }
485 
486  void set(const T &t)
487  {
488  *mPs = t;
489  }
490 
491  void read(SerializationProtocolIn &)
492  {
493  RCF_ASSERT(0);
494  }
495 
496  void write(SerializationProtocolOut &out)
497  {
498  if (!serializeOverride(out, *mPs))
499  {
500  serialize(out, *mPs);
501  }
502  }
503 
504  private:
505  ParmStore<T> mPs;
506  };
507 
508  template<typename CRefT>
509  class Sm_CRef
510  {
511  public:
512 
513  typedef typename RemoveReference<CRefT>::type CT;
514  typedef typename RemoveCv<CT>::type T;
515  BOOST_MPL_ASSERT(( IsReference<CRefT> ));
516 
517  BOOST_MPL_ASSERT(( IsConst<CT> ));
518 
519  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
520 
521  Sm_CRef(std::vector<char> & vec) : mPs(), mVec(vec)
522  {}
523 
524  T &get()
525  {
526  return *mPs;
527  }
528 
529  void set(bool assign, const T &t)
530  {
531  if (assign)
532  {
533  *mPs = t;
534  }
535  }
536 
537  void set(const T &t)
538  {
539  *mPs = t;
540  }
541 
542  void read(SerializationProtocolIn &in)
543  {
544  if (in.getRemainingArchiveLength() != 0)
545  {
546  int ver = in.getRuntimeVersion();
547  if (ver < 8)
548  {
549  // Deserialize as pointer, which means we may get
550  // polymorphic serialization happening.
551 
552  T *pt = NULL;
553  Deleter<T> deleter(pt);
554  deserialize(in, pt);
555  deleter.dismiss();
556  mPs.assign(pt);
557  }
558  else if (ver == 8)
559  {
560  // Deserialize as value.
561  mPs.allocate(mVec);
562  deserialize(in, *mPs);
563  }
564  else if (ver >= 9)
565  {
566  // If BSer, deserialize through pointer.
567  // If SF and caching disabled, deserialize through pointer.
568  // If SF and caching enabled, use object cache and deserialize through value.
569 
570  int sp = in.getSerializationProtocol();
571  if ( (sp == Sp_SfBinary || sp == Sp_SfText)
572  && getObjectPool().isCachingEnabled( (T *) NULL ))
573  {
574  mPs.allocate(mVec);
575  deserialize(in, *mPs);
576  }
577  else
578  {
579  T *pt = NULL;
580  Deleter<T> deleter(pt);
581  deserialize(in, pt);
582  if (!pt)
583  {
584  RCF::Exception e(RCF::_RcfError_DeserializationNullPointer());
585  RCF_THROW(e);
586  }
587  deleter.dismiss();
588  mPs.assign(pt);
589  }
590  }
591  }
592  else
593  {
594  mPs.allocate(mVec);
595  }
596  }
597 
598  void write(SerializationProtocolOut &)
599  {
600  RCF_ASSERT(0);
601  }
602 
603  private:
604  ParmStore<T> mPs;
605  std::vector<char> & mVec;
606  };
607 
608  template<typename RefT>
609  class Sm_Ref
610  {
611  public:
612 
613  typedef typename RemoveReference<RefT>::type T;
614  typedef typename RemoveCv<T>::type U;
615  BOOST_MPL_ASSERT(( IsReference<RefT> ));
616  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
617 
618  Sm_Ref(std::vector<char> & vec) : mVec(vec)
619  {}
620 
621  T &get()
622  {
623  return *mPs;
624  }
625 
626  void set(bool assign, const T &t)
627  {
628  if (assign)
629  {
630  *mPs = t;
631  }
632  }
633 
634  void set(const T &t)
635  {
636  *mPs = t;
637  }
638 
639  void read(SerializationProtocolIn &in)
640  {
641  if (in.getRemainingArchiveLength() != 0)
642  {
643  int ver = in.getRuntimeVersion();
644  if (ver < 8)
645  {
646  // Deserialize as pointer, which means we may get
647  // polymorphic serialization happening.
648 
649  T * pt = NULL;
650  Deleter<T> deleter(pt);
651  deserialize(in, pt);
652  deleter.dismiss();
653  mPs.assign(pt);
654  }
655  else if (ver == 8)
656  {
657  // Deserialize as value.
658 
659  mPs.allocate(mVec);
660  deserialize(in, *mPs);
661  }
662  else if (ver >= 9)
663  {
664  // If BSer, deserialize through pointer.
665  // If SF and caching disabled, deserialize through pointer.
666  // If SF and caching enabled, use object cache and deserialize through value.
667 
668  int sp = in.getSerializationProtocol();
669  if ( (sp == Sp_SfBinary || sp == Sp_SfText)
670  && getObjectPool().isCachingEnabled( (T *) NULL ))
671  {
672  mPs.allocate(mVec);
673  deserialize(in, *mPs);
674  }
675  else
676  {
677  T *pt = NULL;
678  Deleter<T> deleter(pt);
679  deserialize(in, pt);
680  if (!pt)
681  {
682  RCF::Exception e(RCF::_RcfError_DeserializationNullPointer());
683  RCF_THROW(e);
684  }
685  deleter.dismiss();
686  mPs.assign(pt);
687  }
688  }
689  }
690  else
691  {
692  mPs.allocate(mVec);
693  }
694  }
695 
696  void write(SerializationProtocolOut &out)
697  {
698  RCF_ASSERT(mPs.get());
699 
700  if (!serializeOverride(out, *mPs))
701  {
702  // B.Ser. issues - because the client side proxy for a T& has to
703  // deserialize itself as a value, here we have to serialize as a
704  // value.
705 
706  serialize(out, *mPs);
707  }
708  }
709 
710  private:
711  ParmStore<T> mPs;
712  std::vector<char> & mVec;
713  };
714 
715  template<typename OutRefT>
716  class Sm_OutRef
717  {
718  public:
719 
720  typedef typename RemoveOut<OutRefT>::type RefT;
721  typedef typename RemoveReference<RefT>::type T;
722  typedef typename RemoveCv<T>::type U;
723  BOOST_MPL_ASSERT(( IsReference<RefT> ));
724  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
725 
726  Sm_OutRef(std::vector<char> & vec) : mPs(vec)
727  {
728  }
729 
730  T &get()
731  {
732  return *mPs;
733  }
734 
735  void set(bool assign, const T &t)
736  {
737  if (assign)
738  {
739  *mPs = t;
740  }
741  }
742 
743  void set(const T &t)
744  {
745  *mPs = t;
746  }
747 
748  void read(SerializationProtocolIn &)
749  {
750  RCF_ASSERT(0);
751  }
752 
753  void write(SerializationProtocolOut &out)
754  {
755  if (!serializeOverride(out, *mPs))
756  {
757  // B.Ser. issues - because the client side proxy for a T& has to
758  // deserialize itself as a value, here we have to serialize as a
759  // value.
760 
761  serialize(out, *mPs);
762  }
763  }
764 
765  private:
766  ParmStore<T> mPs;
767  };
768 
769  template<typename PtrT>
770  class Sm_Ptr
771  {
772  public:
773 
774  typedef typename RemovePointer<PtrT>::type T;
775  typedef typename RemoveCv<T>::type U;
776  BOOST_MPL_ASSERT(( IsPointer<PtrT> ));
777  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
778 
779  Sm_Ptr(std::vector<char> &)
780  {}
781 
782  T *get()
783  {
784  return mPs.get();
785  }
786 
787  void set(bool assign, const T &t)
788  {
789  if (assign)
790  {
791  *mPs = t;
792  }
793  }
794 
795  void set(const T &t)
796  {
797  *mPs = t;
798  }
799 
800  void read(SerializationProtocolIn &in)
801  {
802  if (in.getRemainingArchiveLength() != 0)
803  {
804  T *pt = NULL;
805  Deleter<T> deleter(pt);
806  deserialize(in, pt);
807  deleter.dismiss();
808  mPs.assign(pt);
809  }
810  }
811 
812  void write(SerializationProtocolOut &)
813  {
814  RCF_ASSERT(0);
815  }
816 
817  private:
818  ParmStore<T> mPs;
819  };
820 
821  // -------------------------------------------------------------------------
822  // Client marshaling.
823 
824  template<typename T>
825  class Cm_Ret
826  {
827  public:
828 
829  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
830  BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));
831 
832  Cm_Ret()
833  {
834  RCF::ClientStub * pClientStub = getTlsClientStubPtr();
835  std::vector<char> & vec = pClientStub->getRetValVec();
836  mPs.allocate(vec);
837  }
838 
839  T &get()
840  {
841  return *mPs;
842  }
843 
844  void set(bool assign, const T &t)
845  {
846  if (assign)
847  {
848  *mPs = t;
849  }
850  }
851 
852  void set(const T &t)
853  {
854  *mPs = t;
855  }
856 
857  void read(SerializationProtocolIn &in)
858  {
859  if (in.getRemainingArchiveLength() != 0)
860  {
861  if (!deserializeOverride(in, *mPs))
862  {
863  deserialize(in, *mPs);
864  }
865  }
866  }
867 
868  void write(SerializationProtocolOut &)
869  {
870  RCF_ASSERT(0);
871  }
872 
873  private:
874  ParmStore<T> mPs;
875  };
876 
877  template<typename T>
878  class Cm_Value
879  {
880  public:
881 
882  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
883  BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));
884 
885  // We use const_cast here, in case T's copy constructor is non-const.
886  // E.g. if T is a std::auto_ptr.
887  Cm_Value(const T &t) : mT( const_cast<T &>(t) )
888  {
889  }
890 
891  const T &get()
892  {
893  return mT;
894  }
895 
896  void read(SerializationProtocolIn &in)
897  {
898  RCF_UNUSED_VARIABLE(in);
899  }
900 
901  void write(SerializationProtocolOut &out)
902  {
903  if (!serializeOverride(out, mT))
904  {
905  serialize(out, mT);
906  }
907  }
908 
909  private:
910  T mT;
911  };
912 
913  template<typename PtrT>
914  class Cm_Ptr
915  {
916  public:
917 
918  typedef typename RemovePointer<PtrT>::type T;
919 
920  BOOST_MPL_ASSERT(( IsPointer<PtrT> ));
921 
922  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
923 
924  // We use const_cast here, in case T's copy constructor is non-const.
925  // E.g. if T is a std::auto_ptr.
926  //Proxy_Ptr(const T &t) : mT( const_cast<T &>(t) )
927  Cm_Ptr(T * pt) : mpT(pt)
928  {
929  }
930 
931  T *& get()
932  {
933  return mpT;
934  }
935 
936  void read(SerializationProtocolIn &in)
937  {
938  RCF_UNUSED_VARIABLE(in);
939  }
940 
941  void write(SerializationProtocolOut &out)
942  {
943  serialize(out, mpT);
944  }
945 
946  private:
947  T * mpT;
948  };
949 
950  template<typename CRefT>
951  class Cm_CRef
952  {
953  public:
954 
955  typedef typename RemoveReference<CRefT>::type CT;
956  typedef typename RemoveCv<CT>::type T;
957  BOOST_MPL_ASSERT(( IsReference<CRefT> ));
958 
959  BOOST_MPL_ASSERT(( IsConst<CT> ));
960 
961  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
962 
963  Cm_CRef(const T &t) : mT(t)
964  {}
965 
966  const T &get()
967  {
968  return mT;
969  }
970 
971  void read(SerializationProtocolIn &in)
972  {
973  RCF_UNUSED_VARIABLE(in);
974  }
975 
976  void write(SerializationProtocolOut &out)
977  {
978  int ver = out.getRuntimeVersion();
979  if (ver < 8)
980  {
981  serialize(out, &mT);
982  }
983  else if (ver == 8)
984  {
985  serialize(out, mT);
986  }
987  else if (ver >= 9)
988  {
989  serialize(out, &mT);
990  }
991  }
992 
993  private:
994  const T &mT;
995  };
996 
997  template<typename RefT>
998  class Cm_Ref
999  {
1000  public:
1001 
1002  typedef typename RemoveReference<RefT>::type T;
1003  BOOST_MPL_ASSERT(( IsReference<RefT> ));
1004  BOOST_MPL_ASSERT(( boost::mpl::not_< IsConst<RefT> > ));
1005  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
1006 
1007  Cm_Ref(T &t) : mT(t)
1008  {}
1009 
1010  T &get()
1011  {
1012  return mT;
1013  }
1014 
1015  void read(SerializationProtocolIn &in)
1016  {
1017  if (in.getRemainingArchiveLength() != 0)
1018  {
1019  if (!deserializeOverride(in, mT))
1020  {
1021  deserialize(in, mT);
1022  }
1023  }
1024  }
1025 
1026  void write(SerializationProtocolOut &out)
1027  {
1028  int ver = out.getRuntimeVersion();
1029  if (ver < 8)
1030  {
1031  serialize(out, &mT);
1032  }
1033  else if (ver == 8)
1034  {
1035  serialize(out, mT);
1036  }
1037  else if (ver >= 9)
1038  {
1039  serialize(out, &mT);
1040  }
1041  }
1042 
1043  private:
1044  T & mT;
1045  };
1046 
1047  template<typename OutRefT>
1048  class Cm_OutRef
1049  {
1050  public:
1051 
1052  typedef typename RemoveOut<OutRefT>::type RefT;
1053  typedef typename RemoveReference<RefT>::type T;
1054  BOOST_MPL_ASSERT(( IsReference<RefT> ));
1055  BOOST_MPL_ASSERT(( boost::mpl::not_< IsConst<RefT> > ));
1056  BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
1057 
1058  Cm_OutRef(T &t) : mT(t)
1059  {}
1060 
1061  T &get()
1062  {
1063  return mT;
1064  }
1065 
1066  void read(SerializationProtocolIn &in)
1067  {
1068  if (in.getRemainingArchiveLength() != 0)
1069  {
1070  if (!deserializeOverride(in, mT))
1071  {
1072  deserialize(in, mT);
1073  }
1074  }
1075  }
1076 
1077  void write(SerializationProtocolOut &)
1078  {
1079  RCF_ASSERT(0);
1080  }
1081 
1082  private:
1083  T &mT;
1084  };
1085 
1086  template<typename T>
1087  struct IsConstReference
1088  {
1089  typedef typename
1090  boost::mpl::and_<
1091  IsReference<T>,
1092  IsConst< typename RemoveReference<T>::type >
1093  >::type type;
1094 
1095  enum { value = type::value };
1096  };
1097 
1098  template<typename T>
1099  struct ServerMarshalRet
1100  {
1101  typedef typename
1102  boost::mpl::if_<
1103  boost::is_same<void, T>,
1104  Sm_Ret<Void>,
1105  Sm_Ret<T> >::type type;
1106  };
1107 
1108  template<typename T>
1109  struct ServerMarshal
1110  {
1111  typedef typename
1112  boost::mpl::if_<
1113  IsPointer<T>,
1114  Sm_Ptr<T>,
1115  typename boost::mpl::if_<
1116  IsConstReference<T>,
1117  Sm_CRef<T>,
1118  typename boost::mpl::if_<
1119  IsReference<T>,
1120  Sm_Ref<T>,
1121  typename boost::mpl::if_<
1122  IsOut<T>,
1123  Sm_OutRef<T>,
1124  Sm_Value<T>
1125  >::type
1126 
1127 
1128 
1129  >::type
1130  >::type
1131  >::type type;
1132  };
1133 
1134  template<typename T>
1135  struct ClientMarshal
1136  {
1137  typedef typename
1138  boost::mpl::if_<
1139  IsPointer<T>,
1140  Cm_Ptr<T>,
1141  typename boost::mpl::if_<
1142  IsConstReference<T>,
1143  Cm_CRef<T>,
1144  typename boost::mpl::if_<
1145  IsReference<T>,
1146  Cm_Ref<T>,
1147  typename boost::mpl::if_<
1148  IsOut<T>,
1149  Cm_OutRef<T>,
1150  Cm_Value<T>
1151  >::type
1152  >::type
1153  >::type
1154  >::type type;
1155  };
1156 
1157 
1158  // ReferenceTo:
1159  // For generic T, return const T &.
1160  // For T &, return T &.
1161  // For const T &, return const T &
1162 
1163  template<typename T>
1164  struct ReferenceTo
1165  {
1166  typedef typename
1167  boost::mpl::if_<
1168  IsReference<T>,
1169  T,
1170  typename boost::mpl::if_<
1171  RCF::IsConst<T>,
1172  typename boost::add_reference<T>::type,
1173  typename boost::add_reference<
1174  typename boost::add_const<T>::type
1175  >::type
1176  >::type
1177  >::type type;
1178  };
1179 
1180  class I_Parameters
1181  {
1182  public:
1183  virtual ~I_Parameters() {}
1184  virtual void read(SerializationProtocolIn &in) = 0;
1185  virtual void write(SerializationProtocolOut &out) = 0;
1186  virtual bool enrolFutures(RCF::ClientStub *pClientStub) = 0;
1187  };
1188 
1189  template<typename T>
1190  struct IsInParameter
1191  {
1192  typedef typename boost::mpl::not_< boost::is_same<T,Void> >::type NotVoid;
1193  typedef typename boost::mpl::not_< IsOut<T> >::type NotExplicitOutParameter;
1194 
1195  typedef typename boost::mpl::and_<
1196  NotVoid,
1197  NotExplicitOutParameter
1198  >::type type;
1199 
1200  enum { value = type::value };
1201  };
1202 
1203  template<typename T>
1204  struct IsOutParameter
1205  {
1206  typedef typename
1207  boost::mpl::and_<
1208  IsReference<T>,
1209  boost::mpl::not_<
1210  boost::is_const<
1211  typename RemoveReference<T>::type
1212  >
1213  >
1214  >::type NonConstRef_;
1215 
1216  typedef typename IsOut<T>::type ExplicitOutParameter;
1217 
1218  // Following construction doesn't compile with VC6 for some reason.
1219 
1220  //typedef typename boost::mpl::or_<
1221  // NonConstRef,
1222  // ExplicitOutParameter
1223  //>::type type;
1224 
1225  enum { value = NonConstRef_::value || ExplicitOutParameter::value };
1226  };
1227 
1228  template<typename T>
1229  struct IsReturnValue
1230  {
1231  typedef typename boost::mpl::not_< boost::is_same<T, Void> >::type type;
1232  enum { value = type::value };
1233  };
1234 
1235  class Candidates
1236  {
1237  public:
1238  I_Future * find(const void * pv)
1239  {
1240  I_Future * pFuture = NULL;
1241  for (std::size_t i=0; i<mCandidateList.size(); ++i)
1242  {
1243  if (mCandidateList[i].first == pv)
1244  {
1245  RCF_ASSERT(!pFuture);
1246  pFuture = mCandidateList[i].second;
1247  }
1248  }
1249  return pFuture;
1250  }
1251 
1252  void erase(const void * pv)
1253  {
1254  for (std::size_t i=0; i<mCandidateList.size(); ++i)
1255  {
1256  if (mCandidateList[i].first == pv)
1257  {
1258  mCandidateList.erase( mCandidateList.begin() + i );
1259  return;
1260  }
1261  }
1262  RCF_ASSERT(0);
1263  }
1264 
1265  void add(const void * pv, I_Future * pFuture)
1266  {
1267  for (std::size_t i=0; i<mCandidateList.size(); ++i)
1268  {
1269  if (mCandidateList[i].first == pv)
1270  {
1271  mCandidateList[i].second = pFuture;
1272  return;
1273  }
1274  }
1275  mCandidateList.push_back( std::make_pair(pv, pFuture) );
1276  }
1277 
1278  private:
1279 
1280  typedef std::vector< std::pair<const void *, I_Future *> > CandidateList;
1281  CandidateList mCandidateList;
1282  };
1283 
1284  //typedef std::vector< std::pair<const void *, I_Future *> > Candidates;
1285 
1286  RCF_EXPORT Mutex & gCandidatesMutex();
1287  RCF_EXPORT Candidates & gCandidates();
1288 
1289  template<
1290  typename R,
1291  typename A1,
1292  typename A2,
1293  typename A3,
1294  typename A4,
1295  typename A5,
1296  typename A6,
1297  typename A7,
1298  typename A8,
1299  typename A9,
1300  typename A10,
1301  typename A11,
1302  typename A12,
1303  typename A13,
1304  typename A14,
1305  typename A15>
1306  class ClientParameters : public I_Parameters
1307  {
1308  public:
1309 
1310  typedef typename RemoveOut<A1 >::type A1_;
1311  typedef typename RemoveOut<A2 >::type A2_;
1312  typedef typename RemoveOut<A3 >::type A3_;
1313  typedef typename RemoveOut<A4 >::type A4_;
1314  typedef typename RemoveOut<A5 >::type A5_;
1315  typedef typename RemoveOut<A6 >::type A6_;
1316  typedef typename RemoveOut<A7 >::type A7_;
1317  typedef typename RemoveOut<A8 >::type A8_;
1318  typedef typename RemoveOut<A9 >::type A9_;
1319  typedef typename RemoveOut<A10>::type A10_;
1320  typedef typename RemoveOut<A11>::type A11_;
1321  typedef typename RemoveOut<A12>::type A12_;
1322  typedef typename RemoveOut<A13>::type A13_;
1323  typedef typename RemoveOut<A14>::type A14_;
1324  typedef typename RemoveOut<A15>::type A15_;
1325 
1326  typedef typename ReferenceTo<A1_ >::type A1Ref;
1327  typedef typename ReferenceTo<A2_ >::type A2Ref;
1328  typedef typename ReferenceTo<A3_ >::type A3Ref;
1329  typedef typename ReferenceTo<A4_ >::type A4Ref;
1330  typedef typename ReferenceTo<A5_ >::type A5Ref;
1331  typedef typename ReferenceTo<A6_ >::type A6Ref;
1332  typedef typename ReferenceTo<A7_ >::type A7Ref;
1333  typedef typename ReferenceTo<A8_ >::type A8Ref;
1334  typedef typename ReferenceTo<A9_ >::type A9Ref;
1335  typedef typename ReferenceTo<A10_>::type A10Ref;
1336  typedef typename ReferenceTo<A11_>::type A11Ref;
1337  typedef typename ReferenceTo<A12_>::type A12Ref;
1338  typedef typename ReferenceTo<A13_>::type A13Ref;
1339  typedef typename ReferenceTo<A14_>::type A14Ref;
1340  typedef typename ReferenceTo<A15_>::type A15Ref;
1341 
1342  ClientParameters(
1343  A1Ref a1, A2Ref a2, A3Ref a3, A4Ref a4, A5Ref a5, A6Ref a6,
1344  A7Ref a7, A8Ref a8, A9Ref a9, A10Ref a10, A11Ref a11, A12Ref a12,
1345  A13Ref a13, A14Ref a14, A15Ref a15) :
1346  a1(a1), a2(a2), a3(a3), a4(a4), a5(a5), a6(a6), a7(a7), a8(a8),
1347  a9(a9), a10(a10), a11(a11), a12(a12), a13(a13), a14(a14), a15(a15)
1348  {
1349  }
1350 
1351  void read(SerializationProtocolIn &in)
1352  {
1353  if (IsReturnValue<R>::value) r.read(in);
1354  if (IsOutParameter<A1 >::value) a1.read(in);
1355  if (IsOutParameter<A2 >::value) a2.read(in);
1356  if (IsOutParameter<A3 >::value) a3.read(in);
1357  if (IsOutParameter<A4 >::value) a4.read(in);
1358  if (IsOutParameter<A5 >::value) a5.read(in);
1359  if (IsOutParameter<A6 >::value) a6.read(in);
1360  if (IsOutParameter<A7 >::value) a7.read(in);
1361  if (IsOutParameter<A8 >::value) a8.read(in);
1362  if (IsOutParameter<A9 >::value) a9.read(in);
1363  if (IsOutParameter<A10>::value) a10.read(in);
1364  if (IsOutParameter<A11>::value) a11.read(in);
1365  if (IsOutParameter<A12>::value) a12.read(in);
1366  if (IsOutParameter<A13>::value) a13.read(in);
1367  if (IsOutParameter<A14>::value) a14.read(in);
1368  if (IsOutParameter<A15>::value) a15.read(in);
1369  }
1370 
1371  void write(SerializationProtocolOut &out)
1372  {
1373  if (IsInParameter<A1 >::value) a1.write(out);
1374  if (IsInParameter<A2 >::value) a2.write(out);
1375  if (IsInParameter<A3 >::value) a3.write(out);
1376  if (IsInParameter<A4 >::value) a4.write(out);
1377  if (IsInParameter<A5 >::value) a5.write(out);
1378  if (IsInParameter<A6 >::value) a6.write(out);
1379  if (IsInParameter<A7 >::value) a7.write(out);
1380  if (IsInParameter<A8 >::value) a8.write(out);
1381  if (IsInParameter<A9 >::value) a9.write(out);
1382  if (IsInParameter<A10>::value) a10.write(out);
1383  if (IsInParameter<A11>::value) a11.write(out);
1384  if (IsInParameter<A12>::value) a12.write(out);
1385  if (IsInParameter<A13>::value) a13.write(out);
1386  if (IsInParameter<A14>::value) a14.write(out);
1387  if (IsInParameter<A15>::value) a15.write(out);
1388  }
1389 
1390  bool enrolFutures(RCF::ClientStub *pClientStub)
1391  {
1392  bool enrolled = false;
1393 
1394  const void * pva[] = {
1395  &a1.get(),
1396  &a2.get(),
1397  &a3.get(),
1398  &a4.get(),
1399  &a5.get(),
1400  &a6.get(),
1401  &a7.get(),
1402  &a8.get(),
1403  &a9.get(),
1404  &a10.get(),
1405  &a11.get(),
1406  &a12.get(),
1407  &a13.get(),
1408  &a14.get(),
1409  &a15.get()
1410  };
1411 
1412  for (std::size_t i=0; i<sizeof(pva)/sizeof(pva[0]); ++i)
1413  {
1414  const void *pv = pva[i];
1415  I_Future * pFuture = NULL;
1416 
1417  {
1418  Lock lock(gCandidatesMutex());
1419  pFuture = gCandidates().find(pv);
1420  if (pFuture)
1421  {
1422  gCandidates().erase(pv);
1423  }
1424  }
1425 
1426  if (pFuture)
1427  {
1428  pClientStub->enrol( pFuture );
1429  enrolled = true;
1430  }
1431  }
1432 
1433  return enrolled;
1434  }
1435 
1436  Cm_Ret<R> r;
1437  typename ClientMarshal<A1>::type a1;
1438  typename ClientMarshal<A2>::type a2;
1439  typename ClientMarshal<A3>::type a3;
1440  typename ClientMarshal<A4>::type a4;
1441  typename ClientMarshal<A5>::type a5;
1442  typename ClientMarshal<A6>::type a6;
1443  typename ClientMarshal<A7>::type a7;
1444  typename ClientMarshal<A8>::type a8;
1445  typename ClientMarshal<A9>::type a9;
1446  typename ClientMarshal<A10>::type a10;
1447  typename ClientMarshal<A11>::type a11;
1448  typename ClientMarshal<A12>::type a12;
1449  typename ClientMarshal<A13>::type a13;
1450  typename ClientMarshal<A14>::type a14;
1451  typename ClientMarshal<A15>::type a15;
1452  };
1453 
1454  template<
1455  typename R,
1456  typename A1,
1457  typename A2,
1458  typename A3,
1459  typename A4,
1460  typename A5,
1461  typename A6,
1462  typename A7,
1463  typename A8,
1464  typename A9,
1465  typename A10,
1466  typename A11,
1467  typename A12,
1468  typename A13,
1469  typename A14,
1470  typename A15>
1471  class AllocateClientParameters
1472  {
1473  public:
1474 
1475  typedef typename RemoveOut<A1 >::type A1_;
1476  typedef typename RemoveOut<A2 >::type A2_;
1477  typedef typename RemoveOut<A3 >::type A3_;
1478  typedef typename RemoveOut<A4 >::type A4_;
1479  typedef typename RemoveOut<A5 >::type A5_;
1480  typedef typename RemoveOut<A6 >::type A6_;
1481  typedef typename RemoveOut<A7 >::type A7_;
1482  typedef typename RemoveOut<A8 >::type A8_;
1483  typedef typename RemoveOut<A9 >::type A9_;
1484  typedef typename RemoveOut<A10>::type A10_;
1485  typedef typename RemoveOut<A11>::type A11_;
1486  typedef typename RemoveOut<A12>::type A12_;
1487  typedef typename RemoveOut<A13>::type A13_;
1488  typedef typename RemoveOut<A14>::type A14_;
1489  typedef typename RemoveOut<A15>::type A15_;
1490 
1491  typedef typename ReferenceTo<A1_ >::type A1Ref;
1492  typedef typename ReferenceTo<A2_ >::type A2Ref;
1493  typedef typename ReferenceTo<A3_ >::type A3Ref;
1494  typedef typename ReferenceTo<A4_ >::type A4Ref;
1495  typedef typename ReferenceTo<A5_ >::type A5Ref;
1496  typedef typename ReferenceTo<A6_ >::type A6Ref;
1497  typedef typename ReferenceTo<A7_ >::type A7Ref;
1498  typedef typename ReferenceTo<A8_ >::type A8Ref;
1499  typedef typename ReferenceTo<A9_ >::type A9Ref;
1500  typedef typename ReferenceTo<A10_>::type A10Ref;
1501  typedef typename ReferenceTo<A11_>::type A11Ref;
1502  typedef typename ReferenceTo<A12_>::type A12Ref;
1503  typedef typename ReferenceTo<A13_>::type A13Ref;
1504  typedef typename ReferenceTo<A14_>::type A14Ref;
1505  typedef typename ReferenceTo<A15_>::type A15Ref;
1506 
1507  typedef ClientParameters<
1508  R,
1509  A1, A2, A3, A4, A5, A6, A7, A8,
1510  A9, A10, A11, A12, A13, A14, A15> ParametersT;
1511 
1512  // TODO: unnecessary copy of a* here, if A* is not a reference
1513  ParametersT &operator()(
1514  ClientStub &clientStub,
1515  A1Ref a1,
1516  A2Ref a2,
1517  A3Ref a3,
1518  A4Ref a4,
1519  A5Ref a5,
1520  A6Ref a6,
1521  A7Ref a7,
1522  A8Ref a8,
1523  A9Ref a9,
1524  A10Ref a10,
1525  A11Ref a11,
1526  A12Ref a12,
1527  A13Ref a13,
1528  A14Ref a14,
1529  A15Ref a15) const
1530  {
1531  CurrentClientStubSentry sentry(clientStub);
1532 
1533  clientStub.clearParameters();
1534 
1535  clientStub.mParametersVec.resize(sizeof(ParametersT));
1536 
1537  clientStub.mpParameters = new ( &clientStub.mParametersVec[0] )
1538  ParametersT(
1539  a1,a2,a3,a4,a5,a6,a7,a8,
1540  a9,a10,a11,a12,a13,a14,a15);
1541 
1542  if (!clientStub.mpParameters)
1543  {
1544  Exception e(_RcfError_ClientStubParms());
1545  RCF_THROW(e);
1546  }
1547 
1548  return static_cast<ParametersT &>(*clientStub.mpParameters);
1549  }
1550  };
1551 
1552  template<
1553  typename R,
1554  typename A1 = Void,
1555  typename A2 = Void,
1556  typename A3 = Void,
1557  typename A4 = Void,
1558  typename A5 = Void,
1559  typename A6 = Void,
1560  typename A7 = Void,
1561  typename A8 = Void,
1562  typename A9 = Void,
1563  typename A10 = Void,
1564  typename A11 = Void,
1565  typename A12 = Void,
1566  typename A13 = Void,
1567  typename A14 = Void,
1568  typename A15 = Void>
1569  class ServerParameters : public I_Parameters
1570  {
1571  public:
1572 
1573  ServerParameters(RcfSession &session) :
1574  r(session.mParmsVec[0]),
1575  a1(session.mParmsVec[1]),
1576  a2(session.mParmsVec[2]),
1577  a3(session.mParmsVec[3]),
1578  a4(session.mParmsVec[4]),
1579  a5(session.mParmsVec[5]),
1580  a6(session.mParmsVec[6]),
1581  a7(session.mParmsVec[7]),
1582  a8(session.mParmsVec[8]),
1583  a9(session.mParmsVec[9]),
1584  a10(session.mParmsVec[10]),
1585  a11(session.mParmsVec[11]),
1586  a12(session.mParmsVec[12]),
1587  a13(session.mParmsVec[13]),
1588  a14(session.mParmsVec[14]),
1589  a15(session.mParmsVec[15])
1590  {
1591  read(session.mIn);
1592  }
1593 
1594  void read(SerializationProtocolIn &in)
1595  {
1596  if (IsInParameter<A1 >::value) a1.read(in);
1597  if (IsInParameter<A2 >::value) a2.read(in);
1598  if (IsInParameter<A3 >::value) a3.read(in);
1599  if (IsInParameter<A4 >::value) a4.read(in);
1600  if (IsInParameter<A5 >::value) a5.read(in);
1601  if (IsInParameter<A6 >::value) a6.read(in);
1602  if (IsInParameter<A7 >::value) a7.read(in);
1603  if (IsInParameter<A8 >::value) a8.read(in);
1604  if (IsInParameter<A9 >::value) a9.read(in);
1605  if (IsInParameter<A10>::value) a10.read(in);
1606  if (IsInParameter<A11>::value) a11.read(in);
1607  if (IsInParameter<A12>::value) a12.read(in);
1608  if (IsInParameter<A13>::value) a13.read(in);
1609  if (IsInParameter<A14>::value) a14.read(in);
1610  if (IsInParameter<A15>::value) a15.read(in);
1611  }
1612 
1613  void write(SerializationProtocolOut &out)
1614  {
1615  if (IsReturnValue<R>::value) r.write(out);
1616  if (IsOutParameter<A1>::value) a1.write(out);
1617  if (IsOutParameter<A2>::value) a2.write(out);
1618  if (IsOutParameter<A3>::value) a3.write(out);
1619  if (IsOutParameter<A4>::value) a4.write(out);
1620  if (IsOutParameter<A5>::value) a5.write(out);
1621  if (IsOutParameter<A6>::value) a6.write(out);
1622  if (IsOutParameter<A7>::value) a7.write(out);
1623  if (IsOutParameter<A8>::value) a8.write(out);
1624  if (IsOutParameter<A9>::value) a9.write(out);
1625  if (IsOutParameter<A10>::value) a10.write(out);
1626  if (IsOutParameter<A11>::value) a11.write(out);
1627  if (IsOutParameter<A12>::value) a12.write(out);
1628  if (IsOutParameter<A13>::value) a13.write(out);
1629  if (IsOutParameter<A14>::value) a14.write(out);
1630  if (IsOutParameter<A15>::value) a15.write(out);
1631  }
1632 
1633  // TODO: we shouldn't need this here
1634  bool enrolFutures(RCF::ClientStub *)
1635  {
1636  RCF_ASSERT(0);
1637  return false;
1638  }
1639 
1640  typename ServerMarshalRet<R>::type r;
1641  typename ServerMarshal<A1>::type a1;
1642  typename ServerMarshal<A2>::type a2;
1643  typename ServerMarshal<A3>::type a3;
1644  typename ServerMarshal<A4>::type a4;
1645  typename ServerMarshal<A5>::type a5;
1646  typename ServerMarshal<A6>::type a6;
1647  typename ServerMarshal<A7>::type a7;
1648  typename ServerMarshal<A8>::type a8;
1649  typename ServerMarshal<A9>::type a9;
1650  typename ServerMarshal<A10>::type a10;
1651  typename ServerMarshal<A11>::type a11;
1652  typename ServerMarshal<A12>::type a12;
1653  typename ServerMarshal<A13>::type a13;
1654  typename ServerMarshal<A14>::type a14;
1655  typename ServerMarshal<A15>::type a15;
1656  };
1657 
1658  typedef boost::shared_ptr<I_Parameters> ParametersPtr;
1659 
1660  template<
1661  typename R,
1662  typename A1 = Void,
1663  typename A2 = Void,
1664  typename A3 = Void,
1665  typename A4 = Void,
1666  typename A5 = Void,
1667  typename A6 = Void,
1668  typename A7 = Void,
1669  typename A8 = Void,
1670  typename A9 = Void,
1671  typename A10 = Void,
1672  typename A11 = Void,
1673  typename A12 = Void,
1674  typename A13 = Void,
1675  typename A14 = Void,
1676  typename A15 = Void>
1677  class AllocateServerParameters
1678  {
1679  public:
1680  typedef ServerParameters<
1681  R,
1682  A1, A2, A3, A4, A5, A6, A7, A8,
1683  A9, A10, A11, A12, A13, A14, A15> ParametersT;
1684 
1685  ParametersT &operator()(RcfSession &session) const
1686  {
1687  session.clearParameters();
1688 
1689  session.mParametersVec.resize(sizeof(ParametersT));
1690 
1691  session.mpParameters = new
1692  ( &session.mParametersVec[0] )
1693  ParametersT(session);
1694 
1695  if (!session.mpParameters)
1696  {
1697  Exception e(_RcfError_ServerStubParms());
1698  RCF_THROW(e);
1699  }
1700 
1701  return static_cast<ParametersT &>(*session.mpParameters);
1702  }
1703  };
1704 
1705  // Bidirectional connections - converting between RcfClient and RcfSession.
1706 
1707  RCF_EXPORT void convertRcfSessionToRcfClient(
1708  OnCallbackConnectionCreated func,
1709  RemoteCallSemantics rcs = RCF::Twoway);
1710 
1711 
1712  RCF_EXPORT RcfSessionPtr convertRcfClientToRcfSession(
1713  ClientStub & clientStub,
1714  ServerTransport & serverTransport,
1715  bool keepClientConnection = false);
1716 
1717  RCF_EXPORT RcfSessionPtr convertRcfClientToRcfSession(
1718  ClientStub & clientStub,
1719  RcfServer & server,
1720  bool keepClientConnection = false);
1721 
1722 
1723  template<typename RcfClientT>
1724  inline RcfSessionPtr convertRcfClientToRcfSession(
1725  RcfClientT & client,
1726  RcfServer & server,
1727  bool keepClientConnection = false)
1728  {
1729  return convertRcfClientToRcfSession(
1730  client.getClientStub(),
1731  server,
1732  keepClientConnection);
1733  }
1734 
1735  template<typename RcfClientT>
1736  inline RcfSessionPtr convertRcfClientToRcfSession(
1737  RcfClientT & client,
1738  ServerTransport & serverTransport,
1739  bool keepClientConnection = false)
1740  {
1741  return convertRcfClientToRcfSession(
1742  client.getClientStub(),
1743  serverTransport,
1744  keepClientConnection);
1745  }
1746 
1747 
1748 
1749  RCF_EXPORT void createCallbackConnectionImpl(
1750  ClientStub & client,
1751  ServerTransport & callbackServer);
1752 
1753  RCF_EXPORT void createCallbackConnectionImpl_Legacy(
1754  ClientStub & client,
1755  ServerTransport & callbackServer);
1756 
1757  RCF_EXPORT void createCallbackConnectionImpl(
1758  ClientStub & client,
1759  RcfServer & callbackServer);
1760 
1761 
1762 
1763  template<typename RcfClientT>
1764  void createCallbackConnection(
1765  RcfClientT & client,
1766  RcfServer & callbackServer)
1767  {
1768  createCallbackConnectionImpl(
1769  client.getClientStub(),
1770  callbackServer);
1771  }
1772 
1773  template<typename RcfClientT>
1774  void createCallbackConnectionImpl(
1775  RcfClientT & client,
1776  ServerTransport & callbackServer)
1777  {
1778  createCallbackConnection(
1779  client.getClientStub(),
1780  callbackServer);
1781  }
1782 
1783 } // namespace RCF
1784 
1785 #endif // ! INCLUDE_RCF_MARSHAL_HPP