home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / mnl-rpc++-2.3.1 / part01 / stub.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-24  |  6.6 KB  |  236 lines

  1. // -*- c++ -*-
  2. /* 
  3. Copyright (C) 1991 Peter Bersen
  4.  
  5. This file is part of the rpc++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  
  17. Modified and partially rewritten March 1992 by Michael N. Lipp,
  18. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  19. conditions apply without change to any modified or new parts.
  20. */
  21.  
  22. static char _rpcpp_stub_cc_[]
  23. = "stub.cc,v 2.5 1992/12/06 18:57:55 mnl Exp";
  24.  
  25. // stub.cc,v
  26. // Revision 2.5  1992/12/06  18:57:55  mnl
  27. // Fixed various bugs and added some Methods.
  28. //
  29. // Revision 2.4  1992/08/08  13:23:13  mnl
  30. // Space allocated for result turned out to be local to a CLIENT*, thus
  31. // "res", "resmax" and "resproc" have been made member variables of
  32. // RpcStub.
  33. //
  34. // Revision 2.3  1992/06/15  19:12:46  mnl
  35. // Fixed a few bugs, clarified interface.
  36. //
  37. // Revision 2.2  1992/06/13  14:27:04  mnl
  38. // Adapted to (patched) gcc-2.2. Fixed several bugs.
  39. //
  40. // Revision 2.1.1.1  1992/03/08  13:28:42  mnl
  41. // Initial mnl version.
  42. //
  43.  
  44. #ifdef __GNUG__
  45. #pragma implementation
  46. #endif
  47.  
  48. #include <stream.h>
  49. #include <memory.h>
  50. #include <assert.h>
  51. #include "rpc++/stub.h"
  52.  
  53. timeval RpcStub::defaultTimeout = { 25, 0 };
  54.  
  55. void RpcStub::init (u_long prog, u_long vers,
  56.            char* srv, timeval timo, bool connect)
  57. {
  58.   errorState = noError;
  59.   program = prog;
  60.   version = vers;
  61.   server = srv;
  62.   timeout = timo;
  63.   svc = 0;
  64.   res = 0;
  65.   resmax = 0;
  66.   resproc = 0;
  67.   if (connect)
  68.     Reconnect ();
  69.   else
  70.     errorState = notConnected;
  71. }
  72.  
  73. RpcStub::~RpcStub ()
  74. {
  75.   if (resproc) // "Call" has been called at least once,
  76.     clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call
  77.   if (svc)
  78.     clnt_destroy (svc);
  79. }
  80.  
  81. void* RpcStub::HandleError ()
  82. {
  83.   switch (errorState)
  84.     {
  85.     case notConnected:
  86.       cerr << "rpc++: Stub has not been connected to server.\n";
  87.     case cantCreate:
  88.       cerr << clnt_spcreateerror ("rpc++") << '\n';
  89.       break;
  90.     case cantCall:
  91.       cerr << clnt_sperror (svc, "rpc++") << '\n';
  92.       exit (1);
  93.     }
  94.   return 0; // suppress compiler warning
  95. }
  96.  
  97. void RpcStub::Reconnect (bool handle_errors)
  98. {
  99.   if (resproc) // "Call" has been called
  100.     {
  101.       clnt_freeres (svc, resproc, res); // free data allocated by clnt_call
  102.       resproc = 0;
  103.     }
  104.   if (svc)
  105.     {
  106.       clnt_destroy (svc);
  107.     }
  108.   svc = clnt_create (server, program, version, "tcp"); // connect to client
  109.   if (svc == 0) // failed ?
  110.     {
  111.       if (handle_errors)
  112.     HandleError (cantCreate);
  113.       errorState = notConnected;
  114.       return;
  115.     }
  116.   clnt_control (svc, CLSET_TIMEOUT, &timeout);
  117.   errorState = noError;
  118. }
  119.  
  120. void* RpcStub::Call (RpcRequest& req, void* in, bool handle_errors)
  121. {
  122.   void* args[] = { in };
  123.   return DoCall (req, args, handle_errors);
  124. }
  125.  
  126. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, bool handle_errors)
  127. {
  128.   void* args[] = { in0, in1 };
  129.   return DoCall (req, args, handle_errors);
  130. }
  131.  
  132. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  133.              bool handle_errors)
  134. {
  135.   void* args[] = { in0, in1, in2 };
  136.   return DoCall (req, args, handle_errors);
  137. }
  138.  
  139. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  140.              void* in3, bool handle_errors)
  141. {
  142.   void* args[] = { in0, in1, in2, in3 };
  143.   return DoCall (req, args, handle_errors);
  144. }
  145.  
  146. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  147.              void* in3, void* in4, bool handle_errors)
  148. {
  149.   void* args[] = { in0, in1, in2, in3, in4 };
  150.   return DoCall (req, args, handle_errors);
  151. }
  152.  
  153. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  154.              void* in3, void* in4, void* in5, bool handle_errors)
  155. {
  156.   void* args[] = { in0, in1, in2, in3, in4, in5 };
  157.   return DoCall (req, args, handle_errors);
  158. }
  159.  
  160. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  161.              void* in3, void* in4, void* in5, void* in6,
  162.              bool handle_errors)
  163. {
  164.   void* args[] = { in0, in1, in2, in3, in4, in5, in6 };
  165.   return DoCall (req, args, handle_errors);
  166. }
  167.  
  168. void* RpcStub::Call (RpcRequest& req, void** ins, bool handle_errors)
  169. {
  170.   return DoCall (req, ins, handle_errors);
  171. }
  172.  
  173. void* RpcStub::DoCall (RpcRequest& req, void** args, bool handle_errors)
  174. {
  175.   if (! OK () )
  176.     {
  177.       if (! handle_errors)
  178.     return 0;
  179.       return HandleError ();
  180.     }
  181.   if (resproc) // "Call" has been called previously,
  182.     clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call
  183.   resproc = 0;
  184.   if (req.OutInfo()->Size () > resmax) // enough space for result?
  185.     {
  186.       delete res; // delete old result buffer
  187.       res = new char[resmax = req.OutInfo()->Size ()]; // get a new one
  188.     }
  189.   if (req.OutInfo()->Size () > 0 ) // preset result (everyone does it, why?)
  190.     memset (res, 0, req.OutInfo()->Size ());
  191.  
  192.   curReq = &req;
  193.   curArgs = args;
  194.   return ReCall (handle_errors);
  195. }
  196.  
  197. void* RpcStub::ReCall (bool handle_errors)
  198. {
  199.   static const timeval nullTimeout = { 0, 0 };
  200.  
  201.   if (resproc) // "ReCall" has been called before.
  202.     clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call
  203.   resproc = curReq->OutInfo()->Proc (); // note current output deserializer
  204.   XdrSeqInfo xsi = { curReq->InInfo (), curArgs };
  205.   if (curReq->Type () == RpcRequest::normal)
  206.     {
  207.       if (clnt_call (svc, curReq->RequestNumber (), // do call
  208.              Xdr::XdrParams, &xsi,
  209.              curReq->OutInfo()->Proc (), res,
  210.              timeout) != RPC_SUCCESS)
  211.     {
  212.       if (! handle_errors)
  213.         return 0;
  214.       return HandleError (cantCall);
  215.     }
  216.       return res ? res : &nullTimeout; // if the return type is void,
  217.       // res may be 0 although the call succeeded. To simplify error
  218.       // checking if handle_errors is FALSE, we return a value != 0.
  219.     }
  220.  
  221.   // curReq->Type () is batched or async
  222.   enum clnt_stat callres;
  223.   callres = clnt_call (svc, curReq->RequestNumber (), // do call
  224.                Xdr::XdrParams, &xsi,
  225.                (curReq->Type () == RpcRequest::batched
  226.                 ? (xdrproc_t)0 : xdr_void), res,
  227.                nullTimeout);
  228.   if (callres != RPC_SUCCESS && callres != RPC_TIMEDOUT)
  229.     {
  230.       if (! handle_errors)
  231.     return 0;
  232.       return HandleError (cantCall);
  233.     }
  234.   return res ? res : &nullTimeout;
  235. }
  236.