From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libjava/classpath/native/jni/xmlj/xmlj_io.c | 799 ++++++++++++++++++++++++++++ 1 file changed, 799 insertions(+) create mode 100644 libjava/classpath/native/jni/xmlj/xmlj_io.c (limited to 'libjava/classpath/native/jni/xmlj/xmlj_io.c') diff --git a/libjava/classpath/native/jni/xmlj/xmlj_io.c b/libjava/classpath/native/jni/xmlj/xmlj_io.c new file mode 100644 index 000000000..aa2964dc3 --- /dev/null +++ b/libjava/classpath/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., 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_io.h" +#include "xmlj_error.h" +#include "xmlj_node.h" +#include "xmlj_sax.h" +#include "xmlj_util.h" + +#include +#include +#include +#include + +#include +#include + +#include + +#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); +} -- cgit v1.2.3