ulxr_dispatcher.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002         ulxr_dispatcher.cpp  -  answer rpc requests ("rpc-server")
00003                              -------------------
00004     begin                : Sat Mar 23 2002
00005     copyright            : (C) 2002-2007 by Ewald Arnold
00006     email                : ulxmlrpcpp@ewald-arnold.de
00007 
00008     $Id: ulxr_dispatcher.cpp 1028 2007-07-25 15:11:31Z ewald-arnold $
00009 
00010  ***************************************************************************/
00011 
00012 /**************************************************************************
00013  *
00014  * This program is free software; you can redistribute it and/or modify
00015  * it under the terms of the GNU Lesser General Public License as
00016  * published by the Free Software Foundation; either version 2 of the License,
00017  * or (at your option) any later version.
00018  *
00019  * This program is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program; if not, write to the Free Software
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00027  *
00028  ***************************************************************************/
00029 
00030 // #define ULXR_SHOW_TRACE
00031 // #define ULXR_DEBUG_OUTPUT
00032 // #define ULXR_SHOW_READ
00033 // #define ULXR_SHOW_WRITE
00034 // #define ULXR_SHOW_XML
00035 
00036 #define ULXR_NEED_EXPORTS
00037 #include <ulxmlrpcpp/ulxmlrpcpp.h>  // always first header
00038 
00039 #if defined(__BORLANDC__) || defined (_MSC_VER)
00040 #include <utility>
00041 #endif
00042 
00043 #include <algorithm>
00044 #include <memory>
00045 
00046 #include <ulxmlrpcpp/ulxr_dispatcher.h>
00047 #include <ulxmlrpcpp/ulxr_protocol.h>
00048 #include <ulxmlrpcpp/ulxr_callparse.h>
00049 #include <ulxmlrpcpp/ulxr_callparse_wb.h>
00050 #include <ulxmlrpcpp/ulxr_except.h>
00051 #include <ulxmlrpcpp/ulxr_signature.h>
00052 
00053 namespace ulxr {
00054 
00055 
00056 ULXR_API_IMPL0
00057   Dispatcher::MethodCallDescriptor::MethodCallDescriptor(const MethodCall &call)
00058 {
00059   method_name = call.getMethodName();
00060   documentation = ULXR_PCHAR("");
00061   return_signature = ULXR_PCHAR("");
00062 
00063   signature = call.getSignature(false);
00064 
00065   calltype = CallNone;
00066   invoked = 0;
00067   enabled = true;
00068 }
00069 
00070 
00071 ULXR_API_IMPL0 Dispatcher::MethodCallDescriptor::MethodCallDescriptor(
00072     CallType type,
00073     const CppString &ret_sig,
00074     const CppString &name,
00075     const CppString &sig,
00076     const CppString &help)
00077 {
00078   method_name = name;
00079   documentation = help;
00080   return_signature = ret_sig;
00081   signature = sig;
00082   calltype = type;
00083   invoked = 0;
00084   enabled = true;
00085 }
00086 
00087 
00088 ULXR_API_IMPL(unsigned long) Dispatcher::MethodCallDescriptor::getInvoked() const
00089 {
00090   return invoked;
00091 }
00092 
00093 
00094 ULXR_API_IMPL(void) Dispatcher::MethodCallDescriptor::incInvoked() const
00095 {
00096   ++invoked;
00097 }
00098 
00099 
00100 ULXR_API_IMPL(bool) Dispatcher::MethodCallDescriptor::isEnabled() const
00101 {
00102   return enabled;
00103 }
00104 
00105 
00106 ULXR_API_IMPL(void) Dispatcher::MethodCallDescriptor::setEnabled(bool ena) const
00107 {
00108   enabled = ena;
00109 }
00110 
00111 
00112 ULXR_API_IMPL(CppString)
00113   Dispatcher::MethodCallDescriptor::getSignature(bool with_name,
00114                                                  bool with_return) const
00115 {
00116   ULXR_TRACE(ULXR_PCHAR("getSignature"));
00117   CppString s;
00118   CppString rs = return_signature;
00119   if (rs.length() == 0)
00120     rs = ULXR_PCHAR("void");  // emergency brake
00121 
00122   CppString sig = signature;
00123   if (sig.length() == 0)
00124     sig = ULXR_PCHAR("void");  // emergency brake
00125 
00126   if (with_return && with_name)
00127     s = rs + ULXR_PCHAR(" ") + method_name + ULXR_PCHAR("(") + sig + ULXR_PCHAR(")");
00128 
00129   else if (!with_return && with_name)
00130     s = method_name + ULXR_PCHAR("(") + sig + ULXR_PCHAR(")");
00131 
00132   else if (with_return && !with_name)
00133   {
00134     s = rs;
00135     if (sig.length() != 0)
00136       s += ULXR_PCHAR(",") + sig;
00137   }
00138 
00139   else if (!with_return && !with_name)
00140     s = sig;
00141 
00142   return s;
00143 }
00144 
00145 
00146 ULXR_API_IMPL(CppString) Dispatcher::MethodCallDescriptor::getMethodName() const
00147 {
00148   return method_name;
00149 }
00150 
00151 
00152 ULXR_API_IMPL(CppString) Dispatcher::MethodCallDescriptor::getParameterSignature() const
00153 {
00154   return signature;
00155 }
00156 
00157 
00158 ULXR_API_IMPL(CppString) Dispatcher::MethodCallDescriptor::getReturnValueSignature() const
00159 {
00160   return return_signature;
00161 }
00162 
00163 
00164 ULXR_API_IMPL(CppString) Dispatcher::MethodCallDescriptor::getDocumentation() const
00165 {
00166   return documentation;
00167 }
00168 
00169 
00170 ULXR_API_IMPL(Dispatcher::CallType) Dispatcher::MethodCallDescriptor::getCallType() const
00171 {
00172   return calltype;
00173 }
00174 
00175 
00176 
00178 
00179 
00180 
00181 ULXR_API_IMPL0 Dispatcher::Dispatcher (Protocol* prot, bool wbxml)
00182 {
00183   wbxml_mode = wbxml;
00184   protocol = prot;
00185   setupSystemMethods();
00186 }
00187 
00188 
00189 void free_dynamic_method (const Dispatcher::MethodCallMap::value_type &method)
00190 {
00191    if (method.first.getCallType() == Dispatcher::CallDynamic)
00192    {
00193      ULXR_TRACE(ULXR_PCHAR("Now deleting dynamic function: ") + method.first.getSignature(true, true));
00194      delete method.second.dynamic_function;
00195      const_cast<Dispatcher::MethodCallMap::value_type&>(method).second.dynamic_function = 0;
00196    }
00197 }
00198 
00199 
00200 ULXR_API_IMPL0 Dispatcher::~Dispatcher ()
00201 {
00202    ULXR_TRACE(ULXR_PCHAR("~Dispatcher ()"));
00203    std::for_each(methodcalls.begin(), methodcalls.end(), free_dynamic_method);
00204    methodcalls.clear();
00205 }
00206 
00207 
00208 ULXR_API_IMPL(void) Dispatcher::removeMethod(const CppString &name)
00209 {
00210    ULXR_TRACE(ULXR_PCHAR("removeMethod ") << name);
00211    MethodCallMap::iterator it;
00212    for(it = methodcalls.begin(); it != methodcalls.end(); ++it)
00213    {
00214      if (name == (*it).first.getMethodName())
00215      {
00216        free_dynamic_method(*it);
00217        methodcalls.erase(it);
00218      }
00219    }
00220 }
00221 
00222 
00223 ULXR_API_IMPL(void) Dispatcher::addMethod (StaticMethodCall_t func,
00224                                         const CppString &ret_signature,
00225                                         const CppString &name,
00226                                         const CppString &signature,
00227                                         const CppString &help)
00228 {
00229   ULXR_TRACE(ULXR_PCHAR("addMethod(static)"));
00230   MethodCallDescriptor desc (CallStatic, ret_signature, name, signature, help);
00231   MethodCall_t mct;
00232   mct.static_function = func;
00233   addMethodDescriptor (desc, mct);
00234 }
00235 
00236 
00237 ULXR_API_IMPL(void) Dispatcher::addMethod (DynamicMethodCall_t func,
00238                                         const CppString &ret_signature,
00239                                         const CppString &name,
00240                                         const CppString &signature,
00241                                         const CppString &help)
00242 {
00243   ULXR_TRACE(ULXR_PCHAR("addMethod(dynamic)"));
00244   MethodCallDescriptor desc (CallDynamic, ret_signature, name, signature, help);
00245   MethodCall_t mct;
00246   mct.dynamic_function = func;  // takes ownership
00247   addMethodDescriptor (desc, mct);
00248 }
00249 
00250 
00251 ULXR_API_IMPL(void) Dispatcher::addMethod (SystemMethodCall_t func,
00252                                         const CppString &ret_signature,
00253                                         const CppString &name,
00254                                         const CppString &signature,
00255                                         const CppString &help)
00256 {
00257   ULXR_TRACE(ULXR_PCHAR("addMethod(system)"));
00258   MethodCallDescriptor desc (CallSystem, ret_signature, name, signature, help);
00259   MethodCall_t mct;
00260   mct.system_function = func;
00261   addMethodDescriptor (desc, mct);
00262 }
00263 
00264 
00265 ULXR_API_IMPL(void) Dispatcher::addMethod (StaticMethodCall_t func,
00266                                         const Signature &ret_signature,
00267                                         const CppString &name,
00268                                         const Signature &signature,
00269                                         const CppString &help)
00270 {
00271   addMethod(func, ret_signature.getString(), name, signature.getString(), help);
00272 }
00273 
00274 
00275 ULXR_API_IMPL(void) Dispatcher::addMethod (DynamicMethodCall_t func,
00276                                         const Signature &ret_signature,
00277                                         const CppString &name,
00278                                         const Signature &signature,
00279                                         const CppString &help)
00280 {
00281   addMethod(func, ret_signature.getString(), name, signature.getString(), help);
00282 }
00283 
00284 
00285 ULXR_API_IMPL(void) Dispatcher::addMethod (SystemMethodCall_t func,
00286                                         const Signature &ret_signature,
00287                                         const CppString &name,
00288                                         const Signature &signature,
00289                                         const CppString &help)
00290 {
00291   addMethod(func, ret_signature.getString(), name, signature.getString(), help);
00292 }
00293 
00294 
00295 ULXR_API_IMPL(void)
00296   Dispatcher::addMethodDescriptor (const MethodCallDescriptor &desc,
00297                                    MethodCall_t mct)
00298 {
00299   ULXR_TRACE("addMethodDescriptor " << desc.getSignature(true, false));
00300   if (methodcalls.find(desc) != methodcalls.end() )
00301     throw RuntimeException(ApplicationError,
00302                            ulxr_i18n(ULXR_PCHAR("Method exists already: ") + desc.getSignature(true, false)));
00303 
00304   methodcalls.insert(std::make_pair(desc, mct));
00305 }
00306 
00307 
00308 ULXR_API_IMPL(MethodCall) Dispatcher::waitForCall(int _timeout)
00309 {
00310   ULXR_TRACE(ULXR_PCHAR("waitForCall"));
00311   if (!protocol->isOpen())
00312   {
00313     if (!protocol->accept(_timeout))
00314       return MethodCall();  // // @todo throw exception?
00315   }
00316   else
00317     protocol->resetConnection();
00318 
00319 #ifdef ULXR_ENFORCE_NON_PERSISTENT
00320   protocol->setPersistent(false);
00321 #endif
00322 
00323   char buffer[ULXR_RECV_BUFFER_SIZE];
00324   char *buff_ptr;
00325 
00326 
00327   std::auto_ptr<XmlParserBase> parser;
00328   MethodCallParserBase *cpb = 0;
00329   if (wbxml_mode)
00330   {
00331     ULXR_TRACE(ULXR_PCHAR("waitForCall in WBXML"));
00332     MethodCallParserWb *cp = new MethodCallParserWb();
00333     cpb = cp;
00334 #ifdef _MSC_VER
00335   std::auto_ptr<XmlParserBase> temp(cp);
00336   parser = temp;
00337 #else
00338     parser.reset(cp);
00339 #endif
00340   }
00341   else
00342   {
00343     ULXR_TRACE(ULXR_PCHAR("waitForCall in XML"));
00344     MethodCallParser *cp = new MethodCallParser();
00345     cpb = cp;
00346 #ifdef _MSC_VER
00347   std::auto_ptr<XmlParserBase> temp(cp);
00348   parser = temp;
00349 #else
00350     parser.reset(cp);
00351 #endif
00352   }
00353 
00354   bool done = false;
00355   long readed;
00356   while (!done && ((readed = protocol->readRaw(buffer, sizeof(buffer))) > 0) )
00357   {
00358     buff_ptr = buffer;
00359     while (readed > 0)
00360     {
00361       Protocol::State state = protocol->connectionMachine(buff_ptr, readed);
00362       if (state == Protocol::ConnError)
00363         throw ConnectionException(TransportError, ulxr_i18n(ULXR_PCHAR("network problem occured")), 500);
00364 
00365       else if (state == Protocol::ConnSwitchToBody)
00366       {
00367         if (!protocol->hasBytesToRead())
00368         {
00369 #ifdef ULXR_SHOW_READ
00370           Cpp8BitString super_data(buff_ptr, readed);
00371           while ((readed = protocol->readRaw(buffer, sizeof(buffer))) > 0)
00372             super_data.append(buffer, readed);
00373           ULXR_DOUT_READ(ULXR_PCHAR("superdata 1 start:\n")
00374                          << ULXR_GET_STRING(super_data)
00375                          << ULXR_PCHAR("superdata 1 end:\n" ));
00376 #endif
00377           throw ConnectionException(NotConformingError,
00378                                     ulxr_i18n(ULXR_PCHAR("Content-Length of message not available")), 411);
00379         }
00380       }
00381 
00382       else if (state == Protocol::ConnBody)
00383       {
00384         ULXR_DOUT_XML(ULXR_GET_STRING(std::string(buff_ptr, readed)));
00385         if (!parser->parse(buff_ptr, readed, done))
00386         {
00387 //          ULXR_DOUT("errline: " << parser->XML_GetCurrentLineNumber());
00388 //          ULXR_DWRITE(buff_ptr, readed);
00389 //          ULXR_DOUT("") ;
00390 
00391           throw XmlException(parser->mapToFaultCode(parser->getErrorCode()),
00392                              ulxr_i18n(ULXR_PCHAR("Problem while parsing xml request")),
00393                              parser->getCurrentLineNumber(),
00394                              ULXR_GET_STRING(parser->getErrorString(parser->getErrorCode())));
00395         }
00396         readed = 0;
00397       }
00398     }
00399 
00400     if (!protocol->hasBytesToRead())
00401 //        || parser->isComplete())
00402       done = true;
00403   }
00404 
00405   ULXR_TRACE(ULXR_PCHAR("waitForCall got " << cpb->getMethodCall().getXml()));
00406   return cpb->getMethodCall();
00407 }
00408 
00409 
00410 ULXR_API_IMPL(const Dispatcher::MethodCallDescriptor) * const Dispatcher::getMethod(unsigned index)
00411 {
00412   ULXR_TRACE(ULXR_PCHAR("getMethod"));
00413   unsigned i = 0;
00414   MethodCallMap::iterator it;
00415   for (it = methodcalls.begin(); it != methodcalls.end(); ++it, ++i)
00416     if (i == index)
00417       return &(*it).first;
00418 
00419  throw RuntimeException(ApplicationError,
00420                         ulxr_i18n(ULXR_PCHAR("Index too big for Dispatcher::getMethod()")));
00421 }
00422 
00423 
00424 ULXR_API_IMPL(unsigned) Dispatcher::numMethods() const
00425 {
00426   ULXR_TRACE(ULXR_PCHAR("numMethods"));
00427   unsigned i = 0;
00428   MethodCallMap::const_iterator it;
00429   for (it = methodcalls.begin(); it != methodcalls.end(); ++it)
00430     ++i;
00431   return i;
00432 }
00433 
00434 
00435 ULXR_API_IMPL(bool) Dispatcher::hasMethod(const MethodCall &call) const
00436 {
00437   MethodCallDescriptor desc(call);
00438   return methodcalls.find(desc) != methodcalls.end();
00439 }
00440 
00441 
00442 ULXR_API_IMPL(MethodResponse) Dispatcher::dispatchCall(const MethodCall &call) const
00443 {
00444   ULXR_TRACE(ULXR_PCHAR("dispatchCall"));
00445   try
00446   {
00447     return dispatchCallLoc(call);
00448   }
00449 
00450   catch (Exception &ex)
00451   {
00452     return MethodResponse (ex.getFaultCode(), ex.why());
00453   }
00454 
00455   catch (std::exception &ex)
00456   {
00457     return MethodResponse (ApplicationError, ULXR_GET_STRING(ex.what()));
00458   }
00459 
00460   catch (...)
00461   {
00462     return MethodResponse (SystemError, ulxr_i18n(ULXR_PCHAR("Unknown error occured")));
00463   }
00464 }
00465 
00466 
00467 ULXR_API_IMPL(MethodResponse) Dispatcher::dispatchCallLoc(const MethodCall &call) const
00468 {
00469   ULXR_TRACE(ULXR_PCHAR("dispatchCallLoc: ") << call.getMethodName());
00470 
00471   MethodCallDescriptor desc(call);
00472   MethodCallMap::const_iterator it;
00473   if ((it = methodcalls.find(desc)) != methodcalls.end() )
00474   {
00475     MethodCall_t mc = (*it).second;
00476     if (!(*it).first.isEnabled())
00477     {
00478       CppString s = ulxr_i18n(ULXR_PCHAR("method \""));
00479       s += desc.getSignature(true, false);
00480       s += ulxr_i18n(ULXR_PCHAR("\": currently unavailable."));
00481       return MethodResponse (MethodNotFoundError, s);
00482     }
00483 
00484     else
00485     {
00486       if ((*it).first.calltype == CallSystem)
00487       {
00488         ULXR_TRACE(ULXR_PCHAR("Now calling system function: ") + (*it).first.getSignature(true, true));
00489         (*it).first.incInvoked();
00490         return mc.system_function(call, this);
00491       }
00492 
00493       else if ((*it).first.calltype == CallStatic)
00494       {
00495         ULXR_TRACE(ULXR_PCHAR("Now calling static function: ") + (*it).first.getSignature(true, true));
00496         (*it).first.incInvoked();
00497         return mc.static_function(call);
00498       }
00499 
00500       else if ((*it).first.calltype == CallDynamic)
00501       {
00502         ULXR_TRACE(ULXR_PCHAR("Now calling dynamic function: ") + (*it).first.getSignature(true, true));
00503         (*it).first.incInvoked();
00504         return mc.dynamic_function->call(call);
00505       }
00506 
00507       else
00508       {
00509         CppString s = ulxr_i18n(ULXR_PCHAR("method \""));
00510         s += desc.getSignature(true, false);
00511         s += ulxr_i18n(ULXR_PCHAR("\": internal problem to find method."));
00512         return MethodResponse (MethodNotFoundError, s);
00513       }
00514     }
00515   }
00516 
00517   CppString s = ulxr_i18n(ULXR_PCHAR("method \""));
00518   s += desc.getSignature(true, false);
00519   s += ulxr_i18n(ULXR_PCHAR("\" unknown method and/or signature."));
00520   return MethodResponse (MethodNotFoundError, s);
00521 }
00522 
00523 
00524 ULXR_API_IMPL(void) Dispatcher::sendResponse(const MethodResponse &resp)
00525 {
00526   ULXR_TRACE(ULXR_PCHAR("sendResponse"));
00527   protocol->sendRpcResponse(resp, wbxml_mode);
00528 }
00529 
00530 
00531 ULXR_API_IMPL(void) Dispatcher::setupSystemMethods()
00532 {
00533   ULXR_TRACE(ULXR_PCHAR("setupSystemMethods"));
00534 
00535   addMethod(&Dispatcher::xml_pretty_print,
00536             ULXR_PCHAR(""), ULXR_PCHAR("ulxmlrpcpp.pretty_print"), ULXR_PCHAR("bool"),
00537             ulxr_i18n(ULXR_PCHAR("Enable pretty-printed xml responses.")));
00538 
00539   //--
00540 
00541   addMethod(&Dispatcher::system_listMethods,
00542             ULXR_PCHAR("array"), ULXR_PCHAR("system.listMethods"), ULXR_PCHAR(""),
00543             ulxr_i18n(ULXR_PCHAR("Lists all methods implemented by this server.")));
00544 
00545   addMethod( &Dispatcher::system_listMethods,
00546             ULXR_PCHAR("array"),ULXR_PCHAR("system.listMethods"), ULXR_PCHAR("string"),
00547             ulxr_i18n(ULXR_PCHAR("Lists all methods implemented by this server (overloaded).")));
00548 
00549   addMethod( &Dispatcher::system_methodSignature,
00550             ULXR_PCHAR("array"), ULXR_PCHAR("system.methodSignature"), ULXR_PCHAR("string"),
00551             ulxr_i18n(ULXR_PCHAR("Returns an array of possible signatures for this method.")));
00552 
00553   addMethod(&Dispatcher::system_methodHelp,
00554             ULXR_PCHAR("string"), ULXR_PCHAR("system.methodHelp"), ULXR_PCHAR("string"),
00555             ulxr_i18n(ULXR_PCHAR("Returns a documentation string describing the use of this method.")));
00556 
00557   addMethod(&Dispatcher::system_getCapabilities,
00558             ULXR_PCHAR("struct"), ULXR_PCHAR("system.getCapabilities"), ULXR_PCHAR(""),
00559             ulxr_i18n(ULXR_PCHAR("Returns Structs describing available capabilities.")));
00560 }
00561 
00562 
00563 ULXR_API_IMPL(MethodResponse)
00564    Dispatcher::xml_pretty_print(const MethodCall &calldata,
00565                                 const Dispatcher *disp)
00566 {
00567   ULXR_TRACE(ULXR_PCHAR("xml_pretty_print"));
00568   if (calldata.numParams() > 1)
00569     throw ParameterException(InvalidMethodParameterError,
00570                              ulxr_i18n(ULXR_PCHAR("At most 1 parameter allowed for \"system.listMethods\"")));
00571 
00572   if (   calldata.numParams() == 1
00573       && calldata.getParam(0).getType() != RpcBoolean)
00574     throw ParameterException(InvalidMethodParameterError,
00575                              ulxr_i18n(ULXR_PCHAR("Parameter 1 not of type \"Boolean\" \"ulxmlrpcpp.xml_pretty_print\"")));
00576 
00577   bool enable = Boolean(calldata.getParam(0)).getBoolean();
00578   enableXmlPrettyPrint(enable);
00579   return MethodResponse (Void());
00580 }
00581 
00582 
00583 ULXR_API_IMPL(MethodResponse)
00584    Dispatcher::system_listMethods(const MethodCall &calldata,
00585                                   const Dispatcher *disp)
00586 {
00587   ULXR_TRACE(ULXR_PCHAR("system_listMethods"));
00588   if (calldata.numParams() > 1)
00589     throw ParameterException(InvalidMethodParameterError,
00590                              ulxr_i18n(ULXR_PCHAR("At most 1 parameter allowed for \"system.listMethods\"")));
00591 
00592   if (   calldata.numParams() == 1
00593       && calldata.getParam(0).getType() != RpcStrType)
00594     throw ParameterException(InvalidMethodParameterError,
00595                              ulxr_i18n(ULXR_PCHAR("Parameter 1 not of type \"String\" \"system.listMethods\"")));
00596 
00597 // FIXME: what to do with param 1 if present ??
00598 
00599   Array arr;
00600   CppString m_prev;
00601 
00602   MethodCallMap::const_iterator it;
00603   for (it = disp->methodcalls.begin(); it != disp->methodcalls.end(); ++it)
00604     if (   m_prev != (*it).first.method_name
00605         && (*it).first.method_name.length() != 0)
00606     {
00607       arr.addItem(RpcString((*it).first.method_name));
00608       m_prev = (*it).first.method_name;
00609     }
00610   return MethodResponse (arr);
00611 }
00612 
00613 
00614 ULXR_API_IMPL(MethodResponse)
00615    Dispatcher::system_methodSignature(const MethodCall &calldata,
00616                                       const Dispatcher *disp)
00617 {
00618   ULXR_TRACE(ULXR_PCHAR("system_methodSignature"));
00619   if (calldata.numParams() != 1)
00620     throw ParameterException(InvalidMethodParameterError,
00621                              ulxr_i18n(ULXR_PCHAR("Exactly 1 parameter allowed for \"system.methodSignature\"")));
00622 
00623   if (calldata.getParam(0).getType() != RpcStrType)
00624     throw ParameterException(InvalidMethodParameterError,
00625                              ulxr_i18n(ULXR_PCHAR("Parameter 1 not of type \"String\" \"system.listMethods\"")));
00626 
00627   RpcString vs = calldata.getParam(0);
00628   CppString name = vs.getString();
00629   MethodCallMap::const_iterator it;
00630   Array ret_arr;
00631   for (it = disp->methodcalls.begin(); it != disp->methodcalls.end(); ++it)
00632   {
00633     Array sigarr;
00634     CppString sig = (*it).first.getSignature(true, true);
00635     if (name == (*it).first.method_name && sig.length() != 0)
00636     {
00637       std::size_t pos;
00638       while ((pos = sig.find(',')) != CppString::npos)
00639       {
00640         sigarr.addItem(RpcString(sig.substr(0, pos)));
00641         sig.erase(0, pos+1);
00642       }
00643       sigarr.addItem(RpcString(sig));
00644       ret_arr.addItem(sigarr);
00645     }
00646   }
00647 
00648   if (ret_arr.size() == 0)
00649     return MethodResponse (Integer(1));  // non-Array ==< no signatures
00650   else
00651     return MethodResponse (ret_arr);
00652 }
00653 
00654 
00655 ULXR_API_IMPL(MethodResponse)
00656    Dispatcher::system_methodHelp(const MethodCall &calldata,
00657                                  const Dispatcher *disp)
00658 {
00659   ULXR_TRACE(ULXR_PCHAR("system_methodHelp"));
00660   if (calldata.numParams() != 1)
00661     throw ParameterException(InvalidMethodParameterError,
00662                              ulxr_i18n(ULXR_PCHAR("Exactly 1 parameter allowed for \"system.methodHelp\"")));
00663 
00664   if (calldata.getParam(0).getType() != RpcStrType)
00665     throw ParameterException(InvalidMethodParameterError,
00666                              ulxr_i18n(ULXR_PCHAR("Parameter 1 not of type \"String\" \"system.listMethods\"")));
00667 
00668   RpcString vs = calldata.getParam(0);
00669   CppString name = vs.getString();
00670   CppString s;
00671 
00672   MethodCallMap::const_iterator it;
00673   CppString s_prev;
00674   for (it = disp->methodcalls.begin(); it != disp->methodcalls.end(); ++it)
00675     if (name == (*it).first.method_name && (*it).first.documentation.length() != 0)
00676     {
00677       if (   s_prev != (*it).first.documentation
00678           && (*it).first.documentation.length() != 0)
00679       {
00680         if (s.length() != 0)
00681           s = ULXR_PCHAR("* ") +s + ULXR_PCHAR("\n* ");
00682         s += (*it).first.documentation;
00683       }
00684       s_prev = (*it).first.documentation;
00685     }
00686 
00687   return MethodResponse (RpcString(s));
00688 }
00689 
00690 
00691 ULXR_API_IMPL(void) Dispatcher::getCapabilities (Struct &str) const
00692 {
00693   // parent::getCapabilities (str);  just in case..
00694   str.addMember(ULXR_PCHAR("specUrl"),
00695                RpcString(ULXR_PCHAR("http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php")));
00696   str.addMember(ULXR_PCHAR("specVersion"), Integer(20010516));
00697 }
00698 
00699 
00700 ULXR_API_IMPL(MethodResponse)
00701   Dispatcher::system_getCapabilities(const MethodCall &calldata,
00702                                      const Dispatcher *disp)
00703 {
00704   if (calldata.numParams() > 1)
00705     throw ParameterException(InvalidMethodParameterError,
00706                              ulxr_i18n(ULXR_PCHAR("No parameters allowed for \"system.listMethods\"")));
00707 
00708   Struct sysCap;
00709   disp->getCapabilities(sysCap);
00710 
00711   Struct opStr;
00712   opStr.addMember(ULXR_PCHAR("faults_interop"), sysCap);
00713   return MethodResponse (opStr);
00714 }
00715 
00716 
00717 ULXR_API_IMPL(Protocol*) Dispatcher::getProtocol() const
00718 {
00719   return protocol;
00720 }
00721 
00722 
00723 ULXR_API_IMPL(void) Dispatcher::setProtocol(Protocol *prot)
00724 {
00725   protocol = prot;
00726 }
00727 
00728 namespace hidden {
00729 
00730 ULXR_API_IMPL0 MethodWrapperBase::~MethodWrapperBase()
00731 {
00732 }
00733 
00734 }
00735 
00736 }  // namespace ulxr
00737 

Generated on Sun Aug 19 20:08:57 2007 for ulxmlrpcpp by  doxygen 1.5.1