Re: [xml] patch: c14n python bindings
- From: Anthony Carrico <acarrico memebeam org>
- To: Daniel Veillard <veillard redhat com>
- Cc: libxml <xml gnome org>
- Subject: Re: [xml] patch: c14n python bindings
- Date: Fri, 5 Mar 2004 23:10:39 -0500
On Fri, Mar 05, 2004 at 10:06:35PM -0500, Anthony Carrico wrote:
Sorry, I didn't want to dig too deep into the Python bindings until I
was sure I didn't just have a build problem. Here is the patch:
Oops, a little bug. Use this patch instead:
Index: libxml.c
===================================================================
RCS file: /cvs/gnome/gnome-xml/python/libxml.c,v
retrieving revision 1.54
diff -u -b -r1.54 libxml.c
--- libxml.c 8 Feb 2004 04:12:49 -0000 1.54
+++ libxml.c 6 Mar 2004 04:08:38 -0000
@@ -22,6 +22,7 @@
#include <libxml/xpathInternals.h>
#include <libxml/xmlmemory.h>
#include <libxml/xmlIO.h>
+#include <libxml/c14n.h>
#include "libxml_wrap.h"
#include "libxml2-py.h"
@@ -2858,6 +2859,299 @@
#endif
+#ifdef LIBXML_C14N_ENABLED
+#ifdef LIBXML_OUTPUT_ENABLED
+
+/************************************************************************
+ * *
+ * XML Canonicalization c14n *
+ * *
+ ************************************************************************/
+
+int PyxmlNodeSet_Convert(PyObject *py_nodeset, xmlNodeSetPtr *result)
+{
+ xmlNodeSetPtr nodeSet;
+ int is_tuple = 0;
+
+ if (PyTuple_Check(py_nodeset))
+ is_tuple = 1;
+ else if (PyList_Check(py_nodeset))
+ is_tuple = 0;
+ else if (py_nodeset == Py_None) {
+ *result = NULL;
+ return 0;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "must be a tuple or list of nodes.");
+ return -1;
+ }
+
+ nodeSet = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
+ if (nodeSet == NULL) {
+ PyErr_SetString(PyExc_MemoryError, "");
+ return -1;
+ }
+
+ nodeSet->nodeNr = 0;
+ nodeSet->nodeMax = (is_tuple
+ ? PyTuple_GET_SIZE(py_nodeset)
+ : PyList_GET_SIZE(py_nodeset));
+ nodeSet->nodeTab
+ = (xmlNodePtr *) xmlMalloc (nodeSet->nodeMax
+ * sizeof(xmlNodePtr));
+ if (nodeSet->nodeTab == NULL) {
+ xmlFree(nodeSet);
+ PyErr_SetString(PyExc_MemoryError, "");
+ return -1;
+ }
+ memset(nodeSet->nodeTab, 0 ,
+ nodeSet->nodeMax * sizeof(xmlNodePtr));
+
+ {
+ int index;
+ for (index=0; index < nodeSet->nodeMax; ++index) {
+ xmlNodePtr pynode =
+ PyxmlNode_Get (is_tuple
+ ? PyTuple_GET_ITEM(py_nodeset, index)
+ : PyList_GET_ITEM(py_nodeset, index));
+ if (pynode)
+ nodeSet->nodeTab[nodeSet->nodeNr++] = pynode;
+ }
+ }
+ *result = nodeSet;
+ return 0;
+}
+
+int PystringSet_Convert(PyObject *py_strings, xmlChar *** result)
+{
+ /* NOTE: the array should be freed, but the strings are shared
+ with the python strings and so must not be freed. */
+
+ xmlChar ** strings;
+ int is_tuple = 0;
+ int count;
+ int init_index = 0;
+
+ if (PyTuple_Check(py_strings))
+ is_tuple = 1;
+ else if (PyList_Check(py_strings))
+ is_tuple = 0;
+ else if (py_strings == Py_None) {
+ *result = NULL;
+ return 0;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "must be a tuple or list of strings.");
+ return -1;
+ }
+
+ count = (is_tuple
+ ? PyTuple_GET_SIZE(py_strings)
+ : PyList_GET_SIZE(py_strings));
+
+ strings = (xmlChar **) xmlMalloc(sizeof(xmlChar *) * count);
+
+ if (strings == NULL) {
+ PyErr_SetString(PyExc_MemoryError, "");
+ return -1;
+ }
+
+ memset(strings, 0 , sizeof(xmlChar *) * count);
+
+ {
+ int index;
+ for (index=0; index < count; ++index) {
+ char* s = PyString_AsString
+ (is_tuple
+ ? PyTuple_GET_ITEM(py_strings, index)
+ : PyList_GET_ITEM(py_strings, index));
+ if (s)
+ strings[init_index++] = s;
+ else {
+ xmlFree(strings);
+ PyErr_SetString(PyExc_TypeError,
+ "must be a tuple or list of strings.");
+ return -1;
+ }
+ }
+ }
+
+ *result = strings;
+ return 0;
+}
+
+static PyObject *
+libxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
+ PyObject * args)
+{
+ PyObject *py_retval = NULL;
+
+ PyObject *pyobj_doc;
+ PyObject *pyobj_nodes;
+ int exclusive;
+ PyObject *pyobj_prefixes;
+ int with_comments;
+
+ xmlDocPtr doc;
+ xmlNodeSetPtr nodes;
+ xmlChar **prefixes = NULL;
+ xmlChar *doc_txt;
+
+ int result;
+
+ if (!PyArg_ParseTuple(args, (char *) "OOiOi:C14NDocDumpMemory",
+ &pyobj_doc,
+ &pyobj_nodes,
+ &exclusive,
+ &pyobj_prefixes,
+ &with_comments))
+ return (NULL);
+
+ doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
+ if (!doc) {
+ PyErr_SetString(PyExc_TypeError, "bad document.");
+ return NULL;
+ }
+
+ result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
+ if (result < 0) return NULL;
+
+ if (exclusive) {
+ result = PystringSet_Convert(pyobj_prefixes, &prefixes);
+ if (result < 0) {
+ if (nodes) {
+ xmlFree(nodes->nodeTab);
+ xmlFree(nodes);
+ }
+ return NULL;
+ }
+ }
+
+ result = xmlC14NDocDumpMemory(doc,
+ nodes,
+ exclusive,
+ prefixes,
+ with_comments,
+ &doc_txt);
+
+ if (nodes) {
+ xmlFree(nodes->nodeTab);
+ xmlFree(nodes);
+ }
+ if (prefixes) {
+ xmlChar ** index = prefixes;
+ while (*index) xmlFree(*(index++));
+ xmlFree(prefixes);
+ }
+
+ if (result < 0) {
+ PyErr_SetString(PyExc_Exception,
+ "libxml2 xmlC14NDocDumpMemory failure.");
+ return NULL;
+ }
+ else {
+ py_retval = PyString_FromStringAndSize((const char *) doc_txt,
+ result);
+ xmlFree(doc_txt);
+ return py_retval;
+ }
+}
+
+static PyObject *
+libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self,
+ PyObject * args)
+{
+ PyObject *pyobj_doc;
+ PyObject *py_file;
+ PyObject *pyobj_nodes;
+ int exclusive;
+ PyObject *pyobj_prefixes;
+ int with_comments;
+
+ xmlDocPtr doc;
+ xmlNodeSetPtr nodes;
+ xmlChar **prefixes = NULL;
+ FILE * output;
+ xmlOutputBufferPtr buf;
+
+ int result;
+ int len;
+
+ if (!PyArg_ParseTuple(args, (char *) "OOiOiO:C14NDocSaveTo",
+ &pyobj_doc,
+ &pyobj_nodes,
+ &exclusive,
+ &pyobj_prefixes,
+ &with_comments,
+ &py_file))
+ return (NULL);
+
+ doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
+ if (!doc) {
+ PyErr_SetString(PyExc_TypeError, "bad document.");
+ return NULL;
+ }
+
+ if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
+ PyErr_SetString(PyExc_TypeError, "bad file.");
+ return NULL;
+ }
+ output = PyFile_AsFile(py_file);
+ if (output == NULL) {
+ PyErr_SetString(PyExc_TypeError, "bad file.");
+ return NULL;
+ }
+ buf = xmlOutputBufferCreateFile(output, NULL);
+
+ result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
+ if (result < 0) return NULL;
+
+ if (exclusive) {
+ result = PystringSet_Convert(pyobj_prefixes, &prefixes);
+ if (result < 0) {
+ if (nodes) {
+ xmlFree(nodes->nodeTab);
+ xmlFree(nodes);
+ }
+ return NULL;
+ }
+ }
+
+ result = xmlC14NDocSaveTo(doc,
+ nodes,
+ exclusive,
+ prefixes,
+ with_comments,
+ buf);
+
+ if (nodes) {
+ xmlFree(nodes->nodeTab);
+ xmlFree(nodes);
+ }
+ if (prefixes) {
+ xmlChar ** index = prefixes;
+ while (*index) xmlFree(*(index++));
+ xmlFree(prefixes);
+ }
+
+ len = xmlOutputBufferClose(buf);
+
+ if (result < 0) {
+ PyErr_SetString(PyExc_Exception,
+ "libxml2 xmlC14NDocSaveTo failure.");
+ return NULL;
+ }
+ else
+ return PyInt_FromLong((long) len);
+}
+
+#endif
+#endif
+
+
+
/************************************************************************
* *
* The registration stuff *
@@ -2897,6 +3191,12 @@
{(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL},
{(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL},
#endif
+#ifdef LIBXML_C14N_ENABLED
+#ifdef LIBXML_OUTPUT_ENABLED
+ {(char *)"xmlC14NDocDumpMemory", libxml_C14NDocDumpMemory, METH_VARARGS, NULL},
+ {(char *)"xmlC14NDocSaveTo", libxml_C14NDocSaveTo, METH_VARARGS, NULL},
+#endif
+#endif
{NULL, NULL, 0, NULL}
};
Index: libxml.py
===================================================================
RCS file: /cvs/gnome/gnome-xml/python/libxml.py,v
retrieving revision 1.28
diff -u -b -r1.28 libxml.py
--- libxml.py 21 Dec 2003 13:01:56 -0000 1.28
+++ libxml.py 6 Mar 2004 04:08:39 -0000
@@ -349,6 +349,48 @@
return libxml2mod.saveNodeTo(self._o, file, encoding, format)
#
+ # Canonicalization routines:
+ #
+ # nodes: the node set (tuple or list) to be included in the
+ # canonized image or None if all document nodes should be
+ # included.
+ # exclusive: the exclusive flag (0 - non-exclusive
+ # canonicalization; otherwise - exclusive canonicalization)
+ # prefixes: the list of inclusive namespace prefixes (strings),
+ # or None if there is no inclusive namespaces (only for
+ # exclusive canonicalization, ignored otherwise)
+ # with_comments: include comments in the result (!=0) or not
+ # (==0)
+ def c14nMemory(self,
+ nodes=None,
+ exclusive=0,
+ prefixes=None,
+ with_comments=0):
+ if nodes:
+ nodes = map(lambda n: n._o, nodes)
+ return libxml2mod.xmlC14NDocDumpMemory(
+ self.get_doc()._o,
+ nodes,
+ exclusive != 0,
+ prefixes,
+ with_comments != 0)
+ def c14nSaveTo(self,
+ file,
+ nodes=None,
+ exclusive=0,
+ prefixes=None,
+ with_comments=0):
+ if nodes:
+ nodes = map(lambda n: n._o, nodes)
+ return libxml2mod.xmlC14NDocSaveTo(
+ self.get_doc()._o,
+ nodes,
+ exclusive != 0,
+ prefixes,
+ with_comments != 0,
+ file)
+
+ #
# Selecting nodes using XPath, a bit slow because the context
# is allocated/freed every time but convenient.
#
--
Anthony Carrico
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]