zipfile.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 312 行

C
312
字号
/* * @(#)ZipFile.c	1.32 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program 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 version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * *//* * Native method support for java.util.zip.ZipFile */#include "javavm/include/porting/ansi/stdio.h"#include "javavm/include/porting/ansi/stdlib.h"#include "javavm/include/porting/ansi/string.h"#include "javavm/include/porting/ansi/errno.h"#include "javavm/include/porting/ansi/ctype.h"#include "javavm/include/porting/ansi/assert.h"#include "javavm/include/ansi2cvm.h"#include "javavm/include/interpreter.h"#include "jlong.h"#include "jvm.h"#include "jni.h"#include "jni_util.h"#include "zip_util.h"#include "java_util_zip_ZipFile.h"#include "java_util_jar_JarFile.h"#define DEFLATED 8#define STORED 0#include "jni_statics.h"/* make these const */static const int OPEN_READ = java_util_zip_ZipFile_OPEN_READ;static const int OPEN_DELETE = java_util_zip_ZipFile_OPEN_DELETE;JNIEXPORT void JNICALLJava_java_util_zip_ZipFile_initIDs(JNIEnv *env, jclass cls){    JNI_STATIC(java_util_zip_ZipFile, jzfileID) = (*env)->GetFieldID(env, cls, "jzfile", "J");    CVMassert(JNI_STATIC(java_util_zip_ZipFile, jzfileID) != 0);}static voidThrowZipException(JNIEnv *env, const char *msg){    jstring s = NULL;    jobject x;        if (msg != NULL) {	s = JNU_NewStringPlatform(env, msg);    }    x = JNU_NewObjectByName(env,			    "java/util/zip/ZipException",			    "(Ljava/lang/String;)V", s);    if (x != NULL) {	(*env)->Throw(env, x);	(*env)->DeleteLocalRef(env, x);	if (s != NULL) {	    (*env)->DeleteLocalRef(env, s);	}    }}JNIEXPORT jlong JNICALLJava_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name,                                         jint mode, jlong lastModified){    const char *path;    jlong result = CVMlongConstZero();    int flag = 0;        /* fix 4210379: throw Null Pointer Exception if file name is null */    if (name == 0) {      JNU_ThrowNullPointerException(env, "null filename");      return CVMlongConstZero();    }    path = JNU_GetStringPlatformChars(env, name, 0);    /* Fix for bug #6264809 : for CDC, mode is cleared before it is passed     * here.  So, the JVM_O_DELETE set operations below is not needed.     *     * For JAVASE, mode is not cleared, and the low level IO HPI expects     * JVM_O_DELETE to be set in the flag when appropriate.    */#ifdef JAVASE    if (mode & OPEN_DELETE) flag |= JVM_O_DELETE;#endif    if (mode & OPEN_READ) flag |= O_RDONLY;    if (path != 0) {	char *msg;	jzfile *zip = ZIP_Open_Generic(path, &msg, flag, lastModified);	JNU_ReleaseStringPlatformChars(env, name, path);	if (zip != 0) {	    result = ptr_to_jlong(zip);	} else if (msg != 0) {	    ThrowZipException(env, msg);	} else if (errno == ENOMEM) {	    JNU_ThrowOutOfMemoryError(env, 0);	} else {	    ThrowZipException(env, "error in opening zip file");	}    }    return result;}JNIEXPORT jint JNICALLJava_java_util_zip_ZipFile_getTotal(JNIEnv *env, jclass cls, jlong zfile){    jzfile *zip = (jzfile *)jlong_to_ptr(zfile);    return zip->total;}JNIEXPORT void JNICALLJava_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile){    ZIP_Close((jzfile *)jlong_to_ptr(zfile));}JNIEXPORT jlong JNICALLJava_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,				    jstring name){#define MAXNAME 1024    jzfile *zip = (jzfile *)jlong_to_ptr(zfile);    jsize slen = (*env)->GetStringLength(env, name);    jsize ulen = (*env)->GetStringUTFLength(env, name);    char buf[MAXNAME+1], *path;    jzentry *ze;    if (ulen > MAXNAME) {	path = (char *)malloc(ulen + 1);	if (path == 0) {	    JNU_ThrowOutOfMemoryError(env, 0);	    return 0;	}    } else {	path = buf;    }    (*env)->GetStringUTFRegion(env, name, 0, slen, path);    path[ulen] = '\0';    ze = ZIP_GetEntry(zip, path);    if (path != buf) {	free(path);    }    return ptr_to_jlong(ze);}JNIEXPORT void JNICALLJava_java_util_zip_ZipFile_freeEntry(JNIEnv *env, jclass cls, jlong zfile,				    jlong zentry){    jzfile *zip = (jzfile *)jlong_to_ptr(zfile);    jzentry *ze = (jzentry *)jlong_to_ptr(zentry);    ZIP_FreeEntry(zip, ze);}JNIEXPORT jlong JNICALLJava_java_util_zip_ZipFile_getNextEntry(JNIEnv *env, jclass cls, jlong zfile,					jint n){    jzentry *ze = ZIP_GetNextEntry((jzfile *)jlong_to_ptr(zfile), n);    return ptr_to_jlong(ze);}JNIEXPORT jint JNICALLJava_java_util_zip_ZipFile_getMethod(JNIEnv *env, jclass cls, jlong zentry){    jzentry *ze = (jzentry *)jlong_to_ptr(zentry);    return ze->csize != 0 ? DEFLATED : STORED;}JNIEXPORT jint JNICALLJava_java_util_zip_ZipFile_getCSize(JNIEnv *env, jclass cls, jlong zentry){    jzentry *ze = (jzentry *)jlong_to_ptr(zentry);    return ze->csize != 0 ? ze->csize : ze->size;}JNIEXPORT jint JNICALLJava_java_util_zip_ZipFile_getSize(JNIEnv *env, jclass cls, jlong zentry){    jzentry *ze = (jzentry *)jlong_to_ptr(zentry);    return ze->size;}JNIEXPORT jint JNICALLJava_java_util_zip_ZipFile_read(JNIEnv *env, jclass cls, jlong zfile,				jlong zentry, jint pos, jbyteArray bytes,				jint off, jint len){    jzfile *zip = (jzfile *)jlong_to_ptr(zfile);    jbyte *buf;    char *msg;    CVMExecEnv *ee = CVMjniEnv2ExecEnv(env);    char errmsg[128];    if (len == 0) {        return 0;    }    if (len > CVM_CSTACK_BUF_SIZE)	len = CVM_CSTACK_BUF_SIZE;    {	char* tmp;	CVMCstackGetBuffer(ee, tmp); /* Lock EE-buffer */	buf = (jbyte*)tmp;    }    if (buf == NULL) {        JNU_ThrowOutOfMemoryError(env, 0);        return 0;    }    ZIP_Lock(zip);    len = ZIP_Read(zip, (jzentry *)jlong_to_ptr(zentry), pos, buf, len);    msg = zip->msg;    ZIP_Unlock(zip);    if (len == -1) {	if (msg != 0) {	    ThrowZipException(env, msg);	} else {	    sprintf(errmsg, "errno: %d, error: %s\n", errno, "Error reading ZIP file");            JNU_ThrowIOExceptionWithLastError(env, errmsg);	}    } else {	(*env)->SetByteArrayRegion(env, bytes, off, len, buf);    }    CVMCstackReleaseBuffer(ee);		/* Unlock EE-buffer */    return len;}/* * Returns an array of strings representing the names of all entries * that begin with "META-INF/" (case ignored). This native method is * used in JarFile as an optimization when looking up manifest and * signature file entries. Returns null if no entries were found. */JNIEXPORT jobjectArray JNICALLJava_java_util_jar_JarFile_getMetaInfEntryNames(JNIEnv *env, jobject obj){    jlong zfile = (*env)->GetLongField(env, obj, JNI_STATIC(java_util_zip_ZipFile, jzfileID));    jzfile *zip;    int i, count;    jobjectArray result = 0;    CVMassert(CVMlongNe(zfile, CVMlongConstZero()));    zip = (jzfile *)jlong_to_ptr(zfile);    /* count the number of valid ZIP metanames */    count = 0;    if (zip->metanames != 0) {	for (i = 0; i < zip->metacount; i++) {	    if (zip->metanames[i] != 0) {		count++;	    }	}    }    /* If some names were found then build array of java strings */    if (count > 0) {	jclass cls = (*env)->FindClass(env, "java/lang/String");	result = (*env)->NewObjectArray(env, count, cls, 0);	if (result != 0) {	    for (i = 0; i < count; i++) {		jstring str = (*env)->NewStringUTF(env, zip->metanames[i]);		if (str == 0) {		    break;		}		(*env)->SetObjectArrayElement(env, result, i, str);		(*env)->DeleteLocalRef(env, str);	    }	}    }    return result;}JNIEXPORT jstring JNICALLJava_java_util_zip_ZipFile_getZipMessage(JNIEnv *env, jclass cls, jlong zfile){    jzfile *zip = (jzfile *)jlong_to_ptr(zfile);    char *msg = zip->msg;    if (msg == NULL) {        return NULL;     }     return JNU_NewStringPlatform(env, msg);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?