[Bindings] accept simple string in string<->xmlNode converter

Some use case ask for passing simple libxml content node (i.e just an
UTF-8 string) when a method argument or a field of the xmlNode* type.
This commit add a static method in bindings/utils.c named
lasso_string_fragment_to_xmlnode which does this transform by trying to
parse an XML document then by trying to parse a well balanced XML
fragment of only one node (if there is more than one node such as in the
string " xxx <tag/> yyy ", we free the node list and return NULL).
This commit is contained in:
Benjamin Dauvergne 2010-06-29 14:15:08 +00:00
parent 2e9e814b09
commit 3534792285
6 changed files with 69 additions and 45 deletions

View File

@ -21,5 +21,6 @@ EXTRA_DIST = bindings.py \
overrides.xml \
utils.py \
utility-scripts/error-analyzer.pl \
ghashtable.h
ghashtable.h \
utils.c

View File

@ -7,6 +7,7 @@
#include <string.h>
#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;

View File

@ -27,6 +27,7 @@
#include <glib-object.h>
#include <lasso/xml/xml.h>
#include <lasso/utils.h>
#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);
}
/**

View File

@ -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*

View File

@ -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) {

53
bindings/utils.c Normal file
View File

@ -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 <libxml/tree.h>
#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;
}