Value XmlRpcSystemMethods::SystemMulticall( const Request::Parameters& parameters) const { const Value dummyId; Value::Array result; for (auto& call : parameters.at(0).AsArray()) { try { if (call[xml::METHOD_NAME_TAG].AsString() == SYSTEM_MULTICALL) { throw InternalErrorFault("Recursive system.multicall forbidden"); } auto& array = call[xml::PARAMS_TAG].AsArray(); Request::Parameters callParams(array.begin(), array.end()); auto retval = myDispatcher.Invoke( call[xml::METHOD_NAME_TAG].AsString(), callParams, dummyId); retval.ThrowIfFault(); Value::Array a; a.emplace_back(std::move(retval.GetResult())); result.push_back(std::move(a)); } catch (const Fault& ex) { Value::Struct fault; fault[xml::FAULT_CODE_NAME] = ex.GetCode(); fault[xml::FAULT_STRING_NAME] = ex.GetString(); result.push_back(std::move(fault)); } catch (const std::exception& ex) { Value::Struct fault; fault[xml::FAULT_CODE_NAME] = 0; fault[xml::FAULT_STRING_NAME] = ex.what(); result.push_back(std::move(fault)); } catch (...) { Value::Struct fault; fault[xml::FAULT_CODE_NAME] = 0; fault[xml::FAULT_STRING_NAME] = "Unknown error"; result.push_back(std::move(fault)); } } return std::move(result); }
Value XmlRpcSystemMethods::SystemMethodSignature( const std::string& methodName) const { try { auto& method = myDispatcher.GetMethod(methodName); if (!method.IsHidden()) { auto& signatures = method.GetSignatures(); if (signatures.empty()) { return SIGNATURE_UNDEFINED; } Value::Array result; result.reserve(signatures.size()); for (auto& signature : signatures) { Value::Array types; types.reserve(signature.size()); for (auto type : signature) { switch (type) { case Value::Type::ARRAY: types.emplace_back(xml::ARRAY_TAG); break; case Value::Type::BINARY: types.emplace_back(xml::BASE_64_TAG); break; case Value::Type::BOOLEAN: types.emplace_back(xml::BOOLEAN_TAG); break; case Value::Type::DATE_TIME: types.emplace_back(xml::DATE_TIME_TAG); break; case Value::Type::DOUBLE: types.emplace_back(xml::DOUBLE_TAG); break; case Value::Type::INTEGER_32: types.emplace_back(xml::INTEGER_32_TAG); break; case Value::Type::INTEGER_64: types.emplace_back(xml::INTEGER_64_TAG); break; case Value::Type::NIL: // Only useful for return value if (types.empty()) { types.emplace_back(xml::NIL_TAG); } break; case Value::Type::STRING: types.emplace_back(xml::STRING_TAG); break; case Value::Type::STRUCT: types.emplace_back(xml::STRUCT_TAG); break; } } result.emplace_back(std::move(types)); } return std::move(result); } } catch (...) { // Ignore } throw Fault("No method " + methodName); }