1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2025-02-02 15:07:36 -05:00

Feature: Allow fully recursive lookup of definitions

This commit is contained in:
Philipp Schafft 2018-06-08 11:21:47 +00:00
parent 5d4430a645
commit 93897aebb3

View File

@ -66,6 +66,7 @@ struct nodedef {
const struct nodeattr *attr[12];
};
static int __attach_copy_of_node_or_definition(reportxml_node_t *parent, reportxml_node_t *node, reportxml_database_t *db, ssize_t depth);
static reportxml_node_t * __reportxml_database_build_node_ext(reportxml_database_t *db, const char *id, ssize_t depth, reportxml_node_type_t *acst_type_ret);
static const struct nodeattr __attr__eol[1] = {{NULL, NULL, NULL, 0, NULL, {NULL}}};
@ -73,6 +74,7 @@ static const struct nodeattr __attr_version[1] = {{"version", "CDA
static const struct nodeattr __attr_xmlns[1] = {{"xmlns", "URI", "xxx", 1, NULL, {"xxx", NULL}}};
static const struct nodeattr __attr_id[1] = {{"id", "ID", NULL, 0, NULL, {NULL}}};
static const struct nodeattr __attr_definition[1] = {{"definition", "UUID", NULL, 0, NULL, {NULL}}};
static const struct nodeattr __attr__definition[1] = {{"_definition", "UUID", NULL, 0, NULL, {NULL}}}; /* for internal use only */
static const struct nodeattr __attr_akindof[1] = {{"akindof", "UUIDs", NULL, 0, NULL, {NULL}}};
static const struct nodeattr __attr_lang[1] = {{"lang", "LanguageCode", NULL, 0, NULL, {NULL}}};
static const struct nodeattr __attr_dir[1] = {{"dir", NULL, NULL, 0, NULL, {"ltr", "rtl", NULL}}};
@ -98,7 +100,7 @@ static const struct nodeattr __attr__reference_type[1] = {{"type", NULL
/* Helper:
* grep '^ *REPORTXML_NODE_TYPE_' reportxml.h | sed 's/^\( *REPORTXML_NODE_TYPE_\([^,]*\)\),*$/\1 \2/;' | while read l s; do c=$(tr A-Z a-z <<<"$s"); printf " {%-32s \"%-16s 0, {__attr__eol}},\n" "$l," "$c\","; done
*/
#define __BASIC_ELEMENT __attr_id, __attr_definition, __attr_akindof
#define __BASIC_ELEMENT __attr_id, __attr_definition, __attr_akindof, __attr__definition
static const struct nodedef __nodedef[] = {
{REPORTXML_NODE_TYPE_REPORT, "report", 0, {__attr_id, __attr_version, __attr_xmlns, __attr__eol}},
{REPORTXML_NODE_TYPE_DEFINITION, "definition", 0, {__BASIC_ELEMENT, __attr_template, __attr_defines, __attr__eol}},
@ -417,7 +419,7 @@ reportxml_node_t * reportxml_node_parse_xmlnode(xmlNodePtr xmlnode)
return node;
}
reportxml_node_t * reportxml_node_copy(reportxml_node_t *node)
static reportxml_node_t * __reportxml_node_copy_with_db(reportxml_node_t *node, reportxml_database_t *db, ssize_t depth)
{
reportxml_node_t *ret;
ssize_t count;
@ -443,32 +445,46 @@ reportxml_node_t * reportxml_node_copy(reportxml_node_t *node)
for (i = 0; i < (size_t)count; i++) {
reportxml_node_t *child = reportxml_node_get_child(node, i);
reportxml_node_t *copy = reportxml_node_copy(child);
refobject_unref(child);
if (db && depth > 0) {
if (__attach_copy_of_node_or_definition(ret, child, db, depth) != 0) {
refobject_unref(child);
refobject_unref(ret);
return NULL;
}
refobject_unref(child);
} else {
reportxml_node_t *copy = __reportxml_node_copy_with_db(child, NULL, -1);
if (!copy) {
refobject_unref(ret);
return NULL;
refobject_unref(child);
if (!copy) {
refobject_unref(ret);
return NULL;
}
if (reportxml_node_add_child(ret, copy) != 0) {
refobject_unref(copy);
refobject_unref(ret);
return NULL;
}
}
if (reportxml_node_add_child(ret, copy) != 0) {
refobject_unref(copy);
refobject_unref(ret);
return NULL;
}
refobject_unref(child);
}
return ret;
}
reportxml_node_t * reportxml_node_copy(reportxml_node_t *node)
{
return __reportxml_node_copy_with_db(node, NULL, -1);
}
xmlNodePtr reportxml_node_render_xmlnode(reportxml_node_t *node)
{
xmlNodePtr ret;
ssize_t count;
size_t i;
xmlChar *definition;
if (!node)
return NULL;
@ -481,6 +497,13 @@ xmlNodePtr reportxml_node_render_xmlnode(reportxml_node_t *node)
if (!ret)
return NULL;
definition = xmlGetProp(ret, XMLSTR("_definition"));
if (definition) {
xmlSetProp(ret, XMLSTR("definition"), definition);
xmlUnsetProp(ret, XMLSTR("_definition"));
xmlFree(definition);
}
for (i = 0; i < (size_t)count; i++) {
reportxml_node_t *child = reportxml_node_get_child(node, i);
xmlNodePtr xmlchild;
@ -600,7 +623,7 @@ int reportxml_node_add_child(reportxml_node_t *node, reportx
node->childs[node->childs_len++] = child;
ICECAST_LOG_DEBUG("Child %p added to Node %p", child, node);
// ICECAST_LOG_DEBUG("Child %p added to Node %p", child, node);
return 0;
}
@ -754,7 +777,7 @@ int reportxml_database_add_report(reportxml_database_t *db,
return 0;
}
static int __attach_copy_of_node_or_definition(reportxml_node_t *parent, reportxml_node_t *node, reportxml_database_t *db, ssize_t depth, const char *norec)
static int __attach_copy_of_node_or_definition(reportxml_node_t *parent, reportxml_node_t *node, reportxml_database_t *db, ssize_t depth)
{
reportxml_node_t *copy;
reportxml_node_t *def = NULL;
@ -767,16 +790,10 @@ static int __attach_copy_of_node_or_definition(reportxml_node_t *parent, reportx
if (depth >= 2) {
definition = reportxml_node_get_attribute(node, "definition");
if (definition) {
if (norec != NULL && strcmp(definition, norec) == 0) {
/* we've already proccessed this. No need to look it up. */
free(definition);
} else {
def = reportxml_database_build_node(db, definition, depth - 1);
ICECAST_LOG_DEBUG("Definition for \"%H\" at %p", definition, def);
if (!def) {
free(definition);
}
}
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi, definition=\"%H\"", parent, node, depth, definition);
def = reportxml_database_build_node(db, definition, depth - 1);
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi, Definition for \"%H\" at %p", parent, node, depth, definition, def);
free(definition);
}
}
@ -784,20 +801,23 @@ static int __attach_copy_of_node_or_definition(reportxml_node_t *parent, reportx
ssize_t count = reportxml_node_count_child(def);
size_t i;
ICECAST_LOG_DEBUG("Found definition.");
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi, Found definition.", parent, node, depth);
if (count < 0) {
refobject_unref(def);
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi <- -1", parent, node, depth);
return -1;
}
for (i = 0; i < (size_t)count; i++) {
reportxml_node_t *child = reportxml_node_get_child(def, i);
if (__attach_copy_of_node_or_definition(parent, child, db, depth - 1, definition) != 0) {
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi, Itering, child #%zu (%p)", parent, node, depth, i, child);
if (__attach_copy_of_node_or_definition(parent, child, db, depth - 1) != 0) {
refobject_unref(child);
refobject_unref(def);
free(definition);
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi <- -1", parent, node, depth);
return -1;
}
@ -805,22 +825,25 @@ static int __attach_copy_of_node_or_definition(reportxml_node_t *parent, reportx
}
refobject_unref(def);
free(definition);
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi <- 0", parent, node, depth);
return 0;
} else {
int ret;
ICECAST_LOG_DEBUG("Found no definition.");
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi, Found no definition.", parent, node, depth);
copy = reportxml_node_copy(node);
if (!copy)
copy = __reportxml_node_copy_with_db(node, db, depth - 1);
if (!copy) {
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi <- -1", parent, node, depth);
return -1;
}
ret = reportxml_node_add_child(parent, copy);
refobject_unref(copy);
ICECAST_LOG_DEBUG("parent=%p, node=%p, depth=%zi <- %i", parent, node, depth, ret);
return ret;
}
}
@ -924,7 +947,7 @@ static reportxml_node_t * __reportxml_database_build_node_ext(reportxml_dat
}
/* We want depth, not depth - 1 here. __attach_copy_of_node_or_definition() takes care of this for us. */
if (__attach_copy_of_node_or_definition(ret, node, db, depth, id) != 0) {
if (__attach_copy_of_node_or_definition(ret, node, db, depth) != 0) {
refobject_unref(node);
refobject_unref(found);
refobject_unref(ret);
@ -952,7 +975,7 @@ static reportxml_node_t * __reportxml_database_build_node_ext(reportxml_dat
return NULL;
}
if (reportxml_node_set_attribute(node, "definition", id) != 0) {
if (reportxml_node_set_attribute(node, "_definition", id) != 0) {
refobject_unref(node);
refobject_unref(ret);
return NULL;