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