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