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