xorp

xrl_cmd_map.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2011 XORP, Inc and Others
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU Lesser General Public License, Version
00008 // 2.1, June 1999 as published by the Free Software Foundation.
00009 // Redistribution and/or modification of this program under the terms of
00010 // any other version of the GNU Lesser General Public License is not
00011 // permitted.
00012 // 
00013 // This program is distributed in the hope that it will be useful, but
00014 // WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00016 // see the GNU Lesser General Public License, Version 2.1, a copy of
00017 // which can be found in the XORP LICENSE.lgpl file.
00018 // 
00019 // XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00020 // http://xorp.net
00021 
00022 
00023 #ifndef __LIBXIPC_XRL_CMD_MAP_HH__
00024 #define __LIBXIPC_XRL_CMD_MAP_HH__
00025 
00026 
00027 
00028 
00029 
00030 
00031 #include "libxorp/callback.hh"
00032 #include "xrl.hh"
00033 #include "xrl_error.hh"
00034 
00035 
00036 
00037 
00038 
00039 // This the the original, synchronous, command callback.
00040 // Out-arguments and error code must be set by the time the function
00041 // returns.
00042 typedef
00043 XorpCallback2<const XrlCmdError, const XrlArgs&, XrlArgs*>::RefPtr
00044 XrlRecvSyncCallback;
00045 
00046 // This is the type of callback that a command implementation must
00047 // call if it wants to operate asynchronously.
00048 typedef
00049 XorpCallback2<void, const XrlCmdError &, const XrlArgs *>::RefPtr
00050 XrlRespCallback;
00051 
00052 // This is the new, asynchronous, command callback.  No errors are
00053 // returned, nor out-arguments passed.  Instead, the XrlRespCallback
00054 // is invoked with the results.
00055 typedef
00056 XorpCallback2<void, const XrlArgs&, XrlRespCallback>::RefPtr
00057 XrlRecvAsyncCallback;
00058 
00059 
00060 
00061 // We define some types depending on whether asynchronous
00062 // implementations are allowed.
00063 #ifdef XORP_ENABLE_ASYNC_SERVER
00064 
00065 // Asynchronous implementations do not return anything.
00066 typedef void XrlCmdRT;
00067 
00068 // To report an error, invoke the callback, and stop.
00069 #define XRL_CMD_RETURN_ERROR(OUT, ERR)  \
00070     do {                \
00071     (OUT)->dispatch((ERR), NULL);   \
00072     return;             \
00073     } while (0)
00074 
00075 // Responses are expressed through a callback.
00076 typedef XrlRespCallback XrlCmdOT;
00077 
00078 // The normal command implementation type is the asynchronous version.
00079 typedef XrlRecvAsyncCallback XrlRecvCallback;
00080 
00081 
00082 #else
00083 
00084 
00085 // Synchronous implementations return the error code.
00086 typedef const XrlCmdError XrlCmdRT;
00087 
00088 // To report an error, return it.
00089 #define XRL_CMD_RETURN_ERROR(OUT, ERR)  \
00090     do {                \
00091     return (ERR);           \
00092     } while (0)
00093 
00094 // Placeholders for out-arguments are supplied to the command
00095 // implementation.
00096 typedef XrlArgs* XrlCmdOT;
00097 
00098 // The normal command implementation type is the synchronous version.
00099 typedef XrlRecvSyncCallback XrlRecvCallback;
00100 
00101 #endif
00102 
00103 
00104 
00105 
00106 class XrlCmdEntry {
00107     // An asynchronous command implementation that calls a synchronous
00108     // one
00109     static void invoke_sync(const XrlArgs& in, XrlRespCallback out,
00110                 XrlRecvSyncCallback impl);
00111 
00112 public:
00113     // Make an asynchronous command implementation out of a
00114     // synchronous one.
00115     static XrlRecvAsyncCallback make_async_cb(const XrlRecvSyncCallback& cb) {
00116     return callback(&XrlCmdEntry::invoke_sync, cb);
00117     }
00118 
00119     XrlCmdEntry(const string& s, XrlRecvAsyncCallback cb) :
00120         _name(s), _cb(cb) {}
00121     XrlCmdEntry(const string& s, XrlRecvSyncCallback cb) :
00122         _name(s), _cb(make_async_cb(cb)) {}
00123 
00124 #ifdef XORP_USE_USTL
00125     XrlCmdEntry() { }
00126 #endif
00127 
00128     const string& name() const { return _name; }
00129 
00130     void dispatch(const XrlArgs& inputs, XrlRespCallback outputs) const {
00131     return _cb->dispatch(inputs, outputs);
00132     }
00133 
00134 protected:
00135     string          _name;
00136     XrlRecvAsyncCallback    _cb;
00137 };
00138 
00139 class XrlCmdMap :
00140     public NONCOPYABLE
00141 {
00142 public:
00143     typedef map<string, XrlCmdEntry> CmdMap;
00144 
00145     XrlCmdMap(const string& name = "anonymous") : _name(name) {}
00146     virtual ~XrlCmdMap() {}
00147 
00148     const string& name() const { return _name; }
00149 
00150     virtual bool add_handler_internal(const string& cmd,
00151                       const XrlRecvAsyncCallback& rcb);
00152 
00153     bool add_handler(const string& cmd, const XrlRecvAsyncCallback& rcb) {
00154     return add_handler_internal(cmd, rcb);
00155     }
00156 
00157     bool add_handler(const string& cmd, const XrlRecvSyncCallback& rcb) {
00158     return add_handler_internal(cmd, XrlCmdEntry::make_async_cb(rcb));
00159     }
00160 
00161     virtual bool remove_handler (const string& name);
00162 
00163     const XrlCmdEntry* get_handler(const string& name) const;
00164 
00165     uint32_t count_handlers() const;
00166 
00167     const XrlCmdEntry* get_handler(uint32_t index) const;
00168 
00169     void get_command_names(list<string>& names) const;
00170 
00174     virtual void finalize();
00175 
00176 protected:
00177     bool add_handler (const XrlCmdEntry& c);
00178 
00179 protected:
00180     const string _name;
00181 
00182     CmdMap _cmd_map;
00183 };
00184 
00185 #endif // __LIBXIPC_XRL_CMD_MAP_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations