/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 #include 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 __attribute__((__unused__)), 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 __attribute__((__unused__)), 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 __attribute__((__unused__)), 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 __attribute__((__unused__)), 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 __attribute__((__unused__)), 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); }