diff --git a/bindings/Makefile.am b/bindings/Makefile.am index fde10816..42ccf450 100644 --- a/bindings/Makefile.am +++ b/bindings/Makefile.am @@ -21,5 +21,6 @@ EXTRA_DIST = bindings.py \ overrides.xml \ utils.py \ utility-scripts/error-analyzer.pl \ - ghashtable.h + ghashtable.h \ + utils.c diff --git a/bindings/java/wrapper_top.c b/bindings/java/wrapper_top.c index 5dcb5fda..e83a2737 100644 --- a/bindings/java/wrapper_top.c +++ b/bindings/java/wrapper_top.c @@ -7,6 +7,7 @@ #include #include "../ghashtable.h" #include "../../lasso/utils.h" +#include "../utils.c" #define LASSO_ROOT "com/entrouvert/lasso/" #define check_exception (*env)->ExceptionCheck(env) @@ -324,18 +325,10 @@ jstring_to_xml_node(JNIEnv *env, jstring jstr, xmlNode **xmlnode) { lasso_return_val_if_fail(jstring_to_local_string(env, jstr, &local_str), 0); if (local_str) { - doc = xmlReadDoc((unsigned char *)local_str, NULL, NULL, XML_PARSE_NONET); - if (!doc) { - exception(env, "could not read an xml document"); - ret = 0; - goto out; - } - node = xmlDocGetRootElement(doc); + node = lasso_string_fragment_to_xmlnode(local_str, 0); } -out: - lasso_assign_xml_node(*xmlnode, node) - if (doc) - lasso_release_doc(doc); + lasso_assign_new_xml_node(*xmlnode, node) + lasso_release_doc(doc); if (jstr && local_str) release_local_string(env, jstr, local_str); return ret; diff --git a/bindings/perl/glist_handling.c b/bindings/perl/glist_handling.c index d36c59b0..4cb09740 100644 --- a/bindings/perl/glist_handling.c +++ b/bindings/perl/glist_handling.c @@ -27,6 +27,7 @@ #include #include #include +#include "../utils.c" /** * xmlnode_to_pv: @@ -67,23 +68,15 @@ xmlnode_to_pv(xmlNode *node, gboolean do_free) static xmlNode * pv_to_xmlnode(SV *value) { - char *string; - xmlDoc *doc; - xmlNode *node = NULL; + int size; if (! SvPOK(value)) return NULL; - string = SvPV_nolen(value); + string = SvPV(value, len); if (! string) return NULL; - doc = xmlReadDoc(BAD_CAST string, NULL, NULL, XML_PARSE_NONET); - if (! doc) - return NULL; - lasso_assign_xml_node(node, xmlDocGetRootElement(doc)); - lasso_release_doc(doc); - - return node; + return lasso_string_fragment_to_xmlnode(string, len); } /** diff --git a/bindings/php5/wrapper_source_top.c b/bindings/php5/wrapper_source_top.c index ebb8eb62..1b6bec7e 100644 --- a/bindings/php5/wrapper_source_top.c +++ b/bindings/php5/wrapper_source_top.c @@ -8,6 +8,7 @@ #include "php_lasso.h" #include "../ghashtable.h" #include "../../lasso/utils.h" +#include "../utils.c" /* utility functions */ static void free_glist(GList **list, GFunc free_function); @@ -126,17 +127,7 @@ get_string_from_xml_node(xmlNode *xmlnode) static xmlNode* get_xml_node_from_string(char *string) { - xmlDoc *doc; - xmlNode *node; - - doc = xmlReadDoc((xmlChar*)string, NULL, NULL, XML_PARSE_NONET); - node = xmlDocGetRootElement(doc); - if (node != NULL) { - node = xmlCopyNode(node, 1); - } - lasso_release_doc(doc); - - return node; + return lasso_string_fragment_to_xmlnode(string, 0); } static GList* diff --git a/bindings/python/wrapper_top.c b/bindings/python/wrapper_top.c index 76d9da95..7879bb13 100644 --- a/bindings/python/wrapper_top.c +++ b/bindings/python/wrapper_top.c @@ -5,6 +5,7 @@ #include "../ghashtable.h" #include "../../lasso/debug.h" #include "../../lasso/utils.h" +#include "../utils.c" #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) typedef int Py_ssize_t; @@ -323,18 +324,10 @@ failure: static xmlNode* get_xml_node_from_pystring(PyObject *string) { - xmlDoc *doc; - xmlNode *node; - - doc = xmlReadDoc((xmlChar*)PyString_AsString(string), NULL, NULL, XML_PARSE_NONET); - node = xmlDocGetRootElement(doc); - if (node != NULL) { - node = xmlCopyNode(node, 1); - } - lasso_release_doc(doc); - - return node; + return lasso_string_fragment_to_xmlnode(PyString_AsString(string), + PyString_Size(string)); } + /** Return a tuple containing the string contained in a_list */ static PyObject * get_list_of_strings(const GList *a_list) { diff --git a/bindings/utils.c b/bindings/utils.c new file mode 100644 index 00000000..d7dd4934 --- /dev/null +++ b/bindings/utils.c @@ -0,0 +1,53 @@ +/* + * In this file we put utility functions shared by all bindings. + * + * They usually are data structure manipulation or conversion functions. + */ +#include +#include "../lasso/utils.h" + +/** + * lasso_string_fragment_to_xmlnode: + * @fragment: a fragment of an XML document + * @size: + * + * Try to get one and only one node from a string, the node can be a simple string or a single node. + * + * Return value: a newly allocated xmlNode* or NULL if parsing fails. + */ +static xmlNode* +lasso_string_fragment_to_xmlnode(const char *fragment, int size) { + xmlDoc *doc = NULL; + xmlNode *node = NULL; + xmlNode *list = NULL, *ref = NULL; + xmlParserErrors errors; + + if (size == 0) { + size = strlen(fragment); + } + + /* single node case, with preceding or following spaces */ + doc = xmlReadMemory(fragment, size, NULL, NULL, XML_PARSE_NONET); + if (doc) { + node = xmlDocGetRootElement(doc); + if (node != NULL) { + node = xmlCopyNode(node, 1); + goto cleanup; + } + lasso_release_doc(doc); + } + /* simple string */ + doc = xmlNewDoc(BAD_CAST "1.0"); + ref = xmlNewNode(NULL, BAD_CAST "root"); + + xmlDocSetRootElement(doc, ref); + errors = xmlParseInNodeContext(ref, fragment, size, + XML_PARSE_NONET, &list); + if (errors == XML_ERR_OK && list != NULL && list->next == NULL) { + node = xmlCopyNode(list, 1); + } +cleanup: + lasso_release_doc(doc); + lasso_release_xml_node_list(list); + return node; +}