summaryrefslogtreecommitdiff
path: root/native/jni
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2004-12-29 21:39:35 +0000
committerMark Wielaard <mark@klomp.org>2004-12-29 21:39:35 +0000
commit4ce3a29bc0cd0364b7ceb2552a93ae99968f6229 (patch)
tree5d26bf2eb32a1b81b584209c0d3a391644880a96 /native/jni
parent78a343044456c8f47d8d73065441cd16b4a13f98 (diff)
downloadclasspath-4ce3a29bc0cd0364b7ceb2552a93ae99968f6229.tar.gz
* configure.ac: Add --enable-xmlj option. Check for libxml2 and
libxslt libraries when enabled. Add native/jni/xmlj/Makefile. * gnu/xml/libxmlj/*: New files. * include/Makefile.am: Add XMLJ_H_FILES. Group awt gtk peer headers under GTKPEER_H_FILES. Generate new headers. * include/gnu_xml_libxmlj_*.h: New generated files. * native/jni/Makefile.am: Conditionally add xmlj dir. * native/jni/xmlj/*: New files.
Diffstat (limited to 'native/jni')
-rw-r--r--native/jni/Makefile.am10
-rw-r--r--native/jni/xmlj/.cvsignore2
-rw-r--r--native/jni/xmlj/Makefile.am22
-rw-r--r--native/jni/xmlj/xmlj_dom.c2603
-rw-r--r--native/jni/xmlj/xmlj_dom.h70
-rw-r--r--native/jni/xmlj/xmlj_error.c169
-rw-r--r--native/jni/xmlj/xmlj_error.h85
-rw-r--r--native/jni/xmlj/xmlj_io.c799
-rw-r--r--native/jni/xmlj/xmlj_io.h170
-rw-r--r--native/jni/xmlj/xmlj_node.c203
-rw-r--r--native/jni/xmlj/xmlj_node.h72
-rw-r--r--native/jni/xmlj/xmlj_sax.c1441
-rw-r--r--native/jni/xmlj/xmlj_sax.h160
-rw-r--r--native/jni/xmlj/xmlj_transform.c868
-rw-r--r--native/jni/xmlj/xmlj_util.c301
-rw-r--r--native/jni/xmlj/xmlj_util.h69
-rw-r--r--native/jni/xmlj/xmlj_xpath.c619
17 files changed, 7661 insertions, 2 deletions
diff --git a/native/jni/Makefile.am b/native/jni/Makefile.am
index c3e6f15f7..70cc35ac7 100644
--- a/native/jni/Makefile.am
+++ b/native/jni/Makefile.am
@@ -4,8 +4,14 @@ if CREATE_GTK_PEER_LIBRARIES
GTKDIR = gtk-peer
endif
-SUBDIRS = classpath java-io java-lang java-net java-nio java-util $(GTKDIR)
-DIST_SUBDIRS = classpath java-io java-lang java-net java-nio java-util gtk-peer
+if CREATE_XMLJ_LIBRARY
+ XMLJDIR = xmlj
+endif
+
+SUBDIRS = classpath java-io java-lang java-net java-nio java-util \
+ $(GTKDIR) $(XMLJDIR)
+DIST_SUBDIRS = classpath java-io java-lang java-net java-nio java-util \
+ gtk-peer xmlj
all-local:
cd $(top_srcdir) && scripts/check_jni_methods.sh
diff --git a/native/jni/xmlj/.cvsignore b/native/jni/xmlj/.cvsignore
new file mode 100644
index 000000000..282522db0
--- /dev/null
+++ b/native/jni/xmlj/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/native/jni/xmlj/Makefile.am b/native/jni/xmlj/Makefile.am
new file mode 100644
index 000000000..ab6626ad5
--- /dev/null
+++ b/native/jni/xmlj/Makefile.am
@@ -0,0 +1,22 @@
+pkglib_LTLIBRARIES = libxmlj.la
+
+libxmlj_la_SOURCES = \
+xmlj_dom.c \
+xmlj_dom.h \
+xmlj_error.c \
+xmlj_error.h \
+xmlj_io.c \
+xmlj_io.h \
+xmlj_node.c \
+xmlj_node.h \
+xmlj_sax.c \
+xmlj_sax.h \
+xmlj_transform.c \
+xmlj_util.c \
+xmlj_util.h \
+xmlj_xpath.c
+
+AM_LDFLAGS = @CLASSPATH_MODULE@ @XML_LIBS@ @XSLT_LIBS@
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@
+
+AM_CFLAGS = @WARNING_CFLAGS@ @ERROR_CFLAGS@ @XML_CFLAGS@ @XSLT_CFLAGS@
diff --git a/native/jni/xmlj/xmlj_dom.c b/native/jni/xmlj/xmlj_dom.c
new file mode 100644
index 000000000..3a14fcad5
--- /dev/null
+++ b/native/jni/xmlj/xmlj_dom.c
@@ -0,0 +1,2603 @@
+/* xmlj_dom.c -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_dom.h"
+#include "xmlj_error.h"
+#include "xmlj_io.h"
+#include "xmlj_node.h"
+#include "xmlj_sax.h"
+#include "xmlj_util.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+JNIEnv *dom_cb_env;
+jobject dom_cb_obj;
+
+typedef struct
+{
+ int index;
+ int count;
+ xmlNodePtr node;
+}
+xmljHashScanData;
+
+/* Prototypes for local functions */
+
+void
+xmljAddAttribute (xmlNodePtr node, xmlAttrPtr attr);
+
+void
+xmljHashScanner (void *payload, void *vdata, xmlChar *name);
+
+xmlChar *
+xmljGetNodeValue (xmlNodePtr node);
+
+/*
+ * Determines whether a child node is suitable for insertion in the list of
+ * children for a given parent node.
+ * Returns 0 on success, a DOMException code otherwise.
+ */
+void
+xmljValidateChildNode (JNIEnv *env, xmlNodePtr parent, xmlNodePtr child)
+{
+ xmlNodePtr cur;
+
+ if (child == NULL || parent == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return;
+ }
+ if (child->doc != parent->doc)
+ {
+ xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
+ return;
+ }
+ /* Check that new parent is of an allowed type */
+ switch (parent->type)
+ {
+ case XML_CDATA_SECTION_NODE:
+ case XML_COMMENT_NODE:
+ case XML_TEXT_NODE:
+ case XML_ENTITY_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_NOTATION_NODE:
+ case XML_PI_NODE:
+ /* these can't have any children */
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "parent type does not allow children");
+ return;
+ case XML_ATTRIBUTE_NODE:
+ if (child->type != XML_TEXT_NODE &&
+ child->type != XML_ENTITY_REF_NODE)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "attributes may only contain text or entity reference nodes");
+ return;
+ }
+ break;
+ case XML_DOCUMENT_FRAG_NODE:
+ case XML_ELEMENT_NODE:
+ if (child->type == XML_DTD_NODE ||
+ child->type == XML_DOCUMENT_TYPE_NODE ||
+ child->type == XML_ENTITY_NODE ||
+ child->type == XML_NOTATION_NODE ||
+ child->type == XML_PI_NODE)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "parent type does not allow child of this type");
+ return;
+ }
+ /* fall through */
+ default:
+ if (child->type == XML_ATTRIBUTE_NODE ||
+ child->type == XML_DOCUMENT_NODE ||
+ child->type == XML_DOCUMENT_FRAG_NODE)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "node type may not be a child");
+ return;
+ }
+ /* TODO others? */
+ }
+ /* Check that new parent is not self or an ancestor */
+ for (cur = parent; cur != NULL; cur = cur->parent)
+ {
+ if (cur == child)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "child cannot be an ancestor of itself");
+ return;
+ }
+ }
+ /* Check that new parent does not add a second doctype or root element
+ * to a document parent */
+ if (parent->type == XML_DOCUMENT_NODE)
+ {
+ cur = parent->children;
+ while (cur != NULL)
+ {
+ if (cur->type == XML_DTD_NODE ||
+ cur->type == XML_DOCUMENT_TYPE_NODE ||
+ (cur->type == XML_ELEMENT_NODE &&
+ parent->type == XML_DOCUMENT_NODE))
+ {
+ if (child->type == cur->type && child != cur)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "cannot add a second doctype or root element");
+ return;
+ }
+ }
+ cur = cur->next;
+ }
+ }
+}
+
+/*
+ * Adds the specified attribute node to the list of attributes for the given
+ * element.
+ */
+void
+xmljAddAttribute (xmlNodePtr node, xmlAttrPtr attr)
+{
+ xmlAttrPtr cur = node->properties;
+
+ if (cur == NULL)
+ {
+ node->properties = attr;
+ attr->prev = NULL;
+ attr->next = NULL;
+ attr->parent = node;
+ attr->doc = node->doc;
+ }
+ else
+ {
+ while (cur->next != NULL)
+ {
+ cur = cur->next;
+ }
+ cur->next = attr;
+ attr->prev = cur;
+ attr->next = NULL;
+ attr->parent = node;
+ attr->doc = node->doc;
+ }
+}
+
+/* -- GnomeAttr -- */
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeAttr_getSpecified (JNIEnv * env, jobject self)
+{
+ xmlAttrPtr attr;
+
+ attr = (xmlAttrPtr) xmljGetNodeID (env, self);
+ return (attr->atype != 0);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeAttr_getValue (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ xmlChar *text;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ text = xmlNodeGetContent (node);
+ ret = xmljNewString (env, (const xmlChar *) text);
+ if (text != NULL)
+ {
+ xmlFree (text);
+ }
+ return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeAttr_setValue (JNIEnv * env,
+ jobject self, jstring value)
+{
+ xmlNodePtr node;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_value = xmljGetStringChars (env, value);
+ xmlNodeSetContent (node, s_value);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeAttr_xmljIsId (JNIEnv * env, jobject self)
+{
+ xmlAttrPtr attr;
+
+ attr = (xmlAttrPtr) xmljGetNodeID (env, self);
+ return (attr->atype == XML_ATTRIBUTE_ID);
+}
+
+/* -- GnomeDocument -- */
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_free (JNIEnv * env,
+ jobject self, jobject id)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljAsPointer (env, id);
+ xmljFreeDoc (env, doc);
+ xmlFree (doc);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getDoctype (JNIEnv * env, jobject self)
+{
+ xmlDocPtr doc;
+ xmlDtdPtr dtd;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ dtd = doc->extSubset;
+ if (dtd == NULL)
+ {
+ dtd = doc->intSubset;
+ }
+ return xmljGetNodeInstance (env, (xmlNodePtr) dtd);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getDocumentElement (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, xmlDocGetRootElement (doc));
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createDocumentType (JNIEnv * env,
+ jobject self,
+ jstring name,
+ jstring publicId,
+ jstring systemId)
+{
+ xmlDocPtr doc;
+ xmlDtdPtr dtd;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ dtd = xmlNewDtd (doc,
+ xmljGetStringChars (env, name),
+ xmljGetStringChars (env, publicId),
+ xmljGetStringChars (env, systemId));
+ return xmljGetNodeInstance (env, (xmlNodePtr) dtd);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createDocumentFragment (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, xmlNewDocFragment (doc));
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createTextNode (JNIEnv * env,
+ jobject self,
+ jstring data)
+{
+ xmlDocPtr doc;
+ xmlNodePtr text;
+ const xmlChar *s_data;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_data = xmljGetStringChars (env, data);
+ text = xmlNewDocText (doc, s_data);
+ return xmljGetNodeInstance (env, text);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createComment (JNIEnv * env,
+ jobject self,
+ jstring data)
+{
+ xmlDocPtr doc;
+ xmlNodePtr comment;
+ const xmlChar *s_data;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_data = xmljGetStringChars (env, data);
+ comment = xmlNewDocComment (doc, s_data);
+ return xmljGetNodeInstance (env, comment);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createCDATASection (JNIEnv * env,
+ jobject self,
+ jstring data)
+{
+ xmlDocPtr doc;
+ xmlNodePtr cdata;
+ const xmlChar *s_data;
+ int len;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_data = xmljGetStringChars (env, data);
+ len = xmlStrlen (s_data);
+ cdata = xmlNewCDataBlock (doc, s_data, len);
+ return xmljGetNodeInstance (env, cdata);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createProcessingInstruction (JNIEnv *
+ env,
+ jobject
+ self,
+ jstring
+ target,
+ jstring
+ data)
+{
+ xmlDocPtr doc;
+ xmlNodePtr pi;
+ const xmlChar *s_target;
+ const xmlChar *s_data;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_target = xmljGetStringChars (env, target);
+ s_data = xmljGetStringChars (env, data);
+ pi = xmlNewPI (s_target, s_data);
+ pi->doc = doc;
+ return xmljGetNodeInstance (env, pi);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createEntityReference (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ xmlDocPtr doc;
+ xmlNodePtr ref;
+ const xmlChar *s_name;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ ref = xmlNewReference (doc, s_name);
+ return xmljGetNodeInstance (env, ref);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_xmljImportNode (JNIEnv * env,
+ jobject self,
+ jobject importedNode,
+ jboolean deep)
+{
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ node = xmljGetNodeID (env, importedNode);
+ if (node == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ if (node->type == XML_DOCUMENT_NODE ||
+ node->type == XML_DOCUMENT_TYPE_NODE)
+ {
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+ }
+ node = xmlDocCopyNode (node, doc, deep);
+ return xmljGetNodeInstance (env, node);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createElementNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring qName)
+{
+ xmlDocPtr doc;
+ xmlNodePtr element;
+ xmlNsPtr ns = NULL;
+ const xmlChar *s_uri;
+ const xmlChar *s_qName;
+ const xmlChar *s_prefix;
+ const xmlChar *s_localName;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_qName = xmljGetStringChars (env, qName);
+ if (xmlValidateQName (s_qName, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return NULL;
+ }
+ if (uri != NULL)
+ {
+ s_uri = xmljGetStringChars (env, uri);
+ s_prefix = xmljGetPrefix (s_qName);
+ s_localName = xmljGetLocalName (s_qName);
+ ns = xmlNewNs ((xmlNodePtr) doc, s_uri, s_prefix);
+ }
+ element = xmlNewDocNode (doc, ns, s_qName, NULL);
+ return xmljGetNodeInstance (env, element);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createAttributeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring qName)
+{
+ xmlDocPtr doc;
+ xmlNodePtr attr;
+ xmlNsPtr ns = NULL;
+ const xmlChar *s_uri;
+ const xmlChar *s_qName;
+ const xmlChar *s_prefix;
+ const xmlChar *s_localName;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_qName = xmljGetStringChars (env, qName);
+ if (xmlValidateQName (s_qName, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return NULL;
+ }
+ if (uri != NULL)
+ {
+ s_uri = xmljGetStringChars (env, uri);
+ s_prefix = xmljGetPrefix (s_qName);
+ s_localName = xmljGetLocalName (s_qName);
+ ns = xmlNewNs ((xmlNodePtr) doc, s_uri, s_prefix);
+ }
+ attr = (xmlNodePtr) xmlNewNsProp ((xmlNodePtr) doc, ns, s_qName, NULL);
+ attr->parent = NULL;
+ return xmljGetNodeInstance (env, attr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_xmljGetElementById (JNIEnv * env,
+ jobject self,
+ jstring elementId)
+{
+ xmlDocPtr doc;
+ xmlNodePtr ctx, tmp;
+ xmlAttrPtr attr;
+ const xmlChar *id;
+ const xmlChar *val;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ id = xmljGetStringChars (env, elementId);
+
+ ctx = xmlDocGetRootElement (doc);
+ while (ctx && ctx != (xmlNodePtr) doc)
+ {
+ if (ctx->type == XML_ELEMENT_NODE)
+ {
+ for (attr = ctx->properties; attr;
+ attr = (xmlAttrPtr) attr->next)
+ {
+ if (xmlIsID (doc, ctx, attr))
+ {
+ val = xmlGetProp (ctx, attr->name);
+ if (val && xmlStrEqual (id, val))
+ {
+ return xmljGetNodeInstance (env, ctx);
+ }
+ }
+ }
+ }
+ if (ctx->children)
+ {
+ ctx = ctx->children;
+ }
+ else
+ {
+ tmp = ctx->next;
+ if (tmp)
+ {
+ ctx = tmp;
+ }
+ else
+ {
+ do
+ {
+ tmp = ctx->parent;
+ if (!tmp)
+ {
+ return NULL;
+ }
+ ctx = tmp;
+ tmp = ctx->next;
+ }
+ while (!tmp);
+ ctx = tmp;
+ }
+ }
+ }
+ return NULL;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getInputEncoding (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ if (doc->encoding)
+ {
+ return xmljNewString (env, doc->encoding);
+ }
+ switch (doc->charset)
+ {
+ case XML_CHAR_ENCODING_ASCII:
+ return xmljNewString (env, BAD_CAST "US-ASCII");
+ case XML_CHAR_ENCODING_UTF16LE:
+ return xmljNewString (env, BAD_CAST "UTF-16LE");
+ case XML_CHAR_ENCODING_UTF16BE:
+ return xmljNewString (env, BAD_CAST "UTF-16BE");
+ case XML_CHAR_ENCODING_8859_1:
+ return xmljNewString (env, BAD_CAST "ISO-8859-1");
+ /* TODO others */
+ default:
+ return xmljNewString (env, BAD_CAST "UTF-8");
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getXmlEncoding (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return (doc->encoding == NULL) ?
+ xmljNewString (env, BAD_CAST "UTF-8") :
+ xmljNewString (env, doc->encoding);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getXmlStandalone (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return doc->standalone;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_setXmlStandalone (JNIEnv * env,
+ jobject self,
+ jboolean xmlStandalone)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ doc->standalone = xmlStandalone;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getXmlVersion (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return (doc->version == NULL) ?
+ xmljNewString (env, BAD_CAST "1.0") :
+ xmljNewString (env, doc->version);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_setXmlVersion (JNIEnv * env,
+ jobject self,
+ jstring xmlVersion)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ if (xmlVersion == NULL)
+ {
+ doc->version = NULL;
+ }
+ else
+ {
+ const xmlChar *version = xmljGetStringChars (env, xmlVersion);
+ if (!xmlStrEqual (version, BAD_CAST "1.0") &&
+ !xmlStrEqual (version, BAD_CAST "1.1"))
+ {
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return;
+ }
+ doc->version = version;
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getDocumentURI (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return (doc->name == NULL) ? NULL :
+ xmljNewString (env, (const xmlChar *) doc->URL);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_setDocumentURI (JNIEnv * env,
+ jobject self,
+ jstring documentURI)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ if (documentURI == NULL)
+ {
+ doc->URL = NULL;
+ }
+ else
+ {
+ doc->URL = xmljGetStringChars (env, documentURI);
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_xmljAdoptNode (JNIEnv *env,
+ jobject self,
+ jobject jnode)
+{
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ node = xmljGetNodeID (env, jnode);
+
+ if (node == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ if (node->type == XML_DOCUMENT_NODE ||
+ node->type == XML_DOCUMENT_TYPE_NODE ||
+ node->type == XML_ENTITY_NODE ||
+ node->type == XML_NOTATION_NODE)
+ {
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+ }
+ xmlUnlinkNode (node);
+ node = xmlDocCopyNode (node, doc, 1);
+ return xmljGetNodeInstance (env, node);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_renameNode (JNIEnv * env,
+ jobject self,
+ jobject n,
+ jstring namespaceURI,
+ jstring qName)
+{
+ xmlNodePtr node;
+ xmlNsPtr ns;
+ const xmlChar *s_qName;
+ const xmlChar *href;
+ const xmlChar *prefix;
+ int *len;
+
+ node = xmljGetNodeID (env, n);
+ if (node == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ s_qName = xmljGetStringChars (env, qName);
+ if (xmlValidateQName (s_qName, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return NULL;
+ }
+ xmlNodeSetName (node, s_qName);
+
+ href = xmljGetStringChars (env, namespaceURI);
+ len = (int *) malloc (sizeof (int));
+ prefix = xmlSplitQName3 (s_qName, len);
+ ns = node->ns;
+ if (ns == NULL)
+ {
+ if (href != NULL)
+ {
+ ns = xmlNewNs (node, href, prefix);
+ xmlSetNs (node, ns);
+ }
+ }
+ else
+ {
+ node->ns = NULL;
+ /*xmlFreeNs (ns); FIXME this can segfault (?) */
+ if (href != NULL)
+ {
+ ns = xmlNewNs (node, href, prefix);
+ xmlSetNs (node, ns);
+ }
+ }
+ free (len);
+ return n;
+}
+
+/* -- GnomeDocumentBuilder -- */
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentBuilder_parseStream (JNIEnv * env,
+ jobject self,
+ jobject in,
+ jbyteArray
+ detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean
+ expandEntities,
+ jboolean
+ entityResolver,
+ jboolean
+ errorHandler)
+{
+ xmlDocPtr doc;
+
+ doc = xmljParseDocument(env,
+ self,
+ in,
+ detectBuffer,
+ publicId,
+ systemId,
+ base,
+ validate,
+ coalesce,
+ expandEntities,
+ 0,
+ 0,
+ entityResolver,
+ errorHandler,
+ 0,
+ 0,
+ 1);
+ return xmljCreateDocument (env, self, doc);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentBuilder_createDocument
+(JNIEnv * env,
+ jobject self,
+ jstring namespaceURI,
+ jstring qualifiedName,
+ jobject doctype)
+{
+ xmlDocPtr doc;
+ xmlNodePtr root;
+ xmlNsPtr ns;
+ const xmlChar *href;
+ const xmlChar *prefix;
+ const xmlChar *qName;
+
+ qName = xmljGetStringChars (env, qualifiedName);
+ href = xmljGetStringChars (env, namespaceURI);
+ if (qName == NULL)
+ {
+ prefix = NULL;
+ }
+ else
+ {
+ int *len;
+
+ len = (int *) malloc (sizeof (int));
+ prefix = xmlSplitQName3 (qName, len);
+ free (len);
+ }
+
+ /* Create the document node */
+ doc = xmlNewDoc (BAD_CAST "1.0");
+
+ /* doctype */
+ if (doctype != NULL)
+ {
+ jclass cls;
+ jmethodID method;
+ jstring ret;
+ const xmlChar *name;
+ const xmlChar *publicId;
+ const xmlChar *systemId;
+ const xmlChar *internalSubset;
+ xmlDtdPtr dtd;
+
+ cls = (*env)->FindClass (env, "org/w3c/dom/DocumentType");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ /* name */
+ method = (*env)->GetMethodID (env, cls, "getName",
+ "()Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
+ name = xmljGetStringChars (env, ret);
+
+ /* publicId */
+ method = (*env)->GetMethodID (env, cls, "getPublicId",
+ "()Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
+ publicId = xmljGetStringChars (env, ret);
+
+ /* systemId */
+ method = (*env)->GetMethodID (env, cls, "getSystemId",
+ "()Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
+ systemId = xmljGetStringChars (env, ret);
+
+ /* internalSubset */
+ method = (*env)->GetMethodID (env, cls, "getInternalSubset",
+ "()Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
+ internalSubset = xmljGetStringChars (env, ret);
+
+ /* TODO notations */
+ /* TODO entities */
+ if (internalSubset == NULL)
+ {
+ dtd = xmlNewDtd (doc, name, publicId, systemId);
+ }
+ else
+ {
+ dtd = xmlCreateIntSubset (doc, name, publicId, systemId);
+ /* TODO parse internal subset? */
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+ }
+ }
+
+ /* Create the root element */
+ root = xmlNewNode (NULL, qName);
+ xmlDocSetRootElement (doc, root);
+ ns = xmlNewNs (root, href, prefix);
+ xmlSetNs (root, ns);
+
+ return xmljCreateDocument (env, self, doc);
+}
+
+/* -- GnomeDocumentType -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentType_getPublicId (JNIEnv * env,
+ jobject self)
+{
+ xmlDtdPtr dtd;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ return xmljNewString (env, dtd->ExternalID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentType_getSystemId (JNIEnv * env,
+ jobject self)
+{
+ xmlDtdPtr dtd;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ return xmljNewString (env, dtd->SystemID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentType_getInternalSubset (JNIEnv * env,
+ jobject self)
+{
+ /* TODO */
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+}
+
+/* -- GnomeElement -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getAttribute (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ xmlNodePtr node;
+ const xmlChar *s_name;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ s_value = xmlGetProp (node, s_name);
+ xmlFree ((xmlChar *) s_name);
+ return (s_value == NULL) ?
+ xmljNewString (env, BAD_CAST "") :
+ xmljNewString (env, s_value);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_setAttribute (JNIEnv * env,
+ jobject self,
+ jstring name,
+ jstring value)
+{
+ xmlNodePtr node;
+ const xmlChar *s_name;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ if (xmlValidateName (s_name, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return;
+ }
+ s_value = xmljGetStringChars (env, value);
+ xmlSetProp (node, s_name, s_value);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getAttributeNode (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ xmlNodePtr node;
+ const xmlChar *s_name;
+ xmlAttrPtr attr;
+
+ node = xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ attr = xmlHasProp (node, s_name);
+ if (attr == NULL)
+ {
+ return NULL;
+ }
+ xmlFree ((xmlChar *) s_name);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_setAttributeNode (JNIEnv * env,
+ jobject self,
+ jobject newAttr)
+{
+ xmlNodePtr node;
+ xmlAttrPtr new_attr;
+ xmlAttrPtr old_attr;
+
+ node = xmljGetNodeID (env, self);
+ new_attr = (xmlAttrPtr) xmljGetNodeID (env, newAttr);
+ if (new_attr->parent != NULL)
+ {
+ xmljThrowDOMException (env, 10, NULL); /* INUSE_ATTRIBUTE_ERR */
+ return NULL;
+ }
+ if (new_attr->doc != node->doc)
+ {
+ xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
+ return NULL;
+ }
+ old_attr = xmlHasProp (node, new_attr->name);
+ if (old_attr)
+ {
+ xmlUnlinkNode ((xmlNodePtr) old_attr);
+ }
+ xmljAddAttribute (node, new_attr);
+ return xmljGetNodeInstance (env, (xmlNodePtr) old_attr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_removeAttributeNode (JNIEnv * env,
+ jobject self,
+ jobject oldAttr)
+{
+ xmlNodePtr attr;
+
+ attr = xmljGetNodeID (env, oldAttr);
+ xmlUnlinkNode (attr);
+ return oldAttr;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getAttributeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ xmlNodePtr node;
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_localName = xmljGetStringChars (env, localName);
+ if (uri == NULL)
+ {
+ s_value = xmlGetNoNsProp (node, s_localName);
+ }
+ else
+ {
+ s_uri = xmljGetStringChars (env, uri);
+ s_value = xmlGetNsProp (node, s_localName, s_uri);
+ xmlFree ((xmlChar *) s_uri);
+ }
+ xmlFree ((xmlChar *) s_localName);
+ return (s_value == NULL) ?
+ xmljNewString (env, BAD_CAST "") :
+ xmljNewString (env, s_value);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_setAttributeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring qName,
+ jstring value)
+{
+ xmlNodePtr node;
+ xmlNsPtr ns;
+ const xmlChar *s_uri;
+ const xmlChar *s_qName;
+ const xmlChar *s_prefix;
+ const xmlChar *s_localName;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_qName = xmljGetStringChars (env, qName);
+ if (xmlValidateQName (s_qName, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return;
+ }
+ s_value = xmljGetStringChars (env, value);
+ if (uri == NULL)
+ {
+ xmlSetProp (node, s_qName, s_value);
+ }
+ else
+ {
+ s_prefix = xmljGetPrefix (s_qName);
+ s_localName = xmljGetLocalName (s_qName);
+ s_uri = xmljGetStringChars (env, uri);
+ ns = xmlNewNs (node, s_uri, s_prefix);
+ xmlSetNsProp (node, ns, s_localName, s_value);
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getAttributeNodeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+
+ node = xmljGetNodeID (env, self);
+ attr = node->properties;
+ s_uri = xmljGetStringChars (env, uri);
+ s_localName = xmljGetStringChars (env, localName);
+ while (attr != NULL)
+ {
+ if (uri == NULL)
+ {
+ if (xmljMatch (s_localName, (xmlNodePtr) attr))
+ break;
+ }
+ else
+ {
+ if (xmljMatchNS (s_uri, s_localName, (xmlNodePtr) attr))
+ break;
+ }
+ attr = attr->next;
+ }
+ xmlFree ((xmlChar *) s_uri);
+ xmlFree ((xmlChar *) s_localName);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_setAttributeNodeNS (JNIEnv * env,
+ jobject self,
+ jobject newAttr)
+{
+ xmlNodePtr node;
+ xmlAttrPtr new_attr;
+ xmlAttrPtr old_attr;
+ const xmlChar *uri;
+
+ node = xmljGetNodeID (env, self);
+ new_attr = (xmlAttrPtr) xmljGetNodeID (env, newAttr);
+ if (new_attr->parent != NULL)
+ {
+ xmljThrowDOMException (env, 10, NULL); /* INUSE_ATTRIBUTE_ERR */
+ return NULL;
+ }
+ if (new_attr->doc != node->doc)
+ {
+ xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
+ return NULL;
+ }
+ uri = (new_attr->ns != NULL) ? new_attr->ns->href : NULL;
+ old_attr = xmlHasNsProp (node, new_attr->name, uri);
+ if (old_attr)
+ {
+ xmlUnlinkNode ((xmlNodePtr) old_attr);
+ }
+ xmljAddAttribute (node, new_attr);
+ return xmljGetNodeInstance (env, (xmlNodePtr) old_attr);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_hasAttribute (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ xmlNodePtr node;
+ const xmlChar *s_name;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ s_value = xmlGetProp (node, s_name);
+ xmlFree ((xmlChar *) s_name);
+ return (s_value != NULL);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_hasAttributeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ xmlNodePtr node;
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_localName = xmljGetStringChars (env, localName);
+ if (uri == NULL)
+ {
+ s_value = xmlGetNoNsProp (node, s_localName);
+ }
+ else
+ {
+ s_uri = xmljGetStringChars (env, uri);
+ s_value = xmlGetNsProp (node, s_localName, s_uri);
+ xmlFree ((xmlChar *) s_uri);
+ }
+ xmlFree ((xmlChar *) s_localName);
+ return (s_value != NULL);
+}
+
+/* -- GnomeEntity -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeEntity_getPublicId (JNIEnv * env, jobject self)
+{
+ xmlEntityPtr entity;
+
+ entity = (xmlEntityPtr) xmljGetNodeID (env, self);
+ return xmljNewString (env, entity->ExternalID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeEntity_getSystemId (JNIEnv * env, jobject self)
+{
+ xmlEntityPtr entity;
+
+ entity = (xmlEntityPtr) xmljGetNodeID (env, self);
+ return xmljNewString (env, entity->SystemID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeEntity_getNotationName (JNIEnv * env,
+ jobject self)
+{
+ /* TODO */
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+}
+
+/* -- GnomeNamedNodeMap -- */
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_getNamedItem (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlAttrPtr attr;
+
+ attr = xmljGetNamedItem (env, self, name);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+ const xmlChar *s_name;
+ xmlNodePtr ret;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ return NULL;
+ }
+ s_name = xmljGetStringChars (env, name);
+ ret = (xmlNodePtr) xmlHashLookup (hash, s_name);
+ xmlFree ((xmlChar *) s_name);
+ return xmljGetNodeInstance (env, ret);
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_setNamedItem (JNIEnv * env,
+ jobject self,
+ jobject arg)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+ xmlNodePtr node;
+ xmlNodePtr argNode;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ node = xmljGetNodeID (env, self);
+ argNode = xmljGetNodeID (env, arg);
+
+ if (argNode->doc != node->doc)
+ {
+ xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
+ }
+ xmljValidateChildNode (env, node, argNode);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+ if (type == 0)
+ {
+ if (argNode->parent != NULL)
+ {
+ xmljThrowDOMException (env, 10, NULL); /* INUSE_ATTRIBUTE_ERR */
+ return NULL;
+ }
+ xmlAddChild (node, argNode);
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ hash = xmlHashCreate (10);
+ if (type == 1)
+ {
+ dtd->entities = hash;
+ }
+ else
+ {
+ dtd->notations = hash;
+ }
+ }
+ xmlHashAddEntry (hash, argNode->name, argNode);
+ }
+ return arg;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_removeNamedItem (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlAttrPtr attr;
+
+ attr = xmljGetNamedItem (env, self, name);
+ if (attr == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ xmlUnlinkNode ((xmlNodePtr) attr);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+ const xmlChar *s_name;
+ xmlNodePtr ret;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ return NULL;
+ }
+ s_name = xmljGetStringChars (env, name);
+ ret = (xmlNodePtr) xmlHashLookup (hash, s_name);
+ if (ret != NULL)
+ {
+ xmlHashRemoveEntry (hash, s_name, NULL);
+ }
+ xmlFree ((xmlChar *) s_name);
+ return xmljGetNodeInstance (env, ret);
+ }
+}
+
+void
+xmljHashScanner (void *payload, void *vdata, xmlChar *name)
+{
+ xmljHashScanData *data;
+
+ data = (xmljHashScanData *) vdata;
+ if (data->count <= data->index)
+ {
+ data->node = (xmlNodePtr) payload;
+ }
+ data->count++;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_item (JNIEnv * env,
+ jobject self, jint index)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ jint count;
+
+ node = xmljGetNodeID (env, self);
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ attr = node->properties;
+ for (count = 0; attr != NULL && count < index; count++)
+ {
+ attr = attr->next;
+ }
+ if (attr == NULL)
+ {
+ char msg[1024];
+ sprintf (msg, "No attribute at index %d\n", (int) index);
+ xmljThrowException (env, "java/lang/NullPointerException", msg);
+ return NULL;
+ }
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ default:
+ return NULL;
+ }
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+ xmljHashScanData *data;
+ xmlNodePtr ret;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ return NULL;
+ }
+ data = (xmljHashScanData *) malloc (sizeof (xmljHashScanData));
+ if (data == NULL)
+ {
+ return NULL;
+ }
+ data->index = index;
+ data->count = 0;
+ data->node = NULL;
+ xmlHashScan (hash, xmljHashScanner, data);
+ ret = data->node;
+ free (data);
+ return xmljGetNodeInstance (env, ret);
+ }
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_getLength (JNIEnv * env,
+ jobject self)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ jint count;
+
+ node = xmljGetNodeID (env, self);
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ count = 0;
+ attr = node->properties;
+ while (attr != NULL)
+ {
+ count++;
+ attr = attr->next;
+ }
+ return count;
+ default:
+ return -1;
+ }
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+ xmljHashScanData *data;
+ jint ret;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ return 0;
+ }
+ data = (xmljHashScanData *) malloc (sizeof (xmljHashScanData));
+ if (data == NULL)
+ {
+ return 0;
+ }
+ data->index = -1;
+ data->count = 0;
+ data->node = NULL;
+ xmlHashScan (hash, xmljHashScanner, data);
+ ret = data->count;
+ free (data);
+ return ret;
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_getNamedItemNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlAttrPtr attr;
+
+ attr = xmljGetNamedItemNS (env, self, uri, localName);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_setNamedItemNS (JNIEnv * env,
+ jobject self,
+ jobject arg)
+{
+ return Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_setNamedItem (env, self,
+ arg);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_removeNamedItemNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring
+ localName)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlAttrPtr attr;
+
+ attr = xmljGetNamedItemNS (env, self, uri, localName);
+ if (attr == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ else
+ {
+ xmlUnlinkNode ((xmlNodePtr) attr);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/* -- GnomeNode -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNodeName (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, node->name);
+}
+
+xmlChar *
+xmljGetNodeValue (xmlNodePtr node)
+{
+ /* If not character data, return null */
+ switch (node->type)
+ {
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_COMMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ return xmlNodeGetContent (node);
+ default:
+ return NULL;
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNodeValue (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ xmlChar *text;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ text = xmljGetNodeValue (node);
+ ret = xmljNewString (env, (const xmlChar *) text);
+ if (text != NULL)
+ {
+ xmlFree (text);
+ }
+ return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_setNodeValue (JNIEnv * env,
+ jobject self,
+ jstring nodeValue)
+{
+ xmlNodePtr node;
+ const xmlChar *s_nodeValue;
+
+ node = xmljGetNodeID (env, self);
+
+ /* If not character data, return */
+ if (node->type != XML_TEXT_NODE &&
+ node->type != XML_CDATA_SECTION_NODE && node->type != XML_COMMENT_NODE)
+ return;
+
+ s_nodeValue = xmljGetStringChars (env, nodeValue);
+ xmlNodeSetContent (node, s_nodeValue);
+}
+
+JNIEXPORT jshort JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNodeType (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ switch (node->type)
+ {
+ case XML_DTD_NODE:
+ return XML_DOCUMENT_TYPE_NODE;
+ case XML_ATTRIBUTE_DECL:
+ return XML_ATTRIBUTE_NODE;
+ case XML_ENTITY_DECL:
+ return XML_ENTITY_NODE;
+ default:
+ return node->type;
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getParentNode (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->parent);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getFirstChild (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->children);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getLastChild (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->last);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getPreviousSibling (JNIEnv * env,
+ jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->prev);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNextSibling (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->next);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getOwnerDocument (JNIEnv * env,
+ jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, (xmlNodePtr) node->doc);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljInsertBefore (JNIEnv * env,
+ jobject self,
+ jobject newChild,
+ jobject refChild)
+{
+ xmlNodePtr node;
+ xmlNodePtr newChildNode;
+ xmlNodePtr refChildNode;
+
+ node = xmljGetNodeID (env, self);
+ newChildNode = xmljGetNodeID (env, newChild);
+ refChildNode = xmljGetNodeID (env, refChild);
+
+ /* Is refChildNode a child of this node? */
+ if (refChildNode == NULL ||
+ refChildNode->parent == NULL ||
+ refChildNode->parent != node)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ /* Check new child */
+ xmljValidateChildNode (env, node, newChildNode);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+
+ newChildNode = xmlAddPrevSibling (refChildNode, newChildNode);
+ return xmljGetNodeInstance (env, newChildNode);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljReplaceChild (JNIEnv * env,
+ jobject self,
+ jobject newChild,
+ jobject oldChild)
+{
+ xmlNodePtr node;
+ xmlNodePtr newChildNode;
+ xmlNodePtr oldChildNode;
+
+ node = xmljGetNodeID (env, self);
+ newChildNode = xmljGetNodeID (env, newChild);
+ oldChildNode = xmljGetNodeID (env, oldChild);
+
+ /* Is oldChildNode a child of this node? */
+ if (oldChildNode == NULL ||
+ oldChildNode->parent == NULL ||
+ oldChildNode->parent != node)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ /* Check new child */
+ xmljValidateChildNode (env, node, newChildNode);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+
+ newChildNode = xmlReplaceNode (oldChildNode, newChildNode);
+ return xmljGetNodeInstance (env, newChildNode);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljRemoveChild (JNIEnv * env,
+ jobject self,
+ jobject oldChild)
+{
+ xmlNodePtr node;
+ xmlNodePtr oldChildNode;
+
+ node = xmljGetNodeID (env, self);
+ oldChildNode = xmljGetNodeID (env, oldChild);
+
+ if (oldChildNode == NULL ||
+ oldChildNode->parent == NULL ||
+ oldChildNode->parent != node)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ xmlUnlinkNode (oldChildNode);
+ return oldChild;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljAppendChild (JNIEnv * env,
+ jobject self,
+ jobject newChild)
+{
+ xmlNodePtr node;
+ xmlNodePtr newChildNode;
+
+ node = xmljGetNodeID (env, self);
+ newChildNode = xmljGetNodeID (env, newChild);
+
+ /* Check new child */
+ xmljValidateChildNode (env, node, newChildNode);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+
+ newChildNode = xmlAddChild (node, newChildNode);
+ return xmljGetNodeInstance (env, newChildNode);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_hasChildNodes (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return (node->children != NULL);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljCloneNode (JNIEnv * env,
+ jobject self, jboolean deep)
+{
+ xmlNodePtr node;
+ xmlNodePtr clone;
+
+ node = xmljGetNodeID (env, self);
+ clone = xmlCopyNode (node, deep);
+ clone->parent = NULL;
+ clone->doc = node->doc;
+ return xmljGetNodeInstance (env, clone);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_normalize (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ xmljNormalizeNode (node);
+}
+
+void
+xmljNormalizeNode (xmlNodePtr node)
+{
+ xmlNodePtr cur;
+ xmlNodePtr last = NULL;
+
+ cur = node->children;
+ while (cur != NULL)
+ {
+ switch (cur->type)
+ {
+ case XML_CDATA_SECTION_NODE:
+ case XML_TEXT_NODE:
+ if (xmlIsBlankNode (cur))
+ {
+ xmlNodePtr next = cur->next;
+ xmlUnlinkNode (cur);
+ xmlFreeNode (cur);
+ cur = next;
+ continue;
+ }
+ if (last != NULL)
+ {
+ last = xmlTextMerge (last, cur);
+ xmlUnlinkNode (cur);
+ xmlFreeNode (cur);
+ cur = last;
+ }
+ else
+ {
+ last = cur;
+ }
+ break;
+ default:
+ last = NULL;
+ xmljNormalizeNode (cur);
+ }
+ cur = cur->next;
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNamespaceURI (JNIEnv * env,
+ jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ if (node->type != XML_ELEMENT_NODE &&
+ node->type != XML_ATTRIBUTE_NODE)
+ {
+ return NULL;
+ }
+ if (node->ns == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, node->ns->href);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getPrefix (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ if (node->type != XML_ELEMENT_NODE &&
+ node->type != XML_ATTRIBUTE_NODE)
+ {
+ return NULL;
+ }
+ if (node->ns == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, node->ns->prefix);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_setPrefix (JNIEnv * env,
+ jobject self, jstring prefix)
+{
+ xmlNodePtr node;
+ const xmlChar *s_prefix;
+
+ s_prefix = xmljGetStringChars (env, prefix);
+ if (xmlValidateName (s_prefix, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ }
+ node = xmljGetNodeID (env, self);
+ if (node->type != XML_ELEMENT_NODE &&
+ node->type != XML_ATTRIBUTE_NODE)
+ {
+ xmljThrowDOMException (env, 3, NULL); /* HIERARCHY_REQUEST_ERR */
+ return;
+ }
+ if (node->ns == NULL)
+ {
+ xmljThrowDOMException (env, 14, NULL); /* NAMESPACE_ERR */
+ return;
+ }
+ node->ns->prefix = s_prefix;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getLocalName (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ int *len;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ if (node->name == NULL)
+ {
+ return NULL;
+ }
+ len = (int *) malloc (sizeof (int));
+ if (xmlSplitQName3 (node->name, len) != NULL)
+ {
+ ret = xmljNewString (env, node->name + (*len));
+ }
+ else
+ {
+ ret = xmljNewString (env, node->name);
+ }
+ free (len);
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_hasAttributes (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return (node->properties != NULL);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getBaseURI (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ xmlChar *baseURI;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ baseURI = xmlNodeGetBase (node->doc, node);
+ ret = xmljNewString (env, (const xmlChar *) baseURI);
+ if (baseURI != NULL)
+ {
+ xmlFree (baseURI);
+ }
+ return ret;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_lookupPrefix (JNIEnv * env, jobject self,
+ jstring namespaceURI)
+{
+ xmlNodePtr node;
+ xmlNsPtr ns;
+ xmlDocPtr doc;
+ const xmlChar *s_uri;
+
+ node = xmljGetNodeID (env, self);
+ doc = node->doc;
+ /* If this is a document node, search from the root element */
+ if (node->type == XML_DOCUMENT_NODE)
+ {
+ doc = (xmlDocPtr) node;
+ node = xmlDocGetRootElement (doc);
+ }
+ s_uri = xmljGetStringChars (env, namespaceURI);
+ ns = xmlSearchNsByHref (doc, node, s_uri);
+ xmlFree ((xmlChar *) s_uri);
+ if (ns == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, ns->prefix);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_isDefaultNamespace (JNIEnv * env,
+ jobject self,
+ jstring namespaceURI)
+{
+ xmlNodePtr node;
+ xmlNsPtr ns;
+ const xmlChar *s_uri;
+
+ node = xmljGetNodeID (env, self);
+ s_uri = xmljGetStringChars (env, namespaceURI);
+ ns = xmlSearchNsByHref (node->doc, node, s_uri);
+ xmlFree ((xmlChar *) s_uri);
+ if (ns == NULL)
+ {
+ return 0;
+ }
+ return (ns->prefix == NULL || xmlStrlen (ns->prefix) == 0);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_lookupNamespaceURI (JNIEnv * env,
+ jobject self,
+ jstring prefix)
+{
+ xmlNodePtr node;
+ xmlDocPtr doc;
+ xmlNsPtr ns;
+ const xmlChar *s_prefix;
+
+ node = xmljGetNodeID (env, self);
+ doc = node->doc;
+ /* If this is a document node, search from the root element */
+ if (node->type == XML_DOCUMENT_NODE)
+ {
+ doc = (xmlDocPtr) node;
+ node = xmlDocGetRootElement (doc);
+ }
+ s_prefix = xmljGetStringChars (env, prefix);
+ ns = xmlSearchNs (doc, node, s_prefix);
+ xmlFree ((xmlChar *) s_prefix);
+ if (ns == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, ns->href);
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljCompareTo (JNIEnv * env,
+ jobject self,
+ jobject other)
+{
+ xmlNodePtr n1, n2, x;
+ int d1, d2, delta, c;
+
+ n1 = xmljGetNodeID (env, self);
+ n2 = xmljGetNodeID (env, other);
+ if (n1->doc != n2->doc)
+ {
+ return 0;
+ }
+ if (n1->type == XML_ATTRIBUTE_NODE || n2->type == XML_ATTRIBUTE_NODE)
+ {
+ return 0;
+ }
+ d1 = 0;
+ for (x = n1->parent; x && x->type != XML_DOCUMENT_NODE; x = x->parent)
+ {
+ d1++;
+ }
+ d2 = 0;
+ for (x = n2->parent; x && x->type != XML_DOCUMENT_NODE; x = x->parent)
+ {
+ d2++;
+ }
+ delta = d1 - d2;
+ while (d1 > d2)
+ {
+ n1 = n1->parent;
+ d1--;
+ }
+ while (d2 > d1)
+ {
+ n2 = n2->parent;
+ d2--;
+ }
+ c = xmljCompare (n1, n2);
+ return (c != 0) ? c : delta;
+}
+
+/* Compare at same level */
+int
+xmljCompare (xmlNodePtr n1, xmlNodePtr n2)
+{
+ int c, i1, i2;
+
+ if (n1->parent == NULL || n1->type == XML_DOCUMENT_NODE ||
+ n2->parent == NULL || n2->type == XML_DOCUMENT_NODE ||
+ n1 == n2)
+ {
+ return 0;
+ }
+ c = xmljCompare (n1->parent, n2->parent);
+ if (c != 0)
+ {
+ return c;
+ }
+ i1 = 0;
+ for (n1 = n1->prev; n1; n1 = n1->prev)
+ {
+ i1++;
+ }
+ i2 = 0;
+ for (n2 = n2->prev; n2; n2 = n2->prev)
+ {
+ i2++;
+ }
+ return i1 - i2;
+}
+
+int
+xmljIsEqualNodeList (xmlNodePtr node1, xmlNodePtr node2)
+{
+ while (node1 != NULL)
+ {
+ if (!xmljIsEqualNode (node1, node2))
+ {
+ return 0;
+ }
+ node1 = node1->next;
+ node2 = node2->next;
+ }
+ return 1;
+}
+
+int
+xmljIsEqualNode (xmlNodePtr node1, xmlNodePtr node2)
+{
+ const xmlChar *val1;
+ const xmlChar *val2;
+
+ if (node1 == node2)
+ {
+ return 1;
+ }
+ if (node1 == NULL || node2 == NULL)
+ {
+ return 0;
+ }
+ /* Check node type */
+ if (node1->type != node2->type)
+ {
+ return 0;
+ }
+ /* Check node name */
+ if (!xmlStrEqual (node1->name, node2->name))
+ {
+ return 0;
+ }
+ /* Check node namespace */
+ if (node1->type == XML_ELEMENT_NODE ||
+ node1->type == XML_ATTRIBUTE_NODE)
+ {
+ xmlNsPtr ns1, ns2;
+
+ ns1 = node1->ns;
+ if (ns1 != NULL)
+ {
+ ns2 = node2->ns;
+ if (ns2 == NULL)
+ {
+ return 0;
+ }
+ val1 = ns1->href;
+ val2 = ns2->href;
+ if (!xmlStrEqual (val1, val2))
+ {
+ return 0;
+ }
+ }
+ }
+ /* Check node value */
+ val1 = xmljGetNodeValue (node1);
+ val2 = xmljGetNodeValue (node2);
+ if (!xmlStrEqual (val1, val2))
+ {
+ return 0;
+ }
+ /* Check attributes */
+ if (node1->type == XML_ELEMENT_NODE &&
+ !xmljIsEqualNodeList ((xmlNodePtr) node1->properties,
+ (xmlNodePtr) node2->properties))
+ {
+ return 0;
+ }
+ /* Check doctype */
+ if (node1->type == XML_DOCUMENT_NODE)
+ {
+ xmlDocPtr doc1 = (xmlDocPtr) node1;
+ xmlDocPtr doc2 = (xmlDocPtr) node2;
+
+ if (!xmljIsEqualNode ((xmlNodePtr) doc1->intSubset,
+ (xmlNodePtr) doc2->intSubset) ||
+ !xmljIsEqualNode ((xmlNodePtr) doc1->extSubset,
+ (xmlNodePtr) doc2->extSubset))
+ {
+ return 0;
+ }
+ }
+ /* Check child nodes */
+ if (!xmljIsEqualNodeList (node1->children, node2->children))
+ {
+ return 0;
+ }
+ return 1;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_isEqualNode (JNIEnv * env,
+ jobject self,
+ jobject arg)
+{
+ xmlNodePtr node1;
+ xmlNodePtr node2;
+
+ node1 = xmljGetNodeID (env, self);
+ node2 = xmljGetNodeID (env, arg);
+ return xmljIsEqualNode (node1, node2);
+}
+
+/* -- GnomeNodeList -- */
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNodeList_item (JNIEnv * env,
+ jobject self, jint index)
+{
+ xmlNodePtr node;
+ jint count;
+
+ node = xmljGetNodeID (env, self);
+ node = node->children;
+ count = 0;
+ for (count = 0; node != NULL && count < index; count++)
+ {
+ node = node->next;
+ }
+ return xmljGetNodeInstance (env, node);
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNodeList_getLength (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ jint count;
+
+ node = xmljGetNodeID (env, self);
+ count = 0;
+ node = node->children;
+ while (node != NULL)
+ {
+ count++;
+ node = node->next;
+ }
+ return count;
+}
+
+/* -- GnomeNotation -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNotation_getPublicId (JNIEnv * env,
+ jobject self)
+{
+ xmlNotationPtr notation;
+
+ notation = (xmlNotationPtr) xmljGetNodeID (env, self);
+ if (notation->PublicID == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, notation->PublicID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNotation_getSystemId (JNIEnv * env,
+ jobject self)
+{
+ xmlNotationPtr notation;
+
+ notation = (xmlNotationPtr) xmljGetNodeID (env, self);
+ if (notation->SystemID == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, notation->SystemID);
+}
+
+/* -- GnomeProcessingInstruction -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeProcessingInstruction_getData (JNIEnv * env,
+ jobject self)
+{
+ xmlNodePtr node;
+ xmlChar *text;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ text = xmlNodeGetContent (node);
+ ret = xmljNewString (env, (const xmlChar *) text);
+ if (text != NULL)
+ {
+ xmlFree (text);
+ }
+ return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeProcessingInstruction_setData (JNIEnv * env,
+ jobject self,
+ jstring data)
+{
+ xmlNodePtr node;
+ const xmlChar *s_data;
+
+ node = xmljGetNodeID (env, self);
+ s_data = xmljGetStringChars (env, data);
+ xmlNodeSetContent (node, s_data);
+}
+
+/* -- GnomeTypeInfo -- */
+
+xmlDtdPtr xmljGetDtd (xmlDocPtr doc)
+{
+ xmlNodePtr ctx;
+
+ for (ctx = doc->children; ctx; ctx = ctx->next)
+ {
+ if (ctx->type == XML_DOCUMENT_TYPE_NODE)
+ {
+ return (xmlDtdPtr) ctx;
+ }
+ }
+ return NULL;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeTypeInfo_getTypeName (JNIEnv *env, jobject self)
+{
+ xmlNodePtr node;
+ xmlDtdPtr dtd;
+ xmlAttributePtr attribute;
+
+ node = xmljGetNodeID (env, self);
+ dtd = xmljGetDtd (node->doc);
+ if (dtd)
+ {
+ switch (node->type)
+ {
+ case XML_ATTRIBUTE_NODE:
+ attribute = xmlGetDtdAttrDesc (dtd, node->parent->name, node->name);
+ if (attribute)
+ {
+ switch (attribute->type)
+ {
+ case XML_ATTRIBUTE_CDATA:
+ return xmljNewString (env, BAD_CAST "CDATA");
+ case XML_ATTRIBUTE_ID:
+ return xmljNewString (env, BAD_CAST "ID");
+ case XML_ATTRIBUTE_IDREF:
+ return xmljNewString (env, BAD_CAST "IDREF");
+ case XML_ATTRIBUTE_IDREFS:
+ return xmljNewString (env, BAD_CAST "IDREFS");
+ case XML_ATTRIBUTE_ENTITY:
+ return xmljNewString (env, BAD_CAST "ENTITY");
+ case XML_ATTRIBUTE_ENTITIES:
+ return xmljNewString (env, BAD_CAST "ENTITIES");
+ case XML_ATTRIBUTE_NMTOKEN:
+ return xmljNewString (env, BAD_CAST "NMTOKEN");
+ case XML_ATTRIBUTE_NMTOKENS:
+ return xmljNewString (env, BAD_CAST "NMTOKENS");
+ default:
+ return NULL;
+ }
+ }
+ return NULL;
+ default:
+ return NULL;
+ }
+ }
+ /* TODO when XML Schema support is available */
+ return NULL;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeTypeInfo_getTypeNamespace (JNIEnv *env,
+ jobject self)
+{
+ xmlNodePtr node;
+ xmlDtdPtr dtd;
+ xmlAttributePtr attribute;
+
+ node = xmljGetNodeID (env, self);
+ dtd = xmljGetDtd (node->doc);
+ if (dtd)
+ {
+ switch (node->type)
+ {
+ case XML_ATTRIBUTE_NODE:
+ attribute = xmlGetDtdAttrDesc (dtd, node->parent->name, node->name);
+ if (attribute)
+ {
+ return xmljNewString (env,
+ BAD_CAST "http://www.w3.org/TR/REC-xml");
+ }
+ return NULL;
+ default:
+ return NULL;
+ }
+ }
+ /* TODO when XML Schema support is available */
+ return NULL;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeTypeInfo_isDerivedFrom (JNIEnv *env,
+ jobject self,
+ jstring typeNS,
+ jstring typeName,
+ jint method)
+{
+ /* TODO when XML Schema support is available */
+ return 0;
+}
+
+/* -- Utility -- */
+
+/*
+ * Create GnomeDocument object from the given xmlDocPtr
+ */
+jobject
+xmljCreateDocument (JNIEnv * env, jobject self, xmlDocPtr doc)
+{
+ jclass cls;
+ jfieldID field;
+ jobject ret;
+
+ if (!doc)
+ {
+ return NULL;
+ }
+
+ /* Get document object */
+ ret = xmljGetNodeInstance (env, (xmlNodePtr) doc);
+
+ /* Set DOM implementation field */
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeDocument");
+ field = (*env)->GetFieldID (env, cls, "dom",
+ "Lorg/w3c/dom/DOMImplementation;");
+ (*env)->SetObjectField (env, ret, field, self);
+ return ret;
+}
+
+xmlAttrPtr
+xmljGetNamedItem (JNIEnv * env, jobject self, jstring name)
+{
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ const xmlChar *s_name;
+
+ s_name = xmljGetStringChars (env, name);
+
+ node = xmljGetNodeID (env, self);
+ attr = node->properties;
+ while (attr != NULL)
+ {
+ if (xmljMatch (s_name, (xmlNodePtr) attr))
+ break;
+ attr = attr->next;
+ }
+ xmlFree ((xmlChar *) s_name);
+
+ return attr;
+}
+
+xmlAttrPtr
+xmljGetNamedItemNS (JNIEnv * env, jobject self, jstring uri, jstring localName)
+{
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+
+ s_uri = xmljGetStringChars (env, uri);
+ s_localName = xmljGetStringChars (env, localName);
+
+ node = xmljGetNodeID (env, self);
+ attr = node->properties;
+ while (attr != NULL)
+ {
+ if (xmljMatchNS (s_uri, s_localName, (xmlNodePtr) attr))
+ break;
+ attr = attr->next;
+ }
+ xmlFree ((xmlChar *) s_uri);
+ xmlFree ((xmlChar *) s_localName);
+
+ return attr;
+}
diff --git a/native/jni/xmlj/xmlj_dom.h b/native/jni/xmlj/xmlj_dom.h
new file mode 100644
index 000000000..e8e2e73a5
--- /dev/null
+++ b/native/jni/xmlj/xmlj_dom.h
@@ -0,0 +1,70 @@
+/* xmlj_dom.h -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_DOM_H
+#define XMLJ_DOM_H
+
+#include "gnu_xml_libxmlj_dom_GnomeAttr.h"
+#include "gnu_xml_libxmlj_dom_GnomeDocument.h"
+#include "gnu_xml_libxmlj_dom_GnomeDocumentBuilder.h"
+#include "gnu_xml_libxmlj_dom_GnomeDocumentType.h"
+#include "gnu_xml_libxmlj_dom_GnomeElement.h"
+#include "gnu_xml_libxmlj_dom_GnomeEntity.h"
+#include "gnu_xml_libxmlj_dom_GnomeNamedNodeMap.h"
+#include "gnu_xml_libxmlj_dom_GnomeNode.h"
+#include "gnu_xml_libxmlj_dom_GnomeNodeList.h"
+#include "gnu_xml_libxmlj_dom_GnomeNotation.h"
+#include "gnu_xml_libxmlj_dom_GnomeProcessingInstruction.h"
+#include "gnu_xml_libxmlj_dom_GnomeTypeInfo.h"
+
+#include <libxml/parser.h>
+#include <libxml/valid.h>
+
+void xmljValidateChildNode (JNIEnv *env, xmlNodePtr parent, xmlNodePtr child);
+int xmljIsEqualNode (xmlNodePtr node1, xmlNodePtr node2);
+int xmljIsEqualNodeList (xmlNodePtr node1, xmlNodePtr node2);
+void xmljNormalizeNode (xmlNodePtr node);
+xmlDtdPtr xmljGetDtd (xmlDocPtr doc);
+int xmljCompare (xmlNodePtr n1, xmlNodePtr n2);
+
+/* Utility */
+jobject xmljCreateDocument (JNIEnv * env, jobject self, xmlDocPtr doc);
+xmlAttrPtr xmljGetNamedItem (JNIEnv * env, jobject self, jstring name);
+xmlAttrPtr xmljGetNamedItemNS (JNIEnv * env, jobject self, jstring uri,
+ jstring localName);
+
+#endif /* !defined XMLJ_DOM_H */
diff --git a/native/jni/xmlj/xmlj_error.c b/native/jni/xmlj/xmlj_error.c
new file mode 100644
index 000000000..5a75c48e9
--- /dev/null
+++ b/native/jni/xmlj/xmlj_error.c
@@ -0,0 +1,169 @@
+/* xmlj_error.c -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_error.h"
+#include "xmlj_io.h"
+#include "xmlj_util.h"
+
+void
+xmljXsltErrorFunc (void *ctx, const char *msg, ...)
+{
+ if (NULL != ctx)
+ {
+ SAXParseContext *sax = ((SAXParseContext *) ctx);
+
+ if (NULL != sax)
+ {
+ JNIEnv *env = sax->env;
+
+ if (!(*env)->ExceptionOccurred (env))
+ {
+ jobject target = sax->obj;
+ xmlChar *x_msg;
+ jstring j_msg;
+ va_list args;
+
+ if (sax->error == NULL)
+ {
+ sax->error =
+ xmljGetMethodID (env,
+ target,
+ "error",
+ "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
+ if (sax->error == NULL)
+ {
+ return;
+ }
+ }
+
+ va_start (args, msg);
+ x_msg = (msg == NULL) ? NULL : xmlCharStrdup (msg);
+ va_end (args);
+ j_msg = xmljNewString (env, x_msg);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->error,
+ j_msg,
+ -1,
+ -1,
+ NULL,
+ NULL);
+ }
+ }
+ }
+ else
+ {
+ va_list va;
+ va_start (va, msg);
+ fprintf (stderr, "libxslt error: ");
+ vfprintf (stderr, msg, va);
+ fflush (stderr);
+ va_end (va);
+ }
+}
+
+void
+xmljThrowException (JNIEnv *env,
+ const char *classname,
+ const char *message)
+{
+ jclass cls;
+ jmethodID method;
+ jthrowable ex;
+ jstring jmsg;
+
+ /*fprintf(stderr, "Throwing exception %s %s\n", classname, message);*/
+ cls = (*env)->FindClass (env, classname);
+ if (cls == NULL)
+ {
+ fprintf (stderr, "Can't find class %s\n", classname);
+ fflush (stderr);
+ return;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(Ljava/lang/String;)V");
+ if (method == NULL)
+ {
+ fprintf (stderr, "Can't find method %s.<init>\n", classname);
+ fflush (stderr);
+ return;
+ }
+ jmsg = (message == NULL) ? NULL : (*env)->NewStringUTF (env, message);
+ ex = (jthrowable) (*env)->NewObject (env, cls, method, jmsg);
+ if (ex == NULL)
+ {
+ fprintf (stderr, "Can't instantiate new %s\n", classname);
+ fflush (stderr);
+ return;
+ }
+ (*env)->Throw (env, ex);
+}
+
+void
+xmljThrowDOMException (JNIEnv *env,
+ int code,
+ const char *message)
+{
+ jclass cls;
+ jmethodID method;
+ jthrowable ex;
+ jstring jmsg;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeDOMException");
+ if (cls == NULL)
+ {
+ fprintf (stderr, "Can't find DOMException class!\n");
+ fflush (stderr);
+ return;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(SLjava/lang/String;)V");
+ if (method == NULL)
+ {
+ fprintf (stderr, "Can't find DOMException constructor!\n");
+ fflush (stderr);
+ return;
+ }
+ jmsg = (message == NULL) ? NULL : (*env)->NewStringUTF (env, message);
+ ex = (jthrowable) (*env)->NewObject (env, cls, method, code, jmsg);
+ (*env)->Throw (env, ex);
+}
+
diff --git a/native/jni/xmlj/xmlj_error.h b/native/jni/xmlj/xmlj_error.h
new file mode 100644
index 000000000..f31ffc45f
--- /dev/null
+++ b/native/jni/xmlj/xmlj_error.h
@@ -0,0 +1,85 @@
+/* xmlj_error.h -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_ERROR_H
+#define XMLJ_ERROR_H
+
+#include <jni.h>
+#include <libxml/xmlIO.h>
+
+/*
+typedef struct SaxErrorContext_
+{
+ JNIEnv * env;
+ jobject saxErrorAdapter;
+ jmethodID saxCommentMethodID;
+ jmethodID saxWarningMethodID;
+ jmethodID saxErrorMethodID;
+ jmethodID saxFatalErrorMethodID;
+ jclass sourceLocatorClass;
+ jmethodID sourceLocatorConstructor;
+ xmlSAXLocatorPtr locator;
+ jstring publicId;
+ jstring systemId;
+ const char *publicIdCstr;
+ const char *systemIdCstr;
+ jmethodID resolveURIMethodID;
+ jmethodID resolveURIAndOpenMethodID;
+ jmethodID getInputStreamMethodID;
+ jmethodID xsltGenericErrorMethodID;
+ jobject theTransformerException;
+ jmethodID getNativeHandleMethodID;
+} SaxErrorContext;
+
+SaxErrorContext * xmljCreateSaxErrorContext (JNIEnv * env,
+ jobject errorContext,
+ jstring systemId,
+ jstring publicId);
+
+void xmljFreeSaxErrorContext (SaxErrorContext * errorContext);
+
+void xmljInitErrorHandling (xmlSAXHandler * saxHandler);
+*/
+
+void xmljXsltErrorFunc (void *ctx, const char *msg, ...);
+
+void xmljThrowException (JNIEnv *, const char *classname, const char *message);
+
+void xmljThrowDOMException (JNIEnv *, int code, const char *message);
+
+#endif /* !defined XMLJ_ERROR_H */
+
diff --git a/native/jni/xmlj/xmlj_io.c b/native/jni/xmlj/xmlj_io.c
new file mode 100644
index 000000000..1cb6c7e19
--- /dev/null
+++ b/native/jni/xmlj/xmlj_io.c
@@ -0,0 +1,799 @@
+/* xmlj_io.c -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_io.h"
+#include "xmlj_error.h"
+#include "xmlj_node.h"
+#include "xmlj_sax.h"
+#include "xmlj_util.h"
+
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <libxml/xmlIO.h>
+#include <libxml/parserInternals.h>
+
+#include <pthread.h>
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define UNSIGN(a) (((a) < 0) ? ((a) + 0x100) : (a))
+
+#define DETECT_BUFFER_SIZE 50
+
+typedef struct _OutputStreamContext
+{
+
+ JNIEnv *env;
+ jobject outputStream;
+ jmethodID outputStreamWriteFunc;
+ jmethodID outputStreamCloseFunc;
+
+}
+OutputStreamContext;
+
+typedef struct _InputStreamContext
+{
+
+ JNIEnv *env;
+ jobject inputStream;
+ jmethodID inputStreamReadFunc;
+ jmethodID inputStreamCloseFunc;
+ jobject bufferByteArray;
+ jint bufferLength;
+
+}
+InputStreamContext;
+
+InputStreamContext *xmljNewInputStreamContext (JNIEnv * env,
+ jobject inputStream);
+
+void xmljFreeInputStreamContext (InputStreamContext * inContext);
+
+int xmljInputReadCallback (void *context, char *buffer, int len);
+
+int xmljInputCloseCallback (void *context);
+
+int xmljOutputWriteCallback (void *context, const char *buffer, int len);
+
+int xmljOutputCloseCallback (void *context);
+
+OutputStreamContext *xmljNewOutputStreamContext (JNIEnv * env,
+ jobject outputStream);
+
+void
+xmljFreeOutputStreamContext (OutputStreamContext * outContext);
+
+xmlCharEncoding
+xmljDetectCharEncoding (JNIEnv * env, jbyteArray buffer);
+
+int
+xmljOutputWriteCallback (void *context, const char *buffer, int len)
+{
+ OutputStreamContext *outContext;
+ JNIEnv *env;
+ jbyteArray byteArray;
+
+ outContext = (OutputStreamContext *) context;
+ env = outContext->env;
+ byteArray = (*env)->NewByteArray (env, len);
+
+ if (0 != byteArray)
+ {
+ (*env)->SetByteArrayRegion (env, byteArray, 0, len, (jbyte *) buffer);
+
+ (*env)->CallVoidMethod (env,
+ outContext->outputStream,
+ outContext->outputStreamWriteFunc, byteArray);
+
+ (*env)->DeleteLocalRef (env, byteArray);
+
+ return (*env)->ExceptionOccurred (env) ? -1 : len;
+ }
+ else
+ {
+ /* Out of memory, signal error */
+ return -1;
+ }
+}
+
+int
+xmljOutputCloseCallback (void *context)
+{
+ OutputStreamContext *outContext;
+ JNIEnv *env;
+
+ outContext = (OutputStreamContext *) context;
+ env = outContext->env;
+ (*env)->CallVoidMethod (env,
+ outContext->outputStream,
+ outContext->outputStreamCloseFunc);
+
+ return (*env)->ExceptionOccurred (env) ? -1 : 0;
+}
+
+int
+xmljInputReadCallback (void *context, char *buffer, int len)
+{
+ InputStreamContext *inContext;
+ JNIEnv *env;
+ jint nread;
+ int offset;
+
+ inContext = (InputStreamContext *) context;
+ env = inContext->env;
+ nread = 0;
+
+ for (offset = 0; offset < len && nread >= 0;)
+ {
+ nread = (*env)->CallIntMethod (env,
+ inContext->inputStream,
+ inContext->inputStreamReadFunc,
+ inContext->bufferByteArray,
+ 0, MIN (len - offset,
+ inContext->bufferLength));
+
+ if (nread > 0)
+ {
+ (*env)->GetByteArrayRegion (env,
+ inContext->bufferByteArray,
+ 0, nread, ((jbyte *) buffer) + offset);
+
+ offset += nread;
+ }
+ }
+
+ return (*env)->ExceptionOccurred (env) ? -1 : offset;
+}
+
+int
+xmljInputCloseCallback (void *context)
+{
+ InputStreamContext *inContext;
+ JNIEnv *env;
+
+ inContext = (InputStreamContext *) context;
+ env = inContext->env;
+ (*env)->CallVoidMethod (env, inContext->inputStream,
+ inContext->inputStreamCloseFunc);
+
+ return (*env)->ExceptionOccurred (env) ? -1 : 0;
+}
+
+InputStreamContext *
+xmljNewInputStreamContext (JNIEnv * env, jobject inputStream)
+{
+ jclass inputStreamClass;
+ InputStreamContext *result;
+
+ inputStreamClass = (*env)->FindClass (env, "java/io/InputStream");
+ if (inputStreamClass == NULL)
+ {
+ return NULL;
+ }
+ result = (InputStreamContext *) malloc (sizeof (InputStreamContext));
+ if (result == NULL)
+ {
+ return NULL;
+ }
+
+ result->env = env;
+ result->inputStream = inputStream;
+ result->inputStreamReadFunc =
+ (*env)->GetMethodID (env, inputStreamClass, "read", "([BII)I");
+ result->inputStreamCloseFunc =
+ (*env)->GetMethodID (env, inputStreamClass, "close", "()V");
+ result->bufferLength = 4096;
+ result->bufferByteArray = (*env)->NewByteArray (env, result->bufferLength);
+ return result;
+}
+
+void
+xmljFreeInputStreamContext (InputStreamContext * inContext)
+{
+ JNIEnv *env;
+
+ env = inContext->env;
+ (*env)->DeleteLocalRef (env, inContext->bufferByteArray);
+ free (inContext);
+}
+
+OutputStreamContext *
+xmljNewOutputStreamContext (JNIEnv * env, jobject outputStream)
+{
+ jclass outputStreamClass;
+ OutputStreamContext *result;
+
+ outputStreamClass = (*env)->FindClass (env, "java/io/OutputStream");
+ if (outputStreamClass == NULL)
+ {
+ return NULL;
+ }
+ result = (OutputStreamContext *) malloc (sizeof (OutputStreamContext));
+ if (result == NULL)
+ {
+ return NULL;
+ }
+
+ result->env = env;
+ result->outputStream = outputStream;
+ result->outputStreamWriteFunc =
+ (*env)->GetMethodID (env, outputStreamClass, "write", "([B)V");
+ result->outputStreamCloseFunc =
+ (*env)->GetMethodID (env, outputStreamClass, "close", "()V");
+ return result;
+}
+
+
+void
+xmljFreeOutputStreamContext (OutputStreamContext * outContext)
+{
+ free (outContext);
+}
+
+SAXParseContext *
+xmljNewSAXParseContext (JNIEnv * env, jobject obj, xmlParserCtxtPtr ctx,
+ jstring publicId, jstring systemId)
+{
+ SAXParseContext *ret;
+
+ ret = (SAXParseContext *) malloc (sizeof (SAXParseContext));
+ ret->env = env;
+ ret->obj = obj;
+ ret->ctx = ctx;
+ ret->sax = ctx->sax;
+ ret->loc = NULL;
+ ret->publicId = publicId;
+ ret->systemId = systemId;
+
+ ret->startDTD = NULL;
+ ret->externalEntityDecl = NULL;
+ ret->internalEntityDecl = NULL;
+ ret->resolveEntity = NULL;
+ ret->notationDecl = NULL;
+ ret->attributeDecl = NULL;
+ ret->elementDecl = NULL;
+ ret->unparsedEntityDecl = NULL;
+ ret->setDocumentLocator = NULL;
+ ret->startDocument = NULL;
+ ret->endDocument = NULL;
+ ret->startElement = NULL;
+ ret->endElement = NULL;
+ ret->characters = NULL;
+ ret->ignorableWhitespace = NULL;
+ ret->processingInstruction = NULL;
+ ret->comment = NULL;
+ ret->cdataBlock = NULL;
+ ret->warning = NULL;
+ ret->error = NULL;
+ ret->fatalError = NULL;
+
+ ret->resolveURIAndOpen = NULL;
+ ret->stringClass = NULL;
+ return ret;
+}
+
+void
+xmljFreeSAXParseContext (SAXParseContext * saxCtx)
+{
+ free (saxCtx);
+}
+
+xmlCharEncoding
+xmljDetectCharEncoding (JNIEnv * env, jbyteArray buffer)
+{
+ xmlCharEncoding ret;
+ jint nread;
+
+ if (buffer == NULL)
+ {
+ return XML_CHAR_ENCODING_ERROR;
+ }
+ nread = (*env)->GetArrayLength (env, buffer);
+ if (nread >= 5)
+ {
+ jbyte nativeBuffer[DETECT_BUFFER_SIZE + 1];
+ unsigned char converted[DETECT_BUFFER_SIZE + 1];
+ int i;
+
+ memset (nativeBuffer, 0, DETECT_BUFFER_SIZE + 1);
+ (*env)->GetByteArrayRegion (env, buffer, 0, nread, nativeBuffer);
+ /* Convert from signed to unsigned */
+ for (i = 0; i < DETECT_BUFFER_SIZE + 1; i++)
+ {
+ converted[i] = UNSIGN (nativeBuffer[i]);
+ }
+ ret = xmlDetectCharEncoding (converted, nread);
+ }
+ else
+ {
+ ret = XML_CHAR_ENCODING_NONE;
+ }
+ return ret;
+}
+
+xmlParserCtxtPtr
+xmljNewParserContext (JNIEnv * env,
+ jobject inputStream,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean expandEntities,
+ jboolean loadEntities)
+{
+ InputStreamContext *inputContext;
+ xmlCharEncoding encoding;
+ xmlParserCtxtPtr ctx;
+ int options;
+
+ encoding = xmljDetectCharEncoding (env, detectBuffer);
+ if (encoding != XML_CHAR_ENCODING_ERROR)
+ {
+ inputContext = xmljNewInputStreamContext (env, inputStream);
+ if (NULL != inputContext)
+ {
+ /* NOTE: userdata must be NULL for DOM to work */
+ ctx = xmlCreateIOParserCtxt (NULL,
+ NULL,
+ xmljInputReadCallback,
+ xmljInputCloseCallback,
+ inputContext,
+ encoding);
+ if (NULL != ctx)
+ {
+ ctx->userData = ctx;
+
+ /* Set parsing options */
+ options = 0;
+ if (validate)
+ {
+ options |= XML_PARSE_DTDVALID;
+ }
+ if (coalesce)
+ {
+ options |= XML_PARSE_NOCDATA;
+ }
+ if (expandEntities)
+ {
+ options |= XML_PARSE_NOENT;
+ }
+ if (loadEntities)
+ {
+ options |= XML_PARSE_DTDLOAD;
+ }
+ if (xmlCtxtUseOptions (ctx, options))
+ {
+ xmljThrowException (env,
+ "java/lang/RuntimeException",
+ "Unable to set xmlParserCtxtPtr options");
+ }
+ if (base != NULL)
+ {
+ ctx->input->directory =
+ (*env)->GetStringUTFChars (env, base, 0);
+ }
+ return ctx;
+ }
+ xmljFreeInputStreamContext (inputContext);
+ }
+ }
+ return NULL;
+}
+
+void
+xmljFreeParserContext (xmlParserCtxtPtr ctx)
+{
+ InputStreamContext *inputStreamContext = NULL;
+
+ if (ctx->input != NULL && ctx->input->buf != NULL)
+ {
+ inputStreamContext
+ = (InputStreamContext *) ctx->input->buf->context;
+
+ }
+ xmlFreeParserCtxt (ctx);
+ if (inputStreamContext != NULL)
+ {
+ xmljFreeInputStreamContext (inputStreamContext);
+ }
+}
+
+xmlDocPtr
+xmljParseDocument (JNIEnv * env,
+ jobject self,
+ jobject in,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean expandEntities,
+ jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean declarationHandler,
+ jboolean lexicalHandler,
+ int mode)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *saxCtx;
+ xmlSAXHandlerPtr sax;
+
+ ctx = xmljNewParserContext (env, in, detectBuffer, publicId, systemId, base,
+ validate, coalesce, expandEntities,
+ entityResolver);
+ if (ctx != NULL)
+ {
+ saxCtx = xmljNewSAXParseContext (env, self, ctx, publicId, systemId);
+ if (saxCtx != NULL)
+ {
+ sax = xmljNewSAXHandler (contentHandler,
+ dtdHandler,
+ entityResolver,
+ errorHandler,
+ declarationHandler,
+ lexicalHandler);
+ if (sax != NULL)
+ {
+ return xmljParseDocument2 (env,
+ ctx,
+ saxCtx,
+ sax,
+ mode);
+ }
+ xmljFreeSAXParseContext (saxCtx);
+ }
+ xmljFreeParserContext (ctx);
+ }
+ if (!(*env)->ExceptionOccurred (env))
+ {
+ xmljThrowException (env, "java/io/IOException",
+ "Unable to create parser context");
+ }
+ return NULL;
+}
+
+xmlDocPtr
+xmljParseDocument2 (JNIEnv * env,
+ xmlParserCtxtPtr ctx,
+ SAXParseContext *saxCtx,
+ xmlSAXHandlerPtr sax,
+ int mode)
+{
+ xmlSAXHandlerPtr orig;
+ xmlDocPtr doc;
+ int ret;
+
+ ctx->_private = saxCtx;
+ ctx->userData = ctx;
+ orig = ctx->sax;
+ ctx->sax = sax;
+
+ xmljSetThreadContext (saxCtx);
+
+ ret = xmlParseDocument (ctx);
+ doc = ctx->myDoc;
+ if (ret || !doc)
+ {
+ const char *msg = ctx->lastError.message;
+ switch (mode)
+ {
+ case 0:
+ xmljSAXFatalError (ctx, msg);
+ break;
+ case 1:
+ xmljThrowDOMException (env, ret, msg);
+ break;
+ case 2:
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerException",
+ msg);
+ }
+ }
+
+ xmljClearThreadContext ();
+
+ ctx->sax = orig;
+ free(sax);
+ xmljFreeSAXParseContext (saxCtx);
+ xmljFreeParserContext (ctx);
+ xmljClearStringCache ();
+ return doc;
+}
+
+xmlParserInputPtr
+xmljNewParserInput (JNIEnv * env,
+ jobject inputStream,
+ jbyteArray detectBuffer,
+ xmlParserCtxtPtr parserContext)
+{
+ xmlParserInputPtr ret;
+ xmlParserInputBufferPtr input;
+ xmlCharEncoding encoding;
+
+ encoding = xmljDetectCharEncoding (env, detectBuffer);
+ if (encoding != XML_CHAR_ENCODING_ERROR)
+ {
+ input = xmljNewParserInputBuffer (env, inputStream, encoding);
+ if (input != NULL)
+ {
+ ret = xmlNewIOInputStream (parserContext, input, encoding);
+ return ret;
+ }
+ xmlFreeParserInputBuffer (input);
+ }
+ return NULL;
+}
+
+xmlParserInputBufferPtr
+xmljNewParserInputBuffer (JNIEnv * env,
+ jobject inputStream, xmlCharEncoding encoding)
+{
+ xmlParserInputBufferPtr ret;
+ InputStreamContext *inputContext;
+
+ inputContext = xmljNewInputStreamContext (env, inputStream);
+ if (NULL != inputContext)
+ {
+ ret = xmlParserInputBufferCreateIO (&xmljInputReadCallback,
+ &xmljInputCloseCallback,
+ inputContext, encoding);
+ if (ret != NULL)
+ return ret;
+ xmljFreeInputStreamContext (inputContext);
+ }
+ return NULL;
+}
+
+void
+xmljSaveFileToJavaOutputStream (JNIEnv * env, jobject outputStream,
+ xmlDocPtr tree,
+ const char *outputEncodingName)
+{
+ OutputStreamContext *outputContext =
+ xmljNewOutputStreamContext (env, outputStream);
+
+ xmlCharEncoding outputEncoding = xmlParseCharEncoding (outputEncodingName);
+
+ xmlOutputBufferPtr outputBuffer =
+ xmlOutputBufferCreateIO (xmljOutputWriteCallback,
+ xmljOutputCloseCallback,
+ outputContext,
+ xmlGetCharEncodingHandler (outputEncoding));
+
+ /* Write result to output stream */
+
+ xmlSaveFileTo (outputBuffer, tree, outputEncodingName);
+
+ xmljFreeOutputStreamContext (outputContext);
+}
+
+/*
+jobject
+xmljResolveURI (SaxErrorContext * saxErrorContext,
+ const char *URL, const char *ID)
+{
+ JNIEnv *env = saxErrorContext->env;
+
+ jstring hrefString = (*env)->NewStringUTF (env, URL);
+ jstring baseString = saxErrorContext->systemId;
+
+ jobject sourceWrapper = (*env)->CallObjectMethod (env,
+ saxErrorContext->
+ saxErrorAdapter,
+ saxErrorContext->
+ resolveURIMethodID,
+ hrefString,
+ baseString);
+ (*env)->DeleteLocalRef (env, hrefString);
+
+ if (NULL == sourceWrapper)
+ {
+ return NULL;
+ }
+ else
+ {
+ jobject sourceInputStream = (*env)->CallObjectMethod (env,
+ sourceWrapper,
+ saxErrorContext->
+ getInputStreamMethodID);
+
+ (*env)->DeleteLocalRef (env, sourceWrapper);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ -* Report to ErrorAdapter here? *-
+ return NULL;
+ }
+
+ return sourceInputStream;
+ }
+}*/
+
+xmlDocPtr
+xmljResolveURIAndOpen (SAXParseContext *saxContext,
+ const char *URL,
+ const char *ID)
+{
+ jobject libxmlDocument;
+ xmlDocPtr doc;
+ JNIEnv *env = saxContext->env;
+
+ jstring hrefString = (*env)->NewStringUTF (env, URL);
+ jstring baseString = saxContext->systemId;
+
+ if (saxContext->resolveURIAndOpen == NULL)
+ {
+ jclass cls = (*env)->GetObjectClass (env, saxContext->obj);
+ saxContext->resolveURIAndOpen =
+ (*env)->GetMethodID (env, cls, "resolveURIAndOpen",
+ "Ljava/lang/String;Ljava/lang/String)Lgnu/xml/libxmlj/transform/LibxmlDocument;");
+ }
+ libxmlDocument =
+ (*env)->CallObjectMethod (env,
+ saxContext->obj,
+ saxContext->resolveURIAndOpen,
+ hrefString,
+ baseString);
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, libxmlDocument);
+
+ (*env)->DeleteLocalRef (env, libxmlDocument);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* Report to ErrorAdapter here? */
+ return NULL;
+ }
+ else
+ {
+ return doc;
+ }
+}
+
+/*xmlParserInputPtr
+xmljLoadExternalEntity (const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt)
+{
+ SaxErrorContext *saxErrorContext = xmljGetThreadContext ();
+
+ JNIEnv *env = saxErrorContext->env;
+
+ jstring hrefString = (*env)->NewStringUTF (env, URL);
+ jstring baseString = saxErrorContext->systemId;
+
+ jobject sourceWrapper = (*env)->CallObjectMethod (env,
+ saxErrorContext->
+ saxErrorAdapter,
+ saxErrorContext->
+ resolveURIMethodID,
+ hrefString,
+ baseString);
+
+ (*env)->DeleteLocalRef (env, hrefString);
+
+ if (NULL == sourceWrapper)
+ {
+ return NULL;
+ }
+ else
+ {
+ InputStreamContext *inputContext;
+ xmlParserInputBufferPtr inputBuffer;
+ xmlParserInputPtr inputStream;
+
+ jobject sourceInputStream = (*env)->CallObjectMethod (env,
+ sourceWrapper,
+ saxErrorContext->
+ getInputStreamMethodID);
+
+ (*env)->DeleteLocalRef (env, sourceWrapper);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ -* Report to ErrorAdapter *-
+ return NULL;
+ }
+
+ inputContext = xmljNewInputStreamContext (env, sourceInputStream);
+
+ inputBuffer
+ = xmlParserInputBufferCreateIO (xmljInputReadCallback,
+ xmljInputCloseCallback,
+ inputContext, XML_CHAR_ENCODING_NONE);
+
+ inputStream = xmlNewInputStream (ctxt);
+ if (inputStream == NULL)
+ {
+ return (NULL);
+ }
+
+ inputStream->filename = NULL;
+ inputStream->directory = NULL;
+ inputStream->buf = inputBuffer;
+
+ inputStream->base = inputStream->buf->buffer->content;
+ inputStream->cur = inputStream->buf->buffer->content;
+ inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
+ if ((ctxt->directory == NULL) && (inputStream->directory != NULL))
+ ctxt->directory =
+ (char *) xmlStrdup ((const xmlChar *) inputStream->directory);
+ return (inputStream);
+ }
+}*/
+
+/* Key for the thread-specific buffer */
+static pthread_key_t thread_context_key;
+
+/* Once-only initialisation of the key */
+static pthread_once_t thread_context_once = PTHREAD_ONCE_INIT;
+
+static void
+thread_context_key_alloc (void);
+
+/* Allocate the key */
+static void
+thread_context_key_alloc ()
+{
+ pthread_key_create (&thread_context_key, NULL);
+}
+
+void
+xmljSetThreadContext (SAXParseContext * context)
+{
+ pthread_once (&thread_context_once, thread_context_key_alloc);
+ pthread_setspecific (thread_context_key, context);
+}
+
+void
+xmljClearThreadContext (void)
+{
+ pthread_setspecific (thread_context_key, NULL);
+}
+
+/* Return the thread-specific buffer */
+SAXParseContext *
+xmljGetThreadContext (void)
+{
+ return (SAXParseContext *) pthread_getspecific (thread_context_key);
+}
diff --git a/native/jni/xmlj/xmlj_io.h b/native/jni/xmlj/xmlj_io.h
new file mode 100644
index 000000000..878fa92dc
--- /dev/null
+++ b/native/jni/xmlj/xmlj_io.h
@@ -0,0 +1,170 @@
+/* xmlj_io.h -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_IO_H
+#define XMLJ_IO_H
+
+#include <jni.h>
+#include <libxml/xmlIO.h>
+#include "xmlj_error.h"
+
+typedef struct _SAXParseContext
+{
+
+ JNIEnv *env; /* Current JNI environment */
+ jobject obj; /* The gnu.xml.libxmlj.sax.GnomeXmlReader instance */
+ xmlParserCtxtPtr ctx; /* libxml2 parser context */
+ xmlSAXLocatorPtr loc; /* libxml2 SAX locator */
+ xmlSAXHandlerPtr sax; /* pristine SAX handler */
+ jstring publicId;
+ jstring systemId;
+
+ jmethodID startDTD;
+ jmethodID externalEntityDecl;
+ jmethodID internalEntityDecl;
+ jmethodID resolveEntity;
+ jmethodID notationDecl;
+ jmethodID attributeDecl;
+ jmethodID elementDecl;
+ jmethodID unparsedEntityDecl;
+ jmethodID setDocumentLocator;
+ jmethodID startDocument;
+ jmethodID endDocument;
+ jmethodID startElement;
+ jmethodID endElement;
+ jmethodID characters;
+ jmethodID ignorableWhitespace;
+ jmethodID processingInstruction;
+ jmethodID comment;
+ jmethodID cdataBlock;
+ jmethodID warning;
+ jmethodID error;
+ jmethodID fatalError;
+
+ jmethodID resolveURIAndOpen; /* JavaProxy */
+ jclass stringClass;
+}
+SAXParseContext;
+
+SAXParseContext *
+xmljNewSAXParseContext (JNIEnv * env, jobject obj, xmlParserCtxtPtr ctx,
+ jstring publicId, jstring systemId);
+
+void
+xmljFreeSAXParseContext (SAXParseContext * saxCtx);
+
+xmlParserCtxtPtr
+xmljNewParserContext (JNIEnv * env,
+ jobject inputStream,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean expandEntities,
+ jboolean loadEntities);
+
+void
+xmljFreeParserContext (xmlParserCtxtPtr parserContext);
+
+xmlDocPtr
+xmljParseDocument (JNIEnv * env,
+ jobject self,
+ jobject in,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean expandEntities,
+ jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean declarationHandler,
+ jboolean lexicalHandler,
+ int saxMode);
+
+xmlDocPtr
+xmljParseDocument2 (JNIEnv * env,
+ xmlParserCtxtPtr ctx,
+ SAXParseContext *saxCtx,
+ xmlSAXHandlerPtr sax,
+ int saxMode);
+
+xmlParserInputPtr
+xmljNewParserInput (JNIEnv * env,
+ jobject inputStream,
+ jbyteArray detectBuffer,
+ xmlParserCtxtPtr parserContext);
+
+xmlParserInputBufferPtr
+xmljNewParserInputBuffer (JNIEnv * env,
+ jobject inputStream,
+ xmlCharEncoding encoding);
+
+void
+xmljSaveFileToJavaOutputStream (JNIEnv * env, jobject outputStream,
+ xmlDocPtr tree,
+ const char *outputEncoding);
+
+/*
+xmlParserInputPtr
+xmljLoadExternalEntity (const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt);
+
+jobject
+xmljResolveURI (SaxErrorContext * saxErrorContext, const char *URL,
+ const char *ID);
+*/
+xmlDocPtr
+xmljResolveURIAndOpen (SAXParseContext *saxContext,
+ const char *URL, const char *ID);
+
+
+void
+xmljSetThreadContext (SAXParseContext * ctxt);
+
+SAXParseContext *
+xmljGetThreadContext (void);
+
+void
+xmljClearThreadContext (void);
+
+#endif /* !defined XMLJ_IO_H */
diff --git a/native/jni/xmlj/xmlj_node.c b/native/jni/xmlj/xmlj_node.c
new file mode 100644
index 000000000..a5f6af201
--- /dev/null
+++ b/native/jni/xmlj/xmlj_node.c
@@ -0,0 +1,203 @@
+/* xmlj_node.c -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_error.h"
+#include "xmlj_node.h"
+#include "xmlj_util.h"
+#include <libxml/xmlstring.h>
+
+/*
+ * Returns the node ID for the given GnomeNode object.
+ */
+xmlNodePtr
+xmljGetNodeID (JNIEnv * env, jobject self)
+{
+ jclass cls;
+ jfieldID field;
+ jobject id;
+ xmlNodePtr node;
+
+ if (self == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ cls = (*env)->GetObjectClass (env, self);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ field = (*env)->GetFieldID (env, cls, "id", "Ljava/lang/Object;");
+ if (field == NULL)
+ {
+ return NULL;
+ }
+ id = (*env)->GetObjectField (env, self, field);
+ node = (xmlNodePtr) xmljAsPointer (env, id);
+ if (node == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ }
+ return node;
+}
+
+/*
+ * Returns the Java node instanced corresponding to the specified node ID.
+ */
+jobject
+xmljGetNodeInstance (JNIEnv * env, xmlNodePtr node)
+{
+ jclass cls;
+ jmethodID method;
+ xmlElementType type;
+
+ if (node == NULL)
+ return NULL;
+
+ /* Invoke the GnomeNode.newInstance class method */
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeNode");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetStaticMethodID (env, cls, "newInstance",
+ "(Ljava/lang/Object;Ljava/lang/Object;I)Lgnu/xml/libxmlj/dom/GnomeNode;");
+
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ type = node->type;
+ switch (type)
+ {
+ case XML_DTD_NODE:
+ type = XML_DOCUMENT_TYPE_NODE;
+ break;
+ case XML_ATTRIBUTE_DECL:
+ type = XML_ATTRIBUTE_NODE;
+ break;
+ case XML_ENTITY_DECL:
+ type = XML_ENTITY_NODE;
+ break;
+ default:
+ break;
+ }
+ return (*env)->CallStaticObjectMethod (env, cls, method,
+ xmljAsField (env, node->doc),
+ xmljAsField (env, node),
+ type);
+}
+
+void
+xmljFreeDoc (JNIEnv * env, xmlDocPtr doc)
+{
+ jclass cls;
+ jmethodID method;
+
+ /* Invoke the GnomeNode.freeDocument class method */
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeNode");
+ if (cls == NULL)
+ {
+ return;
+ }
+ method = (*env)->GetStaticMethodID (env, cls, "freeDocument",
+ "(Ljava/lang/Object;)V");
+ if (method == NULL)
+ {
+ return;
+ }
+ (*env)->CallStaticVoidMethod (env, cls, method, xmljAsField (env, doc));
+}
+
+int
+xmljMatch (const xmlChar * name, xmlNodePtr node)
+{
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ return xmlStrcmp (node->name, name);
+ default:
+ return 1;
+ }
+}
+
+int
+xmljMatchNS (const xmlChar * uri, const xmlChar * localName, xmlNodePtr node)
+{
+ xmlNsPtr ns;
+ const xmlChar *nodeLocalName;
+ int *len;
+ int ret;
+
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ len = (int *) malloc (sizeof (int));
+ if (xmlSplitQName3 (node->name, len) != NULL)
+ {
+ nodeLocalName = node->name + (*len);
+ }
+ else
+ {
+ nodeLocalName = node->name;
+ }
+ free (len);
+ ns = node->ns;
+ if (ns == NULL || ns->href == NULL)
+ {
+ if (uri != NULL)
+ {
+ return 0;
+ }
+ ret = xmlStrcmp (localName, nodeLocalName);
+ }
+ else
+ {
+ if (uri == NULL)
+ {
+ return 0;
+ }
+ ret = (xmlStrcmp (localName, nodeLocalName) &&
+ xmlStrcmp (uri, ns->href));
+ }
+ return ret;
+ default:
+ return 1;
+ }
+}
diff --git a/native/jni/xmlj/xmlj_node.h b/native/jni/xmlj/xmlj_node.h
new file mode 100644
index 000000000..bd5afbbb9
--- /dev/null
+++ b/native/jni/xmlj/xmlj_node.h
@@ -0,0 +1,72 @@
+/* xmlj_node.h -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_NODE_H
+#define XMLJ_NODE_H
+
+#include <jni.h>
+#include <libxml/tree.h>
+
+/* -- Utility method definitions -- */
+
+/*
+ * Returns the node for the given Java node instance
+ */
+xmlNodePtr xmljGetNodeID (JNIEnv *, jobject);
+
+/*
+ * Returns the Java node instance for the given node
+ */
+jobject xmljGetNodeInstance (JNIEnv *, xmlNodePtr);
+
+/*
+ * Frees the specified document pointer,
+ * releasing all its nodes from the cache.
+ */
+void xmljFreeDoc (JNIEnv *, xmlDocPtr);
+
+/*
+ * Match a node name
+ */
+int xmljMatch (const xmlChar *, xmlNodePtr);
+
+/*
+ * Match a node name and namespace
+ */
+int xmljMatchNS (const xmlChar *, const xmlChar *, xmlNodePtr);
+
+#endif /* !defined XMLJ_NODE_H */
diff --git a/native/jni/xmlj/xmlj_sax.c b/native/jni/xmlj/xmlj_sax.c
new file mode 100644
index 000000000..576e54734
--- /dev/null
+++ b/native/jni/xmlj/xmlj_sax.c
@@ -0,0 +1,1441 @@
+/* xmlj_sax.c -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_sax.h"
+#include "xmlj_io.h"
+#include "xmlj_util.h"
+#include <unistd.h>
+#include <string.h>
+
+xmlExternalEntityLoader defaultLoader = NULL;
+
+void
+xmljDispatchError (xmlParserCtxtPtr ctx,
+ xmlSAXLocatorPtr loc,
+ JNIEnv *env,
+ jobject target,
+ jmethodID method,
+ const char *msg,
+ va_list args);
+
+/* -- GnomeLocator -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeLocator_publicId (JNIEnv * env,
+ jobject self,
+ jobject j_ctx,
+ jobject j_loc)
+{
+ xmlParserCtxtPtr ctx;
+ xmlSAXLocatorPtr loc;
+ SAXParseContext *sax;
+
+ ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
+ loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
+ sax = (SAXParseContext *) ctx->_private;
+
+ return sax->publicId;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeLocator_systemId (JNIEnv * env,
+ jobject self,
+ jobject j_ctx,
+ jobject j_loc)
+{
+ xmlParserCtxtPtr ctx;
+ xmlSAXLocatorPtr loc;
+ SAXParseContext *sax;
+
+ ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
+ loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
+ sax = (SAXParseContext *) ctx->_private;
+
+ return sax->systemId;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeLocator_lineNumber (JNIEnv * env,
+ jobject self,
+ jobject j_ctx,
+ jobject j_loc)
+{
+ xmlParserCtxtPtr ctx;
+ xmlSAXLocatorPtr loc;
+
+ ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
+ loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
+ if (ctx == NULL || ctx->input == NULL)
+ {
+ return -1;
+ }
+ return ctx->input->line;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeLocator_columnNumber (JNIEnv * env,
+ jobject self,
+ jobject j_ctx,
+ jobject j_loc)
+{
+ xmlParserCtxtPtr ctx;
+ xmlSAXLocatorPtr loc;
+
+ ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
+ loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
+ if (ctx == NULL || ctx->input == NULL)
+ {
+ return -1;
+ }
+ return ctx->input->col;
+}
+
+/* -- GnomeXMLReader -- */
+
+/*
+ * Entry point for SAX parsing.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeXMLReader_parseStream (JNIEnv * env,
+ jobject self,
+ jobject in,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean
+ declarationHandler,
+ jboolean lexicalHandler)
+{
+ xmljParseDocument (env,
+ self,
+ in,
+ detectBuffer,
+ publicId,
+ systemId,
+ base,
+ validate,
+ 0,
+ 0,
+ contentHandler,
+ dtdHandler,
+ entityResolver,
+ errorHandler,
+ declarationHandler,
+ lexicalHandler,
+ 0);
+}
+
+xmlParserInputPtr
+xmljExternalEntityLoader (const char *url, const char *id,
+ xmlParserCtxtPtr ctx)
+{
+ const xmlChar *systemId;
+ const xmlChar *publicId;
+ xmlParserInputPtr ret;
+
+ systemId = xmlCharStrdup (url);
+ publicId = xmlCharStrdup (id);
+ /* TODO convert systemId to absolute URI */
+ ret = xmljSAXResolveEntity (ctx, publicId, systemId);
+ if (ret == NULL)
+ {
+ ret = defaultLoader (url, id, ctx);
+ }
+ return ret;
+}
+
+/*
+ * Allocates and configures a SAX handler that can report the various
+ * classes of callback.
+ */
+xmlSAXHandlerPtr
+xmljNewSAXHandler (jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean declarationHandler,
+ jboolean lexicalHandler)
+{
+ xmlSAXHandlerPtr sax;
+
+ sax = (xmlSAXHandlerPtr) malloc (sizeof (xmlSAXHandler));
+ if (sax == NULL)
+ {
+ return NULL;
+ }
+ memset (sax, 0, sizeof (xmlSAXHandler));
+ xmlSAXVersion (sax, 1); /* TODO SAX2 */
+
+ if (dtdHandler)
+ {
+ sax->internalSubset = &xmljSAXInternalSubset;
+ }
+ if (defaultLoader == NULL)
+ {
+ defaultLoader = xmlGetExternalEntityLoader ();
+ xmlSetExternalEntityLoader (xmljExternalEntityLoader);
+ }
+ if (entityResolver)
+ {
+ sax->resolveEntity = &xmljSAXResolveEntity;
+ }
+
+ if (declarationHandler)
+ {
+ sax->entityDecl = &xmljSAXEntityDecl;
+ sax->notationDecl = &xmljSAXNotationDecl;
+ sax->attributeDecl = &xmljSAXAttributeDecl;
+ sax->elementDecl = &xmljSAXElementDecl;
+ sax->unparsedEntityDecl = &xmljSAXUnparsedEntityDecl;
+ }
+
+ /* We always listen for the locator callback */
+ sax->setDocumentLocator = &xmljSAXSetDocumentLocator;
+ if (contentHandler)
+ {
+ sax->startDocument = &xmljSAXStartDocument;
+ sax->endDocument = &xmljSAXEndDocument;
+ sax->startElement = &xmljSAXStartElement;
+ sax->endElement = &xmljSAXEndElement;
+ sax->characters = &xmljSAXCharacters;
+ sax->ignorableWhitespace = &xmljSAXIgnorableWhitespace;
+ sax->processingInstruction = &xmljSAXProcessingInstruction;
+ }
+
+ /* We always intercept getEntity */
+ /* TODO this should only be if lexicalHandler */
+ sax->getEntity = &xmljSAXGetEntity;
+ if (lexicalHandler)
+ {
+ sax->getEntity = &xmljSAXGetEntity;
+ sax->reference = &xmljSAXReference;
+ sax->comment = &xmljSAXComment;
+ sax->cdataBlock = &xmljSAXCDataBlock;
+ }
+ else if (contentHandler)
+ {
+ sax->cdataBlock = &xmljSAXCharacters;
+ }
+
+ if (errorHandler)
+ {
+ sax->warning = &xmljSAXWarning;
+ sax->error = &xmljSAXError;
+ sax->fatalError = &xmljSAXFatalError;
+ }
+
+ return sax;
+}
+
+/* -- Callback functions -- */
+
+void
+xmljSAXInternalSubset (void *vctx,
+ const xmlChar * name,
+ const xmlChar * publicId, const xmlChar * systemId)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_publicId;
+ jstring j_systemId;
+
+ xmlSAX2InternalSubset (vctx, name, publicId, systemId);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->startDTD == NULL)
+ {
+ sax->startDTD =
+ xmljGetMethodID (env,
+ target,
+ "startDTD",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->startDTD == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->startDTD,
+ j_name,
+ j_publicId,
+ j_systemId);
+}
+
+xmlParserInputPtr
+xmljSAXResolveEntity (void *vctx,
+ const xmlChar * publicId, const xmlChar * systemId)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_publicId;
+ jstring j_systemId;
+ jobject inputStream;
+
+ /* xmlSAX2ResolveEntity (vctx, publicId, systemId); */
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ if (ctx->_private == NULL)
+ {
+ /* Not in Kansas */
+ return NULL;
+ }
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+
+ if (sax->resolveEntity == NULL)
+ {
+ sax->resolveEntity =
+ xmljGetMethodID (env,
+ target,
+ "resolveEntity",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/io/InputStream;");
+ if (sax->resolveEntity == NULL)
+ {
+ return NULL;
+ }
+ }
+
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+
+ inputStream = (*env)->CallObjectMethod (env,
+ target,
+ sax->resolveEntity,
+ j_publicId,
+ j_systemId,
+ sax->systemId);
+
+ /* Return an xmlParserInputPtr corresponding to the input stream */
+ if (inputStream != NULL)
+ {
+ jbyteArray detectBuffer;
+ jmethodID getDetectBuffer;
+
+ /* Get the detect buffer from the NamedInputStream */
+ getDetectBuffer = xmljGetMethodID (env, inputStream, "getDetectBuffer",
+ "()[B");
+ if (getDetectBuffer == NULL)
+ {
+ return NULL;
+ }
+ detectBuffer = (*env)->CallObjectMethod (env, inputStream,
+ getDetectBuffer);
+
+ return xmljNewParserInput (env, inputStream, detectBuffer, ctx);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+xmlEntityPtr
+xmljSAXGetEntity (void *vctx, const xmlChar * name)
+{
+ xmlEntityPtr ret;
+
+ /* TODO */
+ /* ret = xmlSAX2GetEntity (vctx, name); */
+ ret = NULL;
+ return ret;
+}
+
+void
+xmljSAXEntityDecl (void *vctx,
+ const xmlChar * name,
+ int type,
+ const xmlChar * publicId,
+ const xmlChar * systemId,
+ xmlChar * content)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_publicId;
+ jstring j_systemId;
+ jstring j_value;
+
+ xmlSAX2EntityDecl (vctx, name, type, publicId, systemId, content);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ j_name = xmljNewString (env, name);
+ switch (type)
+ {
+ case XML_INTERNAL_GENERAL_ENTITY:
+ case XML_INTERNAL_PARAMETER_ENTITY:
+ case XML_INTERNAL_PREDEFINED_ENTITY:
+ if (sax->internalEntityDecl == NULL)
+ {
+ sax->internalEntityDecl =
+ xmljGetMethodID (env,
+ target,
+ "internalEntityDecl",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->internalEntityDecl == NULL)
+ {
+ return;
+ }
+ }
+ j_value = xmljNewString (env, content);
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->internalEntityDecl,
+ j_name,
+ j_value);
+ break;
+ default:
+ if (sax->externalEntityDecl == NULL)
+ {
+ sax->externalEntityDecl =
+ xmljGetMethodID (env,
+ target,
+ "externalEntityDecl",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->externalEntityDecl == NULL)
+ {
+ return;
+ }
+ }
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->externalEntityDecl,
+ j_name,
+ j_publicId,
+ j_systemId);
+ }
+}
+
+void
+xmljSAXNotationDecl (void *vctx,
+ const xmlChar * name,
+ const xmlChar * publicId,
+ const xmlChar * systemId)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_publicId;
+ jstring j_systemId;
+
+ xmlSAX2NotationDecl (vctx, name, publicId, systemId);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->notationDecl == NULL)
+ {
+ sax->notationDecl =
+ xmljGetMethodID (env,
+ target,
+ "notationDecl",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->notationDecl == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+
+ /* Invoke the method */
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->notationDecl,
+ j_name,
+ j_publicId,
+ j_systemId);
+}
+
+void
+xmljSAXAttributeDecl (void *vctx,
+ const xmlChar * elem,
+ const xmlChar * fullName,
+ int type,
+ int def,
+ const xmlChar * defaultValue,
+ xmlEnumerationPtr tree)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_eName;
+ jstring j_aName;
+ jstring j_type;
+ jstring j_mode;
+ jstring j_value;
+
+ xmlSAX2AttributeDecl (vctx, elem, fullName, type, def, defaultValue, tree);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->attributeDecl == NULL)
+ {
+ sax->attributeDecl =
+ xmljGetMethodID (env,
+ target,
+ "attributeDecl",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->attributeDecl == NULL)
+ {
+ return;
+ }
+ }
+
+ j_eName = xmljNewString (env, elem);
+ j_aName = xmljNewString (env, fullName);
+ j_type = xmljAttributeTypeName (env, type);
+ j_mode = xmljAttributeModeName (env, def);
+ j_value = xmljNewString (env, defaultValue);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->attributeDecl,
+ j_eName,
+ j_aName,
+ j_type,
+ j_mode,
+ j_value);
+}
+
+void
+xmljSAXElementDecl (void *vctx,
+ const xmlChar * name,
+ int type,
+ xmlElementContentPtr content)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_model;
+
+ xmlSAX2ElementDecl (vctx, name, type, content);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->elementDecl == NULL)
+ {
+ sax->elementDecl =
+ xmljGetMethodID (env,
+ target,
+ "elementDecl",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->elementDecl == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ j_model = NULL; /* TODO */
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->elementDecl,
+ j_name,
+ j_model);
+}
+
+void
+xmljSAXUnparsedEntityDecl (void *vctx,
+ const xmlChar * name,
+ const xmlChar * publicId,
+ const xmlChar * systemId,
+ const xmlChar * notationName)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_publicId;
+ jstring j_systemId;
+ jstring j_notationName;
+
+ xmlSAX2UnparsedEntityDecl (vctx, name, publicId, systemId, notationName);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->unparsedEntityDecl == NULL)
+ {
+ sax->unparsedEntityDecl =
+ xmljGetMethodID (env,
+ target,
+ "unparsedEntityDecl",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->unparsedEntityDecl == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+ j_notationName = xmljNewString (env, notationName);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->unparsedEntityDecl,
+ j_name,
+ j_publicId,
+ j_systemId,
+ j_notationName);
+}
+
+void
+xmljSAXSetDocumentLocator (void *vctx, xmlSAXLocatorPtr loc)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+
+ xmlSAX2SetDocumentLocator (vctx, loc);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ if (target == NULL)
+ {
+ /* No Java parse context */
+ return;
+ }
+
+ /* Update locator on sax context */
+ sax->loc = loc;
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->setDocumentLocator == NULL)
+ {
+ sax->setDocumentLocator = xmljGetMethodID (env,
+ target,
+ "setDocumentLocator",
+ "(Ljava/lang/Object;Ljava/lang/Object;)V");
+ if (sax->setDocumentLocator == NULL)
+ {
+ return;
+ }
+ }
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->setDocumentLocator,
+ xmljAsField (env, ctx),
+ xmljAsField (env, loc));
+}
+
+void
+xmljSAXStartDocument (void *vctx)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+
+ xmlSAX2StartDocument (vctx);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->startDocument == NULL)
+ {
+ sax->startDocument = xmljGetMethodID (env,
+ target,
+ "startDocument",
+ "(Z)V");
+ if (sax->startDocument == NULL)
+ {
+ return;
+ }
+ }
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->startDocument,
+ ctx->standalone);
+}
+
+void
+xmljSAXEndDocument (void *vctx)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+
+ xmlSAX2EndDocument (vctx);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->endDocument == NULL)
+ {
+ sax->endDocument = xmljGetMethodID (env,
+ target,
+ "endDocument",
+ "()V");
+ if (sax->endDocument == NULL)
+ {
+ return;
+ }
+ }
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->endDocument);
+}
+
+void
+xmljSAXStartElement (void *vctx,
+ const xmlChar * name,
+ const xmlChar ** attrs)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jobjectArray j_attrs;
+ jstring j_attr;
+ jsize len;
+
+ xmlSAX2StartElement (vctx, name, attrs);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->startElement == NULL)
+ {
+ sax->startElement =
+ xmljGetMethodID (env,
+ target,
+ "startElement",
+ "(Ljava/lang/String;[Ljava/lang/String;)V");
+ if (sax->startElement == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ /* build attributes array */
+ len = 0;
+ for (len = 0; attrs && attrs[len]; len++)
+ {
+ }
+ if (len)
+ {
+ if (sax->stringClass == NULL)
+ {
+ sax->stringClass = (*env)->FindClass (env, "java/lang/String");
+ if (sax->stringClass == NULL)
+ {
+ fprintf (stderr, "Can't find java.lang.String class!\n");
+ return;
+ }
+ }
+ j_attrs = (*env)->NewObjectArray (env, len, sax->stringClass, NULL);
+ if (j_attrs == NULL)
+ {
+ fprintf (stderr, "Can't allocate attributes array!\n");
+ return;
+ }
+ len = 0;
+ for (len = 0; attrs && attrs[len]; len++)
+ {
+ j_attr = xmljNewString (env, attrs[len]);
+ (*env)->SetObjectArrayElement (env, j_attrs, len, j_attr);
+ }
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->startElement,
+ j_name,
+ j_attrs);
+ (*env)->DeleteLocalRef (env, j_attrs);
+ }
+ else
+ {
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->startElement,
+ j_name,
+ NULL);
+
+ }
+}
+
+void
+xmljSAXEndElement (void *vctx,
+ const xmlChar * name)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+
+ xmlSAX2EndElement (vctx, name);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->endElement == NULL)
+ {
+ sax->endElement = xmljGetMethodID (env,
+ target,
+ "endElement",
+ "(Ljava/lang/String;)V");
+ if (sax->endElement == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->endElement,
+ j_name);
+}
+
+void
+xmljSAXReference (void *vctx,
+ const xmlChar * name)
+{
+ xmlSAX2Reference (vctx, name);
+}
+
+void
+xmljSAXCharacters (void *vctx,
+ const xmlChar * ch,
+ int len)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_ch;
+ xmlChar *dup;
+
+ xmlSAX2Characters (vctx, ch, len);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->characters == NULL)
+ {
+ sax->characters = xmljGetMethodID (env,
+ target,
+ "characters",
+ "(Ljava/lang/String;)V");
+ if (sax->characters == NULL)
+ {
+ return;
+ }
+ }
+
+ dup = xmlStrndup (ch, len);
+ j_ch = xmljNewString (env, dup);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->characters,
+ j_ch);
+ xmlFree (dup);
+}
+
+void
+xmljSAXIgnorableWhitespace (void *vctx,
+ const xmlChar * ch,
+ int len)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_ch;
+ xmlChar *dup;
+
+ xmlSAX2IgnorableWhitespace (vctx, ch, len);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->ignorableWhitespace == NULL)
+ {
+ sax->ignorableWhitespace = xmljGetMethodID (env,
+ target,
+ "ignorableWhitespace",
+ "(Ljava/lang/String;)V");
+ if (sax->ignorableWhitespace == NULL)
+ {
+ return;
+ }
+ }
+
+ dup = xmlStrndup (ch, len);
+ j_ch = xmljNewString (env, dup);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->ignorableWhitespace,
+ j_ch);
+ xmlFree (dup);
+}
+
+void
+xmljSAXProcessingInstruction (void *vctx,
+ const xmlChar * targ,
+ const xmlChar * data)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_targ;
+ jstring j_data;
+
+ xmlSAX2ProcessingInstruction (vctx, targ, data);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->processingInstruction == NULL)
+ {
+ sax->processingInstruction =
+ xmljGetMethodID (env,
+ target,
+ "processingInstruction",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->processingInstruction == NULL)
+ {
+ return;
+ }
+ }
+
+ j_targ = xmljNewString (env, targ);
+ j_data = xmljNewString (env, data);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->processingInstruction,
+ j_targ,
+ j_data);
+}
+
+void
+xmljSAXComment (void *vctx,
+ const xmlChar * value)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_text;
+
+ xmlSAX2Comment (vctx, value);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->comment == NULL)
+ {
+ sax->comment =
+ xmljGetMethodID (env,
+ target,
+ "comment",
+ "(Ljava/lang/String;)V");
+ if (sax->comment == NULL)
+ {
+ return;
+ }
+ }
+
+ j_text = xmljNewString (env, value);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->comment,
+ j_text);
+}
+
+void
+xmljSAXCDataBlock (void *vctx,
+ const xmlChar * ch,
+ int len)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_ch;
+ xmlChar *dup;
+
+ xmlSAX2CDataBlock (vctx, ch, len);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->cdataBlock == NULL)
+ {
+ sax->cdataBlock =
+ xmljGetMethodID (env,
+ target,
+ "cdataBlock",
+ "(Ljava/lang/String;)V");
+ if (sax->cdataBlock == NULL)
+ {
+ return;
+ }
+ }
+
+ dup = xmlStrndup (ch, len);
+ j_ch = xmljNewString (env, dup);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->cdataBlock,
+ j_ch);
+ xmlFree (dup);
+}
+
+void
+xmljDispatchError (xmlParserCtxtPtr ctx,
+ xmlSAXLocatorPtr loc,
+ JNIEnv *env,
+ jobject target,
+ jmethodID method,
+ const char *msg,
+ va_list args)
+{
+ jint lineNumber;
+ jint columnNumber;
+ jstring publicId;
+ jstring systemId;
+ char buffer[2048] = "";
+
+ if (msg != NULL)
+ {
+ vsnprintf (buffer, sizeof buffer, msg, args);
+ }
+ lineNumber = loc->getLineNumber (ctx);
+ columnNumber = loc->getColumnNumber (ctx);
+ publicId = xmljNewString (env, loc->getPublicId (ctx));
+ systemId = xmljNewString (env, loc->getSystemId (ctx));
+ (*env)->CallVoidMethod (env,
+ target,
+ method,
+ (*env)->NewStringUTF (env, buffer),
+ lineNumber,
+ columnNumber,
+ publicId,
+ systemId);
+}
+
+void
+xmljSAXWarning (void *vctx,
+ const char *msg,
+ ...)
+{
+ va_list args;
+
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ xmlSAXLocatorPtr loc;
+ JNIEnv *env;
+ jobject target;
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ loc = (xmlSAXLocatorPtr) sax->loc;
+ env = sax->env;
+ target = sax->obj;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+ if (sax->warning == NULL)
+ {
+ sax->warning =
+ xmljGetMethodID (env,
+ target,
+ "warning",
+ "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
+ if (sax->warning == NULL)
+ {
+ return;
+ }
+ }
+
+ va_start (args, msg);
+ /* xmlParserWarning (vctx, msg, args); */
+ xmljDispatchError (ctx, loc, env, target, sax->warning, msg, args);
+ va_end (args);
+}
+
+void
+xmljSAXError (void *vctx,
+ const char *msg,
+ ...)
+{
+ va_list args;
+
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ xmlSAXLocatorPtr loc;
+ JNIEnv *env;
+ jobject target;
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ loc = (xmlSAXLocatorPtr) sax->loc;
+ env = sax->env;
+ target = sax->obj;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+ if (sax->error == NULL)
+ {
+ sax->error =
+ xmljGetMethodID (env,
+ target,
+ "error",
+ "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
+ if (sax->error == NULL)
+ {
+ return;
+ }
+ }
+
+ va_start (args, msg);
+ /* xmlParserError (vctx, msg, args); */
+ xmljDispatchError (ctx, loc, env, target, sax->error, msg, args);
+ va_end (args);
+}
+
+void
+xmljSAXFatalError (void *vctx,
+ const char *msg,
+ ...)
+{
+ va_list args;
+
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ xmlSAXLocatorPtr loc;
+ JNIEnv *env;
+ jobject target;
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ loc = (xmlSAXLocatorPtr) sax->loc;
+ env = sax->env;
+ target = sax->obj;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+ if (sax->fatalError == NULL)
+ {
+ sax->fatalError =
+ xmljGetMethodID (env,
+ target,
+ "fatalError",
+ "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
+ if (sax->fatalError == NULL)
+ {
+ return;
+ }
+ }
+
+ va_start (args, msg);
+ /* xmlParserError (vctx, msg, args); */
+ xmljDispatchError (ctx, loc, env, target, sax->fatalError, msg, args);
+ va_end (args);
+}
+
+void
+xmljCheckWellFormed (xmlParserCtxtPtr ctx)
+{
+ if (!ctx->wellFormed)
+ {
+ xmljSAXFatalError (ctx, "document is not well-formed");
+ }
+ if (ctx->validate && !ctx->valid)
+ {
+ xmljSAXFatalError (ctx, "document is not valid");
+ }
+}
+
+/*
+ * Convert a libxml2 attribute type to a string.
+ */
+jstring
+xmljAttributeTypeName (JNIEnv * env, int type)
+{
+ const char *text;
+
+ switch (type)
+ {
+ case XML_ATTRIBUTE_CDATA:
+ text = "CDATA";
+ break;
+ case XML_ATTRIBUTE_ID:
+ text = "ID";
+ break;
+ case XML_ATTRIBUTE_IDREF:
+ text = "IDREF";
+ break;
+ case XML_ATTRIBUTE_IDREFS:
+ text = "IDREFS";
+ break;
+ case XML_ATTRIBUTE_NMTOKEN:
+ text = "NMTOKEN";
+ break;
+ case XML_ATTRIBUTE_NMTOKENS:
+ text = "NMTOKENS";
+ break;
+ case XML_ATTRIBUTE_ENTITY:
+ text = "ID";
+ break;
+ case XML_ATTRIBUTE_ENTITIES:
+ text = "ID";
+ break;
+ default:
+ return NULL;
+ }
+
+ return (*env)->NewStringUTF (env, text);
+}
+
+/*
+ * Convert a libxml2 attribute default value type to a string.
+ */
+jstring
+xmljAttributeModeName (JNIEnv * env, int type)
+{
+ const char *text;
+
+ switch (type)
+ {
+ case XML_ATTRIBUTE_IMPLIED:
+ text = "#IMPLIED";
+ break;
+ case XML_ATTRIBUTE_REQUIRED:
+ text = "#REQUIRED";
+ break;
+ case XML_ATTRIBUTE_FIXED:
+ text = "#FIXED";
+ break;
+ default:
+ return NULL;
+ }
+
+ return (*env)->NewStringUTF (env, text);
+}
diff --git a/native/jni/xmlj/xmlj_sax.h b/native/jni/xmlj/xmlj_sax.h
new file mode 100644
index 000000000..f63606c97
--- /dev/null
+++ b/native/jni/xmlj/xmlj_sax.h
@@ -0,0 +1,160 @@
+/* xmlj_sax.h -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_SAX_H
+#define XMLJ_SAX_H
+
+#include "gnu_xml_libxmlj_sax_GnomeLocator.h"
+#include "gnu_xml_libxmlj_sax_GnomeXMLReader.h"
+
+#include <libxml/SAX.h>
+#include <libxml/parser.h>
+
+xmlSAXHandlerPtr
+xmljNewSAXHandler (jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean declarationHandler,
+ jboolean lexicalHandler);
+
+xmlParserInputPtr
+xmljExternalEntityLoader (const char *systemId, const char *publicId,
+ xmlParserCtxtPtr context);
+
+/* -- Function declarations for callback functions -- */
+
+void xmljSAXInternalSubset(void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+
+xmlParserInputPtr xmljSAXResolveEntity(void *ctx,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+
+xmlEntityPtr xmljSAXGetEntity(void *ctx,
+ const xmlChar *name);
+
+void xmljSAXEntityDecl(void *ctx,
+ const xmlChar *name,
+ int type,
+ const xmlChar *publicId,
+ const xmlChar *systemId,
+ xmlChar *content);
+
+void xmljSAXNotationDecl(void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+
+void xmljSAXAttributeDecl(void *ctx,
+ const xmlChar *elem,
+ const xmlChar *fullName,
+ int type,
+ int def,
+ const xmlChar *defaultValue,
+ xmlEnumerationPtr tree);
+
+void xmljSAXElementDecl(void *ctx,
+ const xmlChar *name,
+ int type,
+ xmlElementContentPtr content);
+
+void xmljSAXUnparsedEntityDecl(void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId,
+ const xmlChar *notationName);
+
+void xmljSAXSetDocumentLocator(void *ctx,
+ xmlSAXLocatorPtr loc);
+
+void xmljSAXStartDocument(void *ctx);
+
+void xmljSAXEndDocument(void *ctx);
+
+void xmljSAXStartElement(void *ctx,
+ const xmlChar *name,
+ const xmlChar **atts);
+
+void xmljSAXEndElement(void *ctx,
+ const xmlChar *name);
+
+void xmljSAXReference(void *ctx,
+ const xmlChar *name);
+
+void xmljSAXCharacters(void *ctx,
+ const xmlChar *ch,
+ int len);
+
+void xmljSAXIgnorableWhitespace(void *ctx,
+ const xmlChar *ch,
+ int len);
+
+void xmljSAXProcessingInstruction(void *ctx,
+ const xmlChar *target,
+ const xmlChar *data);
+
+void xmljSAXComment(void *ctx,
+ const xmlChar *value);
+
+void xmljSAXCDataBlock(void *ctx,
+ const xmlChar *ch,
+ int len);
+
+void xmljSAXWarning(void *ctx,
+ const char *msg,
+ ...);
+
+void xmljSAXError(void *ctx,
+ const char *msg,
+ ...);
+
+void xmljSAXFatalError(void *ctx,
+ const char *msg,
+ ...);
+
+void xmljCheckWellFormed(xmlParserCtxtPtr ctx);
+
+jstring xmljAttributeTypeName (JNIEnv *env,
+ int type);
+
+jstring xmljAttributeModeName (JNIEnv *env,
+ int type);
+
+#endif /* !defined XMLJ_SAX_H */
diff --git a/native/jni/xmlj/xmlj_transform.c b/native/jni/xmlj/xmlj_transform.c
new file mode 100644
index 000000000..e578ba8c7
--- /dev/null
+++ b/native/jni/xmlj/xmlj_transform.c
@@ -0,0 +1,868 @@
+/* xmlj_transform.c -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "gnu_xml_libxmlj_transform_GnomeTransformerFactory.h"
+#include "gnu_xml_libxmlj_transform_GnomeTransformer.h"
+
+#include "xmlj_dom.h"
+#include "xmlj_io.h"
+#include "xmlj_error.h"
+#include "xmlj_node.h"
+#include "xmlj_sax.h"
+#include "xmlj_util.h"
+
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlIO.h>
+#include <libxml/xinclude.h>
+#include <libxml/parser.h>
+#include <libxml/catalog.h>
+#include <libxslt/keys.h>
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/functions.h>
+#include <libxslt/extensions.h>
+#include <libxslt/documents.h>
+
+/* Local function prototypes */
+
+void
+xmljDocumentFunction (xmlXPathParserContextPtr ctxt, int nargs);
+
+xsltStylesheetPtr
+xmljGetStylesheetID (JNIEnv * env, jobject transformer);
+
+jobject
+xmljGetTransformerProperties (JNIEnv *env, jobject transformer);
+
+const xmlChar *
+xmljBooleanToString (int value);
+
+void
+xmljSetOutputProperties (JNIEnv *env, jobject transformer,
+ xsltStylesheetPtr stylesheet);
+
+jobjectArray
+xmljGetParameterArray (JNIEnv *env, jobject transformer);
+
+const char **
+xmljGetParameters (JNIEnv *env, jobjectArray pa);
+
+void
+xmljFreeParameters (JNIEnv *env, jobjectArray pa, const char **parameters);
+
+xmlDocPtr
+xmljTransform (JNIEnv *env, jobject transformer, xmlDocPtr source);
+
+void
+xmljTransformToSAX (JNIEnv *env, jobject transformer, xmlDocPtr source,
+ jobject callback);
+
+xmlDocPtr
+xmljDocLoader (const xmlChar *uri, xmlDictPtr dict, int options,
+ void *ctxt, xsltLoadType type);
+
+/* HACK: store stylesheet URL as context for resolving URIs in xmljDocLoader */
+static jstring stylesheetURL = NULL;
+
+/*
+ * --------------------------------------------------------------------------
+ *
+ * Native implementation for class
+ * gnu.xml.libxmlj.transform.GnomeTransformer follows.
+ */
+
+static void
+xmljSetProperty (JNIEnv * env, jobject outputProperties,
+ jmethodID setPropertyMethodID, const char *name,
+ const xmlChar * value)
+{
+ if (NULL != value)
+ {
+ jstring nameString = (*env)->NewStringUTF (env, name);
+ jstring valueString = (*env)->NewStringUTF (env, (const char *) value);
+
+ jobject prevValue = (*env)->CallObjectMethod (env, outputProperties,
+ setPropertyMethodID,
+ nameString, valueString);
+ if (NULL != prevValue)
+ {
+ (*env)->DeleteLocalRef (env, prevValue);
+ }
+
+ (*env)->DeleteLocalRef (env, nameString);
+ (*env)->DeleteLocalRef (env, valueString);
+ }
+}
+
+typedef struct CdataSectionScannerInfo_
+{
+ JNIEnv *env;
+ jobject stringBuffer;
+ jmethodID appendMethodID;
+ int isFirst;
+} CdataSectionScannerInfo;
+
+static void
+cdataSectionScanner (void *payload, void *data, xmlChar * name)
+{
+ CdataSectionScannerInfo *info = (CdataSectionScannerInfo *) data;
+ JNIEnv *env = info->env;
+ jstring nameString = (*env)->NewStringUTF (env, (const char *) name);
+ jstring blankString = (*env)->NewStringUTF (env, " ");
+ jobject stringBuffer;
+ if (!info->isFirst)
+ {
+ stringBuffer
+ = (*env)->CallObjectMethod (env,
+ info->stringBuffer,
+ info->appendMethodID, blankString);
+ (*env)->DeleteLocalRef (env, stringBuffer);
+ }
+ info->isFirst = 0;
+ stringBuffer
+ = (*env)->CallObjectMethod (env,
+ info->stringBuffer,
+ info->appendMethodID, nameString);
+ (*env)->DeleteLocalRef (env, stringBuffer);
+ (*env)->DeleteLocalRef (env, blankString);
+ (*env)->DeleteLocalRef (env, nameString);
+}
+
+void
+xmljDocumentFunction (xmlXPathParserContextPtr ctxt, int nargs)
+{
+ xmlXPathObjectPtr obj, obj2 = NULL;
+
+ if ((nargs < 1) || (nargs > 2))
+ {
+ xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
+ "document() : invalid number of args %d\n", nargs);
+ ctxt->error = XPATH_INVALID_ARITY;
+ return;
+ }
+ if (ctxt->value == NULL)
+ {
+ xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
+ "document() : invalid arg value\n");
+ ctxt->error = XPATH_INVALID_TYPE;
+ return;
+ }
+
+ if (nargs == 2)
+ {
+ if (ctxt->value->type != XPATH_NODESET)
+ {
+ xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
+ "document() : invalid arg expecting a nodeset\n");
+ ctxt->error = XPATH_INVALID_TYPE;
+ return;
+ }
+
+ obj2 = valuePop (ctxt);
+ }
+
+ if (ctxt->value->type == XPATH_NODESET)
+ {
+ int i;
+ xmlXPathObjectPtr newobj, ret;
+
+ obj = valuePop (ctxt);
+ ret = xmlXPathNewNodeSet (NULL);
+
+ if (obj->nodesetval)
+ {
+ for (i = 0; i < obj->nodesetval->nodeNr; i++)
+ {
+ valuePush (ctxt,
+ xmlXPathNewNodeSet (obj->nodesetval->nodeTab[i]));
+ xmlXPathStringFunction (ctxt, 1);
+ if (nargs == 2)
+ {
+ valuePush (ctxt, xmlXPathObjectCopy (obj2));
+ }
+ else
+ {
+ valuePush (ctxt,
+ xmlXPathNewNodeSet (obj->nodesetval->
+ nodeTab[i]));
+ }
+ xsltDocumentFunction (ctxt, 2);
+ newobj = valuePop (ctxt);
+ ret->nodesetval = xmlXPathNodeSetMerge (ret->nodesetval,
+ newobj->nodesetval);
+ xmlXPathFreeObject (newobj);
+ }
+ }
+
+ xmlXPathFreeObject (obj);
+ if (obj2 != NULL)
+ {
+ xmlXPathFreeObject (obj2);
+ }
+ valuePush (ctxt, ret);
+ return;
+ }
+ /*
+ * Make sure it's converted to a string
+ */
+ xmlXPathStringFunction (ctxt, 1);
+ if (ctxt->value->type != XPATH_STRING)
+ {
+ xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
+ "document() : invalid arg expecting a string\n");
+ ctxt->error = XPATH_INVALID_TYPE;
+ if (obj2 != NULL)
+ xmlXPathFreeObject (obj2);
+ return;
+ }
+ obj = valuePop (ctxt);
+ if (obj->stringval == NULL)
+ {
+ valuePush (ctxt, xmlXPathNewNodeSet (NULL));
+ }
+ else
+ {
+
+ xsltTransformContextPtr tctxt;
+
+ tctxt = xsltXPathGetTransformContext (ctxt);
+
+ {
+ SAXParseContext *saxContext =
+ (SAXParseContext *) tctxt->style->_private;
+
+ xmlDocPtr tree = xmljResolveURIAndOpen (saxContext,
+ (const char*)obj->stringval,
+ NULL);
+
+ xsltNewDocument (tctxt, tree); /* FIXME - free at a later point */
+
+ valuePush (ctxt, xmlXPathNewNodeSet ((xmlNodePtr) tree));
+ }
+ }
+ xmlXPathFreeObject (obj);
+ if (obj2 != NULL) {
+ xmlXPathFreeObject (obj2);
+ }
+}
+
+/*
+ * Returns the stylesheet pointer for the given GnomeTransformer.
+ */
+xsltStylesheetPtr
+xmljGetStylesheetID (JNIEnv * env, jobject transformer)
+{
+ jclass cls;
+ jfieldID field;
+ jobject id;
+ xsltStylesheetPtr stylesheet;
+
+ if (transformer == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "Transformer is null");
+ return NULL;
+ }
+ cls = (*env)->GetObjectClass (env, transformer);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ field = (*env)->GetFieldID (env, cls, "stylesheet", "Ljava/lang/Object;");
+ if (field == NULL)
+ {
+ return NULL;
+ }
+ id = (*env)->GetObjectField (env, transformer, field);
+ stylesheet = (xsltStylesheetPtr) xmljAsPointer (env, id);
+ if (stylesheet == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "Stylesheet is null");
+ return NULL;
+ }
+ return stylesheet;
+}
+
+jobject
+xmljGetTransformerProperties (JNIEnv *env, jobject transformer)
+{
+ jclass cls;
+ jfieldID field;
+
+ cls = (*env)->GetObjectClass (env, transformer);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ field = (*env)->GetFieldID (env, cls, "outputProperties",
+ "Ljava/util/Properties;");
+ if (field == NULL)
+ {
+ return NULL;
+ }
+ return (*env)->GetObjectField (env, transformer, field);
+}
+
+const xmlChar *
+xmljBooleanToString (int value)
+{
+ return value ? BAD_CAST "yes" : BAD_CAST "no";
+}
+
+/*
+ * Sets the output properties for the given transformer,
+ * based on its stylesheet.
+ */
+void
+xmljSetOutputProperties (JNIEnv *env, jobject transformer,
+ xsltStylesheetPtr stylesheet)
+{
+ jobject outputProperties;
+ jclass propertiesClass;
+ jmethodID setPropertyMethod;
+
+ outputProperties = xmljGetTransformerProperties (env, transformer);
+ if (outputProperties == NULL)
+ {
+ return;
+ }
+ propertiesClass = (*env)->FindClass (env, "java/util/Properties");
+ if (propertiesClass == NULL)
+ {
+ return;
+ }
+ setPropertyMethod =
+ (*env)->GetMethodID (env, propertiesClass, "setProperty",
+ "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
+ if (setPropertyMethod == NULL)
+ {
+ return;
+ }
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "encoding", stylesheet->encoding);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "media-type", stylesheet->mediaType);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "doctype-public", stylesheet->doctypePublic);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "doctype-system", stylesheet->doctypeSystem);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "indent", xmljBooleanToString (stylesheet->indent));
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "method", stylesheet->method);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "standalone", xmljBooleanToString (stylesheet->standalone));
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "version", stylesheet->version);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "omit-xml-declaration",
+ xmljBooleanToString (stylesheet->omitXmlDeclaration));
+
+ {
+ CdataSectionScannerInfo info;
+ jclass stringBufferClass
+ =
+ (*env)->FindClass (env,
+ "java/lang/StringBuffer");
+ jmethodID stringBufferConstructorID =
+ (*env)->GetMethodID (env, stringBufferClass,
+ "<init>", "()V");
+ jmethodID toStringMethodID =
+ (*env)->GetMethodID (env, stringBufferClass,
+ "toString",
+ "()Ljava/lang/String;");
+ info.env = env;
+ info.isFirst = 1;
+ info.stringBuffer
+ = (*env)->AllocObject (env, stringBufferClass);
+ (*env)->CallVoidMethod (env, info.stringBuffer,
+ stringBufferConstructorID);
+ info.appendMethodID =
+ (*env)->GetMethodID (env, stringBufferClass,
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+
+ xmlHashScan (stylesheet->cdataSection,
+ cdataSectionScanner, &info);
+
+ {
+ jstring result = (jstring)
+ (*env)->CallObjectMethod (env,
+ info.stringBuffer,
+ toStringMethodID);
+
+ jstring nameString =
+ (*env)->NewStringUTF (env,
+ "cdata-section-elements");
+
+ jobject prevValue
+ =
+ (*env)->CallObjectMethod (env,
+ outputProperties,
+ setPropertyMethod,
+ nameString, result);
+ if (NULL != prevValue)
+ {
+ (*env)->DeleteLocalRef (env, prevValue);
+ }
+ (*env)->DeleteLocalRef (env, nameString);
+ }
+
+ (*env)->DeleteLocalRef (env, info.stringBuffer);
+ }
+}
+
+/*
+ * Returns the parameter array for the given GnomeTransformer.
+ */
+jobjectArray
+xmljGetParameterArray (JNIEnv *env, jobject transformer)
+{
+ jclass cls;
+ jmethodID method;
+
+ cls = (*env)->GetObjectClass (env, transformer);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetMethodID (env, cls, "getParameterArray",
+ "()[Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ return (jobjectArray) (*env)->CallObjectMethod (env, transformer, method);
+}
+
+/* Convert parameter array to xmlChar ** */
+const char **
+xmljGetParameters (JNIEnv *env, jobjectArray pa)
+{
+ int i, len;
+ const char **parameters;
+
+ len = (*env)->GetArrayLength (env, pa);
+ parameters = (const char **) malloc ((len + 2) * sizeof (const char *));
+ if (parameters == NULL)
+ {
+ return NULL;
+ }
+
+ for (i = 0; i < len; i++)
+ {
+ jstring string = (jstring) (*env)->GetObjectArrayElement (env, pa, i);
+
+ if (string != NULL)
+ {
+ parameters[i] = (*env)->GetStringUTFChars (env, string, NULL);
+ }
+ else
+ {
+ parameters[i] = NULL;
+ }
+ }
+
+ parameters[len] = 0;
+ parameters[len + 1] = 0;
+ return parameters;
+}
+
+/* Release parameter strings */
+void
+xmljFreeParameters (JNIEnv *env, jobjectArray pa, const char **parameters)
+{
+ int i, len;
+
+ len = (*env)->GetArrayLength (env, pa);
+ for (i = 0; i < len; i++)
+ {
+ jstring string = (jstring) (*env)->GetObjectArrayElement (env, pa, i);
+ if (string != NULL)
+ {
+ (*env)->ReleaseStringUTFChars (env, string, parameters[i]);
+ }
+ }
+
+ free (parameters);
+}
+
+xmlDocPtr
+xmljTransform (JNIEnv *env, jobject transformer, xmlDocPtr source)
+{
+ xsltStylesheetPtr stylesheet;
+ xmlDocPtr result;
+ jobjectArray pa;
+ const char **parameters;
+
+ stylesheet = xmljGetStylesheetID (env, transformer);
+ pa = xmljGetParameterArray (env, transformer);
+ parameters = xmljGetParameters (env, pa);
+ if (parameters == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "Couldn't allocate memory for parameters");
+ return NULL;
+ }
+ result = xsltApplyStylesheet (stylesheet, source, parameters);
+ xmljFreeParameters (env, pa, parameters);
+ if (result == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "XSLT transformation failed");
+ }
+ return result;
+}
+
+void
+xmljTransformToSAX (JNIEnv *env, jobject transformer, xmlDocPtr source,
+ jobject callback)
+{
+ xsltStylesheetPtr stylesheet;
+ int ret;
+ jobjectArray pa;
+ const char **parameters;
+ xmlSAXHandlerPtr sax;
+
+ stylesheet = xmljGetStylesheetID (env, transformer);
+ pa = xmljGetParameterArray (env, transformer);
+ parameters = xmljGetParameters (env, pa);
+ if (parameters == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "Couldn't allocate memory for parameters");
+ return;
+ }
+ sax = NULL; /* TODO link up sax and callback */
+ ret = xsltRunStylesheet (stylesheet, source, parameters, NULL, sax, NULL);
+ xmljFreeParameters (env, pa, parameters);
+ if (ret == -1)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "XSLT transformation failed");
+ }
+}
+
+xmlDocPtr
+xmljDocLoader (const xmlChar *uri, xmlDictPtr dict, int options,
+ void *ctxt, xsltLoadType type)
+{
+ JNIEnv *env;
+ jclass xmljClass;
+ jclass inputStreamClass;
+ jmethodID getInputStream;
+ jmethodID getDetectBuffer;
+ jstring systemId;
+ jobject inputStream;
+ jbyteArray detectBuffer;
+
+ /*fprintf(stderr,"xmljDocLoader:1\n");*/
+ fflush(stdout);
+ env = xmljGetJNIEnv ();
+ if (!env)
+ {
+ return NULL;
+ }
+ xmljClass = (*env)->FindClass (env, "gnu/xml/libxmlj/util/XMLJ");
+ if (!xmljClass)
+ {
+ return NULL;
+ }
+ getInputStream =
+ (*env)->GetStaticMethodID (env, xmljClass, "xmljGetInputStream",
+ "(Ljava/lang/String;Ljava/lang/String;)Lgnu/xml/libxmlj/util/NamedInputStream;");
+ if (!getInputStream)
+ {
+ return NULL;
+ }
+ systemId = xmljNewString (env, uri);
+ inputStream = (*env)->CallStaticObjectMethod (env, xmljClass, getInputStream,
+ stylesheetURL, systemId);
+ if (!inputStream)
+ {
+ return NULL;
+ }
+ inputStreamClass = (*env)->GetObjectClass (env, inputStream);
+ if (!inputStreamClass)
+ {
+ return NULL;
+ }
+ getDetectBuffer = (*env)->GetMethodID (env, inputStreamClass,
+ "getDetectBuffer", "()[B");
+ if (!getDetectBuffer)
+ {
+ return NULL;
+ }
+ detectBuffer = (*env)->CallObjectMethod (env, inputStream, getDetectBuffer);
+ if (!detectBuffer)
+ {
+ return NULL;
+ }
+ return xmljParseDocument (env, NULL, inputStream, detectBuffer,
+ NULL, systemId, stylesheetURL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2);
+}
+
+/* GnomeTransformer.newStylesheet */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_newStylesheet (JNIEnv *env,
+ jobject self)
+{
+ xsltStylesheetPtr stylesheet;
+ jobject ret;
+
+ stylesheetURL = NULL;
+ xsltSetLoaderFunc (xmljDocLoader);
+ stylesheet = xsltNewStylesheet ();
+ xmljSetOutputProperties (env, self, stylesheet);
+ ret = xmljAsField (env, stylesheet);
+ if (ret == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Can't create Java object for stylesheet");
+ }
+ return ret;
+}
+
+/* GnomeTransformer.newStylesheetFromStream */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_newStylesheetFromStream
+(JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
+ jstring publicId, jstring systemId, jstring base,
+ jboolean entityResolver, jboolean errorHandler)
+{
+ xmlDocPtr doc;
+ xsltStylesheetPtr stylesheet;
+ jobject ret;
+
+ doc = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
+ base, 0, 0, 0, 0, 0,
+ entityResolver, errorHandler, 0, 0, 2);
+ if (doc == NULL)
+ {
+ return NULL;
+ }
+ stylesheetURL = systemId;
+ xsltSetLoaderFunc (xmljDocLoader);
+ stylesheet = xsltParseStylesheetDoc (doc);
+ if (stylesheet == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Error parsing XSLT stylesheet");
+ return NULL;
+ }
+ xmljSetOutputProperties (env, self, stylesheet);
+ ret = xmljAsField (env, stylesheet);
+ if (ret == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Can't create Java object for stylesheet");
+ }
+ return ret;
+}
+
+/* GnomeTransformer.newStylesheetFromDoc */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_newStylesheetFromDoc
+(JNIEnv *env, jobject self, jobject in)
+{
+ xmlDocPtr doc;
+ xsltStylesheetPtr stylesheet;
+ jobject ret;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, in);
+ if (doc == NULL)
+ {
+ return NULL;
+ }
+ stylesheetURL = xmljNewString (env, doc->URL);
+ xsltSetLoaderFunc (xmljDocLoader);
+ stylesheet = xsltParseStylesheetDoc (doc);
+ if (stylesheet == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Error parsing XSLT stylesheet");
+ }
+ xmljSetOutputProperties (env, self, stylesheet);
+ ret = xmljAsField (env, stylesheet);
+ if (ret == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Can't create Java object for stylesheet");
+ }
+ return ret;
+}
+
+/* GnomeTransformer.transformStreamToStream */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformStreamToStream
+(JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
+ jstring publicId, jstring systemId, jstring base,
+ jboolean entityResolver, jboolean errorHandler, jobject out)
+{
+ xmlDocPtr source;
+ xmlDocPtr result;
+
+ source = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
+ base, 0, 0, 0, 0, 0,
+ entityResolver, errorHandler, 0, 0, 2);
+ result = xmljTransform (env, self, source);
+ xmljSaveFileToJavaOutputStream (env, out, result,
+ (const char*) result->encoding);
+ xmlFreeDoc (result);
+}
+
+/* GnomeTransformer.transformStreamToDoc */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformStreamToDoc
+(JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
+ jstring publicId, jstring systemId, jstring base,
+ jboolean entityResolver, jboolean errorHandler)
+{
+ xmlDocPtr source;
+ xmlDocPtr result;
+
+ source = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
+ base, 0, 0, 0, 0, 0,
+ entityResolver, errorHandler, 0, 0, 2);
+ result = xmljTransform (env, self, source);
+ return xmljGetNodeInstance (env, (xmlNodePtr) result);
+}
+
+/* GnomeTransformer.transformStreamToSAX */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformStreamToSAX
+(JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
+ jstring publicId, jstring systemId, jstring base,
+ jboolean entityResolver, jboolean errorHandler, jobject callback)
+{
+ xmlDocPtr source;
+
+ source = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
+ base, 0, 0, 0, 0, 0,
+ entityResolver, errorHandler, 0, 0, 2);
+ xmljTransformToSAX (env, self, source, callback);
+}
+
+/* GnomeTransformer.transformDocToStream */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformDocToStream
+(JNIEnv *env, jobject self, jobject doc, jobject out)
+{
+ xmlDocPtr source;
+ xmlDocPtr result;
+
+ source = (xmlDocPtr) xmljGetNodeID (env, doc);
+ result = xmljTransform (env, self, source);
+ xmljSaveFileToJavaOutputStream (env, out, result,
+ (const char*) result->encoding);
+ xmlFreeDoc (result);
+}
+
+/* GnomeTransformer.transformDocToDoc */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformDocToDoc
+(JNIEnv *env, jobject self, jobject doc)
+{
+ xmlDocPtr source;
+ xmlDocPtr result;
+
+ source = (xmlDocPtr) xmljGetNodeID (env, doc);
+ result = xmljTransform (env, self, source);
+ return xmljGetNodeInstance (env, (xmlNodePtr) result);
+}
+
+/* GnomeTransformer.transformDocToSAX */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformDocToSAX
+(JNIEnv *env, jobject self, jobject doc, jobject callback)
+{
+ xmlDocPtr source;
+
+ source = (xmlDocPtr) xmljGetNodeID (env, doc);
+ xmljTransformToSAX (env, self, source, callback);
+}
+
+/* GnomeTransformer.free */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_free (JNIEnv *env,
+ jobject self)
+{
+ xsltStylesheetPtr stylesheet;
+
+ stylesheet = xmljGetStylesheetID (env, self);
+ xsltFreeStylesheet (stylesheet);
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * Native implementation for class
+ * gnu.xml.libxmlj.transform.GnomeTransformerFactory follows.
+ */
+
+/* GnomeTransformerFactory.freeLibxsltGlobal */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformerFactory_freeLibxsltGlobal (
+ JNIEnv *env, jclass clazz)
+{
+ xsltCleanupGlobals ();
+ xmlCleanupParser ();
+}
+
diff --git a/native/jni/xmlj/xmlj_util.c b/native/jni/xmlj/xmlj_util.c
new file mode 100644
index 000000000..2c9f05d08
--- /dev/null
+++ b/native/jni/xmlj/xmlj_util.c
@@ -0,0 +1,301 @@
+/* xmlj_util.c
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_util.h"
+#include "xmlj_error.h"
+#include <libxml/tree.h>
+#include <unistd.h>
+
+/* xmlChar->jstring cache */
+#ifdef XMLJ_STRING_CACHE
+#define XMLJ_STRING_CACHE_SIZE 1024
+xmlHashTablePtr xmljStringCache = NULL;
+
+void
+xmljHashDeallocate (void *data, xmlChar *name);
+
+void
+xmljHashDeallocate (void *data, xmlChar *name)
+{
+ /* NOOP */
+}
+#endif /* XMLJ_STRING_CACHE */
+
+jstring
+xmljNewString (JNIEnv * env, const xmlChar * text)
+{
+ jstring ret;
+
+ if (text == NULL || (*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+#ifdef XMLJ_STRING_CACHE
+ if (xmljStringCache == NULL) /* Init cache */
+ {
+ xmljStringCache = xmlHashCreate (XMLJ_STRING_CACHE_SIZE);
+ }
+ ret = (jstring) xmlHashLookup (xmljStringCache, text);
+ if (ret == NULL)
+ {
+ ret = (*env)->NewStringUTF (env, (char *) text);
+ if (ret == NULL) /* Why? */
+ {
+ fprintf(stderr, "xmljNewString: ERROR: NewStringUTF returned null for \"%s\"\n", text);
+ fflush (stderr);
+ }
+ else
+ {
+ xmlHashAddEntry (xmljStringCache, text, ret);
+ }
+ }
+#else
+ ret = (*env)->NewStringUTF (env, (char *) text);
+ if (ret == NULL) /* Why? */
+ {
+ printf("xmljNewString: ERROR: NewStringUTF returned null for \"%s\"\n", text);
+ }
+#endif /* XMLJ_STRING_CACHE */
+ return ret;
+}
+
+void
+xmljClearStringCache ()
+{
+#ifdef XMLJ_STRING_CACHE
+ if (xmljStringCache != NULL)
+ {
+ xmlHashFree (xmljStringCache, &xmljHashDeallocate);
+ }
+#endif /* XMLJ_STRING_CACHE */
+}
+
+const xmlChar *
+xmljGetStringChars (JNIEnv * env, jstring text)
+{
+ const char *s_text;
+ xmlChar *x_text;
+
+ if (text == NULL)
+ {
+ return NULL;
+ }
+
+ s_text = (*env)->GetStringUTFChars (env, text, 0);
+ x_text = (s_text == NULL) ? NULL : xmlCharStrdup (s_text);
+ if (s_text != NULL && x_text == NULL)
+ {
+ /* TODO raise exception */
+ }
+ (*env)->ReleaseStringUTFChars (env, text, s_text);
+ return x_text;
+}
+
+const xmlChar *
+xmljGetPrefix (const xmlChar * qName)
+{
+ const xmlChar *localName;
+ const xmlChar *ret;
+ xmlChar **prefix;
+
+ prefix = (xmlChar **) malloc (sizeof (xmlChar *));
+ localName = xmlSplitQName2 (qName, prefix);
+ if (localName == NULL)
+ {
+ return NULL;
+ }
+ ret = *prefix;
+ free (prefix);
+ return ret;
+}
+
+const xmlChar *
+xmljGetLocalName (const xmlChar * qName)
+{
+ const xmlChar *localName;
+ xmlChar **prefix;
+
+ prefix = (xmlChar **) malloc (sizeof (xmlChar *));
+ localName = xmlSplitQName2 (qName, prefix);
+ if (localName == NULL)
+ {
+ return qName;
+ }
+ free (prefix);
+ return localName;
+}
+
+jmethodID xmljGetMethodID (JNIEnv *env,
+ jobject target,
+ const char *name,
+ const char *signature)
+{
+ jclass cls;
+ jmethodID ret;
+
+ cls = (*env)->GetObjectClass (env, target);
+ if (cls == NULL)
+ {
+ xmljThrowException (env,
+ "java/lang/ClassNotFoundException",
+ NULL);
+ return NULL;
+ }
+ ret = (*env)->GetMethodID (env,
+ cls,
+ name,
+ signature);
+ if (ret == NULL)
+ {
+ jclass clscls;
+ jmethodID nm;
+ jstring clsname;
+ const char *c_clsName;
+ char cat[512] = "[method signature too long]";
+
+ clscls = (*env)->FindClass (env, "java/lang/Class");
+ if (clscls == NULL)
+ {
+ return NULL;
+ }
+ nm = (*env)->GetMethodID (env, clscls, "getName",
+ "()Ljava/lang/String;");
+ if (nm == NULL)
+ {
+ return NULL;
+ }
+ clsname = (jstring) (*env)->CallObjectMethod (env,
+ (jobject)cls,
+ nm);
+ if (clsname == NULL)
+ {
+ return NULL;
+ }
+ c_clsName = (*env)->GetStringUTFChars (env, clsname, 0);
+ sprintf (cat, "%s.%s %s", c_clsName, name, signature);
+ xmljThrowException (env,
+ "java/lang/NoSuchMethodException",
+ cat);
+ (*env)->ReleaseStringUTFChars (env, clsname, c_clsName);
+ }
+ return ret;
+}
+
+void *
+xmljAsPointer (JNIEnv *env, jobject ptr)
+{
+ jclass cls;
+ jfieldID field;
+
+#if defined XMLJ_64BIT_POINTER
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ field = (*env)->GetFieldID (env, cls, "data", "J");
+ return (void *) (*env)->GetLongField (env, ptr, field);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ field = (*env)->GetFieldID (env, cls, "data", "I");
+ return (void *) (*env)->GetIntField (env, ptr, field);
+#endif
+}
+
+jobject
+xmljAsField (JNIEnv *env, void * ptr)
+{
+ jclass cls;
+ jmethodID method;
+
+#if defined XMLJ_64BIT_POINTER
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(J)V");
+ return (*env)->NewObject (env, cls, method, (jlong) ptr);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
+ return (*env)->NewObject (env, cls, method, (jint) ptr);
+#endif
+}
+
+JNIEnv *
+xmljGetJNIEnv ()
+{
+ JavaVM **jvms;
+ jsize *jvm_count;
+ JavaVM *jvm;
+ JNIEnv **envs;
+ JNIEnv *env;
+
+ jvms = (JavaVM **) malloc (sizeof (JavaVM *));
+ if (!jvms)
+ {
+ return NULL;
+ }
+ jvm_count = (jsize *) malloc (sizeof (jsize));
+ if (!jvm_count)
+ {
+ free (jvms);
+ return NULL;
+ }
+ if (JNI_GetCreatedJavaVMs (jvms, 1, jvm_count))
+ {
+ free (jvms);
+ free (jvm_count);
+ return NULL;
+ }
+ jvm = *jvms;
+ envs = (JNIEnv **) malloc (sizeof (JNIEnv *));
+ if (!envs)
+ {
+ free (jvms);
+ free (jvm_count);
+ return NULL;
+ }
+ (*jvm)->AttachCurrentThread (jvm, (void **) envs, NULL);
+ (*jvm)->GetEnv (jvm, (void **) envs, JNI_VERSION_1_2);
+ if (envs)
+ {
+ env = *envs;
+ free (envs);
+ }
+ else
+ {
+ env = NULL;
+ }
+ free (jvms);
+ free (jvm_count);
+ return env;
+}
+
diff --git a/native/jni/xmlj/xmlj_util.h b/native/jni/xmlj/xmlj_util.h
new file mode 100644
index 000000000..ad3dd1f99
--- /dev/null
+++ b/native/jni/xmlj/xmlj_util.h
@@ -0,0 +1,69 @@
+/* xmlj_util.h -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_UTIL_H
+#define XMLJ_UTIL_H
+
+#if defined __64BIT__ || defined __LP64 || defined _LP64 || defined __LP64__ || defined _ADDR64
+# define XMLJ_64BIT_POINTER 1
+#endif
+
+#include <jni.h>
+#include <libxml/xmlstring.h>
+
+jstring xmljNewString (JNIEnv *, const xmlChar *);
+
+void xmljClearStringCache (void);
+
+const xmlChar *xmljGetStringChars (JNIEnv *, jstring);
+
+const xmlChar *xmljGetPrefix (const xmlChar * qName);
+
+const xmlChar *xmljGetLocalName (const xmlChar * qName);
+
+jmethodID xmljGetMethodID (JNIEnv *env,
+ jobject target,
+ const char *name,
+ const char *signature);
+
+void * xmljAsPointer (JNIEnv *env, jobject field);
+
+jobject xmljAsField (JNIEnv *env, void * ptr);
+
+JNIEnv * xmljGetJNIEnv (void);
+
+#endif /* !defined XMLJ_UTIL_H */
diff --git a/native/jni/xmlj/xmlj_xpath.c b/native/jni/xmlj/xmlj_xpath.c
new file mode 100644
index 000000000..0a8aabf1f
--- /dev/null
+++ b/native/jni/xmlj/xmlj_xpath.c
@@ -0,0 +1,619 @@
+/* xmlj_xpath.c -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "gnu_xml_libxmlj_dom_GnomeDocument.h"
+#include "gnu_xml_libxmlj_dom_GnomeElement.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathExpression.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathNodeList.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathNSResolver.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathResult.h"
+#include "xmlj_node.h"
+#include "xmlj_util.h"
+#include <libxml/xpath.h>
+
+/* Local function prototypes */
+
+xmlXPathContextPtr
+xmljCreateXPathContextPtr (JNIEnv *env, xmlNodePtr node);
+
+jobject
+xmljGetXPathResult (JNIEnv *env, xmlXPathObjectPtr obj);
+
+jobject
+xmljGetXPathNodeList (JNIEnv *env, xmlXPathObjectPtr obj);
+
+xmlXPathObjectPtr
+xmljGetXPathObjectID (JNIEnv *env, jobject obj);
+
+/**
+ * Creates an XPath context for the given node.
+ */
+xmlXPathContextPtr
+xmljCreateXPathContextPtr (JNIEnv *env, xmlNodePtr node)
+{
+ xmlXPathContextPtr ctx;
+
+ ctx = xmlXPathNewContext (node->doc);
+ ctx->node = node;
+ return ctx;
+}
+
+/**
+ * Converts an xmlXPathObjectPtr to a Java XPathResult.
+ */
+jobject
+xmljGetXPathResult (JNIEnv *env, xmlXPathObjectPtr obj)
+{
+ jclass cls;
+ jmethodID method;
+ jobject ret;
+ jobject val;
+
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeXPathResult");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(Ljava/lang/Object;)V");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ val = xmljAsField (env, obj);
+ ret = (*env)->NewObject (env, cls, method, val);
+
+ return ret;
+}
+
+/**
+ * Converts an xmlXPathObjectPtr to a Java XPathNodeList.
+ */
+jobject
+xmljGetXPathNodeList (JNIEnv *env, xmlXPathObjectPtr obj)
+{
+ jclass cls;
+ jmethodID method;
+ jobject ret;
+ jobject val;
+
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeXPathNodeList");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(Ljava/lang/Object;)V");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ val = xmljAsField (env, obj);
+ ret = (*env)->NewObject (env, cls, method, val);
+
+ return ret;
+}
+
+xmlXPathObjectPtr
+xmljGetXPathObjectID (JNIEnv *env, jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+ jobject val;
+ xmlXPathObjectPtr ret;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ field = (*env)->GetFieldID (env, cls, "obj", "Ljava/lang/Object;");
+ if (field == NULL)
+ {
+ return NULL;
+ }
+ val = (*env)->GetObjectField (env, obj, field);
+ ret = (xmlXPathObjectPtr) xmljAsPointer (env, val);
+
+ return ret;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_evaluate (JNIEnv *env,
+ jobject self,
+ jstring expression,
+ jobject contextNode,
+ jobject resolver,
+ jshort type,
+ jobject result)
+{
+ const xmlChar *str;
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ str = xmljGetStringChars (env, expression);
+ node = xmljGetNodeID (env, contextNode);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ ctx = xmljCreateXPathContextPtr (env, node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathEval (str, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ xmlFree ((xmlChar *) str);
+ return xmljGetXPathResult (env, eval);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathExpression_init (JNIEnv *env,
+ jobject self,
+ jstring expression)
+{
+ const xmlChar *str;
+ xmlXPathCompExprPtr ptr;
+
+ str = xmljGetStringChars (env, expression);
+ ptr = xmlXPathCompile (str);
+ xmlFree ((xmlChar *) str);
+ return xmljAsField (env, ptr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathExpression_free (JNIEnv *env,
+ jobject self,
+ jobject ptr)
+{
+ xmlXPathCompExprPtr expr;
+
+ expr = (xmlXPathCompExprPtr) xmljAsPointer (env, ptr);
+ xmlXPathFreeCompExpr (expr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathExpression_doEvaluate (JNIEnv *env,
+ jobject self,
+ jobject ptr,
+ jobject contextNode,
+ jshort type,
+ jobject result)
+{
+ xmlXPathCompExprPtr expr;
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ expr = (xmlXPathCompExprPtr) xmljAsPointer (env, ptr);
+ node = xmljGetNodeID (env, contextNode);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ ctx = xmljCreateXPathContextPtr (env, node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathCompiledEval (expr, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ return xmljGetXPathResult (env, eval);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_free (JNIEnv *env,
+ jobject self,
+ jobject obj)
+{
+ xmlXPathFreeObject ((xmlXPathObjectPtr) xmljAsPointer (env, obj));
+}
+
+JNIEXPORT jshort JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getResultType (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ switch (obj->type)
+ {
+ case XPATH_UNDEFINED:
+ return 0; /* ANY_TYPE */
+ case XPATH_NUMBER:
+ return 1; /* NUMBER_TYPE */
+ case XPATH_STRING:
+ return 2; /* STRING_TYPE */
+ case XPATH_BOOLEAN:
+ return 3; /* BOOLEAN_TYPE */
+ case XPATH_NODESET:
+ return 6; /* UNORDERED_NODE_SNAPSHOT_TYPE */
+ case XPATH_POINT:
+ case XPATH_RANGE:
+ case XPATH_LOCATIONSET:
+ case XPATH_USERS:
+ case XPATH_XSLT_TREE:
+ /* TODO */
+ default:
+ return -1; /* TODO */
+ }
+}
+
+JNIEXPORT jdouble JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getNumberValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return 0.0;
+ }
+ return obj->floatval;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getStringValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, obj->stringval);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getBooleanValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ return obj->boolval;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getSingleNodeValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval->nodeNr > 0)
+ {
+ return xmljGetNodeInstance (env, obj->nodesetval->nodeTab[0]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getInvalidIteratorState (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ return 0; /* TODO */
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getSnapshotLength (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return -1;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return -1;
+ }
+ return obj->nodesetval->nodeNr;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_iterateNext (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ return NULL; /* TODO */
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_snapshotItem (JNIEnv *env,
+ jobject self,
+ jint index)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval->nodeNr > 0)
+ {
+ return xmljGetNodeInstance (env, obj->nodesetval->nodeTab[index]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/* -- GnomeXPathNodeList -- */
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getElementsByTagName (JNIEnv *env,
+ jobject self,
+ jstring name)
+{
+ return Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagName (env,
+ self,
+ name);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagName (JNIEnv *env,
+ jobject self,
+ jstring name)
+{
+ const xmlChar *s_name;
+ const xmlChar *format;
+ xmlChar expr[256];
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ node = xmljGetNodeID (env, self);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ s_name = xmljGetStringChars (env, name);
+ if (xmlStrEqual (s_name, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_name) == -1)
+ {
+ return NULL;
+ }
+ }
+ xmlFree ((xmlChar *) s_name);
+ ctx = xmljCreateXPathContextPtr (env, node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathEval (expr, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ return xmljGetXPathNodeList (env, eval);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getElementsByTagNameNS (JNIEnv *env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ return Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagNameNS (env,
+ self,
+ uri,
+ localName);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagNameNS (JNIEnv *env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+ const xmlChar *format;
+ xmlChar expr[256];
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ node = xmljGetNodeID (env, self);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ s_uri = xmljGetStringChars (env, uri);
+ s_localName = xmljGetStringChars (env, localName);
+ if (uri == NULL)
+ {
+ /* namespace URI is empty */
+ if (xmlStrEqual (s_localName, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='' and node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='' and local-name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_localName) == -1)
+ {
+ return NULL;
+ }
+ }
+ }
+ else if (xmlStrEqual (s_uri, BAD_CAST "*"))
+ {
+ /* matches all namespaces */
+ if (xmlStrEqual (s_localName, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[local-name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_localName) == -1)
+ {
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ if (xmlStrEqual (s_localName, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='%s' and node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format, s_uri) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='%s' and local-name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_uri, s_localName) == -1)
+ {
+ return NULL;
+ }
+ }
+ }
+ xmlFree ((xmlChar *) s_uri);
+ xmlFree ((xmlChar *) s_localName);
+ ctx = xmljCreateXPathContextPtr (env, node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathEval (expr, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ return xmljGetXPathNodeList (env, eval);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathNodeList_free (JNIEnv *env,
+ jobject self,
+ jobject obj)
+{
+ xmlXPathFreeObject ((xmlXPathObjectPtr) xmljAsPointer (env, obj));
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathNodeList_getLength (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return 0;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return 0;
+ }
+ return obj->nodesetval->nodeNr;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathNodeList_item (JNIEnv *env,
+ jobject self,
+ jint index)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval->nodeNr > 0)
+ {
+ return xmljGetNodeInstance (env, obj->nodesetval->nodeTab[index]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+