Example #1
0
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);
}
Example #2
0
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);
}