RCFProto
 All Classes Functions Typedefs
ServerStub.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_RCF_SERVERSTUB_HPP
20 #define INCLUDE_RCF_SERVERSTUB_HPP
21 
22 #include <map>
23 #include <memory>
24 #include <vector>
25 
26 #include <boost/shared_ptr.hpp>
27 
28 #include <RCF/Config.hpp>
29 #include <RCF/Export.hpp>
30 #include <RCF/GetInterfaceName.hpp>
31 #include <RCF/RcfClient.hpp>
32 #include <RCF/RcfSession.hpp>
33 #include <RCF/SerializationProtocol.hpp>
34 #include <RCF/Token.hpp>
35 
36 // NB: occurrences of "interface" in this file have been replaced with "interface_", due to obscure bugs with Visual C++
37 
38 namespace RCF {
39 
40  class I_RcfClient;
41  typedef boost::shared_ptr<I_RcfClient> RcfClientPtr;
42 
43  template<typename T>
44  class I_Deref
45  {
46  public:
47  virtual ~I_Deref() {}
48  virtual T &deref() = 0;
49  };
50 
51  template<typename T>
52  class DerefPtr
53  {
54  public:
55  typedef boost::shared_ptr< I_Deref<T> > type;
56  };
57 
58  template<typename T>
59  class DerefObj : public I_Deref<T>
60  {
61  public:
62  DerefObj(T &t) :
63  mT(t)
64  {}
65 
66  T &deref()
67  {
68  return mT;
69  }
70 
71  private:
72  T &mT;
73  };
74 
75  template<typename T>
76  class DerefSharedPtr : public I_Deref<T>
77  {
78  public:
79  DerefSharedPtr(boost::shared_ptr<T> tPtr) :
80  mTPtr(tPtr)
81  {}
82 
83  T &deref()
84  {
85  return *mTPtr;
86  }
87 
88  private:
89  boost::shared_ptr<T> mTPtr;
90  };
91 
92  template<typename T>
93  class DerefWeakPtr : public I_Deref<T>
94  {
95  public:
96  DerefWeakPtr(boost::weak_ptr<T> tWeakPtr) :
97  mTWeakPtr(tWeakPtr)
98  {}
99 
100  T &deref()
101  {
102  boost::shared_ptr<T> tPtr(mTWeakPtr);
103  if (tPtr.get())
104  {
105  return *tPtr;
106  }
107  Exception e(_RcfError_ServerStubExpired());
108  RCF_THROW(e);
109  }
110 
111  private:
112  boost::weak_ptr<T> mTWeakPtr;
113  };
114 
115  template<typename T>
116  class DerefAutoPtr : public I_Deref<T>
117  {
118  public:
119  DerefAutoPtr(const std::auto_ptr<T> &tAutoPtr) :
120  mTAutoPtr( const_cast<std::auto_ptr<T> &>(tAutoPtr))
121  {}
122 
123  T &deref()
124  {
125  return *mTAutoPtr;
126  }
127 
128  private:
129  std::auto_ptr<T> mTAutoPtr;
130  };
131 
132  typedef boost::function2<
133  void,
134  int,
135  RcfSession &> InvokeFunctor;
136 
137  typedef std::map<std::string, InvokeFunctor> InvokeFunctorMap;
138 
139  RCF_EXPORT void setCurrentCallDesc(std::string& desc, RCF::MethodInvocationRequest& request, const char * szFunc, const char * szArity);
140 
141  class StubAccess
142  {
143  public:
144 
145 #ifdef _MSC_VER
146 #pragma warning( push )
147 #pragma warning( disable: 4702 )
148 #endif
149 
150  template<typename InterfaceT, typename IdT, typename ImplementationT>
151  void invoke(
152  InterfaceT & interface_,
153  const IdT & id,
154  RcfSession & session,
155  ImplementationT & t)
156  {
157  setCurrentCallDesc(session.mCurrentCallDesc, session.mRequest, interface_.getFunctionName(id), interface_.getArity(id));
158  RCF_LOG_2() << "RcfServer - begin remote call. " << session.mCurrentCallDesc;
159  interface_.invoke(id, session, t);
160  }
161 
162 #ifdef _MSC_VER
163 #pragma warning( pop )
164 #endif
165 
166  template<typename InterfaceT, typename DerefPtrT>
167  void registerInvokeFunctors(
168  InterfaceT & interface_,
169  InvokeFunctorMap & invokeFunctorMap,
170  DerefPtrT derefPtr)
171  {
172  interface_.registerInvokeFunctors(invokeFunctorMap, derefPtr);
173  }
174 
175  template<typename InheritT, typename InterfaceT, typename DerefPtrT>
176  void registerParentInvokeFunctors(
177  InheritT *,
178  InterfaceT & interface_,
179  InvokeFunctorMap & invokeFunctorMap,
180  DerefPtrT derefPtr,
181  boost::mpl::false_ *)
182  {
183  typedef typename GetInterface<InheritT>::type ParentInterfaceT;
184  interface_.ParentInterfaceT::registerInvokeFunctors(
185  invokeFunctorMap,
186  derefPtr);
187  }
188 
189  template<typename InheritT, typename InterfaceT, typename DerefPtrT>
190  void registerParentInvokeFunctors(
191  InheritT *,
192  InterfaceT &,
193  InvokeFunctorMap &,
194  DerefPtrT,
195  boost::mpl::true_*)
196  {}
197 
198  template<typename InheritT, typename InterfaceT, typename DerefPtrT>
199  void registerParentInvokeFunctors(
200  InheritT * i,
201  InterfaceT & interface_,
202  InvokeFunctorMap & invokeFunctorMap,
203  DerefPtrT derefPtr)
204  {
205 
206  typedef BOOST_DEDUCED_TYPENAME boost::is_same<
207  InheritT,
208  BOOST_DEDUCED_TYPENAME GetInterface<InheritT>::type >::type type;
209 
210  registerParentInvokeFunctors(
211  i,
212  interface_,
213  invokeFunctorMap,
214  derefPtr,
215  (type *) NULL);
216  }
217 
218  template<typename InheritT, typename InterfaceT>
219  void setClientStubPtr(
220  InheritT *,
221  InterfaceT &interface_,
222  boost::mpl::false_ *)
223  {
224  typedef typename InheritT::RcfClientT ParentInterfaceT;
225  interface_.ParentInterfaceT::setClientStubPtr(
226  interface_.mClientStubPtr);
227  }
228 
229  template<typename InheritT, typename InterfaceT>
230  void setClientStubPtr(
231  InheritT *,
232  InterfaceT &,
233  boost::mpl::true_ *)
234  {}
235 
236  template<typename InheritT, typename InterfaceT>
237  void setClientStubPtr(
238  InheritT *i,
239  InterfaceT &interface_)
240  {
241 
242  typedef BOOST_DEDUCED_TYPENAME boost::is_same<
243  InheritT,
244  BOOST_DEDUCED_TYPENAME GetInterface<InheritT>::type >::type type;
245 
246  setClientStubPtr(i, interface_, (type *) NULL);
247  }
248 
249  template<typename Archive, typename RcfClientT>
250  void serialize(
251  Archive & ar,
252  RcfClientT & rcfClient)
253  {
254  if (ar.isWrite())
255  {
256  rcfClient.mClientStubPtr ?
257  ar & true & rcfClient.getClientStub() :
258  ar & false;
259  }
260  else //if (ar.isRead())
261  {
262  bool hasClientStub = false;
263  ar & hasClientStub;
264  if (hasClientStub)
265  {
266  if (!rcfClient.mClientStubPtr)
267  {
268  typedef typename RcfClientT::Interface Interface;
269  std::string interfaceName = getInterfaceName( (Interface*) 0);
270  ClientStubPtr clientStubPtr(new ClientStub(interfaceName));
271  rcfClient.setClientStubPtr(clientStubPtr);
272  }
273  ar & rcfClient.getClientStub();
274  }
275  else
276  {
277  rcfClient.setClientStubPtr( ClientStubPtr());
278  }
279  }
280  }
281 
282  template<typename Archive, typename RcfClientT>
283  void serialize(
284  Archive & ar,
285  RcfClientT & rcfClient,
286  const unsigned int)
287  {
288  typedef typename Archive::is_saving IsSaving;
289  const bool isSaving = IsSaving::value;
290 
291  if (isSaving)
292  {
293  bool hasClientStub = rcfClient.mClientStubPtr;
294  ar & hasClientStub;
295  if (hasClientStub)
296  {
297  ar & rcfClient.getClientStub();
298  }
299  }
300  else //if (ar.isRead())
301  {
302  bool hasClientStub = false;
303  ar & hasClientStub;
304 
305  if (hasClientStub)
306  {
307  if (!rcfClient.mClientStubPtr)
308  {
309  typedef typename RcfClientT::Interface Interface;
310  std::string interfaceName = getInterfaceName( (Interface*) 0);
311  ClientStubPtr clientStubPtr(new ClientStub(interfaceName));
312  rcfClient.setClientStubPtr(clientStubPtr);
313  }
314  ar & rcfClient.getClientStub();
315  }
316  else
317  {
318  rcfClient.setClientStubPtr( ClientStubPtr());
319  }
320  }
321  }
322 
323  template<typename RcfClientT>
324  ClientStubPtr getClientStubPtr(const RcfClientT &rcfClient)
325  {
326  return rcfClient.mClientStubPtr;
327  }
328 
329  };
330 
331  template<typename InterfaceT, typename ImplementationT>
332  inline void invoke(
333  InterfaceT & interface_,
334  ImplementationT & t,
335  int fnId,
336  RcfSession & session)
337  {
338  switch (fnId) {
339  case 0: StubAccess().invoke(interface_, boost::mpl::int_< 0>(), session, t); break;
340  case 1: StubAccess().invoke(interface_, boost::mpl::int_< 1>(), session, t); break;
341  case 2: StubAccess().invoke(interface_, boost::mpl::int_< 2>(), session, t); break;
342  case 3: StubAccess().invoke(interface_, boost::mpl::int_< 3>(), session, t); break;
343  case 4: StubAccess().invoke(interface_, boost::mpl::int_< 4>(), session, t); break;
344  case 5: StubAccess().invoke(interface_, boost::mpl::int_< 5>(), session, t); break;
345  case 6: StubAccess().invoke(interface_, boost::mpl::int_< 6>(), session, t); break;
346  case 7: StubAccess().invoke(interface_, boost::mpl::int_< 7>(), session, t); break;
347  case 8: StubAccess().invoke(interface_, boost::mpl::int_< 8>(), session, t); break;
348  case 9: StubAccess().invoke(interface_, boost::mpl::int_< 9>(), session, t); break;
349  case 10: StubAccess().invoke(interface_, boost::mpl::int_< 10>(), session, t); break;
350  case 11: StubAccess().invoke(interface_, boost::mpl::int_< 11>(), session, t); break;
351  case 12: StubAccess().invoke(interface_, boost::mpl::int_< 12>(), session, t); break;
352  case 13: StubAccess().invoke(interface_, boost::mpl::int_< 13>(), session, t); break;
353  case 14: StubAccess().invoke(interface_, boost::mpl::int_< 14>(), session, t); break;
354  case 15: StubAccess().invoke(interface_, boost::mpl::int_< 15>(), session, t); break;
355  case 16: StubAccess().invoke(interface_, boost::mpl::int_< 16>(), session, t); break;
356  case 17: StubAccess().invoke(interface_, boost::mpl::int_< 17>(), session, t); break;
357  case 18: StubAccess().invoke(interface_, boost::mpl::int_< 18>(), session, t); break;
358  case 19: StubAccess().invoke(interface_, boost::mpl::int_< 19>(), session, t); break;
359  case 20: StubAccess().invoke(interface_, boost::mpl::int_< 20>(), session, t); break;
360  case 21: StubAccess().invoke(interface_, boost::mpl::int_< 21>(), session, t); break;
361  case 22: StubAccess().invoke(interface_, boost::mpl::int_< 22>(), session, t); break;
362  case 23: StubAccess().invoke(interface_, boost::mpl::int_< 23>(), session, t); break;
363  case 24: StubAccess().invoke(interface_, boost::mpl::int_< 24>(), session, t); break;
364  case 25: StubAccess().invoke(interface_, boost::mpl::int_< 25>(), session, t); break;
365  case 26: StubAccess().invoke(interface_, boost::mpl::int_< 26>(), session, t); break;
366  case 27: StubAccess().invoke(interface_, boost::mpl::int_< 27>(), session, t); break;
367  case 28: StubAccess().invoke(interface_, boost::mpl::int_< 28>(), session, t); break;
368  case 29: StubAccess().invoke(interface_, boost::mpl::int_< 29>(), session, t); break;
369  case 30: StubAccess().invoke(interface_, boost::mpl::int_< 30>(), session, t); break;
370  case 31: StubAccess().invoke(interface_, boost::mpl::int_< 31>(), session, t); break;
371  case 32: StubAccess().invoke(interface_, boost::mpl::int_< 32>(), session, t); break;
372  case 33: StubAccess().invoke(interface_, boost::mpl::int_< 33>(), session, t); break;
373  case 34: StubAccess().invoke(interface_, boost::mpl::int_< 34>(), session, t); break;
374  case 35: StubAccess().invoke(interface_, boost::mpl::int_< 35>(), session, t); break;
375  case 36: StubAccess().invoke(interface_, boost::mpl::int_< 36>(), session, t); break;
376  case 37: StubAccess().invoke(interface_, boost::mpl::int_< 37>(), session, t); break;
377  case 38: StubAccess().invoke(interface_, boost::mpl::int_< 38>(), session, t); break;
378  case 39: StubAccess().invoke(interface_, boost::mpl::int_< 39>(), session, t); break;
379  case 40: StubAccess().invoke(interface_, boost::mpl::int_< 40>(), session, t); break;
380  case 41: StubAccess().invoke(interface_, boost::mpl::int_< 41>(), session, t); break;
381  case 42: StubAccess().invoke(interface_, boost::mpl::int_< 42>(), session, t); break;
382  case 43: StubAccess().invoke(interface_, boost::mpl::int_< 43>(), session, t); break;
383  case 44: StubAccess().invoke(interface_, boost::mpl::int_< 44>(), session, t); break;
384  case 45: StubAccess().invoke(interface_, boost::mpl::int_< 45>(), session, t); break;
385  case 46: StubAccess().invoke(interface_, boost::mpl::int_< 46>(), session, t); break;
386  case 47: StubAccess().invoke(interface_, boost::mpl::int_< 47>(), session, t); break;
387  case 48: StubAccess().invoke(interface_, boost::mpl::int_< 48>(), session, t); break;
388  case 49: StubAccess().invoke(interface_, boost::mpl::int_< 49>(), session, t); break;
389  case 50: StubAccess().invoke(interface_, boost::mpl::int_< 50>(), session, t); break;
390  case 51: StubAccess().invoke(interface_, boost::mpl::int_< 51>(), session, t); break;
391  case 52: StubAccess().invoke(interface_, boost::mpl::int_< 52>(), session, t); break;
392  case 53: StubAccess().invoke(interface_, boost::mpl::int_< 53>(), session, t); break;
393  case 54: StubAccess().invoke(interface_, boost::mpl::int_< 54>(), session, t); break;
394  case 55: StubAccess().invoke(interface_, boost::mpl::int_< 55>(), session, t); break;
395  case 56: StubAccess().invoke(interface_, boost::mpl::int_< 56>(), session, t); break;
396  case 57: StubAccess().invoke(interface_, boost::mpl::int_< 57>(), session, t); break;
397  case 58: StubAccess().invoke(interface_, boost::mpl::int_< 58>(), session, t); break;
398  case 59: StubAccess().invoke(interface_, boost::mpl::int_< 59>(), session, t); break;
399  case 60: StubAccess().invoke(interface_, boost::mpl::int_< 60>(), session, t); break;
400  case 61: StubAccess().invoke(interface_, boost::mpl::int_< 61>(), session, t); break;
401  case 62: StubAccess().invoke(interface_, boost::mpl::int_< 62>(), session, t); break;
402  case 63: StubAccess().invoke(interface_, boost::mpl::int_< 63>(), session, t); break;
403  case 64: StubAccess().invoke(interface_, boost::mpl::int_< 64>(), session, t); break;
404  case 65: StubAccess().invoke(interface_, boost::mpl::int_< 65>(), session, t); break;
405  case 66: StubAccess().invoke(interface_, boost::mpl::int_< 66>(), session, t); break;
406  case 67: StubAccess().invoke(interface_, boost::mpl::int_< 67>(), session, t); break;
407  case 68: StubAccess().invoke(interface_, boost::mpl::int_< 68>(), session, t); break;
408  case 69: StubAccess().invoke(interface_, boost::mpl::int_< 69>(), session, t); break;
409  case 70: StubAccess().invoke(interface_, boost::mpl::int_< 70>(), session, t); break;
410  case 71: StubAccess().invoke(interface_, boost::mpl::int_< 71>(), session, t); break;
411  case 72: StubAccess().invoke(interface_, boost::mpl::int_< 72>(), session, t); break;
412  case 73: StubAccess().invoke(interface_, boost::mpl::int_< 73>(), session, t); break;
413  case 74: StubAccess().invoke(interface_, boost::mpl::int_< 74>(), session, t); break;
414  case 75: StubAccess().invoke(interface_, boost::mpl::int_< 75>(), session, t); break;
415  case 76: StubAccess().invoke(interface_, boost::mpl::int_< 76>(), session, t); break;
416  case 77: StubAccess().invoke(interface_, boost::mpl::int_< 77>(), session, t); break;
417  case 78: StubAccess().invoke(interface_, boost::mpl::int_< 78>(), session, t); break;
418  case 79: StubAccess().invoke(interface_, boost::mpl::int_< 79>(), session, t); break;
419  case 80: StubAccess().invoke(interface_, boost::mpl::int_< 80>(), session, t); break;
420  case 81: StubAccess().invoke(interface_, boost::mpl::int_< 81>(), session, t); break;
421  case 82: StubAccess().invoke(interface_, boost::mpl::int_< 82>(), session, t); break;
422  case 83: StubAccess().invoke(interface_, boost::mpl::int_< 83>(), session, t); break;
423  case 84: StubAccess().invoke(interface_, boost::mpl::int_< 84>(), session, t); break;
424  case 85: StubAccess().invoke(interface_, boost::mpl::int_< 85>(), session, t); break;
425  case 86: StubAccess().invoke(interface_, boost::mpl::int_< 86>(), session, t); break;
426  case 87: StubAccess().invoke(interface_, boost::mpl::int_< 87>(), session, t); break;
427  case 88: StubAccess().invoke(interface_, boost::mpl::int_< 88>(), session, t); break;
428  case 89: StubAccess().invoke(interface_, boost::mpl::int_< 89>(), session, t); break;
429  case 90: StubAccess().invoke(interface_, boost::mpl::int_< 90>(), session, t); break;
430  case 91: StubAccess().invoke(interface_, boost::mpl::int_< 91>(), session, t); break;
431  case 92: StubAccess().invoke(interface_, boost::mpl::int_< 92>(), session, t); break;
432  case 93: StubAccess().invoke(interface_, boost::mpl::int_< 93>(), session, t); break;
433  case 94: StubAccess().invoke(interface_, boost::mpl::int_< 94>(), session, t); break;
434  case 95: StubAccess().invoke(interface_, boost::mpl::int_< 95>(), session, t); break;
435  case 96: StubAccess().invoke(interface_, boost::mpl::int_< 96>(), session, t); break;
436  case 97: StubAccess().invoke(interface_, boost::mpl::int_< 97>(), session, t); break;
437  case 98: StubAccess().invoke(interface_, boost::mpl::int_< 98>(), session, t); break;
438  case 99: StubAccess().invoke(interface_, boost::mpl::int_< 99>(), session, t); break;
439  case 100: StubAccess().invoke(interface_, boost::mpl::int_<100>(), session, t); break;
440  case 101: StubAccess().invoke(interface_, boost::mpl::int_<101>(), session, t); break;
441  case 102: StubAccess().invoke(interface_, boost::mpl::int_<102>(), session, t); break;
442  case 103: StubAccess().invoke(interface_, boost::mpl::int_<103>(), session, t); break;
443  case 104: StubAccess().invoke(interface_, boost::mpl::int_<104>(), session, t); break;
444  case 105: StubAccess().invoke(interface_, boost::mpl::int_<105>(), session, t); break;
445  case 106: StubAccess().invoke(interface_, boost::mpl::int_<106>(), session, t); break;
446  case 107: StubAccess().invoke(interface_, boost::mpl::int_<107>(), session, t); break;
447  case 108: StubAccess().invoke(interface_, boost::mpl::int_<108>(), session, t); break;
448  case 109: StubAccess().invoke(interface_, boost::mpl::int_<109>(), session, t); break;
449  case 110: StubAccess().invoke(interface_, boost::mpl::int_<110>(), session, t); break;
450  case 111: StubAccess().invoke(interface_, boost::mpl::int_<111>(), session, t); break;
451  case 112: StubAccess().invoke(interface_, boost::mpl::int_<112>(), session, t); break;
452  case 113: StubAccess().invoke(interface_, boost::mpl::int_<113>(), session, t); break;
453  case 114: StubAccess().invoke(interface_, boost::mpl::int_<114>(), session, t); break;
454  case 115: StubAccess().invoke(interface_, boost::mpl::int_<115>(), session, t); break;
455  case 116: StubAccess().invoke(interface_, boost::mpl::int_<116>(), session, t); break;
456  case 117: StubAccess().invoke(interface_, boost::mpl::int_<117>(), session, t); break;
457  case 118: StubAccess().invoke(interface_, boost::mpl::int_<118>(), session, t); break;
458  case 119: StubAccess().invoke(interface_, boost::mpl::int_<119>(), session, t); break;
459  case 120: StubAccess().invoke(interface_, boost::mpl::int_<120>(), session, t); break;
460  case 121: StubAccess().invoke(interface_, boost::mpl::int_<121>(), session, t); break;
461  case 122: StubAccess().invoke(interface_, boost::mpl::int_<122>(), session, t); break;
462  case 123: StubAccess().invoke(interface_, boost::mpl::int_<123>(), session, t); break;
463  case 124: StubAccess().invoke(interface_, boost::mpl::int_<124>(), session, t); break;
464  case 125: StubAccess().invoke(interface_, boost::mpl::int_<125>(), session, t); break;
465  case 126: StubAccess().invoke(interface_, boost::mpl::int_<126>(), session, t); break;
466  case 127: StubAccess().invoke(interface_, boost::mpl::int_<127>(), session, t); break;
467  case 128: StubAccess().invoke(interface_, boost::mpl::int_<128>(), session, t); break;
468  case 129: StubAccess().invoke(interface_, boost::mpl::int_<129>(), session, t); break;
469  case 130: StubAccess().invoke(interface_, boost::mpl::int_<130>(), session, t); break;
470  case 131: StubAccess().invoke(interface_, boost::mpl::int_<131>(), session, t); break;
471  case 132: StubAccess().invoke(interface_, boost::mpl::int_<132>(), session, t); break;
472  case 133: StubAccess().invoke(interface_, boost::mpl::int_<133>(), session, t); break;
473  case 134: StubAccess().invoke(interface_, boost::mpl::int_<134>(), session, t); break;
474  case 135: StubAccess().invoke(interface_, boost::mpl::int_<135>(), session, t); break;
475  case 136: StubAccess().invoke(interface_, boost::mpl::int_<136>(), session, t); break;
476  case 137: StubAccess().invoke(interface_, boost::mpl::int_<137>(), session, t); break;
477  case 138: StubAccess().invoke(interface_, boost::mpl::int_<138>(), session, t); break;
478  case 139: StubAccess().invoke(interface_, boost::mpl::int_<139>(), session, t); break;
479  case 140: StubAccess().invoke(interface_, boost::mpl::int_<140>(), session, t); break;
480  case 141: StubAccess().invoke(interface_, boost::mpl::int_<141>(), session, t); break;
481  case 142: StubAccess().invoke(interface_, boost::mpl::int_<142>(), session, t); break;
482  case 143: StubAccess().invoke(interface_, boost::mpl::int_<143>(), session, t); break;
483  case 144: StubAccess().invoke(interface_, boost::mpl::int_<144>(), session, t); break;
484  case 145: StubAccess().invoke(interface_, boost::mpl::int_<145>(), session, t); break;
485  case 146: StubAccess().invoke(interface_, boost::mpl::int_<146>(), session, t); break;
486  case 147: StubAccess().invoke(interface_, boost::mpl::int_<147>(), session, t); break;
487  case 148: StubAccess().invoke(interface_, boost::mpl::int_<148>(), session, t); break;
488  case 149: StubAccess().invoke(interface_, boost::mpl::int_<149>(), session, t); break;
489  case 150: StubAccess().invoke(interface_, boost::mpl::int_<150>(), session, t); break;
490  case 151: StubAccess().invoke(interface_, boost::mpl::int_<151>(), session, t); break;
491  case 152: StubAccess().invoke(interface_, boost::mpl::int_<152>(), session, t); break;
492  case 153: StubAccess().invoke(interface_, boost::mpl::int_<153>(), session, t); break;
493  case 154: StubAccess().invoke(interface_, boost::mpl::int_<154>(), session, t); break;
494  case 155: StubAccess().invoke(interface_, boost::mpl::int_<155>(), session, t); break;
495  case 156: StubAccess().invoke(interface_, boost::mpl::int_<156>(), session, t); break;
496  case 157: StubAccess().invoke(interface_, boost::mpl::int_<157>(), session, t); break;
497  case 158: StubAccess().invoke(interface_, boost::mpl::int_<158>(), session, t); break;
498  case 159: StubAccess().invoke(interface_, boost::mpl::int_<159>(), session, t); break;
499  case 160: StubAccess().invoke(interface_, boost::mpl::int_<160>(), session, t); break;
500  case 161: StubAccess().invoke(interface_, boost::mpl::int_<161>(), session, t); break;
501  case 162: StubAccess().invoke(interface_, boost::mpl::int_<162>(), session, t); break;
502  case 163: StubAccess().invoke(interface_, boost::mpl::int_<163>(), session, t); break;
503  case 164: StubAccess().invoke(interface_, boost::mpl::int_<164>(), session, t); break;
504  case 165: StubAccess().invoke(interface_, boost::mpl::int_<165>(), session, t); break;
505  case 166: StubAccess().invoke(interface_, boost::mpl::int_<166>(), session, t); break;
506  case 167: StubAccess().invoke(interface_, boost::mpl::int_<167>(), session, t); break;
507  case 168: StubAccess().invoke(interface_, boost::mpl::int_<168>(), session, t); break;
508  case 169: StubAccess().invoke(interface_, boost::mpl::int_<169>(), session, t); break;
509  case 170: StubAccess().invoke(interface_, boost::mpl::int_<170>(), session, t); break;
510  case 171: StubAccess().invoke(interface_, boost::mpl::int_<171>(), session, t); break;
511  case 172: StubAccess().invoke(interface_, boost::mpl::int_<172>(), session, t); break;
512  case 173: StubAccess().invoke(interface_, boost::mpl::int_<173>(), session, t); break;
513  case 174: StubAccess().invoke(interface_, boost::mpl::int_<174>(), session, t); break;
514  case 175: StubAccess().invoke(interface_, boost::mpl::int_<175>(), session, t); break;
515  case 176: StubAccess().invoke(interface_, boost::mpl::int_<176>(), session, t); break;
516  case 177: StubAccess().invoke(interface_, boost::mpl::int_<177>(), session, t); break;
517  case 178: StubAccess().invoke(interface_, boost::mpl::int_<178>(), session, t); break;
518  case 179: StubAccess().invoke(interface_, boost::mpl::int_<179>(), session, t); break;
519  case 180: StubAccess().invoke(interface_, boost::mpl::int_<180>(), session, t); break;
520  case 181: StubAccess().invoke(interface_, boost::mpl::int_<181>(), session, t); break;
521  case 182: StubAccess().invoke(interface_, boost::mpl::int_<182>(), session, t); break;
522  case 183: StubAccess().invoke(interface_, boost::mpl::int_<183>(), session, t); break;
523  case 184: StubAccess().invoke(interface_, boost::mpl::int_<184>(), session, t); break;
524  case 185: StubAccess().invoke(interface_, boost::mpl::int_<185>(), session, t); break;
525  case 186: StubAccess().invoke(interface_, boost::mpl::int_<186>(), session, t); break;
526  case 187: StubAccess().invoke(interface_, boost::mpl::int_<187>(), session, t); break;
527  case 188: StubAccess().invoke(interface_, boost::mpl::int_<188>(), session, t); break;
528  case 189: StubAccess().invoke(interface_, boost::mpl::int_<189>(), session, t); break;
529  case 190: StubAccess().invoke(interface_, boost::mpl::int_<190>(), session, t); break;
530  case 191: StubAccess().invoke(interface_, boost::mpl::int_<191>(), session, t); break;
531  case 192: StubAccess().invoke(interface_, boost::mpl::int_<192>(), session, t); break;
532  case 193: StubAccess().invoke(interface_, boost::mpl::int_<193>(), session, t); break;
533  case 194: StubAccess().invoke(interface_, boost::mpl::int_<194>(), session, t); break;
534  case 195: StubAccess().invoke(interface_, boost::mpl::int_<195>(), session, t); break;
535  case 196: StubAccess().invoke(interface_, boost::mpl::int_<196>(), session, t); break;
536  case 197: StubAccess().invoke(interface_, boost::mpl::int_<197>(), session, t); break;
537  case 198: StubAccess().invoke(interface_, boost::mpl::int_<198>(), session, t); break;
538  case 199: StubAccess().invoke(interface_, boost::mpl::int_<199>(), session, t); break;
539  case 200: StubAccess().invoke(interface_, boost::mpl::int_<200>(), session, t); break;
540 
541  default: RCF_THROW(Exception(_RcfError_FnId(fnId)));
542  }
543  }
544 
545  template<typename InterfaceT, typename DerefPtrT>
546  class InterfaceInvocator
547  {
548  public:
549  InterfaceInvocator(InterfaceT &interface_, DerefPtrT derefPtr) :
550  mInterface(interface_),
551  mDerefPtr(derefPtr)
552  {}
553 
554  void operator()(
555  int fnId,
556  RcfSession & session)
557  {
558  invoke<InterfaceT>(mInterface, mDerefPtr->deref(), fnId, session);
559  }
560 
561  private:
562  InterfaceT & mInterface;
563  DerefPtrT mDerefPtr;
564  };
565 
566  template<typename InterfaceT, typename DerefPtrT>
567  void registerInvokeFunctors(
568  InterfaceT & interface_,
569  InvokeFunctorMap & invokeFunctorMap,
570  DerefPtrT derefPtr)
571  {
572  // NB: same interface may occur more than once in the inheritance hierarchy of another interface, and in
573  // that case, via overwriting, only one InterfaceInvocator is registered, so only the functions in one of the interfaces will ever be called.
574  // But it doesn't matter, since even if an interface occurs several times in the inheritance hierarchy, each occurrence
575  // of the interface will be bound to derefPtr in exactly the same way.
576 
577  typedef typename InterfaceT::Interface Interface;
578  std::string interfaceName = ::RCF::getInterfaceName( (Interface *) NULL);
579 
580  invokeFunctorMap[ interfaceName ] =
581  InterfaceInvocator<InterfaceT, DerefPtrT>(interface_, derefPtr);
582  }
583 
584  class ServerBinding;
585 
586  typedef boost::shared_ptr<ServerBinding> ServerBindingPtr;
587 
588  class RCF_EXPORT ServerBinding
589  {
590  public:
591 
592  typedef boost::function<bool(int)> CbAccessControl;
593 
594  void setAccessControl(CbAccessControl cbAccessControl);
595 
596  template<typename InterfaceT, typename DerefPtrT>
597  void registerInvokeFunctors(InterfaceT &interface_, DerefPtrT derefPtr)
598  {
599  StubAccess access;
600  access.registerInvokeFunctors(
601  interface_,
602  mInvokeFunctorMap,
603  derefPtr);
604  }
605 
606  void merge(RcfClientPtr rcfClientPtr);
607 
608  private:
609 
610  friend class RcfServer;
611  friend class RcfSession;
612 
613  void invoke(
614  const std::string & subInterface,
615  int fnId,
616  RcfSession & session);
617 
618  private:
619 
620  Mutex mMutex;
621 
622  // TODO: too much overhead per server stub?
623  InvokeFunctorMap mInvokeFunctorMap;
624  std::vector<RcfClientPtr> mMergedStubs;
625 
626  CbAccessControl mCbAccessControl;
627  };
628 
629  template<typename InterfaceT, typename ImplementationT, typename ImplementationPtrT>
630  RcfClientPtr createServerStub(
631  InterfaceT *,
632  ImplementationT *,
633  ImplementationPtrT px)
634  {
635  typedef typename InterfaceT::RcfClientT RcfClientT;
636  return RcfClientPtr( new RcfClientT(
637  ServerBindingPtr(new ServerBinding()),
638  px,
639  (boost::mpl::true_ *) NULL));
640  }
641 
642 } // namespace RCF
643 
644 #endif // ! INCLUDE_RCF_SERVERSTUB_HPP