void XmlRpcValue::assertArray(int in_size) const { if (_type != TypeArray) throw XmlRpcException("type error: expected an array"); else if (int(_value.asArray->size()) < in_size) throw XmlRpcException("range error: array index too large"); }
// STATIC ProtocolUtilities::BuddyListPtr BuddyListParser::ExtractBuddyListFromXMLRPCReply(XmlRpcEpi &call) { XmlRpcCall *xmlrpcCall = call.GetXMLRPCCall(); if (!xmlrpcCall) throw XmlRpcException("Failed to read buddy list, no XMLRPC Reply to read!"); XMLRPC_REQUEST request = xmlrpcCall->GetReply(); if (!request) throw XmlRpcException("Failed to read buddy list, no XMLRPC Reply to read!"); XMLRPC_VALUE result = XMLRPC_RequestGetData(request); if (!result) throw XmlRpcException("Failed to read buddy list, the XMLRPC Reply did not contain any data!"); XMLRPC_VALUE buddy_list_node = XMLRPC_VectorGetValueWithID(result, "buddy-list"); if (!buddy_list_node || XMLRPC_GetValueType(buddy_list_node) != xmlrpc_vector) throw XmlRpcException("Failed to read buddy list, buddy-list in the reply was not properly formed!"); ProtocolUtilities::BuddyListPtr buddy_list = ProtocolUtilities::BuddyListPtr(new ProtocolUtilities::BuddyList()); XMLRPC_VALUE item = XMLRPC_VectorRewind(buddy_list_node); while(item) { XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(item); if (type == xmlrpc_vector) // xmlrpc-epi handles structs as arrays. { RexUUID id; int rights_given = 0; int rights_has = 0; XMLRPC_VALUE val = XMLRPC_VectorGetValueWithID(item, "buddy_id"); if (val && XMLRPC_GetValueType(val) == xmlrpc_string) id.FromString( XMLRPC_GetValueString(val) ); val = XMLRPC_VectorGetValueWithID(item, "buddy_rights_given"); if (val && XMLRPC_GetValueType(val) == xmlrpc_type_int) rights_given = XMLRPC_GetValueInt(val); val = XMLRPC_VectorGetValueWithID(item, "buddy_rights_has"); if (val && XMLRPC_GetValueType(val) == xmlrpc_type_int) rights_has = XMLRPC_GetValueInt(val); ProtocolUtilities::Buddy *buddy = new ProtocolUtilities::Buddy(id, rights_given, rights_has); buddy_list->AddBuddy(buddy); } item = XMLRPC_VectorNext(buddy_list_node); } return buddy_list; }
// Type checking void XmlRpcValue::assertTypeOrInvalid(Type t) { if (_type == TypeInvalid) { _type = t; switch (_type) { // Ensure there is a valid value for the type case TypeString: _value.asString = new std::string(); break; case TypeDateTime: _value.asTime = new struct tm(); break; case TypeBase64: _value.asBinary = new BinaryData(); break; case TypeArray: _value.asArray = new ValueArray(); break; case TypeStruct: _value.asStruct = new ValueStruct(); break; default: _value.asBinary = 0; break; } } else if (_type != t) throw XmlRpcException("type error"); }
// Type checking void XmlRpcValue::assertType(Type t) const { if (_type != t) { throw XmlRpcException("type error"); } }
void XmlRpcValue::assertStruct() { if (_type == TypeInvalid) { _type = TypeStruct; _value.asStruct = new ValueStruct(); } else if (_type != TypeStruct) throw XmlRpcException("type error: expected a struct"); }
// Works for arrays. void XmlRpcValue::popFront() { switch (_type) { case TypeArray: _value.asArray->erase(_value.asArray->begin()); return; default: break; } throw XmlRpcException("type error"); }
XMLRPC_REQUEST XmlRpcConnection::Send(const char* data) { HttpUtilities::HttpRequest request; request.SetUrl(strUrl_); request.SetRequestData("text/xml", data); request.SetMethod(HttpUtilities::HttpRequest::Post); request.Perform(); const std::vector<u8> response_data = request.GetResponseData(); if (!request.GetSuccess()) throw XmlRpcException(std::string("XmlRpcEpi exception in XmlRpcConnection::Send() " + request.GetReason())); if (response_data.size() == 0) throw XmlRpcException(std::string("XmlRpcEpi exception in XmlRpcConnection::Send() response data size was zero: ")); // Convert the XML string to a XMLRPC reply structure. return XMLRPC_REQUEST_FromXML((const char*)&response_data[0], (int)(response_data.size()), 0); }
void XmlRpcValue::assertArray(int size) { if (_type == TypeInvalid) { _type = TypeArray; _value.asArray = new ValueArray(size); } else if (_type == TypeArray) { if (int(_value.asArray->size()) < size) _value.asArray->resize(size); } else throw XmlRpcException("type error: expected an array"); }
// Works for strings, binary data, arrays, and structs. int XmlRpcValue::size() const { switch (_type) { case TypeString: return int(_value.asString->size()); case TypeBase64: return int(_value.asBinary->size()); case TypeArray: return int(_value.asArray->size()); case TypeStruct: return int(_value.asStruct->size()); default: break; } throw XmlRpcException("type error"); }
void XMLRPC2DIServerDIMethod::execute(XmlRpcValue& params, XmlRpcValue& result) { try { if (params.size() < 2) { DBG("XMLRPC2DI: ERROR: need at least factory name" " and function name to call\n"); throw XmlRpcException("need at least factory name" " and function name to call", 400); } string fact_name = params[0]; string fct_name = params[1]; DBG("XMLRPC2DI: factory '%s' function '%s'\n", fact_name.c_str(), fct_name.c_str()); // get args AmArg args; XMLRPC2DIServer::xmlrpcval2amarg(params, args, 2); AmDynInvokeFactory* di_f = AmPlugIn::instance()->getFactory4Di(fact_name); if(!di_f){ throw XmlRpcException("could not get factory", 500); } AmDynInvoke* di = di_f->getInstance(); if(!di){ throw XmlRpcException("could not get instance from factory", 500); } AmArg ret; di->invoke(fct_name, args, ret); XMLRPC2DIServer::amarg2xmlrpcval(ret, result); } catch (const XmlRpcException& e) { throw; } catch (const AmDynInvoke::NotImplemented& e) { throw XmlRpcException("Exception: AmDynInvoke::NotImplemented: " + e.what, 504); } catch (const AmArg::OutOfBoundsException& e) { throw XmlRpcException("Exception: AmArg out of bounds - paramter number mismatch.", 300); } catch (const AmArg::TypeMismatchException& e) { throw XmlRpcException("Exception: Type mismatch in arguments.", 300); } catch (const string& e) { throw XmlRpcException("Exception: "+e, 500); } catch (...) { throw XmlRpcException("Exception occured.", 500); } }
void XMLRPC2DIServer::xmlrpcval2amarg(XmlRpcValue& v, AmArg& a, unsigned int start_index) { if (v.valid()) { for (int i=start_index; i<v.size();i++) { switch (v[i].getType()) { case XmlRpcValue::TypeInt: { a.push(AmArg((int)v[i])); } break; case XmlRpcValue::TypeDouble:{ a.push(AmArg((double)v[i])); } break; case XmlRpcValue::TypeString:{ a.push(AmArg(((string)v[i]).c_str())); } break; // TODO: support more types (datetime, struct, ...) default: throw XmlRpcException("unsupported parameter type", 400); }; } } }
void XMLRPC2DIServer::xmlrpcval2amarg(XmlRpcValue& v, AmArg& a, unsigned int start_index) { if (v.valid()) { for (int i=start_index; i<v.size();i++) { switch (v[i].getType()) { case XmlRpcValue::TypeInt: { /* DBG("X->A INT\n");*/ a.push(AmArg((int)v[i])); } break; case XmlRpcValue::TypeDouble:{ /* DBG("X->A DBL\n");*/ a.push(AmArg((double)v[i])); } break; case XmlRpcValue::TypeString:{ /* DBG("X->A STR\n");*/ a.push(AmArg(((string)v[i]).c_str())); } break; case XmlRpcValue::TypeArray: { // DBG("X->A ARR\n"); a.push(AmArg()); a[a.size()-1].assertArray(0); AmArg arr; xmlrpcval2amarg(v[i], a[a.size()-1], 0); } break; // TODO: support more types (datetime, struct, ...) default: throw XmlRpcException("unsupported parameter type", 400); }; } } }
void DIMethodProxy::execute(XmlRpcValue& params, XmlRpcValue& result) { try { if (NULL == di_factory) { throw XmlRpcException("could not get DI factory", 500); } AmDynInvoke* di = di_factory->getInstance(); if(NULL == di){ throw XmlRpcException("could not get instance from factory", 500); } AmArg args, ret; XMLRPC2DIServer::xmlrpcval2amarg(params, args); DBG("XMLRPC2DI '%s': function '%s'\n", server_method_name.c_str(), di_method_name.c_str()); di->invoke(di_method_name, args, ret); XMLRPC2DIServer::amarg2xmlrpcval(ret, result); } catch (const XmlRpcException& e) { throw; } catch (const AmDynInvoke::NotImplemented& e) { throw XmlRpcException("Exception: AmDynInvoke::NotImplemented: " + e.what, 504); } catch (const AmArg::OutOfBoundsException& e) { throw XmlRpcException("Exception: AmArg out of bounds - paramter number mismatch.", 300); } catch (const AmArg::TypeMismatchException& e) { throw XmlRpcException("Exception: Type mismatch in arguments.", 300); } catch (const string& e) { throw XmlRpcException("Exception: "+e, 500); } catch (...) { throw XmlRpcException("Exception occured.", 500); } }