mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-01-03 14:56:34 -05:00
Feature: Added first level recursive definition lookup
This commit is contained in:
parent
ae489acc93
commit
a014f1c5cc
150
src/reportxml.c
150
src/reportxml.c
@ -66,6 +66,8 @@ struct nodedef {
|
|||||||
const struct nodeattr *attr[12];
|
const struct nodeattr *attr[12];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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}}};
|
static const struct nodeattr __attr__eol[1] = {{NULL, NULL, NULL, 0, NULL, {NULL}}};
|
||||||
static const struct nodeattr __attr_version[1] = {{"version", "CDATA", "0.0.1", 1, NULL, {"0.0.1", NULL}}};
|
static const struct nodeattr __attr_version[1] = {{"version", "CDATA", "0.0.1", 1, NULL, {"0.0.1", NULL}}};
|
||||||
static const struct nodeattr __attr_xmlns[1] = {{"xmlns", "URI", "xxx", 1, NULL, {"xxx", NULL}}};
|
static const struct nodeattr __attr_xmlns[1] = {{"xmlns", "URI", "xxx", 1, NULL, {"xxx", NULL}}};
|
||||||
@ -752,11 +754,88 @@ int reportxml_database_add_report(reportxml_database_t *db,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
reportxml_node_t * reportxml_database_build_node(reportxml_database_t *db, const char *id, ssize_t depth)
|
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)
|
||||||
|
{
|
||||||
|
reportxml_node_t *copy;
|
||||||
|
reportxml_node_t *def = NULL;
|
||||||
|
char *definition;
|
||||||
|
|
||||||
|
if (!parent || !node || !db)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
|
if (depth >= 2) {
|
||||||
|
definition = reportxml_node_get_attribute(node, "definition");
|
||||||
|
if (definition) {
|
||||||
|
if (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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def) {
|
||||||
|
ssize_t count = reportxml_node_count_child(def);
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
ICECAST_LOG_DEBUG("Found definition.");
|
||||||
|
|
||||||
|
if (count < 0) {
|
||||||
|
refobject_unref(def);
|
||||||
|
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) {
|
||||||
|
refobject_unref(child);
|
||||||
|
refobject_unref(def);
|
||||||
|
free(definition);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
refobject_unref(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
refobject_unref(def);
|
||||||
|
free(definition);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ICECAST_LOG_DEBUG("Found no definition.");
|
||||||
|
|
||||||
|
copy = reportxml_node_copy(node);
|
||||||
|
if (!copy)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = reportxml_node_add_child(parent, copy);
|
||||||
|
|
||||||
|
refobject_unref(copy);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
reportxml_node_t *search;
|
reportxml_node_t *search;
|
||||||
reportxml_node_t *found;
|
reportxml_node_t *found;
|
||||||
reportxml_node_t *ret;
|
reportxml_node_t *ret;
|
||||||
|
enum {
|
||||||
|
ACST_FIRST,
|
||||||
|
ACST_YES,
|
||||||
|
ACST_NO,
|
||||||
|
} all_childs_same_type = ACST_FIRST;
|
||||||
|
reportxml_node_type_t acst_type = REPORTXML_NODE_TYPE__ERROR;
|
||||||
char *template;
|
char *template;
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -768,6 +847,8 @@ reportxml_node_t * reportxml_database_build_node(reportxml_database_t *db,
|
|||||||
if (depth < 0)
|
if (depth < 0)
|
||||||
depth = 8;
|
depth = 8;
|
||||||
|
|
||||||
|
ICECAST_LOG_DEBUG("Looking up \"%H\" in database %p with depth %zu", id, db, depth);
|
||||||
|
|
||||||
if (!depth)
|
if (!depth)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -826,28 +907,77 @@ reportxml_node_t * reportxml_database_build_node(reportxml_database_t *db,
|
|||||||
/* TODO: Look up definitions of our childs and childs' childs. */
|
/* TODO: Look up definitions of our childs and childs' childs. */
|
||||||
|
|
||||||
reportxml_node_t *node = reportxml_node_get_child(found, i);
|
reportxml_node_t *node = reportxml_node_get_child(found, i);
|
||||||
reportxml_node_t *copy = reportxml_node_copy(node);
|
reportxml_node_type_t type = reportxml_node_get_type(node);
|
||||||
|
|
||||||
|
switch (all_childs_same_type) {
|
||||||
|
case ACST_FIRST:
|
||||||
|
acst_type = type;
|
||||||
|
all_childs_same_type = ACST_YES;
|
||||||
|
break;
|
||||||
|
case ACST_YES:
|
||||||
|
if (acst_type != type)
|
||||||
|
all_childs_same_type = ACST_NO;
|
||||||
|
break;
|
||||||
|
case ACST_NO:
|
||||||
|
/* noop */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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) {
|
||||||
|
refobject_unref(node);
|
||||||
|
refobject_unref(found);
|
||||||
|
refobject_unref(ret);
|
||||||
|
ICECAST_LOG_ERROR("Can not attach child #%zu (%p) to attachment point (%p) in report. BAD.", i, node, ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
refobject_unref(node);
|
refobject_unref(node);
|
||||||
|
}
|
||||||
|
|
||||||
if (!copy) {
|
refobject_unref(found);
|
||||||
refobject_unref(found);
|
|
||||||
|
if (all_childs_same_type == ACST_YES) {
|
||||||
|
count = reportxml_node_count_child(ret);
|
||||||
|
if (count < 0) {
|
||||||
refobject_unref(ret);
|
refobject_unref(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reportxml_node_add_child(ret, copy) != 0) {
|
for (i = 0; i < (size_t)count; i++) {
|
||||||
refobject_unref(found);
|
reportxml_node_t *node = reportxml_node_get_child(ret, i);
|
||||||
refobject_unref(ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
refobject_unref(copy);
|
if (!node) {
|
||||||
|
refobject_unref(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reportxml_node_set_attribute(node, "definition", id) != 0) {
|
||||||
|
refobject_unref(node);
|
||||||
|
refobject_unref(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
refobject_unref(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acst_type_ret) {
|
||||||
|
if (all_childs_same_type == ACST_YES) {
|
||||||
|
*acst_type_ret = acst_type;
|
||||||
|
} else {
|
||||||
|
*acst_type_ret = REPORTXML_NODE_TYPE__ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reportxml_node_t * reportxml_database_build_node(reportxml_database_t *db, const char *id, ssize_t depth)
|
||||||
|
{
|
||||||
|
return __reportxml_database_build_node_ext(db, id, depth, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* We try to build a a report from the definition. Exat structure depends on what is defined. */
|
/* We try to build a a report from the definition. Exat structure depends on what is defined. */
|
||||||
reportxml_t * reportxml_database_build_report(reportxml_database_t *db, const char *id, ssize_t depth)
|
reportxml_t * reportxml_database_build_report(reportxml_database_t *db, const char *id, ssize_t depth)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user