From 8c20fd111c4311d828ee6262c6ec3387c1b2c96d Mon Sep 17 00:00:00 2001 From: garylwy Date: Fri, 1 Jan 2021 14:47:44 +0800 Subject: [PATCH] Expose native LZ4_compress_fast_continue API in LZ4JNI --- src/java/net/jpountz/lz4/LZ4JNI.java | 1 + src/jni/net_jpountz_lz4_LZ4JNI.c | 48 +++++++++++++++++++++++++++ src/test/net/jpountz/lz4/LZ4Test.java | 14 ++++++++ 3 files changed, 63 insertions(+) diff --git a/src/java/net/jpountz/lz4/LZ4JNI.java b/src/java/net/jpountz/lz4/LZ4JNI.java index 0b5c1617..5b8fc7a8 100644 --- a/src/java/net/jpountz/lz4/LZ4JNI.java +++ b/src/java/net/jpountz/lz4/LZ4JNI.java @@ -34,6 +34,7 @@ enum LZ4JNI { static native void init(); static native int LZ4_compress_limitedOutput(byte[] srcArray, ByteBuffer srcBuffer, int srcOff, int srcLen, byte[] destArray, ByteBuffer destBuffer, int destOff, int maxDestLen); + static native int LZ4_compress_fast_continue(byte[] srcArray, ByteBuffer srcBuffer, int srcOff, int srcLen, byte[] destArray, ByteBuffer destBuffer, int destOff, int maxDestLen, int acceleration); static native int LZ4_compressHC(byte[] srcArray, ByteBuffer srcBuffer, int srcOff, int srcLen, byte[] destArray, ByteBuffer destBuffer, int destOff, int maxDestLen, int compressionLevel); static native int LZ4_decompress_fast(byte[] srcArray, ByteBuffer srcBuffer, int srcOff, byte[] destArray, ByteBuffer destBuffer, int destOff, int destLen); static native int LZ4_decompress_safe(byte[] srcArray, ByteBuffer srcBuffer, int srcOff, int srcLen, byte[] destArray, ByteBuffer destBuffer, int destOff, int maxDestLen); diff --git a/src/jni/net_jpountz_lz4_LZ4JNI.c b/src/jni/net_jpountz_lz4_LZ4JNI.c index c2f8c226..ed359cc9 100644 --- a/src/jni/net_jpountz_lz4_LZ4JNI.c +++ b/src/jni/net_jpountz_lz4_LZ4JNI.c @@ -85,6 +85,54 @@ JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1compress_1limitedOutput } +/* + * Class: net_jpountz_lz4_LZ4JNI + * Method: LZ4_compress_fast_contine + * Signature: ([BLjava/nio/ByteBuffer;II[BLjava/nio/ByteBuffer;III)I + */ +JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1compress_1fast_1continue + (JNIEnv *env, jclass cls, jbyteArray srcArray, jobject srcBuffer, jint srcOff, jint srcLen, jbyteArray destArray, jobject destBuffer, jint destOff, jint maxDestLen, jint acceleration) { + + char* in; + char* out; + jint compressed; + + if (srcArray != NULL) { + in = (char*) (*env)->GetPrimitiveArrayCritical(env, srcArray, 0); + } else { + in = (char*) (*env)->GetDirectBufferAddress(env, srcBuffer); + } + + if (in == NULL) { + throw_OOM(env); + return 0; + } + + if (destArray != NULL) { + out = (char*) (*env)->GetPrimitiveArrayCritical(env, destArray, 0); + } else { + out = (char*) (*env)->GetDirectBufferAddress(env, destBuffer); + } + + if (out == NULL) { + throw_OOM(env); + return 0; + } + + LZ4_stream_t lz4_state; + LZ4_resetStream (&lz4_state); + compressed = LZ4_compress_fast_continue (&lz4_state, in + srcOff, out + destOff, srcLen, maxDestLen, acceleration); + + if (srcArray != NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, srcArray, in, 0); + } + if (destArray != NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, destArray, out, 0); + } + + return compressed; +} + /* * Class: net_jpountz_lz4_LZ4JNI * Method: LZ4_compressHC diff --git a/src/test/net/jpountz/lz4/LZ4Test.java b/src/test/net/jpountz/lz4/LZ4Test.java index 92ad9433..bae3aac2 100644 --- a/src/test/net/jpountz/lz4/LZ4Test.java +++ b/src/test/net/jpountz/lz4/LZ4Test.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ReadOnlyBufferException; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.io.File; import java.io.FilenameFilter; @@ -485,6 +486,19 @@ public void testRoundtripIssue12() { testRoundTrip(data, 9, data.length - 9); } + @Test + public void testNativeFastContinue() { + final byte[] src = "01234567890123456789".getBytes(StandardCharsets.US_ASCII); + final byte[] dest = new byte[LZ4JNI.LZ4_compressBound(src.length)]; + final int compressLen = LZ4JNI.LZ4_compress_fast_continue(src, null, 0, src.length, dest, null, 0, dest.length, 1); + final byte[] compressed = Arrays.copyOf(dest, compressLen); + + final byte[] decompressed = new byte[src.length]; + final int decompressedLen = LZ4JNI.LZ4_decompress_fast(compressed, null, 0, decompressed, null, 0, decompressed.length); + assertEquals(compressLen, decompressedLen); + assertArrayEquals(src, decompressed); + } + private static void assertCompressedArrayEquals(String message, byte[] expected, byte[] actual) { int off = 0; int decompressedOff = 0;