static xmlrpc_value * convert_params(xmlrpc_env * const envP, const xml_element * const elemP) { /*---------------------------------------------------------------------------- Convert an XML element representing a list of parameters (i.e. a <params> element) to an xmlrpc_value of type array. Note that an array is normally represented in XML by a <value> element. We use type xmlrpc_value to represent the parameter list just for convenience. -----------------------------------------------------------------------------*/ xmlrpc_value *array, *item; int size, i; xml_element **params, *param, *value; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(elemP != NULL); /* Set up our error-handling preconditions. */ array = item = NULL; /* Allocate an array to hold our parameters. */ array = xmlrpc_build_value(envP, "()"); XMLRPC_FAIL_IF_FAULT(envP); /* We're responsible for checking our own element name. */ CHECK_NAME(envP, elemP, "params"); /* Iterate over our children. */ size = xml_element_children_size(elemP); params = xml_element_children(elemP); for (i = 0; i < size; ++i) { unsigned int const maxNest = xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); param = params[i]; CHECK_NAME(envP, param, "param"); CHECK_CHILD_COUNT(envP, param, 1); value = xml_element_children(param)[0]; CHECK_NAME(envP, value, "value"); xmlrpc_parseValue(envP, maxNest, value, &item); XMLRPC_FAIL_IF_FAULT(envP); xmlrpc_array_append_item(envP, array, item); xmlrpc_DECREF(item); item = NULL; XMLRPC_FAIL_IF_FAULT(envP); } cleanup: if (envP->fault_occurred) { if (array) xmlrpc_DECREF(array); if (item) xmlrpc_DECREF(item); return NULL; } return array; }
void xmlrpc_parse_value_xml(xmlrpc_env * const envP, const char * const xmlData, size_t const xmlDataLen, xmlrpc_value ** const valuePP) { /*---------------------------------------------------------------------------- Compute the xmlrpc_value represented by the XML document 'xmlData' (of length 'xmlDataLen' characters), which must consist of a single <value> element. Return that xmlrpc_value. We call convert_array() and convert_struct(), which may ultimately call us recursively. Don't recurse any more than 'maxRecursion' times. This isn't generally useful in XML-RPC programs, because such programs parse a whole XML-RPC call or response document, and never see the XML text of just a <value> element. But a program may do some weird form of XML-RPC processing or just borrow Xmlrpc-c's value serialization facilities for something unrelated to XML-RPC. In any case, it makes sense to have an inverse of xmlrpc_serialize_value2(), which generates XML text from an xmlrpc_value. -----------------------------------------------------------------------------*/ xmlrpc_env env; xml_element * valueEltP; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(xmlData != NULL); xmlrpc_env_init(&env); xml_parse(&env, xmlData, xmlDataLen, &valueEltP); if (env.fault_occurred) { setParseFault(envP, "Not valid XML. %s", env.fault_string); } else { if (xmlrpc_streq(xml_element_name(valueEltP), "value")) { unsigned int const maxRecursion = (unsigned int) xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); xmlrpc_parseValue(envP, maxRecursion, valueEltP, valuePP); } else setParseFault(envP, "XML-RPC value XML document must consist of " "a <value> element. This has a <%s> instead.", xml_element_name(valueEltP)); xml_element_free(valueEltP); } xmlrpc_env_clean(&env); }
static void parseFaultElement(xmlrpc_env * const envP, const xml_element * const faultElement, int * const faultCodeP, const char ** const faultStringP) { unsigned int const maxRecursion = (unsigned int) xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(faultElement), "fault")); if (xml_element_children_size(faultElement) != 1) setParseFault(envP, "<fault> element should have 1 child, " "but it has %u.", xml_element_children_size(faultElement)); else { xml_element * const faultValueP = xml_element_children(faultElement)[0]; const char * const elemName = xml_element_name(faultValueP); if (!xmlrpc_streq(elemName, "value")) setParseFault(envP, "<fault> contains a <%s> element. " "Only <value> makes sense.", elemName); else { xmlrpc_value * faultVP; xmlrpc_parseValue(envP, maxRecursion, faultValueP, &faultVP); if (!envP->fault_occurred) { interpretFaultValue(envP, faultVP, faultCodeP, faultStringP); xmlrpc_DECREF(faultVP); } } } }
static void parseArrayDataChild(xmlrpc_env * const envP, xml_element * const childP, unsigned int const maxRecursion, xmlrpc_value * const arrayP) { const char * const elemName = xml_element_name(childP); if (!xmlrpc_streq(elemName, "value")) setParseFault(envP, "<data> element has <%s> child. " "Only <value> makes sense.", elemName); else { xmlrpc_value * itemP; xmlrpc_parseValue(envP, maxRecursion-1, childP, &itemP); if (!envP->fault_occurred) { xmlrpc_array_append_item(envP, arrayP, itemP); xmlrpc_DECREF(itemP); } } }
static void parseMember(xmlrpc_env * const envP, xml_element * const memberP, unsigned int const maxRecursion, xmlrpc_value ** const keyPP, xmlrpc_value ** const valuePP) { unsigned int const childCount = xml_element_children_size(memberP); if (childCount != 2) setParseFault(envP, "<member> element has %u children. Only one <name> and " "one <value> make sense.", childCount); else { xml_element * nameElemP; getNameChild(envP, memberP, &nameElemP); if (!envP->fault_occurred) { parseName(envP, nameElemP, keyPP); if (!envP->fault_occurred) { xml_element * valueElemP; getValueChild(envP, memberP, &valueElemP); if (!envP->fault_occurred) xmlrpc_parseValue(envP, maxRecursion-1, valueElemP, valuePP); if (envP->fault_occurred) xmlrpc_DECREF(*keyPP); } } } }