00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #define ULXR_NEED_EXPORTS
00037 #include <ulxmlrpcpp/ulxmlrpcpp.h>
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");
00121
00122 CppString sig = signature;
00123 if (sig.length() == 0)
00124 sig = ULXR_PCHAR("void");
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;
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();
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
00388
00389
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
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
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));
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
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 }
00737