diff options
Diffstat (limited to 'pjlib-util/src')
-rw-r--r-- | pjlib-util/src/pjlib-util/xml.c | 106 |
1 files changed, 87 insertions, 19 deletions
diff --git a/pjlib-util/src/pjlib-util/xml.c b/pjlib-util/src/pjlib-util/xml.c index e1bb43eb..b7b8faa5 100644 --- a/pjlib-util/src/pjlib-util/xml.c +++ b/pjlib-util/src/pjlib-util/xml.c @@ -340,22 +340,42 @@ PJ_DEF(void) pj_xml_add_attr( pj_xml_node *node, pj_xml_attr *attr ) pj_list_push_back(&node->attr_head, attr); } -PJ_DEF(pj_xml_node*) pj_xml_find_node(pj_xml_node *parent, const pj_str_t *name) +PJ_DEF(pj_xml_node*) pj_xml_find_node(const pj_xml_node *parent, + const pj_str_t *name) { - pj_xml_node *node = parent->node_head.next; + const pj_xml_node *node = parent->node_head.next; PJ_CHECK_STACK(); while (node != (void*)&parent->node_head) { if (pj_stricmp(&node->name, name) == 0) - return node; + return (pj_xml_node*)node; node = node->next; } return NULL; } +PJ_DEF(pj_xml_node*) pj_xml_find_node_rec(const pj_xml_node *parent, + const pj_str_t *name) +{ + const pj_xml_node *node = parent->node_head.next; + + PJ_CHECK_STACK(); + + while (node != (void*)&parent->node_head) { + pj_xml_node *found; + if (pj_stricmp(&node->name, name) == 0) + return (pj_xml_node*)node; + found = pj_xml_find_node_rec(node, name); + if (found) + return (pj_xml_node*)found; + node = node->next; + } + return NULL; +} -PJ_DEF(pj_xml_node*) pj_xml_find_next_node( pj_xml_node *parent, pj_xml_node *node, +PJ_DEF(pj_xml_node*) pj_xml_find_next_node( const pj_xml_node *parent, + const pj_xml_node *node, const pj_str_t *name) { PJ_CHECK_STACK(); @@ -363,24 +383,25 @@ PJ_DEF(pj_xml_node*) pj_xml_find_next_node( pj_xml_node *parent, pj_xml_node *no node = node->next; while (node != (void*)&parent->node_head) { if (pj_stricmp(&node->name, name) == 0) - return node; + return (pj_xml_node*)node; node = node->next; } return NULL; } -PJ_DEF(pj_xml_attr*) pj_xml_find_attr( pj_xml_node *node, const pj_str_t *name, +PJ_DEF(pj_xml_attr*) pj_xml_find_attr( const pj_xml_node *node, + const pj_str_t *name, const pj_str_t *value) { - pj_xml_attr *attr = node->attr_head.next; + const pj_xml_attr *attr = node->attr_head.next; while (attr != (void*)&node->attr_head) { if (pj_stricmp(&attr->name, name)==0) { if (value) { if (pj_stricmp(&attr->value, value)==0) - return attr; + return (pj_xml_attr*)attr; } else { - return attr; + return (pj_xml_attr*)attr; } } attr = attr->next; @@ -390,26 +411,73 @@ PJ_DEF(pj_xml_attr*) pj_xml_find_attr( pj_xml_node *node, const pj_str_t *name, -PJ_DEF(pj_xml_node*) pj_xml_find( pj_xml_node *parent, const pj_str_t *name, +PJ_DEF(pj_xml_node*) pj_xml_find( const pj_xml_node *parent, + const pj_str_t *name, const void *data, - pj_bool_t (*match)(pj_xml_node *, const void*)) + pj_bool_t (*match)(const pj_xml_node *, + const void*)) { - pj_xml_node *head = (pj_xml_node*) &parent->node_head, *node = head->next; + const pj_xml_node *node = (const pj_xml_node *)parent->node_head.next; - while (node != (void*)head) { - if (name && pj_stricmp(&node->name, name)==0) { - if (match) { - if (match(node, data)) - return node; - } else { - return node; + if (!name && !match) + return NULL; + + while (node != (const pj_xml_node*) &parent->node_head) { + if (name) { + if (pj_stricmp(&node->name, name)!=0) { + node = node->next; + continue; } } + if (match) { + if (match(node, data)) + return (pj_xml_node*)node; + } else { + return (pj_xml_node*)node; + } + node = node->next; } return NULL; } +PJ_DEF(pj_xml_node*) pj_xml_find_rec( const pj_xml_node *parent, + const pj_str_t *name, + const void *data, + pj_bool_t (*match)(const pj_xml_node*, + const void*)) +{ + const pj_xml_node *node = (const pj_xml_node *)parent->node_head.next; + + if (!name && !match) + return NULL; + + while (node != (const pj_xml_node*) &parent->node_head) { + pj_xml_node *found; + + if (name) { + if (pj_stricmp(&node->name, name)==0) { + if (match) { + if (match(node, data)) + return (pj_xml_node*)node; + } else { + return (pj_xml_node*)node; + } + } + + } else if (match) { + if (match(node, data)) + return (pj_xml_node*)node; + } + + found = pj_xml_find_rec(node, name, data, match); + if (found) + return found; + + node = node->next; + } + return NULL; +} PJ_DEF(pj_xml_node*) pj_xml_clone( pj_pool_t *pool, const pj_xml_node *rhs) { |