|
xorp
|
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__