mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Merge branch 'ph3-comments'
This commit is contained in:
commit
1d4ce33c1b
@ -6,6 +6,10 @@
|
||||
* Copyright 2018, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
|
||||
*/
|
||||
|
||||
/* This file contains the API for the refobject helper type.
|
||||
* The refobject helper type is a base type that allows building other types with safe reference counting.
|
||||
*/
|
||||
|
||||
#ifndef __REFOBJECT_H__
|
||||
#define __REFOBJECT_H__
|
||||
|
||||
@ -18,6 +22,20 @@
|
||||
#include "icecasttypes.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* The following macros are defined. The definition depends on if the compiler
|
||||
* supports transparent unions. If supported full type checking is enabled.
|
||||
* If the compiler does not support transparent unions, we fall back to using
|
||||
* (void*) pointers.
|
||||
*
|
||||
* REFOBJECT_NULL
|
||||
* Can be used to set an refobject to NULL.
|
||||
* REFOBJECT_IS_NULL(x)
|
||||
* Can be used to check if the refobject x is NULL.
|
||||
* Checking by doing (x == NULL) does not work with transparent unions
|
||||
* as the operation is only defined for it's members.
|
||||
* REFOBJECT_TO_TYPE(type,x)
|
||||
* This casts the refobject (x) to the type (type).
|
||||
*/
|
||||
#ifdef HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION
|
||||
#define REFOBJECT_NULL ((refobject_t)(refobject_base_t*)NULL)
|
||||
#define REFOBJECT_IS_NULL(x) (((refobject_t)(x)).refobject_base == NULL)
|
||||
@ -28,8 +46,19 @@
|
||||
#define REFOBJECT_TO_TYPE(x,y) ((y)(x))
|
||||
#endif
|
||||
|
||||
/* Type used for callback called then the object is actually freed
|
||||
* That is once all references to it are gone.
|
||||
*
|
||||
* If the callback does not set *userdata to NULL *userdata will
|
||||
* be freed automatically by calling free(3).
|
||||
*
|
||||
* This function must not try to deallocate or alter self.
|
||||
*/
|
||||
typedef void (*refobject_free_t)(refobject_t self, void **userdata);
|
||||
|
||||
/* Only defined here as the size must be publically known.
|
||||
* DO NOT use any of the members in here directly!
|
||||
*/
|
||||
struct refobject_base_tag {
|
||||
size_t refc;
|
||||
mutex_t lock;
|
||||
@ -39,12 +68,33 @@ struct refobject_base_tag {
|
||||
refobject_t associated;
|
||||
};
|
||||
|
||||
/* Create a new refobject
|
||||
* The total length of the new object is given by len (see malloc(3)),
|
||||
* the callback called on free is given by freecb (see refobject_free_t above),
|
||||
* the userdata us given by userdata,
|
||||
* the name for the object is given by name, and
|
||||
* the associated refobject is given by associated.
|
||||
*
|
||||
* All parameters beside len are optional and can be NULL/REFOBJECT_NULL.
|
||||
* If no freecb is given the userdata is freed (see refobject_free_t above).
|
||||
*/
|
||||
refobject_t refobject_new(size_t len, refobject_free_t freecb, void *userdata, const char *name, refobject_t associated);
|
||||
|
||||
/* This increases the reference counter of the object */
|
||||
int refobject_ref(refobject_t self);
|
||||
/* This decreases the reference counter of the object.
|
||||
* If the object's reference counter reaches zero the object is freed.
|
||||
*/
|
||||
int refobject_unref(refobject_t self);
|
||||
|
||||
/* This gets and sets the userdata */
|
||||
void * refobject_get_userdata(refobject_t self);
|
||||
int refobject_set_userdata(refobject_t self, void *userdata);
|
||||
|
||||
/* This gets the object's name */
|
||||
const char * refobject_get_name(refobject_t self);
|
||||
|
||||
/* This gets the object's associated object. */
|
||||
refobject_t refobject_get_associated(refobject_t self);
|
||||
|
||||
#endif
|
||||
|
@ -28,57 +28,90 @@
|
||||
#include "logging.h"
|
||||
#define CATMODULE "reportxml"
|
||||
|
||||
/* The report XML document type */
|
||||
struct reportxml_tag {
|
||||
/* base object */
|
||||
refobject_base_t __base;
|
||||
/* the root report XML node of the document */
|
||||
reportxml_node_t *root;
|
||||
};
|
||||
|
||||
/* The report XML node type */
|
||||
struct reportxml_node_tag {
|
||||
/* base object */
|
||||
refobject_base_t __base;
|
||||
/* an XML node used to store the attributes */
|
||||
xmlNodePtr xmlnode;
|
||||
/* the type of the node */
|
||||
reportxml_node_type_t type;
|
||||
/* the report XML childs */
|
||||
reportxml_node_t **childs;
|
||||
size_t childs_len;
|
||||
/* the XML childs (used by <extension>) */
|
||||
xmlNodePtr *xml_childs;
|
||||
size_t xml_childs_len;
|
||||
/* the node's text content (used by <text>) */
|
||||
char *content;
|
||||
};
|
||||
|
||||
/* The report XML database type */
|
||||
struct reportxml_database_tag {
|
||||
/* base object */
|
||||
refobject_base_t __base;
|
||||
/* the lock used to ensure the database object is thread safe. */
|
||||
mutex_t lock;
|
||||
/* The tree of definitions */
|
||||
avl_tree *definitions;
|
||||
};
|
||||
|
||||
/* The nodeattr structure is used to store definition of node attributes */
|
||||
struct nodeattr;
|
||||
|
||||
struct nodeattr {
|
||||
/* name of the attribute */
|
||||
const char *name;
|
||||
/* the type of the attribute. This is based on the DTD */
|
||||
const char *type;
|
||||
/* the default value for the attribute if any */
|
||||
const char *def;
|
||||
/* whether the attribute is required or not */
|
||||
int required;
|
||||
/* a function that can be used to check the content of the attribute if any */
|
||||
int (*checker)(const struct nodeattr *attr, const char *str);
|
||||
/* NULL terminated list of possible values (if enum) */
|
||||
const char *values[32];
|
||||
};
|
||||
|
||||
/* The type of the content an node has */
|
||||
enum nodecontent {
|
||||
/* The node may not have any content */
|
||||
NC_NONE,
|
||||
/* The node may have children */
|
||||
NC_CHILDS,
|
||||
/* The node may have a text content */
|
||||
NC_CONTENT,
|
||||
/* The node may have XML children */
|
||||
NC_XML
|
||||
};
|
||||
|
||||
/* This structure is used to define a node */
|
||||
struct nodedef {
|
||||
/* the type of the node */
|
||||
reportxml_node_type_t type;
|
||||
/* the name of the corresponding XML node */
|
||||
const char *name;
|
||||
/* The type of the content the node may have */
|
||||
enum nodecontent content;
|
||||
/* __attr__eol terminated list of attributes the node may have */
|
||||
const struct nodeattr *attr[12];
|
||||
/* REPORTXML_NODE_TYPE__ERROR terminated list of child node types the node may have */
|
||||
const reportxml_node_type_t childs[12];
|
||||
};
|
||||
|
||||
/* Prototypes */
|
||||
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);
|
||||
|
||||
/* definition of known attributes */
|
||||
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_xmlns[1] = {{"xmlns", "URI", "http://icecast.org/specs/reportxml-0.0.1", 1, NULL, {"http://icecast.org/specs/reportxml-0.0.1", NULL}}};
|
||||
@ -108,6 +141,7 @@ static const struct nodeattr __attr__resource_type[1] = {{"type", NULL
|
||||
static const struct nodeattr __attr__value_type[1] = {{"type", NULL, NULL, 1, NULL, {"null", "int", "float", "uuid", "string", "structure", "uri", "pointer", "version", "protocol", "username", "password", NULL}}};
|
||||
static const struct nodeattr __attr__reference_type[1] = {{"type", NULL, NULL, 1, NULL, {"documentation", "log", "report", "related", NULL}}};
|
||||
|
||||
/* definition of known nodes */
|
||||
/* 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
|
||||
*/
|
||||
|
@ -6,6 +6,8 @@
|
||||
* Copyright 2018, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
|
||||
*/
|
||||
|
||||
/* This file contains the API for report XML document parsing, manipulation, and rendering. */
|
||||
|
||||
#ifndef __REPORTXML_H__
|
||||
#define __REPORTXML_H__
|
||||
|
||||
@ -14,52 +16,121 @@
|
||||
#include "icecasttypes.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* XML Tag Types
|
||||
* While a hint of what the nodes are used for is given, see the specification for more details.
|
||||
*/
|
||||
typedef enum {
|
||||
/* This is a virtual type used to indicate error conditions */
|
||||
REPORTXML_NODE_TYPE__ERROR,
|
||||
/* <report> is the root element of report XML documents */
|
||||
REPORTXML_NODE_TYPE_REPORT,
|
||||
/* <definition> is used to define templates */
|
||||
REPORTXML_NODE_TYPE_DEFINITION,
|
||||
/* <incident> defines an event that is reported */
|
||||
REPORTXML_NODE_TYPE_INCIDENT,
|
||||
/* <state> defines the state an <incident> resulted in */
|
||||
REPORTXML_NODE_TYPE_STATE,
|
||||
/* <backtrace> provides helpful information about the location some event happend */
|
||||
REPORTXML_NODE_TYPE_BACKTRACE,
|
||||
/* <position> defines an element within <backtrace> */
|
||||
REPORTXML_NODE_TYPE_POSITION,
|
||||
/* <more> allows to skip <position>s in <backtrace> for any reason
|
||||
* (e.g. they are unknown or consider of no intrest)
|
||||
*/
|
||||
REPORTXML_NODE_TYPE_MORE,
|
||||
/* <fix> provides a machine readable way to actually fix the problem */
|
||||
REPORTXML_NODE_TYPE_FIX,
|
||||
/* <action> defines a specific action to do */
|
||||
REPORTXML_NODE_TYPE_ACTION,
|
||||
/* <reason> allows to define why an event happend */
|
||||
REPORTXML_NODE_TYPE_REASON,
|
||||
/* <text> is used to provide messages to the user.
|
||||
* The content of <text> is not machine readable.
|
||||
*/
|
||||
REPORTXML_NODE_TYPE_TEXT,
|
||||
/* <timestamp> provides a way to present a point in time an event happend */
|
||||
REPORTXML_NODE_TYPE_TIMESTAMP,
|
||||
/* <resource> names a resource that was involved in the event such as user input or the result */
|
||||
REPORTXML_NODE_TYPE_RESOURCE,
|
||||
/* <value> provides an actual value for a <resource> */
|
||||
REPORTXML_NODE_TYPE_VALUE,
|
||||
/* <reference> provides a way to refer to external documents such as documentation */
|
||||
REPORTXML_NODE_TYPE_REFERENCE,
|
||||
/* <extension> is used to allow application specific extensions */
|
||||
REPORTXML_NODE_TYPE_EXTENSION
|
||||
} reportxml_node_type_t;
|
||||
|
||||
|
||||
/* ---[ Document level ]--- */
|
||||
/* The document object is NOT thread safe. */
|
||||
|
||||
|
||||
/* This creates a new, empty report XML document */
|
||||
reportxml_t * reportxml_new(void);
|
||||
/* This gets the root node of a report XML document */
|
||||
reportxml_node_t * reportxml_get_root_node(reportxml_t *report);
|
||||
/* This selects a node by an attribute and it's value.
|
||||
* This is mostly useful to look for an object by using it's ID.
|
||||
* If more than one node matches the first one found is returned.
|
||||
* If the parameter include_definitions is true nodes from within
|
||||
* <definition> are also considered. If it is false nodes inside
|
||||
* <definition>s are skipped.
|
||||
*/
|
||||
reportxml_node_t * reportxml_get_node_by_attribute(reportxml_t *report, const char *key, const char *value, int include_definitions);
|
||||
/* This function parses an XML document and returns the parst report XML document */
|
||||
reportxml_t * reportxml_parse_xmldoc(xmlDocPtr doc);
|
||||
/* This function renders an report XML document as XML structure */
|
||||
xmlDocPtr reportxml_render_xmldoc(reportxml_t *report);
|
||||
|
||||
|
||||
/* ---[ Node level ]--- */
|
||||
/* The node object is NOT thread safe. */
|
||||
|
||||
|
||||
/* This creates a new node of type type.
|
||||
* It's id, definition, and akindof attributes can be given as parameters.
|
||||
*/
|
||||
reportxml_node_t * reportxml_node_new(reportxml_node_type_t type, const char *id, const char *definition, const char *akindof);
|
||||
/* This parses an XML node and returns the resulting report XML node */
|
||||
reportxml_node_t * reportxml_node_parse_xmlnode(xmlNodePtr xmlnode);
|
||||
/* Copy an report XML node (and it's children) */
|
||||
reportxml_node_t * reportxml_node_copy(reportxml_node_t *node);
|
||||
/* Renders an report XML node as XML node */
|
||||
xmlNodePtr reportxml_node_render_xmlnode(reportxml_node_t *node);
|
||||
/* This gets the type of an report XML node */
|
||||
reportxml_node_type_t reportxml_node_get_type(reportxml_node_t *node);
|
||||
/* Gets and Sets attribute values */
|
||||
int reportxml_node_set_attribute(reportxml_node_t *node, const char *key, const char *value);
|
||||
char * reportxml_node_get_attribute(reportxml_node_t *node, const char *key);
|
||||
/* Adds, counts, and get child nodes */
|
||||
int reportxml_node_add_child(reportxml_node_t *node, reportxml_node_t *child);
|
||||
ssize_t reportxml_node_count_child(reportxml_node_t *node);
|
||||
reportxml_node_t * reportxml_node_get_child(reportxml_node_t *node, size_t idx);
|
||||
/* This gets an child by it's value of the given attribute. See reportxml_get_node_by_attribute() for more details. */
|
||||
reportxml_node_t * reportxml_node_get_child_by_attribute(reportxml_node_t *node, const char *key, const char *value, int include_definitions);
|
||||
/* This gets and sets the text content of an node (used for <text>) */
|
||||
int reportxml_node_set_content(reportxml_node_t *node, const char *value);
|
||||
char * reportxml_node_get_content(reportxml_node_t *node);
|
||||
/* Adds, counts, and gets XML childs (used for <extension>) */
|
||||
int reportxml_node_add_xml_child(reportxml_node_t *node, xmlNodePtr child);
|
||||
ssize_t reportxml_node_count_xml_child(reportxml_node_t *node);
|
||||
xmlNodePtr reportxml_node_get_xml_child(reportxml_node_t *node, size_t idx);
|
||||
|
||||
|
||||
/* ---[ Database level ]--- */
|
||||
/* The database object is thread safe. */
|
||||
|
||||
|
||||
/* Create a new database object */
|
||||
reportxml_database_t * reportxml_database_new(void);
|
||||
/* Add an report to the database */
|
||||
int reportxml_database_add_report(reportxml_database_t *db, reportxml_t *report);
|
||||
/* Build a node (copy) from the data in the database based on the given ID (using "definition" and "defines" attributes)
|
||||
* depth may be used to select how many recursions may be used to resolve definitions within defines.
|
||||
* The default value is selected by passing -1 (recommended).
|
||||
*/
|
||||
reportxml_node_t * reportxml_database_build_node(reportxml_database_t *db, const char *id, ssize_t depth);
|
||||
/* This does the same as reportxml_database_build_node() except that a new report document is returned. */
|
||||
reportxml_t * reportxml_database_build_report(reportxml_database_t *db, const char *id, ssize_t depth);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user