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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
            }
        }
    }
}