// Execute multiple calls and return the results in an array. bool XmlRpcServerConnection::executeMulticall(const std::string& in_methodName, XmlRpcValue& params, XmlRpcValue& result) { if (in_methodName != SYSTEM_MULTICALL) return false; // There ought to be 1 parameter, an array of structs if (params.size() != 1 || params[0].getType() != XmlRpcValue::TypeArray) throw XmlRpcException(SYSTEM_MULTICALL + ": Invalid argument (expected an array)"); int nc = params[0].size(); result.setSize(nc); for (int i=0; i<nc; ++i) { if ( ! params[0][i].hasMember(METHODNAME) || ! params[0][i].hasMember(PARAMS)) { result[i][FAULTCODE] = -1; result[i][FAULTSTRING] = SYSTEM_MULTICALL + ": Invalid argument (expected a struct with members methodName and params)"; continue; } const std::string& methodName = params[0][i][METHODNAME]; XmlRpcValue& methodParams = params[0][i][PARAMS]; XmlRpcValue resultValue; resultValue.setSize(1); try { if ( ! executeMethod(methodName, methodParams, resultValue[0]) && ! executeMulticall(methodName, params, resultValue[0])) { result[i][FAULTCODE] = -1; result[i][FAULTSTRING] = methodName + ": unknown method name"; } else result[i] = resultValue; } catch (const XmlRpcException& fault) { result[i][FAULTCODE] = fault.getCode(); result[i][FAULTSTRING] = fault.getMessage(); } } return true; }
void testArray(XmlRpcValue const& d) { // Array XmlRpcValue a; a.setSize(4); a[0] = 1; a[1] = std::string("two"); a[2] = 43.7; a[3] = "four"; assert(int(a[0]) == 1); assert(a[2] == d); char csaXml[] = "<value><array>\n" " <data>\n" " <value><i4>1</i4></value> \n" " <value> <string>two</string></value>\n" " <value><double>43.7</double></value>\n" " <value>four</value>\n" " </data>\n" "</array></value>"; int offset = 0; XmlRpcValue aXml(csaXml, &offset); assert(a == aXml); }
void XmlRpcServer::listMethods(XmlRpcValue& result) { int i = 0; result.setSize(_methods.size()+1); for (MethodMap::iterator it=_methods.begin(); it != _methods.end(); ++it) result[i++] = it->first; // Multicall support is built into XmlRpcServer::executeRequest result[i] = MULTICALL; }
void XMLRPC2DIServer::amarg2xmlrpcval(AmArg& a, XmlRpcValue& result) { switch (a.getType()) { case AmArg::CStr: result = string(a.asCStr()); break; case AmArg::Int: result=a.asInt(); break; case AmArg::Double: result=a.asDouble(); break; case AmArg::Array: result.setSize(a.size()); for (size_t i=0;i<a.size();i++) { // duh... recursion... amarg2xmlrpcval(a.get(i), result[i]); } break; default: { WARN("unsupported return value type %d\n", a.getType()); } break; // TODO: do sth with the data here ? } }
void XMLRPC2DIServer::amarg2xmlrpcval(const AmArg& a, XmlRpcValue& result) { switch (a.getType()) { case AmArg::CStr: // DBG("a->X CSTR\n"); result = string(a.asCStr()); break; case AmArg::Int: // DBG("a->X INT\n"); result=a.asInt(); break; case AmArg::Double: // DBG("a->X DOUBLE\n"); result=a.asDouble(); break; case AmArg::Array: // DBG("a->X ARRAY size %u\n", a.size()); result.setSize(a.size()); for (size_t i=0;i<a.size();i++) { // duh... recursion... amarg2xmlrpcval(a.get(i), result[i]); } break; case AmArg::Struct: // DBG("a->X STRUCT size %u\n", a.size()); for (AmArg::ValueStruct::const_iterator it = a.begin(); it != a.end(); it++) { // duh... recursion... amarg2xmlrpcval(it->second, result[it->first]); } break; default: { WARN("unsupported return value type %d\n", a.getType()); } break; // TODO: do sth with the data here ? } }
void testStruct() { XmlRpcValue struct1; struct1["i4"] = 1; struct1["str"] = "two"; struct1["d"] = 43.7; XmlRpcValue a; a.setSize(4); a[0] = 1; a[1] = std::string("two"); a[2] = 43.7; a[3] = "four"; assert(struct1["d"] == a[2]); char csStructXml[] = "<value><struct>\n" " <member>\n" " <name>i4</name> \n" " <value><i4>1</i4></value> \n" " </member>\n" " <member>\n" " <name>d</name> \n" " <value><double>43.7</double></value>\n" " </member>\n" " <member>\n" " <name>str</name> \n" " <value> <string>two</string></value>\n" " </member>\n" "</struct></value>"; int offset = 0; XmlRpcValue structXml(csStructXml, &offset); assert(struct1 == structXml); XmlRpcValue astruct; astruct["array"] = a; assert(astruct["array"][2] == struct1["d"]); for (int i=0; i<10; i++) { XmlRpcValue Event; Event["Name"] = "string"; Event.clear(); const int NELMTS = 100; int ii; for (ii=0; ii< NELMTS; ++ii) { char buf[40]; sprintf(buf,"%d", ii); Event[std::string(buf)] = buf; } Event.clear(); for (ii=0; ii< NELMTS; ++ii) { char buf[40]; sprintf(buf,"%d", ii); if (ii != NELMTS/2) Event[std::string(buf)] = ii; else for (int jj=0; jj< NELMTS; ++jj) { char bufj[40]; sprintf(bufj,"%d", jj); Event[std::string(buf)][std::string(bufj)] = bufj; } } for (ii=0; ii< NELMTS; ++ii) { char buf[40]; sprintf(buf,"%d", ii); if (ii != NELMTS/2) assert(Event[std::string(buf)] == XmlRpcValue(ii)); else assert(Event[std::string(buf)].size() == NELMTS); } } }