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
1.2.6 written by Dimitri van Heesch,
© 1997-2001