1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-03 17:59:33 +02:00

fixed zip deflating on android 4.0 devices

This commit is contained in:
Nikolay Pultsin 2011-12-03 01:53:47 +00:00
parent e10597aadb
commit 46ef1eaeb4
4 changed files with 218 additions and 226 deletions

View file

@ -7,52 +7,41 @@
#define SIZE 10
static jobject keys[SIZE] = { 0 };
static z_stream* values[SIZE] = { 0 };
static z_stream* ourStreams[SIZE] = { 0 };
extern "C"
jboolean Java_org_amse_ys_zip_DeflatingDecompressor_startInflating(JNIEnv *env, jobject thiz) {
jint Java_org_amse_ys_zip_DeflatingDecompressor_startInflating(JNIEnv *env, jobject thiz) {
int i;
for (i = 0; i < SIZE; ++i) {
if (keys[i] == 0) {
keys[i] = thiz;
values[i] = new z_stream;
memset(values[i], 0, sizeof(z_stream));
inflateInit2(values[i], -MAX_WBITS);
return 1;
if (ourStreams[i] == 0) {
ourStreams[i] = new z_stream;
memset(ourStreams[i], 0, sizeof(z_stream));
inflateInit2(ourStreams[i], -MAX_WBITS);
return i;
}
}
return 0;
return -1;
}
extern "C"
void Java_org_amse_ys_zip_DeflatingDecompressor_endInflating(JNIEnv *env, jobject thiz) {
int i;
for (i = 0; i < SIZE; ++i) {
if (keys[i] == thiz) {
keys[i] = 0;
inflateEnd(values[i]);
delete values[i];
values[i] = 0;
break;
}
void Java_org_amse_ys_zip_DeflatingDecompressor_endInflating(JNIEnv *env, jobject thiz, jint inflatorId) {
if (inflatorId >= 0 && inflatorId < SIZE) {
inflateEnd(ourStreams[inflatorId]);
delete ourStreams[inflatorId];
ourStreams[inflatorId] = 0;
}
}
// returns (endFlag << 32) + ((used inLength) << 16) + outLength
extern "C"
jlong Java_org_amse_ys_zip_DeflatingDecompressor_inflate(JNIEnv *env, jobject thiz, jbyteArray in, jint inOffset, jint inLength, jbyteArray out) {
int i;
z_stream *stream = 0;
for (i = 0; i < SIZE; ++i) {
if (keys[i] == thiz) {
stream = values[i];
break;
}
}
if (stream == 0) {
jlong Java_org_amse_ys_zip_DeflatingDecompressor_inflate(JNIEnv *env, jobject thiz, jint inflatorId, jbyteArray in, jint inOffset, jint inLength, jbyteArray out) {
if (inflatorId < 0 || inflatorId >= SIZE) {
return -1;
}
z_stream *stream = ourStreams[inflatorId];
if (stream == 0) {
return -2;
}
jbyte* inStart = env->GetByteArrayElements(in, 0);
jbyte* outStart = env->GetByteArrayElements(out, 0);
@ -71,5 +60,5 @@ jlong Java_org_amse_ys_zip_DeflatingDecompressor_inflate(JNIEnv *env, jobject th
}
return result;
}
return -2;
return -3;
}

View file

@ -26,7 +26,7 @@ public abstract class Decompressor {
}
}
public static Decompressor init(MyBufferedInputStream is, LocalFileHeader header) throws IOException {
static Decompressor init(MyBufferedInputStream is, LocalFileHeader header) throws IOException {
switch (header.CompressionMethod) {
case 0:
return new NoCompressionDecompressor(is, header);

View file

@ -22,7 +22,7 @@ class DeflatingDecompressor extends Decompressor {
private int myOutBufferOffset;
private int myOutBufferLength;
private boolean myInflatingInProgress;
private volatile int myInflatorId = -1;
public DeflatingDecompressor(MyBufferedInputStream inputStream, LocalFileHeader header) throws IOException {
super();
@ -30,9 +30,9 @@ class DeflatingDecompressor extends Decompressor {
}
void reset(MyBufferedInputStream inputStream, LocalFileHeader header) throws IOException {
if (myInflatingInProgress) {
endInflating();
myInflatingInProgress = false;
if (myInflatorId != -1) {
endInflating(myInflatorId);
myInflatorId = -1;
}
myStream = inputStream;
@ -50,8 +50,10 @@ class DeflatingDecompressor extends Decompressor {
myOutBufferOffset = OUT_BUFFER_SIZE;
myOutBufferLength = 0;
startInflating();
myInflatingInProgress = true;
myInflatorId = startInflating();
if (myInflatorId == -1) {
throw new IOException("cannot start inflating");
}
}
@Override
@ -72,7 +74,7 @@ class DeflatingDecompressor extends Decompressor {
fillOutBuffer();
}
if (myOutBufferLength == 0) {
if (myInflatingInProgress) {
if (myInflatorId != -1) {
throw new IOException("cannot read from zip");
} else {
len -= toFill;
@ -105,7 +107,7 @@ class DeflatingDecompressor extends Decompressor {
fillOutBuffer();
}
if (myOutBufferLength == 0) {
if (myInflatingInProgress) {
if (myInflatorId != -1) {
throw new IOException("cannot read from zip");
} else {
myAvailable = 0;
@ -118,7 +120,7 @@ class DeflatingDecompressor extends Decompressor {
}
private void fillOutBuffer() throws IOException {
if (!myInflatingInProgress) {
if (myInflatorId == -1) {
return;
}
@ -136,7 +138,7 @@ class DeflatingDecompressor extends Decompressor {
if (myInBufferLength == 0) {
break;
}
final long result = inflate(myInBuffer, myInBufferOffset, myInBufferLength, myOutBuffer);
final long result = inflate(myInflatorId, myInBuffer, myInBufferOffset, myInBufferLength, myOutBuffer);
if (result <= 0) {
throw new IOException("Cannot inflate zip-compressed block, code = " + result);
}
@ -147,15 +149,15 @@ class DeflatingDecompressor extends Decompressor {
myOutBufferOffset = 0;
myOutBufferLength = out;
if ((result & (1L << 32)) != 0) {
endInflating();
myInflatingInProgress = false;
endInflating(myInflatorId);
myInflatorId = -1;
myStream.backSkip(myInBufferLength);
break;
}
}
}
private native boolean startInflating();
private native void endInflating();
private native long inflate(byte[] in, int inOffset, int inLength, byte[] out);
private native int startInflating();
private native void endInflating(int inflatorId);
private native long inflate(int inflatorId, byte[] in, int inOffset, int inLength, byte[] out);
}

View file

@ -107,6 +107,7 @@ public final class ZipFile {
uncompressedSize += blockSize;
}
header.UncompressedSize = uncompressedSize;
Decompressor.storeDecompressor(decompressor);
}
private final Queue<MyBufferedInputStream> myStoredStreams = new LinkedList<MyBufferedInputStream>();