// 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; }
bool XMLRPC::bytesToString(std::string* _destination) { // Clear the destination before adding any chars. #if HAVE_STRING_CLEAR == 1 _destination->clear(); #else _destination->erase(_destination->begin(), _destination->end()); #endif XMLRPC_VALUE v = getNextValue(); if(XMLRPC_GetValueType(v) != xmlrpc_string) { return 0; } const char* s = XMLRPC_GetValueString(v); if(s == 0) { return false; } _destination->append(s); return true; }
bool XMLRPC::getBytes(t_byteP* _bytes, t_uint &_size) { *_bytes = 0; _size = 0; BTG_ICHECK(genericSDTDeserialize<t_uint>(&_size)); if(_size == 0) { return true; } XMLRPC_VALUE v = getNextValue(); if(XMLRPC_GetValueType(v) != xmlrpc_base64) { return 0; } // Determine size and get pointer _size = XMLRPC_GetValueStringLen(v); const char *p = XMLRPC_GetValueBase64(v); // Copy from xmlrpc-epi internal buffer to new buffer *_bytes = new t_byte[_size]; for (t_uint i=0; i < _size; i++) { (*_bytes)[i] = p[i]; } return true; }
bool XMLRPC::bytesToBool(bool & _destination) { XMLRPC_VALUE v = getNextValue(); if(XMLRPC_GetValueType(v) != xmlrpc_boolean) { return 0; } int res = XMLRPC_GetValueBoolean(v); switch (res) { case 0: _destination = false; break; case 1: _destination = true; break; default: return false; } success(); return true; }
bool XMLRPC::bytesToFloat(t_float* _destination) { XMLRPC_VALUE v = getNextValue(); if(XMLRPC_GetValueType(v) != xmlrpc_double) { return 0; } double d = XMLRPC_GetValueDouble(v); (*_destination) = static_cast<t_float>(d); return true; }
t_int XMLRPC::genericSDTDeserialize(destinationType *_destination) { destinationType d; XMLRPC_VALUE v=getNextValue(); if(XMLRPC_GetValueType(v) != xmlrpc_int) { return 0; } d = XMLRPC_GetValueInt(v); (*_destination) = d; return sizeof(d); }
bool XMLRPC::getByte(t_byte & _byte) { XMLRPC_VALUE v = getNextValue(); if(XMLRPC_GetValueType(v) != xmlrpc_int) { return 0; } int res = XMLRPC_GetValueInt(v); _byte = static_cast<t_byte>(res); success(); return true; }
/* system.describeMethods() callback */ static XMLRPC_VALUE xi_system_describe_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { XMLRPC_VALUE xParams = XMLRPC_VectorRewind(XMLRPC_RequestGetData(input)); XMLRPC_VALUE xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VALUE xMethodList = XMLRPC_CreateVector("methodList", xmlrpc_vector_array); XMLRPC_VALUE xTypeList = NULL; int bAll = 1; /* lazy loading of introspection data */ check_docs_loaded(server, userData); xTypeList = XMLRPC_VectorGetValueWithID(server->xIntrospection, "typeList"); XMLRPC_AddValueToVector(xResponse, xTypeList); XMLRPC_AddValueToVector(xResponse, xMethodList); /* check if we have any param */ if(xParams) { /* check if string or vector (1 or n) */ XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(xParams); if(type == xmlrpc_string) { /* just one. spit it out. */ describe_method(server, xMethodList, XMLRPC_GetValueString(xParams)); bAll = 0; } else if(type == xmlrpc_vector) { /* multiple. spit all out */ XMLRPC_VALUE xIter = XMLRPC_VectorRewind(xParams); while(xIter) { describe_method(server, xMethodList, XMLRPC_GetValueString(xIter)); xIter = XMLRPC_VectorNext(xParams); } bAll = 0; } } /* otherwise, default to sending all methods */ if(bAll) { q_iter qi = Q_Iter_Head_F(&server->methodlist); while( qi ) { server_method* sm = Q_Iter_Get_F(qi); if(sm) { XMLRPC_AddValueToVector(xMethodList, sm->desc); } qi = Q_Iter_Next_F(qi); } } return xResponse; }
xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VALUE node, XMLRPC_REQUEST_TYPE request_type, int depth) { #define BUF_SIZE 512 xml_element* root = NULL; if (node) { char buf[BUF_SIZE]; XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(node); XMLRPC_VECTOR_TYPE vtype = XMLRPC_GetVectorType(node); xml_element* elem_val = xml_elem_new(); /* special case for when root element is not an array */ if (depth == 0 && !(type == xmlrpc_vector && vtype == xmlrpc_vector_array && request_type == xmlrpc_request_call) ) { int bIsFault = (vtype == xmlrpc_vector_struct && XMLRPC_VectorGetValueWithID(node, ELEM_FAULTCODE)); xml_element* next_el = XMLRPC_to_xml_element_worker(NULL, node, request_type, depth + 1); if (next_el) { Q_PushTail(&elem_val->children, next_el); } elem_val->name = strdup(bIsFault ? ELEM_FAULT : ELEM_PARAMS); } else { switch (type) { case xmlrpc_empty: /* treat null value as empty string in xmlrpc. */ case xmlrpc_string: elem_val->name = strdup(ELEM_STRING); simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node)); break; case xmlrpc_int: elem_val->name = strdup(ELEM_INT); snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node)); simplestring_add(&elem_val->text, buf); break; case xmlrpc_boolean: elem_val->name = strdup(ELEM_BOOLEAN); snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node)); simplestring_add(&elem_val->text, buf); break; case xmlrpc_double: elem_val->name = strdup(ELEM_DOUBLE); snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node)); simplestring_add(&elem_val->text, buf); break; case xmlrpc_datetime: elem_val->name = strdup(ELEM_DATETIME); simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node)); break; case xmlrpc_base64: { struct buffer_st buf; elem_val->name = strdup(ELEM_BASE64); base64_encode(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node)); simplestring_addn(&elem_val->text, buf.data, buf.offset ); buffer_delete(&buf); } break; case xmlrpc_vector: { XMLRPC_VECTOR_TYPE my_type = XMLRPC_GetVectorType(node); XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node); xml_element* root_vector_elem = elem_val; switch (my_type) { case xmlrpc_vector_array: { if(depth == 0) { elem_val->name = strdup(ELEM_PARAMS); } else { /* Hi my name is Dave and I like to make things as confusing * as possible, thus I will throw in this 'data' element * where it absolutely does not belong just so that people * cannot code arrays and structs in a similar and straight * forward manner. Have a good day. * * GRRRRRRRRR! */ xml_element* data = xml_elem_new(); data->name = strdup(ELEM_DATA); elem_val->name = strdup(ELEM_ARRAY); Q_PushTail(&elem_val->children, data); root_vector_elem = data; } } break; case xmlrpc_vector_mixed: /* not officially supported */ case xmlrpc_vector_struct: elem_val->name = strdup(ELEM_STRUCT); break; default: break; } /* recurse through sub-elements */ while ( xIter ) { xml_element* next_el = XMLRPC_to_xml_element_worker(node, xIter, request_type, depth + 1); if (next_el) { Q_PushTail(&root_vector_elem->children, next_el); } xIter = XMLRPC_VectorNext(node); } } break; default: break; } } { XMLRPC_VECTOR_TYPE vtype = XMLRPC_GetVectorType(current_vector); if (depth == 1) { xml_element* value = xml_elem_new(); value->name = strdup(ELEM_VALUE); /* yet another hack for the "fault" crap */ if (XMLRPC_VectorGetValueWithID(node, ELEM_FAULTCODE)) { root = value; } else { xml_element* param = xml_elem_new(); param->name = strdup(ELEM_PARAM); Q_PushTail(¶m->children, value); root = param; } Q_PushTail(&value->children, elem_val); } else if (vtype == xmlrpc_vector_struct || vtype == xmlrpc_vector_mixed) { xml_element* member = xml_elem_new(); xml_element* name = xml_elem_new(); xml_element* value = xml_elem_new(); member->name = strdup(ELEM_MEMBER); name->name = strdup(ELEM_NAME); value->name = strdup(ELEM_VALUE); simplestring_add(&name->text, XMLRPC_GetValueID(node)); Q_PushTail(&member->children, name); Q_PushTail(&member->children, value); Q_PushTail(&value->children, elem_val); root = member; } else if (vtype == xmlrpc_vector_array) { xml_element* value = xml_elem_new(); value->name = strdup(ELEM_VALUE); Q_PushTail(&value->children, elem_val); root = value; } else if (vtype == xmlrpc_vector_none) { /* no parent. non-op */ root = elem_val; } else { xml_element* value = xml_elem_new(); value->name = strdup(ELEM_VALUE); Q_PushTail(&value->children, elem_val); root = value; } } } return root; }
xml_element* DANDARPC_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE node) { #define BUF_SIZE 512 xml_element* root = NULL; if(node) { char buf[BUF_SIZE]; const char* id = XMLRPC_GetValueID(node); XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(node); XMLRPC_REQUEST_OUTPUT_OPTIONS output = XMLRPC_RequestGetOutputOptions(request); int bNoAddType = (type == xmlrpc_string && request && output && output->xml_elem_opts.verbosity == xml_elem_no_white_space); xml_element* elem_val = xml_elem_new(); const char* pAttrType = NULL; xml_element_attr* attr_type = bNoAddType ? NULL : emalloc(sizeof(xml_element_attr)); if(attr_type) { attr_type->key = estrdup(ATTR_TYPE); attr_type->val = 0; Q_PushTail(&elem_val->attrs, attr_type); } elem_val->name = (type == xmlrpc_vector) ? estrdup(ATTR_VECTOR) : estrdup(ATTR_SCALAR); if(id && *id) { xml_element_attr* attr_id = emalloc(sizeof(xml_element_attr)); if(attr_id) { attr_id->key = estrdup(ATTR_ID); attr_id->val = estrdup(id); Q_PushTail(&elem_val->attrs, attr_id); } } switch(type) { case xmlrpc_string: pAttrType = ATTR_STRING; simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node)); break; case xmlrpc_int: pAttrType = ATTR_INT; snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node)); simplestring_add(&elem_val->text, buf); break; case xmlrpc_boolean: pAttrType = ATTR_BOOLEAN; snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node)); simplestring_add(&elem_val->text, buf); break; case xmlrpc_double: pAttrType = ATTR_DOUBLE; snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node)); simplestring_add(&elem_val->text, buf); break; case xmlrpc_datetime: pAttrType = ATTR_DATETIME; simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node)); break; case xmlrpc_base64: { struct buffer_st buf; pAttrType = ATTR_BASE64; base64_encode_xmlrpc(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node)); simplestring_addn(&elem_val->text, buf.data, buf.offset ); buffer_delete(&buf); } break; case xmlrpc_vector: { XMLRPC_VECTOR_TYPE my_type = XMLRPC_GetVectorType(node); XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node); switch(my_type) { case xmlrpc_vector_array: pAttrType = ATTR_ARRAY; break; case xmlrpc_vector_mixed: pAttrType = ATTR_MIXED; break; case xmlrpc_vector_struct: pAttrType = ATTR_STRUCT; break; default: break; } /* recurse through sub-elements */ while( xIter ) { xml_element* next_el = DANDARPC_to_xml_element_worker(request, xIter); if(next_el) { Q_PushTail(&elem_val->children, next_el); } xIter = XMLRPC_VectorNext(node); } } break; default: break; } if(pAttrType && attr_type && !bNoAddType) { attr_type->val = estrdup(pAttrType); } root = elem_val; } return root; }
XMLRPC_VALUE XMLRPC::getNextValue() { XMLRPC_VALUE params = XMLRPC_RequestGetData(xmlrpc_request); XMLRPC_VALUE param; if(doRewind) { doRewind = false; param = XMLRPC_VectorRewind(params); }else param = XMLRPC_VectorNext(params); #if BTG_EXTERNALIZATION_DEBUG BTG_NOTICE(logWrapper(), "XMLRPC::getNextValue() retrieved param of type " << XMLRPC_GetValueType(param)); #endif return param; }