00001 /* -*- c++ -*- */ 00002 /************************************************************************** 00003 Copyright (c) 2000-2001, Tony Garnock-Jones 00004 All rights reserved. 00005 00006 Redistribution and use in source and binary forms, with or without 00007 modification, are permitted provided that the following conditions are 00008 met: 00009 00010 * Redistributions of source code must retain the above copyright 00011 notice, this list of conditions and the following disclaimer. 00012 00013 * Redistributions in binary form must reproduce the above 00014 copyright notice, this list of conditions and the following 00015 disclaimer in the documentation and/or other materials provided 00016 with the distribution. 00017 00018 * Neither the names of the copyright holders nor the names of this 00019 software's contributors may be used to endorse or promote 00020 products derived from this software without specific prior 00021 written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00026 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 00027 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00028 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00029 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00030 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00031 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00032 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00033 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 **************************************************************************/ 00035 00036 /* -*- c++ -*- */ 00037 #ifndef MPS_Server_H 00038 #define MPS_Server_H 00039 00040 namespace MPS { 00041 00042 class Server; 00043 class InterfaceServer; 00044 00045 /** 00046 * Generalised server for MPS objects, proxies, and gateways. Responds 00047 * to requests which come in over a connection. Subclasses implement 00048 * particular request dispatch strategies. */ 00049 class Server { 00050 private: 00051 typedef map<string, string> boundNames_t; ///< A transport-vs-address map. 00052 boundNames_t boundNames; ///< All addresses this server is reachable at. 00053 00054 string objectName; ///< The human-readable name for this server object. 00055 00056 friend class Transport; ///< Allows access to bindName() and unbindName(). 00057 00058 /// Register an address that this server is available at. 00059 void bindName(Address const &addr) { 00060 boundNames[addr.getTransport()] = addr.getResolvedName(); 00061 } 00062 00063 /// Deregister an address that this server was available at. 00064 void unbindName(string const &transport) { 00065 boundNames.erase(transport); 00066 } 00067 00068 protected: 00069 /// Construct a Server with the given human-readable name. 00070 Server(string const &_o) 00071 : objectName(_o) 00072 {} 00073 00074 public: 00075 virtual ~Server() {} 00076 00077 /// Retrieve the symbolic/human name for this object. 00078 string const &getObjectName() const { return objectName; } 00079 00080 /** 00081 * Returns all addresses that this server has been bound to. */ 00082 vector<string> getBoundNames() const; 00083 00084 /** 00085 * Returns the address that this Interface has been bound to via a 00086 * particular Transport, or the empty-string if this Interface has 00087 * not been bound to the named transport. */ 00088 string getBoundName(string const &transportName) const { 00089 boundNames_t::const_iterator i = boundNames.find(transportName); 00090 return (i == boundNames.end()) ? "" : (*i).second; 00091 } 00092 00093 /// Dispatches an method request coming in over a connection. 00094 virtual void dispatch(InputStream &request, OutputStream &reply) = 0; 00095 }; 00096 00097 /////////////////////////////////////////////////////////////////////////// 00098 00099 /** 00100 * Base class for MPS object servers. The dispatcher here reads a 00101 * message, takes the first int from it, and uses it to index into a 00102 * list of request-handler function pointers, which then further 00103 * deconstruct the incoming message, call their implementation object, 00104 * and fill in a reply message, which is sent along the Connection by 00105 * the InterfaceServer::dispatch() method. */ 00106 class InterfaceServer: public Server { 00107 public: 00108 /** 00109 * This is the type that each method in the MPS 00110 * automatically-generated server-glue should have. The __impl 00111 * parameter is used to pass down a handle on the implementation 00112 * object; the __input and __output parameters are used for 00113 * communication with the client. 00114 * 00115 * Request handlers that do not wish to send a reply message 00116 * containing any data (ie. void-typed methods) should not fill in 00117 * any bytes in __output. The dispatch() method below takes this as 00118 * an indication of a void response. 00119 * 00120 * @param __impl the implementation object this method is operating on 00121 * @param __input the input message 00122 * @param __output the reply message 00123 */ 00124 typedef void (*request_handler_t)(ref<Interface> const &__impl, 00125 InputStream &__input, 00126 OutputStream &__output); 00127 00128 private: 00129 friend class Transport; // for special-casing locally-bound interfaces. 00130 00131 typedef vector<request_handler_t> requesthandlervec_t; ///< A list of method-handlers. 00132 00133 ref<Interface> __impl; ///< Our implementation object. 00134 requesthandlervec_t methods; ///< All the methods we implement 00135 00136 public: 00137 /// Create an MPS object server called objectName, implemented by impl. 00138 InterfaceServer(string const &objectName, ref<Interface> const &impl) 00139 : Server(objectName), 00140 __impl(impl), 00141 methods() 00142 { 00143 __impl->_setInterfaceServer(this); 00144 } 00145 00146 protected: 00147 /// Called by (automatically-generated) subclasses to register method-handlers. 00148 void registerMethod(int methodIndex, string const &methodName, request_handler_t handler); 00149 00150 public: 00151 virtual void dispatch(InputStream &request, OutputStream &reply); 00152 }; 00153 00154 } 00155 00156 #endif