Unpack .zip.xz archives using liblzma and JNI instead of Java implementation, because Java heap is small and it crashes with out of memory error

This commit is contained in:
pelya
2014-11-12 00:59:04 +02:00
parent 244866c48e
commit a44892d72e
9 changed files with 233 additions and 9 deletions

View File

@@ -7,8 +7,7 @@ LOCAL_MODULE := lzma
APP_SUBDIRS := $(patsubst $(LOCAL_PATH)/%, %, $(shell find $(LOCAL_PATH)/src -type d))
LOCAL_C_INCLUDES := $(foreach D, $(APP_SUBDIRS), $(LOCAL_PATH)/$(D)) $(LOCAL_PATH)/include
LOCAL_CFLAGS := -O3 -DHAVE_CONFIG_H -DTUKLIB_SYMBOL_PREFIX=lzma_ -std=c99 # Enable "restrict" keyword
LOCAL_CFLAGS := -O3 -DHAVE_CONFIG_H -DTUKLIB_SYMBOL_PREFIX=lzma_ -std=c99 -DSDL_JAVA_PACKAGE_PATH=$(SDL_JAVA_PACKAGE_PATH)
LOCAL_CPP_EXTENSION := .cpp

View File

@@ -0,0 +1,65 @@
#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <jni.h>
#include "lzma.h"
#include "jniwrapperstuff.h"
JNIEXPORT jlong JNICALL
JAVA_EXPORT_NAME(XZInputStream_nativeInit) (JNIEnv* env, jobject thiz)
{
lzma_stream * stream = (lzma_stream *) malloc(sizeof(lzma_stream));
lzma_stream tmp = LZMA_STREAM_INIT;
*stream = tmp;
int ret = lzma_stream_decoder(stream, UINT64_MAX, LZMA_CONCATENATED);
if (ret != LZMA_OK)
{
free(stream);
return 0;
}
return (jlong) (intptr_t) stream;
}
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(XZInputStream_nativeClose) (JNIEnv* env, jobject thiz, jlong nativeData)
{
lzma_stream * stream = (lzma_stream *) (intptr_t) nativeData;
lzma_end(stream);
}
JNIEXPORT jint JNICALL
JAVA_EXPORT_NAME(XZInputStream_nativeRead) (JNIEnv* env, jobject thiz, jlong nativeData,
jobject inBuf, jint inAvailable, jobject outBuf,
jint outCount, jobject offsets)
{
lzma_stream * stream = (lzma_stream *) (intptr_t) nativeData;
uint8_t *inBufNative = (uint8_t *) (*env)->GetPrimitiveArrayCritical(env, inBuf, NULL);
uint8_t *outBufNative = (uint8_t *) (*env)->GetPrimitiveArrayCritical(env, outBuf, NULL);
jint *offsetsNative = (jint *) (*env)->GetPrimitiveArrayCritical(env, offsets, NULL);
jint inOffset = offsetsNative[0];
jint outOffset = offsetsNative[1];
int ret;
stream->avail_in = inAvailable - inOffset;
stream->next_in = inBufNative + inOffset;
stream->avail_out = outCount;
stream->next_out = outBufNative + outOffset;
ret = lzma_code(stream, inAvailable == -1 ? LZMA_FINISH : LZMA_RUN);
(*env)->ReleasePrimitiveArrayCritical(env, offsets, offsetsNative, 0);
(*env)->ReleasePrimitiveArrayCritical(env, outBuf, outBufNative, 0);
(*env)->ReleasePrimitiveArrayCritical(env, inBuf, inBufNative, 0);
inOffset = inAvailable - stream->avail_in;
outOffset += outCount - stream->avail_out;
offsetsNative[0] = inOffset;
offsetsNative[1] = outOffset;
return ret;
}