Click here to Skip to main content
15,891,184 members
Articles / Programming Languages / C++

RCF - Interprocess Communication for C++

Rate me:
Please Sign up or sign in to vote.
4.94/5 (147 votes)
25 Oct 2011CPOL20 min read 4.6M   8.4K   331  
A server/client IPC framework, using the C++ preprocessor as an IDL compiler.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>RCF: Marshal.hpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.5 -->
<div class="tabs">
  <ul>
    <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
    <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
    <li id="current"><a href="files.html"><span>Files</span></a></li>
    <li><a href="dirs.html"><span>Directories</span></a></li>
  </ul></div>
<div class="nav">
<a class="el" href="dir_G_3A_2FDevelopment_2Fbuild_2Fscripts_2Fwin_2FBuildRcf2_5FOutput_2FRCF_2D0_2E4_2Finclude_2F.html">include</a>&nbsp;&raquo&nbsp;<a class="el" href="dir_G_3A_2FDevelopment_2Fbuild_2Fscripts_2Fwin_2FBuildRcf2_5FOutput_2FRCF_2D0_2E4_2Finclude_2FRCF_2F.html">RCF</a></div>
<h1>Marshal.hpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 
<a name="l00002"></a>00002 <span class="comment">//*****************************************************************************</span>
<a name="l00003"></a>00003 <span class="comment">// RCF - Remote Call Framework</span>
<a name="l00004"></a>00004 <span class="comment">// Copyright (c) 2005. All rights reserved.</span>
<a name="l00005"></a>00005 <span class="comment">// Developed by Jarl Lindrud.</span>
<a name="l00006"></a>00006 <span class="comment">// Contact: jlindrud@hotmail.com .</span>
<a name="l00007"></a>00007 <span class="comment">//*****************************************************************************</span>
<a name="l00008"></a>00008 
<a name="l00009"></a>00009 <span class="preprocessor">#ifndef INCLUDE_RCF_MARSHAL_HPP</span>
<a name="l00010"></a>00010 <span class="preprocessor"></span><span class="preprocessor">#define INCLUDE_RCF_MARSHAL_HPP</span>
<a name="l00011"></a>00011 <span class="preprocessor"></span>
<a name="l00012"></a>00012 <span class="preprocessor">#include &lt;RCF/ClientStub.hpp&gt;</span>
<a name="l00013"></a>00013 <span class="preprocessor">#include &lt;RCF/SerializationProtocol.hpp&gt;</span>
<a name="l00014"></a>00014 <span class="preprocessor">#include &lt;RCF/MethodInvocation.hpp&gt;</span>
<a name="l00015"></a>00015 <span class="preprocessor">#include &lt;RCF/Tools.hpp&gt;</span>
<a name="l00016"></a>00016 <span class="preprocessor">#include &lt;RCF/util/Meta.hpp&gt;</span>
<a name="l00017"></a>00017 
<a name="l00018"></a>00018 <span class="preprocessor">#include &lt;SF/Tools.hpp&gt;</span> <span class="comment">// FOR_EACH_PRIMITIVE_TYPE</span>
<a name="l00019"></a>00019 
<a name="l00020"></a>00020 <span class="preprocessor">#include &lt;boost/mpl/not.hpp&gt;</span>
<a name="l00021"></a>00021 <span class="preprocessor">#include &lt;boost/static_assert.hpp&gt;</span>
<a name="l00022"></a>00022 <span class="preprocessor">#include &lt;boost/type_traits.hpp&gt;</span>
<a name="l00023"></a>00023 
<a name="l00024"></a>00024 <span class="comment">// TODO: move code into Marshal.inl</span>
<a name="l00025"></a>00025 
<a name="l00026"></a>00026 <span class="keyword">namespace </span>RCF {
<a name="l00027"></a>00027 
<a name="l00028"></a>00028     <span class="comment">// Boost.Serialization treats pointers of primitive types differently than other types,</span>
<a name="l00029"></a>00029     <span class="comment">// hence the following hack, which unfortunately overrides all the serialization protocols,</span>
<a name="l00030"></a>00030     <span class="comment">// not just Boost.Serialization.</span>
<a name="l00031"></a>00031 
<a name="l00032"></a>00032 <span class="preprocessor">#define RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION(type)                                                                                                \</span>
<a name="l00033"></a>00033 <span class="preprocessor">    inline SerializationProtocolOut &amp;operator&lt;&lt;(SerializationProtocolOut &amp;out, const type *pt) { return out &lt;&lt; *pt; }                                   \</span>
<a name="l00034"></a>00034 <span class="preprocessor">    inline SerializationProtocolOut &amp;operator&lt;&lt;(SerializationProtocolOut &amp;out, type *const pt) { return out &lt;&lt; *pt; }                                   \</span>
<a name="l00035"></a>00035 <span class="preprocessor">    inline SerializationProtocolIn &amp;operator&gt;&gt;(SerializationProtocolIn &amp;in, type *&amp;pt) { RCF_ASSERT(pt==NULL); pt = new type(); return in &gt;&gt; *pt; }</span>
<a name="l00036"></a>00036 <span class="preprocessor"></span>
<a name="l00037"></a>00037     SF_FOR_EACH_FUNDAMENTAL_TYPE( RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION )
<a name="l00038"></a>00038     RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION(std::string)
<a name="l00039"></a>00039 
<a name="l00040"></a>00040 #undef RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION
<a name="l00041"></a>00041 
<a name="l00042"></a>00042     <span class="comment">// Boost.Serialization handles smart pointers very clumsily, so we'll do those ourselves</span>
<a name="l00043"></a>00043 
<a name="l00044"></a>00044     <span class="comment">//#define RCF_SERIALIZE_REFCOUNTSMARTPTR(RefCountSmartPtr)                                            </span>
<a name="l00045"></a>00045 
<a name="l00046"></a>00046 #define RefCountSmartPtr boost::shared_ptr
<a name="l00047"></a>00047 
<a name="l00048"></a>00048     template&lt;typename T&gt;
<a name="l00049"></a>00049     inline SerializationProtocolOut &amp;operator&lt;&lt;(SerializationProtocolOut &amp;out, const RefCountSmartPtr&lt;T&gt; *spt)
<a name="l00050"></a>00050     {
<a name="l00051"></a>00051         <span class="keywordflow">return</span> out &lt;&lt; *spt;
<a name="l00052"></a>00052     }
<a name="l00053"></a>00053 
<a name="l00054"></a>00054     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00055"></a>00055     <span class="keyword">inline</span> SerializationProtocolOut &amp;operator&lt;&lt;(SerializationProtocolOut &amp;out, RefCountSmartPtr&lt;T&gt; *<span class="keyword">const</span> spt)
<a name="l00056"></a>00056     {
<a name="l00057"></a>00057         <span class="keywordflow">return</span> out &lt;&lt; *spt;
<a name="l00058"></a>00058     }
<a name="l00059"></a>00059 
<a name="l00060"></a>00060     template&lt;typename T&gt;
<a name="l00061"></a>00061     <span class="keyword">inline</span> SerializationProtocolIn &amp;<span class="keyword">operator</span>&gt;&gt;(SerializationProtocolIn &amp;in, RefCountSmartPtr&lt;T&gt; *&amp;spt)
<a name="l00062"></a>00062     {
<a name="l00063"></a>00063         spt = <span class="keyword">new</span> RefCountSmartPtr&lt;T&gt;();
<a name="l00064"></a>00064         <span class="keywordflow">return</span> in &gt;&gt; *spt;
<a name="l00065"></a>00065     }
<a name="l00066"></a>00066 
<a name="l00067"></a>00067     template&lt;typename T&gt;
<a name="l00068"></a>00068     <span class="keyword">inline</span> SerializationProtocolOut &amp;<span class="keyword">operator</span>&lt;&lt;(SerializationProtocolOut &amp;out, <span class="keyword">const</span> RefCountSmartPtr&lt;T&gt; &amp;spt)
<a name="l00069"></a>00069     {
<a name="l00070"></a>00070         <span class="keywordflow">return</span> out &lt;&lt; spt.get();
<a name="l00071"></a>00071     }
<a name="l00072"></a>00072 
<a name="l00073"></a>00073     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00074"></a>00074     <span class="keyword">inline</span> SerializationProtocolIn &amp;operator&gt;&gt;(SerializationProtocolIn &amp;in, RefCountSmartPtr&lt;T&gt; &amp;spt)
<a name="l00075"></a>00075     {
<a name="l00076"></a>00076         T *pt = NULL;
<a name="l00077"></a>00077         in &gt;&gt; pt;
<a name="l00078"></a>00078         RefCountSmartPtr&lt;T&gt; *pspt = 
<a name="l00079"></a>00079             in.getPointerContext().template get&lt; RefCountSmartPtr&lt;T&gt; * &gt;(pt);
<a name="l00080"></a>00080         <span class="keywordflow">if</span> (pspt == NULL)
<a name="l00081"></a>00081         {
<a name="l00082"></a>00082             spt = RefCountSmartPtr&lt;T&gt;(pt);
<a name="l00083"></a>00083             in.getPointerContext().template set&lt; RefCountSmartPtr&lt;T&gt; * &gt;(&amp;spt, pt);
<a name="l00084"></a>00084         }
<a name="l00085"></a>00085         <span class="keywordflow">else</span>
<a name="l00086"></a>00086         {
<a name="l00087"></a>00087             spt = *pspt;
<a name="l00088"></a>00088         }
<a name="l00089"></a>00089         <span class="keywordflow">return</span> in;
<a name="l00090"></a>00090     }
<a name="l00091"></a>00091 
<a name="l00092"></a>00092 #undef RefCountSmartPtr
<a name="l00093"></a>00093 
<a name="l00094"></a>00094     
<a name="l00095"></a>00095     <span class="keyword">struct</span> Void {};
<a name="l00096"></a>00096 
<a name="l00097"></a>00097     <span class="keyword">namespace</span> IDL {
<a name="l00098"></a>00098 
<a name="l00099"></a>00099         <span class="keyword">class</span> DoRequest 
<a name="l00100"></a>00100         {
<a name="l00101"></a>00101         <span class="keyword">public</span>:
<a name="l00102"></a>00102             DoRequest(ClientStub &amp;stub, <span class="keywordtype">bool</span> oneway, <span class="keyword">const</span> std::string &amp;subInterface, <span class="keywordtype">int</span> fnId, SerializationProtocolOut &amp;out)
<a name="l00103"></a>00103             {
<a name="l00104"></a>00104                 stub.onPreCall();
<a name="l00105"></a>00105                 stub.connectTransport();
<a name="l00106"></a>00106                 out.reset(stub.getSerializationProtocol());
<a name="l00107"></a>00107                 out &lt;&lt; RCF::MethodInvocationRequest(stub.getToken(), stub.getServerBindingName(), subInterface, fnId, oneway, <span class="keyword">false</span>);
<a name="l00108"></a>00108             }
<a name="l00109"></a>00109         };
<a name="l00110"></a>00110 
<a name="l00111"></a>00111         template&lt;typename T&gt;
<a name="l00112"></a>00112         <span class="keyword">class</span> InParameter
<a name="l00113"></a>00113         {
<a name="l00114"></a>00114         <span class="keyword">public</span>:
<a name="l00115"></a>00115             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_pointer&lt;T&gt;::type &gt;::value );
<a name="l00116"></a>00116             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_reference&lt;T&gt;::type &gt;::value );
<a name="l00117"></a>00117             InParameter(<span class="keyword">const</span> T &amp;t, SerializationProtocolOut &amp;out) : t_() { out &lt;&lt; t; }
<a name="l00118"></a>00118             InParameter(SerializationProtocolIn &amp;in) : t_() { in &gt;&gt; t_; }
<a name="l00119"></a>00119             <span class="keyword">const</span> T &amp;get() { <span class="keywordflow">return</span> t_; }
<a name="l00120"></a>00120         <span class="keyword">private</span>:
<a name="l00121"></a>00121             T t_;
<a name="l00122"></a>00122         };
<a name="l00123"></a>00123 
<a name="l00124"></a>00124         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00125"></a>00125         <span class="keyword">class </span>InParameter&lt;T *&gt;
<a name="l00126"></a>00126         {
<a name="l00127"></a>00127         <span class="keyword">public</span>:
<a name="l00128"></a>00128             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_pointer&lt;T&gt;::type &gt;::value );
<a name="l00129"></a>00129             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_reference&lt;T&gt;::type &gt;::value );
<a name="l00130"></a>00130             <span class="keyword">typedef</span> <span class="keyword">typename</span> boost::remove_const&lt;T&gt;::type U;
<a name="l00131"></a>00131             InParameter(T *pt, SerializationProtocolOut &amp;out) 
<a name="l00132"></a>00132             { 
<a name="l00133"></a>00133                 out &lt;&lt; pt; 
<a name="l00134"></a>00134             }
<a name="l00135"></a>00135             InParameter(SerializationProtocolIn &amp;in)
<a name="l00136"></a>00136             {
<a name="l00137"></a>00137                 U *pu = NULL;
<a name="l00138"></a>00138                 in &gt;&gt; pu;
<a name="l00139"></a>00139                 boost::shared_ptr&lt;U&gt; *ppu = in.getPointerContext().template get&lt; boost::shared_ptr&lt;U&gt;* &gt;(pu);
<a name="l00140"></a>00140                 <span class="keywordflow">if</span> (ppu == NULL)
<a name="l00141"></a>00141                 {
<a name="l00142"></a>00142                     pu_ = boost::shared_ptr&lt;U&gt;(pu);
<a name="l00143"></a>00143                     in.getPointerContext().template set&lt; boost::shared_ptr&lt;U&gt;* &gt;(&amp;pu_, pu);
<a name="l00144"></a>00144                 }
<a name="l00145"></a>00145                 <span class="keywordflow">else</span>
<a name="l00146"></a>00146                 {
<a name="l00147"></a>00147                     pu_ = *ppu;
<a name="l00148"></a>00148                 }
<a name="l00149"></a>00149             }
<a name="l00150"></a>00150             T *get() 
<a name="l00151"></a>00151             { 
<a name="l00152"></a>00152                 <span class="keywordflow">return</span> pu_.get(); 
<a name="l00153"></a>00153             }
<a name="l00154"></a>00154         <span class="keyword">private</span>:
<a name="l00155"></a>00155             boost::shared_ptr&lt;U&gt; pu_;
<a name="l00156"></a>00156         };
<a name="l00157"></a>00157 
<a name="l00158"></a>00158         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00159"></a>00159         <span class="keyword">class </span>InParameter&lt;T &amp;&gt;
<a name="l00160"></a>00160         {
<a name="l00161"></a>00161         <span class="keyword">public</span>:
<a name="l00162"></a>00162             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_pointer&lt;T&gt;::type &gt;::value );
<a name="l00163"></a>00163             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_reference&lt;T&gt;::type &gt;::value );
<a name="l00164"></a>00164             <span class="keyword">typedef</span> <span class="keyword">typename</span> boost::remove_const&lt;T&gt;::type U;
<a name="l00165"></a>00165             InParameter(T &amp;t, SerializationProtocolOut &amp;out) 
<a name="l00166"></a>00166             { 
<a name="l00167"></a>00167                 out &lt;&lt; &amp;t; 
<a name="l00168"></a>00168             }
<a name="l00169"></a>00169             InParameter(SerializationProtocolIn &amp;in) 
<a name="l00170"></a>00170             {
<a name="l00171"></a>00171                 U *pu = NULL;
<a name="l00172"></a>00172                 in &gt;&gt; pu;
<a name="l00173"></a>00173                 boost::shared_ptr&lt;U&gt; *ppu = in.getPointerContext().template get&lt; boost::shared_ptr&lt;U&gt;* &gt;(pu);
<a name="l00174"></a>00174                 <span class="keywordflow">if</span> (ppu == NULL)
<a name="l00175"></a>00175                 {
<a name="l00176"></a>00176                     pu_ = boost::shared_ptr&lt;U&gt;(pu);
<a name="l00177"></a>00177                     in.getPointerContext().template set&lt; boost::shared_ptr&lt;U&gt;* &gt;(&amp;pu_, pu);
<a name="l00178"></a>00178                 }
<a name="l00179"></a>00179                 <span class="keywordflow">else</span>
<a name="l00180"></a>00180                 {
<a name="l00181"></a>00181                     pu_ = *ppu;
<a name="l00182"></a>00182                 }
<a name="l00183"></a>00183             }
<a name="l00184"></a>00184 
<a name="l00185"></a>00185             T &amp;get() 
<a name="l00186"></a>00186             { 
<a name="l00187"></a>00187                 <span class="keywordflow">return</span> *pu_; 
<a name="l00188"></a>00188             }
<a name="l00189"></a>00189         <span class="keyword">private</span>:
<a name="l00190"></a>00190             boost::shared_ptr&lt;U&gt; pu_;
<a name="l00191"></a>00191         };
<a name="l00192"></a>00192 
<a name="l00193"></a>00193         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00194"></a>00194         <span class="keyword">class </span>OutParameter
<a name="l00195"></a>00195         {
<a name="l00196"></a>00196         <span class="keyword">public</span>:
<a name="l00197"></a>00197             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_pointer&lt;T&gt;::type &gt;::value );
<a name="l00198"></a>00198             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_reference&lt;T&gt;::type &gt;::value );
<a name="l00199"></a>00199             OutParameter(<span class="keyword">const</span> T &amp;, SerializationProtocolIn &amp;, <span class="keywordtype">bool</span>) 
<a name="l00200"></a>00200             {}
<a name="l00201"></a>00201             <span class="keyword">template</span>&lt;<span class="keyword">typename</span> V&gt; OutParameter( InParameter&lt; V &gt; &amp;, SerializationProtocolOut &amp;) 
<a name="l00202"></a>00202             {}
<a name="l00203"></a>00203         };
<a name="l00204"></a>00204 
<a name="l00205"></a>00205         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00206"></a>00206         <span class="keyword">class </span>OutParameter&lt;T *&gt;
<a name="l00207"></a>00207         {
<a name="l00208"></a>00208         <span class="keyword">public</span>:
<a name="l00209"></a>00209             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_pointer&lt;T&gt;::type &gt;::value );
<a name="l00210"></a>00210             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_reference&lt;T&gt;::type &gt;::value );
<a name="l00211"></a>00211             OutParameter(<span class="keyword">const</span> T *t, SerializationProtocolIn &amp;in, <span class="keywordtype">bool</span> oneway) 
<a name="l00212"></a>00212             {}
<a name="l00213"></a>00213             <span class="keyword">template</span>&lt;<span class="keyword">typename</span> V&gt; OutParameter( InParameter&lt; V &gt; &amp;v, SerializationProtocolOut &amp;out) 
<a name="l00214"></a>00214             {}
<a name="l00215"></a>00215         };
<a name="l00216"></a>00216 
<a name="l00217"></a>00217         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00218"></a>00218         <span class="keyword">class </span>OutParameter&lt;const T &amp;&gt;
<a name="l00219"></a>00219         {
<a name="l00220"></a>00220         <span class="keyword">public</span>:
<a name="l00221"></a>00221             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_pointer&lt;T&gt;::type &gt;::value );
<a name="l00222"></a>00222             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_reference&lt;T&gt;::type &gt;::value );
<a name="l00223"></a>00223             OutParameter(<span class="keyword">const</span> T &amp;t, SerializationProtocolIn &amp;in, <span class="keywordtype">bool</span> oneway) 
<a name="l00224"></a>00224             {
<a name="l00225"></a>00225                 RCF_UNUSED_VARIABLE(t);
<a name="l00226"></a>00226                 RCF_UNUSED_VARIABLE(in);
<a name="l00227"></a>00227                 RCF_UNUSED_VARIABLE(oneway);
<a name="l00228"></a>00228             }
<a name="l00229"></a>00229             <span class="keyword">template</span>&lt;<span class="keyword">typename</span> V&gt; OutParameter( InParameter&lt; V &gt; &amp;v, SerializationProtocolOut &amp;out) 
<a name="l00230"></a>00230             {
<a name="l00231"></a>00231                 RCF_UNUSED_VARIABLE(v);
<a name="l00232"></a>00232                 RCF_UNUSED_VARIABLE(out);
<a name="l00233"></a>00233             }
<a name="l00234"></a>00234         };
<a name="l00235"></a>00235 
<a name="l00236"></a>00236         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00237"></a>00237         <span class="keyword">class </span>OutParameter&lt;T &amp;&gt;
<a name="l00238"></a>00238         {
<a name="l00239"></a>00239         <span class="keyword">public</span>:
<a name="l00240"></a>00240             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_pointer&lt;T&gt;::type &gt;::value );
<a name="l00241"></a>00241             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_reference&lt;T&gt;::type &gt;::value );
<a name="l00242"></a>00242             OutParameter(T &amp;t, SerializationProtocolIn &amp;in, <span class="keywordtype">bool</span> oneway) 
<a name="l00243"></a>00243             {
<a name="l00244"></a>00244                 <span class="keywordflow">if</span> (!oneway)
<a name="l00245"></a>00245                 {
<a name="l00246"></a>00246                     in &gt;&gt; t; 
<a name="l00247"></a>00247                 }
<a name="l00248"></a>00248             }
<a name="l00249"></a>00249             <span class="keyword">template</span>&lt;<span class="keyword">typename</span> V&gt; OutParameter( InParameter&lt; V &gt; &amp;v, SerializationProtocolOut &amp;out) 
<a name="l00250"></a>00250             { 
<a name="l00251"></a>00251                 out &lt;&lt; v.get(); 
<a name="l00252"></a>00252             }
<a name="l00253"></a>00253         };
<a name="l00254"></a>00254 
<a name="l00255"></a>00255         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T = Vo<span class="keywordtype">id</span>&gt;
<a name="l00256"></a>00256         <span class="keyword">class </span>OutReturnValue 
<a name="l00257"></a>00257         {
<a name="l00258"></a>00258         <span class="keyword">public</span>:
<a name="l00259"></a>00259             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_pointer&lt;T&gt;::type &gt;::value );
<a name="l00260"></a>00260             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_reference&lt;T&gt;::type &gt;::value );
<a name="l00261"></a>00261             OutReturnValue(SerializationProtocolOut &amp;out, <span class="keyword">const</span> T &amp;t)
<a name="l00262"></a>00262             {
<a name="l00263"></a>00263                 out &lt;&lt; RCF::MethodInvocationResponse(<span class="keyword">false</span>); 
<a name="l00264"></a>00264                 out  &lt;&lt; t;
<a name="l00265"></a>00265             }
<a name="l00266"></a>00266         };
<a name="l00267"></a>00267 
<a name="l00268"></a>00268         <span class="keyword">template</span>&lt;&gt;
<a name="l00269"></a>00269         <span class="keyword">class </span>OutReturnValue&lt;Void&gt;
<a name="l00270"></a>00270         {
<a name="l00271"></a>00271         <span class="keyword">public</span>:
<a name="l00272"></a>00272             OutReturnValue(SerializationProtocolOut &amp;out, <span class="keywordtype">int</span> t)
<a name="l00273"></a>00273             {
<a name="l00274"></a>00274                 RCF_UNUSED_VARIABLE(t);
<a name="l00275"></a>00275                 out &lt;&lt; RCF::MethodInvocationResponse(<span class="keyword">false</span>); 
<a name="l00276"></a>00276             }
<a name="l00277"></a>00277         };
<a name="l00278"></a>00278 
<a name="l00279"></a>00279         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T = Vo<span class="keywordtype">id</span>&gt;
<a name="l00280"></a>00280         <span class="keyword">class </span>InReturnValue 
<a name="l00281"></a>00281         {
<a name="l00282"></a>00282         <span class="keyword">public</span>:
<a name="l00283"></a>00283             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_pointer&lt;T&gt;::type &gt;::value );
<a name="l00284"></a>00284             BOOST_STATIC_ASSERT( boost::mpl::not_&lt; <span class="keyword">typename</span> boost::is_reference&lt;T&gt;::type &gt;::value );
<a name="l00285"></a>00285             InReturnValue(ClientStub &amp;clientStub, SerializationProtocolIn &amp;in, SerializationProtocolOut &amp;out, <span class="keywordtype">bool</span> oneway);
<a name="l00286"></a>00286             T &amp;get();
<a name="l00287"></a>00287         <span class="keyword">private</span>:
<a name="l00288"></a>00288             T t_;
<a name="l00289"></a>00289         };
<a name="l00290"></a>00290 
<a name="l00291"></a>00291         <span class="keyword">template</span>&lt;&gt;
<a name="l00292"></a>00292         <span class="keyword">class </span>InReturnValue&lt;Void&gt; 
<a name="l00293"></a>00293         {
<a name="l00294"></a>00294         <span class="keyword">public</span>:
<a name="l00295"></a>00295             InReturnValue(ClientStub &amp;clientStub, SerializationProtocolIn &amp;in, SerializationProtocolOut &amp;out, <span class="keywordtype">bool</span> oneway);
<a name="l00296"></a>00296             Void get() { <span class="keywordflow">return</span> Void(); }
<a name="l00297"></a>00297         };
<a name="l00298"></a>00298 
<a name="l00299"></a>00299     } <span class="comment">// namespace IDL</span>
<a name="l00300"></a>00300 
<a name="l00301"></a>00301     <span class="comment">// ClientMarshal</span>
<a name="l00302"></a>00302 
<a name="l00303"></a>00303     <span class="keyword">template</span>&lt;
<a name="l00304"></a>00304         <span class="keyword">typename</span> R, 
<a name="l00305"></a>00305         <span class="keyword">typename</span> A1 = Meta::Null, 
<a name="l00306"></a>00306         <span class="keyword">typename</span> A2 = Meta::Null, 
<a name="l00307"></a>00307         <span class="keyword">typename</span> A3 = Meta::Null, 
<a name="l00308"></a>00308         <span class="keyword">typename</span> A4 = Meta::Null,
<a name="l00309"></a>00309         <span class="keyword">typename</span> A5 = Meta::Null,
<a name="l00310"></a>00310         <span class="keyword">typename</span> A6 = Meta::Null&gt;
<a name="l00311"></a>00311     <span class="keyword">class </span>ClientMarshal;
<a name="l00312"></a>00312 
<a name="l00313"></a>00313     <span class="comment">// NB: using this instead of ScopeGuard,because Borland C++ is not triggering ScopeGuard at all.</span>
<a name="l00314"></a>00314     <span class="comment">// At least with this class, it's triggered in debug builds (but not release apparently).</span>
<a name="l00315"></a>00315     <span class="keyword">class </span>ConnectionResetGuard
<a name="l00316"></a>00316     {
<a name="l00317"></a>00317     <span class="keyword">public</span>:
<a name="l00318"></a>00318         ConnectionResetGuard(ClientStub &amp;clientStub) :
<a name="l00319"></a>00319             mClientStub(clientStub),
<a name="l00320"></a>00320             mDismissed()
<a name="l00321"></a>00321         {}
<a name="l00322"></a>00322 
<a name="l00323"></a>00323         <span class="keywordtype">void</span> dismiss()
<a name="l00324"></a>00324         {
<a name="l00325"></a>00325             mDismissed = <span class="keyword">true</span>;
<a name="l00326"></a>00326         }
<a name="l00327"></a>00327 
<a name="l00328"></a>00328         ~ConnectionResetGuard()
<a name="l00329"></a>00329         {
<a name="l00330"></a>00330             <span class="keywordflow">if</span> (!mDismissed)
<a name="l00331"></a>00331             {
<a name="l00332"></a>00332                 <span class="keywordflow">try</span>
<a name="l00333"></a>00333                 {
<a name="l00334"></a>00334                     mClientStub.resetTransport();
<a name="l00335"></a>00335                 }
<a name="l00336"></a>00336                 <span class="keywordflow">catch</span>(...)
<a name="l00337"></a>00337                 {}
<a name="l00338"></a>00338             }
<a name="l00339"></a>00339         }
<a name="l00340"></a>00340 
<a name="l00341"></a>00341     <span class="keyword">private</span>:
<a name="l00342"></a>00342         ClientStub &amp;mClientStub;
<a name="l00343"></a>00343         <span class="keywordtype">bool</span> mDismissed;
<a name="l00344"></a>00344     };
<a name="l00345"></a>00345 
<a name="l00346"></a>00346     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> R&gt;
<a name="l00347"></a>00347     <span class="keyword">class </span>ClientMarshal&lt;R, Meta::Null, Meta::Null, Meta::Null, Meta::Null, Meta::Null, Meta::Null&gt;
<a name="l00348"></a>00348     {
<a name="l00349"></a>00349     <span class="keyword">public</span>:
<a name="l00350"></a>00350         R operator()(ClientStub &amp;clientStub, RemoteCallSemantics rcs, <span class="keyword">const</span> std::string &amp;subInterface, <span class="keywordtype">int</span> fnId)<span class="keyword"> const</span>
<a name="l00351"></a>00351 <span class="keyword">        </span>{
<a name="l00352"></a>00352             <span class="keywordtype">bool</span> oneway = (Oneway == rcs);
<a name="l00353"></a>00353             ConnectionResetGuard connectionResetGuard(clientStub);
<a name="l00354"></a>00354             RCF::IDL::DoRequest(clientStub, oneway, subInterface, fnId, clientStub.out);
<a name="l00355"></a>00355             RCF::IDL::InReturnValue&lt; R &gt; ret(clientStub, clientStub.in, clientStub.out, oneway);
<a name="l00356"></a>00356             connectionResetGuard.dismiss();
<a name="l00357"></a>00357             <span class="keywordflow">return</span> ret.get();
<a name="l00358"></a>00358         }
<a name="l00359"></a>00359     };
<a name="l00360"></a>00360 
<a name="l00361"></a>00361     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> R, <span class="keyword">typename</span> A1&gt;
<a name="l00362"></a>00362     <span class="keyword">class </span>ClientMarshal&lt;R,A1, Meta::Null, Meta::Null, Meta::Null, Meta::Null, Meta::Null&gt;
<a name="l00363"></a>00363     {
<a name="l00364"></a>00364     <span class="keyword">public</span>:
<a name="l00365"></a>00365         R operator()(ClientStub &amp;clientStub, RemoteCallSemantics rcs, <span class="keyword">const</span> std::string &amp;subInterface, <span class="keywordtype">int</span> fnId, A1 a1)<span class="keyword"> const</span>
<a name="l00366"></a>00366 <span class="keyword">        </span>{
<a name="l00367"></a>00367             <span class="keywordtype">bool</span> oneway = (Oneway == rcs);
<a name="l00368"></a>00368             ConnectionResetGuard connectionResetGuard(clientStub);
<a name="l00369"></a>00369             RCF::IDL::DoRequest(clientStub, oneway, subInterface, fnId, clientStub.out);
<a name="l00370"></a>00370             RCF::IDL::InParameter&lt; A1 &gt;(a1, clientStub.out);
<a name="l00371"></a>00371             RCF::IDL::InReturnValue&lt; R &gt; ret(clientStub, clientStub.in, clientStub.out, oneway);
<a name="l00372"></a>00372             RCF::IDL::OutParameter&lt; A1 &gt;(a1, clientStub.in, oneway);
<a name="l00373"></a>00373             connectionResetGuard.dismiss();
<a name="l00374"></a>00374             <span class="keywordflow">return</span> ret.get();
<a name="l00375"></a>00375         }
<a name="l00376"></a>00376     };
<a name="l00377"></a>00377 
<a name="l00378"></a>00378     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> R, <span class="keyword">typename</span> A1, <span class="keyword">typename</span> A2&gt;
<a name="l00379"></a>00379     <span class="keyword">class </span>ClientMarshal&lt;R,A1,A2, Meta::Null, Meta::Null, Meta::Null, Meta::Null &gt;
<a name="l00380"></a>00380     {
<a name="l00381"></a>00381     <span class="keyword">public</span>:
<a name="l00382"></a>00382         R operator()(ClientStub &amp;clientStub, RemoteCallSemantics rcs, <span class="keyword">const</span> std::string &amp;subInterface, <span class="keywordtype">int</span> fnId, A1 a1, A2 a2)<span class="keyword"> const</span>
<a name="l00383"></a>00383 <span class="keyword">        </span>{
<a name="l00384"></a>00384             <span class="keywordtype">bool</span> oneway = (Oneway == rcs);
<a name="l00385"></a>00385             ConnectionResetGuard connectionResetGuard(clientStub);
<a name="l00386"></a>00386             RCF::IDL::DoRequest(clientStub, oneway, subInterface, fnId, clientStub.out);
<a name="l00387"></a>00387             RCF::IDL::InParameter&lt; A1 &gt;(a1, clientStub.out);
<a name="l00388"></a>00388             RCF::IDL::InParameter&lt; A2 &gt;(a2, clientStub.out);
<a name="l00389"></a>00389             RCF::IDL::InReturnValue&lt; R &gt; ret(clientStub, clientStub.in, clientStub.out, oneway);
<a name="l00390"></a>00390             RCF::IDL::OutParameter&lt; A1 &gt;(a1, clientStub.in, oneway);
<a name="l00391"></a>00391             RCF::IDL::OutParameter&lt; A2 &gt;(a2, clientStub.in, oneway);
<a name="l00392"></a>00392             connectionResetGuard.dismiss();
<a name="l00393"></a>00393             <span class="keywordflow">return</span> ret.get();
<a name="l00394"></a>00394         }
<a name="l00395"></a>00395     };
<a name="l00396"></a>00396 
<a name="l00397"></a>00397     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> R, <span class="keyword">typename</span> A1, <span class="keyword">typename</span> A2, <span class="keyword">typename</span> A3&gt;
<a name="l00398"></a>00398     <span class="keyword">class </span>ClientMarshal&lt;R,A1,A2,A3, Meta::Null, Meta::Null, Meta::Null&gt;
<a name="l00399"></a>00399     {
<a name="l00400"></a>00400     <span class="keyword">public</span>:
<a name="l00401"></a>00401         R operator()(ClientStub &amp;clientStub, RemoteCallSemantics rcs, <span class="keyword">const</span> std::string &amp;subInterface, <span class="keywordtype">int</span> fnId, A1 a1, A2 a2, A3 a3)<span class="keyword"> const</span>
<a name="l00402"></a>00402 <span class="keyword">        </span>{
<a name="l00403"></a>00403             <span class="keywordtype">bool</span> oneway = (Oneway == rcs);
<a name="l00404"></a>00404             ConnectionResetGuard connectionResetGuard(clientStub);
<a name="l00405"></a>00405             RCF::IDL::DoRequest(clientStub, oneway, subInterface, fnId, clientStub.out);
<a name="l00406"></a>00406             RCF::IDL::InParameter&lt; A1 &gt;(a1, clientStub.out);
<a name="l00407"></a>00407             RCF::IDL::InParameter&lt; A2 &gt;(a2, clientStub.out);
<a name="l00408"></a>00408             RCF::IDL::InParameter&lt; A3 &gt;(a3, clientStub.out);
<a name="l00409"></a>00409             RCF::IDL::InReturnValue&lt; R &gt; ret(clientStub, clientStub.in, clientStub.out, oneway);
<a name="l00410"></a>00410             RCF::IDL::OutParameter&lt; A1 &gt;(a1, clientStub.in, oneway);
<a name="l00411"></a>00411             RCF::IDL::OutParameter&lt; A2 &gt;(a2, clientStub.in, oneway);
<a name="l00412"></a>00412             RCF::IDL::OutParameter&lt; A3 &gt;(a3, clientStub.in, oneway);
<a name="l00413"></a>00413             connectionResetGuard.dismiss();
<a name="l00414"></a>00414             <span class="keywordflow">return</span> ret.get();
<a name="l00415"></a>00415         }
<a name="l00416"></a>00416     };
<a name="l00417"></a>00417 
<a name="l00418"></a>00418     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> R, <span class="keyword">typename</span> A1, <span class="keyword">typename</span> A2, <span class="keyword">typename</span> A3, <span class="keyword">typename</span> A4&gt;
<a name="l00419"></a>00419     <span class="keyword">class </span>ClientMarshal&lt;R,A1,A2,A3,A4, Meta::Null, Meta::Null&gt;
<a name="l00420"></a>00420     {
<a name="l00421"></a>00421     <span class="keyword">public</span>:
<a name="l00422"></a>00422         R operator()(ClientStub &amp;clientStub, RemoteCallSemantics rcs, <span class="keyword">const</span> std::string &amp;subInterface, <span class="keywordtype">int</span> fnId, A1 a1, A2 a2, A3 a3, A4 a4)<span class="keyword"> const</span>
<a name="l00423"></a>00423 <span class="keyword">        </span>{
<a name="l00424"></a>00424             <span class="keywordtype">bool</span> oneway = (Oneway == rcs);
<a name="l00425"></a>00425             ConnectionResetGuard connectionResetGuard(clientStub);
<a name="l00426"></a>00426             RCF::IDL::DoRequest(clientStub, oneway, subInterface, fnId, clientStub.out);
<a name="l00427"></a>00427             RCF::IDL::InParameter&lt; A1 &gt;(a1, clientStub.out);
<a name="l00428"></a>00428             RCF::IDL::InParameter&lt; A2 &gt;(a2, clientStub.out);
<a name="l00429"></a>00429             RCF::IDL::InParameter&lt; A3 &gt;(a3, clientStub.out);
<a name="l00430"></a>00430             RCF::IDL::InParameter&lt; A4 &gt;(a4, clientStub.out);
<a name="l00431"></a>00431             RCF::IDL::InReturnValue&lt; R &gt; ret(clientStub, clientStub.in, clientStub.out, oneway);
<a name="l00432"></a>00432             RCF::IDL::OutParameter&lt; A1 &gt;(a1, clientStub.in, oneway);
<a name="l00433"></a>00433             RCF::IDL::OutParameter&lt; A2 &gt;(a2, clientStub.in, oneway);
<a name="l00434"></a>00434             RCF::IDL::OutParameter&lt; A3 &gt;(a3, clientStub.in, oneway);
<a name="l00435"></a>00435             RCF::IDL::OutParameter&lt; A4 &gt;(a4, clientStub.in, oneway);
<a name="l00436"></a>00436             connectionResetGuard.dismiss();
<a name="l00437"></a>00437             <span class="keywordflow">return</span> ret.get();
<a name="l00438"></a>00438         }
<a name="l00439"></a>00439     };
<a name="l00440"></a>00440 
<a name="l00441"></a>00441     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> R, <span class="keyword">typename</span> A1, <span class="keyword">typename</span> A2, <span class="keyword">typename</span> A3, <span class="keyword">typename</span> A4, <span class="keyword">typename</span> A5&gt;
<a name="l00442"></a>00442     <span class="keyword">class </span>ClientMarshal&lt;R,A1,A2,A3,A4,A5, Meta::Null&gt;
<a name="l00443"></a>00443     {
<a name="l00444"></a>00444     <span class="keyword">public</span>:
<a name="l00445"></a>00445         R operator()(ClientStub &amp;clientStub, RemoteCallSemantics rcs, <span class="keyword">const</span> std::string &amp;subInterface, <span class="keywordtype">int</span> fnId, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)<span class="keyword"> const</span>
<a name="l00446"></a>00446 <span class="keyword">        </span>{
<a name="l00447"></a>00447             <span class="keywordtype">bool</span> oneway = (Oneway == rcs);
<a name="l00448"></a>00448             ConnectionResetGuard connectionResetGuard(clientStub);
<a name="l00449"></a>00449             RCF::IDL::DoRequest(clientStub, oneway, subInterface, fnId, clientStub.out);
<a name="l00450"></a>00450             RCF::IDL::InParameter&lt; A1 &gt;(a1, clientStub.out);
<a name="l00451"></a>00451             RCF::IDL::InParameter&lt; A2 &gt;(a2, clientStub.out);
<a name="l00452"></a>00452             RCF::IDL::InParameter&lt; A3 &gt;(a3, clientStub.out);
<a name="l00453"></a>00453             RCF::IDL::InParameter&lt; A4 &gt;(a4, clientStub.out);
<a name="l00454"></a>00454             RCF::IDL::InParameter&lt; A5 &gt;(a5, clientStub.out);
<a name="l00455"></a>00455             RCF::IDL::InReturnValue&lt; R &gt; ret(clientStub, clientStub.in, clientStub.out, oneway);
<a name="l00456"></a>00456             RCF::IDL::OutParameter&lt; A1 &gt;(a1, clientStub.in, oneway);
<a name="l00457"></a>00457             RCF::IDL::OutParameter&lt; A2 &gt;(a2, clientStub.in, oneway);
<a name="l00458"></a>00458             RCF::IDL::OutParameter&lt; A3 &gt;(a3, clientStub.in, oneway);
<a name="l00459"></a>00459             RCF::IDL::OutParameter&lt; A4 &gt;(a4, clientStub.in, oneway);
<a name="l00460"></a>00460             RCF::IDL::OutParameter&lt; A5 &gt;(a5, clientStub.in, oneway);
<a name="l00461"></a>00461             connectionResetGuard.dismiss();
<a name="l00462"></a>00462             <span class="keywordflow">return</span> ret.get();
<a name="l00463"></a>00463         }
<a name="l00464"></a>00464     };
<a name="l00465"></a>00465 
<a name="l00466"></a>00466 } <span class="comment">// namespace RCF</span>
<a name="l00467"></a>00467 
<a name="l00468"></a>00468 <span class="preprocessor">#include &lt;RCF/Marshal.inl&gt;</span>
<a name="l00469"></a>00469 
<a name="l00470"></a>00470 <span class="preprocessor">#endif // ! INCLUDE_RCF_MARSHAL_HPP</span>
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Tue Sep 19 19:02:37 2006 for RCF by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.5 </small></address>
</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Australia Australia
Software developer, from Sweden and now living in Canberra, Australia, working on distributed C++ applications. When he is not programming, Jarl enjoys skiing and playing table tennis. He derives immense satisfaction from referring to himself in third person.

Comments and Discussions