static char *mupnp_xml_node_attribute_tostring(mUpnpXmlNode *node, mUpnpString *str) { mUpnpXmlAttribute *attr; const char *name; const char *value; mUpnpString *valueStr; mupnp_log_debug_l4("Entering...\n"); valueStr = mupnp_string_new(); if (valueStr == NULL) return NULL; for (attr = mupnp_xml_node_getattributes(node); attr != NULL; attr = mupnp_xml_attribute_next(attr)) { name = mupnp_xml_attribute_getname(attr); value = mupnp_xml_attribute_getvalue(attr); mupnp_string_setvalue(valueStr, value); mupnp_xml_escapechars(valueStr); /* All the following functions return NULL only when memory allocation fails, so we can check them all */ if (!mupnp_string_naddvalue(str, " ", 1) || !mupnp_string_addvalue(str, name) || !mupnp_string_naddvalue(str, "=\"", 2) || !mupnp_string_addvalue(str, mupnp_string_getvalue(valueStr)) || !mupnp_string_naddvalue(str, "\"", 1)) { /* Memory allocation failed */ mupnp_string_delete(valueStr); return NULL; } } mupnp_string_delete(valueStr); mupnp_log_debug_l4("Leaving...\n"); return mupnp_string_getvalue(str); }
static char *mupnp_xml_node_tostring_indent(mUpnpXmlNode *node, int indentLevel, bool withChildNode, mUpnpString *str) { char *name; char *value; mUpnpString *valueStr; mUpnpXmlNode *childNode; mupnp_log_debug_l4("Entering...\n"); name = mupnp_xml_node_getname(node); value = mupnp_xml_node_getvalue(node); if (mupnp_xml_node_haschildnodes(node) == false || withChildNode == false) { mupnp_string_addrepvalue(str, MUPNP_XML_INDENT_STRING, indentLevel); if (!mupnp_string_naddvalue(str, "<", 1) || !mupnp_string_addvalue(str, name) || !mupnp_xml_node_attribute_tostring(node, str)) /* Memory allocation failed */ return NULL; valueStr = mupnp_string_new(); if (!valueStr) /* Memory allocation failed */ return NULL; mupnp_string_setvalue(valueStr, value); mupnp_xml_escapechars(valueStr); if (!mupnp_string_naddvalue(str, ">", 1) || !mupnp_string_addvalue(str, mupnp_string_getvalue(valueStr)) || !mupnp_string_naddvalue(str, "</", 2) || !mupnp_string_addvalue(str, name) || !mupnp_string_naddvalue(str, ">", 1) || !mupnp_string_addvalue(str, "\n")) { /* Memory allocation failed */ mupnp_string_delete(valueStr); return NULL; } mupnp_string_delete(valueStr); return mupnp_string_getvalue(str); } mupnp_string_addrepvalue(str, MUPNP_XML_INDENT_STRING, indentLevel); if (!mupnp_string_naddvalue(str, "<", 1) || !mupnp_string_addvalue(str, name) || !mupnp_xml_node_attribute_tostring(node, str) || !mupnp_string_naddvalue(str, ">", 1) || !mupnp_string_addvalue(str, "\n")) /* Memory allocation failed */ return NULL; for (childNode = mupnp_xml_node_getchildnodes(node); childNode != NULL; childNode = mupnp_xml_node_next(childNode)) if (!mupnp_xml_node_tostring_indent(childNode, indentLevel+1, true, str)) /* Memory allocation failed */ return NULL; mupnp_string_addrepvalue(str, MUPNP_XML_INDENT_STRING, indentLevel); if (!mupnp_string_naddvalue(str, "</", 2) || !mupnp_string_addvalue(str, name) || !mupnp_string_naddvalue(str, ">", 1) || !mupnp_string_addvalue(str, "\n")) /* Memory allocation failed */ return NULL; mupnp_log_debug_l4("Leaving...\n"); return mupnp_string_getvalue(str); }
bool mupnp_xml_parse(mUpnpXmlParser* parser, mUpnpXmlNodeList* nodeList, const char* data, size_t len) { #if defined DEBUG_XML_RESULT mUpnpString* resdata = NULL; #endif XML_Parser p; mUpnpExpatData expatData; #ifdef MUPNP_SHOW_TIMINGS struct timeval start_time, end_time, elapsed_time; #endif mupnp_log_debug_l4("Entering...\n"); #ifdef MUPNP_SHOW_TIMINGS gettimeofday(&start_time, NULL); #endif if (!data || len <= 0) return false; p = XML_ParserCreate(NULL); if (!p) return false; /* Fix to get expat parser to work with DLink-routers */ if (data[len - 1] == 0) len--; expatData.rootNode = NULL; expatData.currNode = NULL; XML_SetUserData(p, &expatData); XML_SetElementHandler(p, mupnp_expat_element_start, mupnp_expat_element_end); XML_SetCharacterDataHandler(p, mupnp_expat_character_data); parser->parseResult = XML_Parse(p, data, len, 1); XML_ParserFree(p); if (parser->parseResult == 0 /*XML_STATUS_ERROR*/) { if (expatData.rootNode != NULL) mupnp_xml_node_delete(expatData.rootNode); #if defined DEBUG_XML_RESULT resdata = mupnp_string_new(); mupnp_string_naddvalue(resdata, data, len); printf("XML parse Error on data %s\n time used = %ds\n", mupnp_string_getvalue(resdata), time(NULL) - startTime); mupnp_string_delete(resdata); #endif return false; } mupnp_xml_nodelist_add(nodeList, expatData.rootNode); #ifdef MUPNP_SHOW_TIMINGS gettimeofday(&end_time, NULL); timersub(&end_time, &start_time, &elapsed_time); mupnp_log_debug_s("Parsing XML completed. Elapsed time: " "%ld msec\n", ((elapsed_time.tv_sec * 1000) + (elapsed_time.tv_usec / 1000))); mupnp_total_elapsed_time += (elapsed_time.tv_sec * 1000000) + (elapsed_time.tv_usec); mupnp_log_debug_s("Total elapsed time: %ld msec\n", mupnp_total_elapsed_time / 1000); #endif #if defined DEBUG_XML_RESULT resdata = mupnp_string_new(); mupnp_string_naddvalue(resdata, data, len); printf("XML parse success - time used %ds\n", time(NULL) - startTime); mupnp_string_delete(resdata); #endif return true; mupnp_log_debug_l4("Leaving...\n"); }