summaryrefslogtreecommitdiffstats
path: root/luni/src/main/native
diff options
context:
space:
mode:
Diffstat (limited to 'luni/src/main/native')
-rw-r--r--luni/src/main/native/Register.cpp1
-rw-r--r--luni/src/main/native/java_util_jar_StrictJarFile.cpp173
-rw-r--r--luni/src/main/native/sub.mk4
3 files changed, 177 insertions, 1 deletions
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 15f6953..68c59c3 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -49,6 +49,7 @@ jint JNI_OnLoad(JavaVM* vm, void*) {
REGISTER(register_java_nio_ByteOrder);
REGISTER(register_java_nio_charset_Charsets);
REGISTER(register_java_text_Bidi);
+ REGISTER(register_java_util_jar_StrictJarFile);
REGISTER(register_java_util_regex_Matcher);
REGISTER(register_java_util_regex_Pattern);
REGISTER(register_java_util_zip_Adler32);
diff --git a/luni/src/main/native/java_util_jar_StrictJarFile.cpp b/luni/src/main/native/java_util_jar_StrictJarFile.cpp
new file mode 100644
index 0000000..7611749
--- /dev/null
+++ b/luni/src/main/native/java_util_jar_StrictJarFile.cpp
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "StrictJarFile"
+
+#include <string>
+
+#include "JNIHelp.h"
+#include "JniConstants.h"
+#include "ScopedLocalRef.h"
+#include "ScopedUtfChars.h"
+#include "UniquePtr.h"
+#include "jni.h"
+#include "ziparchive/zip_archive.h"
+#include "cutils/log.h"
+
+static void throwIoException(JNIEnv* env, const int32_t errorCode) {
+ jniThrowException(env, "java/io/IOException", ErrorCodeString(errorCode));
+}
+
+static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName,
+ const uint16_t nameLength) {
+ ScopedLocalRef<jclass> zipEntryClass(env, env->FindClass("java/util/zip/ZipEntry"));
+ const jmethodID zipEntryCtor = env->GetMethodID(zipEntryClass.get(), "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;JJJIII[BIJJ)V");
+
+ return env->NewObject(zipEntryClass.get(),
+ zipEntryCtor,
+ entryName,
+ NULL, // comment
+ static_cast<jlong>(entry.crc32),
+ static_cast<jlong>(entry.compressed_length),
+ static_cast<jlong>(entry.uncompressed_length),
+ static_cast<jint>(entry.method),
+ static_cast<jint>(0), // time
+ static_cast<jint>(0), // modData
+ NULL, // byte[] extra
+ static_cast<jint>(nameLength),
+ static_cast<jlong>(-1), // local header offset
+ static_cast<jlong>(entry.offset));
+}
+
+static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring fileName) {
+ ScopedUtfChars fileChars(env, fileName);
+ if (fileChars.c_str() == NULL) {
+ return static_cast<jlong>(-1);
+ }
+
+ ZipArchiveHandle handle;
+ int32_t error = OpenArchive(fileChars.c_str(), &handle);
+ if (error) {
+ throwIoException(env, error);
+ return static_cast<jlong>(-1);
+ }
+
+ return reinterpret_cast<jlong>(handle);
+}
+
+class IterationHandle {
+ public:
+ IterationHandle(const char* prefix) :
+ cookie_(NULL), prefix_(strdup(prefix)) {
+ }
+
+ void** CookieAddress() {
+ return &cookie_;
+ }
+
+ const char* Prefix() const {
+ return prefix_;
+ }
+
+ ~IterationHandle() {
+ free(prefix_);
+ }
+
+ private:
+ void* cookie_;
+ char* prefix_;
+};
+
+
+static jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nativeHandle,
+ jstring prefix) {
+ ScopedUtfChars prefixChars(env, prefix);
+ if (prefixChars.c_str() == NULL) {
+ return static_cast<jlong>(-1);
+ }
+
+ IterationHandle* handle = new IterationHandle(prefixChars.c_str());
+ int32_t error = 0;
+ if (prefixChars.size() == 0) {
+ error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
+ handle->CookieAddress(), NULL);
+ } else {
+ error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
+ handle->CookieAddress(), handle->Prefix());
+ }
+
+ if (error) {
+ throwIoException(env, error);
+ return static_cast<jlong>(-1);
+ }
+
+ return reinterpret_cast<jlong>(handle);
+}
+
+static jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterationHandle) {
+ ZipEntry data;
+ ZipEntryName entryName;
+
+ IterationHandle* handle = reinterpret_cast<IterationHandle*>(iterationHandle);
+ const int32_t error = Next(*handle->CookieAddress(), &data, &entryName);
+ if (error) {
+ delete handle;
+ return NULL;
+ }
+
+ UniquePtr<char[]> entryNameCString(new char[entryName.name_length + 1]);
+ memcpy(entryNameCString.get(), entryName.name, entryName.name_length);
+ entryNameCString[entryName.name_length] = '\0';
+ ScopedLocalRef<jstring> entryNameString(env, env->NewStringUTF(entryNameCString.get()));
+
+ return newZipEntry(env, data, entryNameString.get(), entryName.name_length);
+}
+
+static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle,
+ jstring entryName) {
+ ScopedUtfChars entryNameChars(env, entryName);
+ if (entryNameChars.c_str() == NULL) {
+ return NULL;
+ }
+
+ ZipEntry data;
+ const int32_t error = FindEntry(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
+ entryNameChars.c_str(), &data);
+ if (error) {
+ return NULL;
+ }
+
+ return newZipEntry(env, data, entryName, entryNameChars.size());
+}
+
+static void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) {
+ CloseArchive(reinterpret_cast<ZipArchiveHandle>(nativeHandle));
+}
+
+static JNINativeMethod gMethods[] = {
+ NATIVE_METHOD(StrictJarFile, nativeOpenJarFile, "(Ljava/lang/String;)J"),
+ NATIVE_METHOD(StrictJarFile, nativeStartIteration, "(JLjava/lang/String;)J"),
+ NATIVE_METHOD(StrictJarFile, nativeNextEntry, "(J)Ljava/util/zip/ZipEntry;"),
+ NATIVE_METHOD(StrictJarFile, nativeFindEntry, "(JLjava/lang/String;)Ljava/util/zip/ZipEntry;"),
+ NATIVE_METHOD(StrictJarFile, nativeClose, "(J)V"),
+};
+
+void register_java_util_jar_StrictJarFile(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "java/util/jar/StrictJarFile", gMethods, NELEM(gMethods));
+
+}
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 9e1a05b..4e10cc7 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
java_nio_ByteOrder.cpp \
java_nio_charset_Charsets.cpp \
java_text_Bidi.cpp \
+ java_util_jar_StrictJarFile.cpp \
java_util_regex_Matcher.cpp \
java_util_regex_Pattern.cpp \
java_util_zip_Adler32.cpp \
@@ -60,7 +61,8 @@ LOCAL_C_INCLUDES += \
external/icu4c/common \
external/icu4c/i18n \
external/openssl/include \
- external/zlib
+ external/zlib \
+ system/core/include
LOCAL_STATIC_LIBRARIES += \
libfdlibm