diff --git a/src/main/java/org/xerial/snappy/Snappy.java b/src/main/java/org/xerial/snappy/Snappy.java index f21ab4f..aaafa7c 100755 --- a/src/main/java/org/xerial/snappy/Snappy.java +++ b/src/main/java/org/xerial/snappy/Snappy.java @@ -60,17 +60,32 @@ public class Snappy * @throws SnappyException */ public static byte[] compress(byte[] input) throws SnappyException { - byte[] buf = new byte[Snappy.maxCompressedLength(input.length)]; - int compressedByteSize = Snappy.compress(input, 0, input.length, buf, 0); - byte[] result = new byte[compressedByteSize]; - System.arraycopy(buf, 0, result, 0, compressedByteSize); - return result; + return compressBytes(input, input.length); } - public static byte[] compress(float[] data) { - int floatArraySize = data.length * 4;// float use 4 bytes - byte[] buf = new byte[Snappy.maxCompressedLength(floatArraySize)]; - int compressedByteSize = SnappyNative.rawCompressFloat(data, 0, floatArraySize, buf, 0); + public static byte[] compress(char[] input) { + return compressBytes(input, input.length * 2); // short use 2 bytes + } + + public static byte[] compress(short[] input) { + return compressBytes(input, input.length * 2); // short use 2 bytes + } + + public static byte[] compress(float[] input) { + return compressBytes(input, input.length * 4); // float use 4 bytes + } + + public static byte[] compress(long[] input) { + return compressBytes(input, input.length * 8); // long use 8 bytes + } + + public static byte[] compress(double[] input) { + return compressBytes(input, input.length * 8); // double use 8 bytes + } + + private static byte[] compressBytes(Object data, int byteSize) { + byte[] buf = new byte[Snappy.maxCompressedLength(byteSize)]; + int compressedByteSize = SnappyNative.rawCompress(data, 0, byteSize, buf, 0); byte[] result = new byte[compressedByteSize]; System.arraycopy(buf, 0, result, 0, compressedByteSize); return result; @@ -92,10 +107,55 @@ public class Snappy return result; } + public static char[] uncompressChar(byte[] input) throws SnappyException { + int uncompressedLength = Snappy.uncompressedLength(input, 0, input.length); + char[] result = new char[uncompressedLength / 2]; + int byteSize = SnappyNative.rawUncompress(input, 0, input.length, result, 0); + if (byteSize != uncompressedLength) + throw new SnappyException(SnappyErrorCode.INVALID_DECOMPRESSION); + return result; + } + + public static short[] uncompressShort(byte[] input) throws SnappyException { + int uncompressedLength = Snappy.uncompressedLength(input, 0, input.length); + short[] result = new short[uncompressedLength / 2]; + int byteSize = SnappyNative.rawUncompress(input, 0, input.length, result, 0); + if (byteSize != uncompressedLength) + throw new SnappyException(SnappyErrorCode.INVALID_DECOMPRESSION); + return result; + } + + public static int[] uncompressInt(byte[] input) throws SnappyException { + int uncompressedLength = Snappy.uncompressedLength(input, 0, input.length); + int[] result = new int[uncompressedLength / 4]; + int byteSize = SnappyNative.rawUncompress(input, 0, input.length, result, 0); + if (byteSize != uncompressedLength) + throw new SnappyException(SnappyErrorCode.INVALID_DECOMPRESSION); + return result; + } + public static float[] uncompressFloat(byte[] input) throws SnappyException { int uncompressedLength = Snappy.uncompressedLength(input, 0, input.length); float[] result = new float[uncompressedLength / 4]; - int byteSize = SnappyNative.rawUncompressFloat(input, 0, input.length, result, 0); + int byteSize = SnappyNative.rawUncompress(input, 0, input.length, result, 0); + if (byteSize != uncompressedLength) + throw new SnappyException(SnappyErrorCode.INVALID_DECOMPRESSION); + return result; + } + + public static double[] uncompressDouble(byte[] input) throws SnappyException { + int uncompressedLength = Snappy.uncompressedLength(input, 0, input.length); + double[] result = new double[uncompressedLength / 8]; + int byteSize = SnappyNative.rawUncompress(input, 0, input.length, result, 0); + if (byteSize != uncompressedLength) + throw new SnappyException(SnappyErrorCode.INVALID_DECOMPRESSION); + return result; + } + + public static long[] uncompressLong(byte[] input) throws SnappyException { + int uncompressedLength = Snappy.uncompressedLength(input, 0, input.length); + long[] result = new long[uncompressedLength / 8]; + int byteSize = SnappyNative.rawUncompress(input, 0, input.length, result, 0); if (byteSize != uncompressedLength) throw new SnappyException(SnappyErrorCode.INVALID_DECOMPRESSION); return result; @@ -150,6 +210,11 @@ public class Snappy */ public static int compress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) throws SnappyException { + return compressBytes(input, inputOffset, inputLength, output, outputOffset); + } + + private static int compressBytes(Object input, int inputOffset, int inputLength, Object output, int outputOffset) + throws SnappyException { if (input == null || output == null) throw new NullPointerException("input or output is null"); diff --git a/src/main/java/org/xerial/snappy/SnappyNative.cpp b/src/main/java/org/xerial/snappy/SnappyNative.cpp index 407ab9f..e304615 100755 --- a/src/main/java/org/xerial/snappy/SnappyNative.cpp +++ b/src/main/java/org/xerial/snappy/SnappyNative.cpp @@ -55,11 +55,11 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__Ljava_ni } -jint snappyRawCompress - (JNIEnv * env, jclass self, jarray input, jint inputOffset, jint inputLen, jarray output, jint outputOffset) +JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__Ljava_lang_Object_2IILjava_lang_Object_2I + (JNIEnv * env, jclass self, jobject input, jint inputOffset, jint inputLen, jobject output, jint outputOffset) { - char* in = (char*) env->GetPrimitiveArrayCritical(input, 0); - char* out = (char*) env->GetPrimitiveArrayCritical(output, 0); + char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0); + char* out = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0); if(in == 0 || out == 0) { // out of memory throw_exception(env, self, 4); @@ -69,17 +69,17 @@ jint snappyRawCompress size_t compressedLength; snappy::RawCompress(in + inputOffset, (size_t) inputLen, out + outputOffset, &compressedLength); - env->ReleasePrimitiveArrayCritical(input, in, 0); - env->ReleasePrimitiveArrayCritical(output, out, 0); + env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); + env->ReleasePrimitiveArrayCritical((jarray) output, out, 0); return (jint) compressedLength; } -jint snappyRawUncompress -(JNIEnv * env, jclass self, jarray input, jint inputOffset, jint inputLength, jarray output, jint outputOffset) +JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__Ljava_lang_Object_2IILjava_lang_Object_2I +(JNIEnv * env, jclass self, jobject input, jint inputOffset, jint inputLength, jobject output, jint outputOffset) { - char* in = (char*) env->GetPrimitiveArrayCritical(input, 0); - char* out = (char*) env->GetPrimitiveArrayCritical(output, 0); + char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0); + char* out = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0); if(in == 0 || out == 0) { // out of memory throw_exception(env, self, 4); @@ -90,8 +90,8 @@ jint snappyRawUncompress snappy::GetUncompressedLength(in + inputOffset, (size_t) inputLength, &uncompressedLength); bool ret = snappy::RawUncompress(in + inputOffset, (size_t) inputLength, out + outputOffset); - env->ReleasePrimitiveArrayCritical(input, in, 0); - env->ReleasePrimitiveArrayCritical(output, out, 0); + env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); + env->ReleasePrimitiveArrayCritical((jarray) output, out, 0); if(!ret) { throw_exception(env, self, 2); @@ -102,26 +102,6 @@ jint snappyRawUncompress } -/* - * Class: org_xerial_snappy_SnappyNative - * Method: rawCompress - * Signature: ([BII[BI)I - */ - -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress___3BII_3BI - (JNIEnv * env, jclass self, jbyteArray input, jint inputOffset, jint inputLen, jbyteArray output, jint outputOffset) -{ - return snappyRawCompress(env, self, input, inputOffset, inputLen, output, outputOffset); -} - - -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompressFloat - (JNIEnv * env, jclass self, jfloatArray input, jint inputOffset, jint inputLen, jbyteArray output, jint outputOffset) -{ - return snappyRawCompress(env, self, input, inputOffset, inputLen, output, outputOffset); -} - - /* * Class: org_xerial_snappy_Snappy * Method: uncompress @@ -148,18 +128,6 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__Ljava_ return (jint) decompressedLength; } -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress___3BII_3BI - (JNIEnv * env, jclass self, jbyteArray input, jint inputOffset, jint inputLength, jbyteArray output, jint outputOffset) -{ - snappyRawUncompress(env, self, input, inputOffset, inputLength, output, outputOffset); -} - - -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompressFloat - (JNIEnv * env, jclass self, jbyteArray input, jint inputOffset, jint inputLength, jfloatArray output, jint outputOffset) -{ - snappyRawUncompress(env, self, input, inputOffset, inputLength, output, outputOffset); -} /* @@ -198,10 +166,10 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__L return (jint) result; } -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength___3BII - (JNIEnv * env, jclass self, jbyteArray input, jint offset, jint length) +JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__Ljava_lang_Object_2II + (JNIEnv * env, jclass self, jobject input, jint offset, jint length) { - char* in = (char*) env->GetPrimitiveArrayCritical(input, 0); + char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0); if(in == 0) { // out of memory throw_exception(env, self, 4); @@ -210,7 +178,7 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength___ size_t result; bool ret = snappy::GetUncompressedLength(in + offset, (size_t) length, &result); - env->ReleasePrimitiveArrayCritical(input, in, 0); + env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); return (jint) result; } @@ -228,17 +196,17 @@ JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressed } -JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer___3BII - (JNIEnv * env, jclass self, jbyteArray input, jint offset, jint length) +JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__Ljava_lang_Object_2II + (JNIEnv * env, jclass self, jobject input, jint offset, jint length) { - char* in = (char*) env->GetPrimitiveArrayCritical(input, 0); + char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0); if(in == 0) { // out of memory throw_exception(env, self, 4); return 0; } bool ret = snappy::IsValidCompressedBuffer(in + offset, (size_t) length); - env->ReleasePrimitiveArrayCritical(input, in, 0); + env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); return ret; } diff --git a/src/main/java/org/xerial/snappy/SnappyNative.h b/src/main/java/org/xerial/snappy/SnappyNative.h index 2115fb8..5b08836 100755 --- a/src/main/java/org/xerial/snappy/SnappyNative.h +++ b/src/main/java/org/xerial/snappy/SnappyNative.h @@ -26,18 +26,10 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__Ljava_ni /* * Class: org_xerial_snappy_SnappyNative * Method: rawCompress - * Signature: ([BII[BI)I + * Signature: (Ljava/lang/Object;IILjava/lang/Object;I)I */ -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress___3BII_3BI - (JNIEnv *, jclass, jbyteArray, jint, jint, jbyteArray, jint); - -/* - * Class: org_xerial_snappy_SnappyNative - * Method: rawCompressFloat - * Signature: ([FII[BI)I - */ -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompressFloat - (JNIEnv *, jclass, jfloatArray, jint, jint, jbyteArray, jint); +JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__Ljava_lang_Object_2IILjava_lang_Object_2I + (JNIEnv *, jclass, jobject, jint, jint, jobject, jint); /* * Class: org_xerial_snappy_SnappyNative @@ -50,18 +42,10 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__Ljava_ /* * Class: org_xerial_snappy_SnappyNative * Method: rawUncompress - * Signature: ([BII[BI)I + * Signature: (Ljava/lang/Object;IILjava/lang/Object;I)I */ -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress___3BII_3BI - (JNIEnv *, jclass, jbyteArray, jint, jint, jbyteArray, jint); - -/* - * Class: org_xerial_snappy_SnappyNative - * Method: rawUncompressFloat - * Signature: ([BII[FI)I - */ -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompressFloat - (JNIEnv *, jclass, jbyteArray, jint, jint, jfloatArray, jint); +JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__Ljava_lang_Object_2IILjava_lang_Object_2I + (JNIEnv *, jclass, jobject, jint, jint, jobject, jint); /* * Class: org_xerial_snappy_SnappyNative @@ -82,10 +66,10 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__L /* * Class: org_xerial_snappy_SnappyNative * Method: uncompressedLength - * Signature: ([BII)I + * Signature: (Ljava/lang/Object;II)I */ -JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength___3BII - (JNIEnv *, jclass, jbyteArray, jint, jint); +JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__Ljava_lang_Object_2II + (JNIEnv *, jclass, jobject, jint, jint); /* * Class: org_xerial_snappy_SnappyNative @@ -98,10 +82,10 @@ JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressed /* * Class: org_xerial_snappy_SnappyNative * Method: isValidCompressedBuffer - * Signature: ([BII)Z + * Signature: (Ljava/lang/Object;II)Z */ -JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer___3BII - (JNIEnv *, jclass, jbyteArray, jint, jint); +JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__Ljava_lang_Object_2II + (JNIEnv *, jclass, jobject, jint, jint); #ifdef __cplusplus } diff --git a/src/main/java/org/xerial/snappy/SnappyNative.java b/src/main/java/org/xerial/snappy/SnappyNative.java index 3c58f11..cbe8a14 100755 --- a/src/main/java/org/xerial/snappy/SnappyNative.java +++ b/src/main/java/org/xerial/snappy/SnappyNative.java @@ -35,44 +35,36 @@ import java.nio.ByteBuffer; public class SnappyNative { - public native static String nativeLibraryVersion(); + native static String nativeLibraryVersion(); // ------------------------------------------------------------------------ // Generic compression/decompression routines. // ------------------------------------------------------------------------ - public native static int rawCompress(ByteBuffer input, int inputOffset, int inputLength, ByteBuffer compressed, + native static int rawCompress(ByteBuffer input, int inputOffset, int inputLength, ByteBuffer compressed, int outputOffset) throws SnappyException; - public native static int rawCompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + native static int rawCompress(Object input, int inputOffset, int inputByteLength, Object output, int outputOffset); + + native static int rawUncompress(ByteBuffer compressed, int inputOffset, int inputLength, ByteBuffer uncompressed, + int outputOffset) throws SnappyException; + + native static int rawUncompress(Object input, int inputOffset, int inputLength, Object output, int outputOffset) throws SnappyException; - public native static int rawCompressFloat(float[] input, int inputOffset, int inputLength, byte[] output, - int outputOffset); - - public native static int rawUncompress(ByteBuffer compressed, int inputOffset, int inputLength, - ByteBuffer uncompressed, int outputOffset) throws SnappyException; - - public native static int rawUncompress(byte[] input, int inputOffset, int inputLength, byte[] output, - int outputOffset) throws SnappyException; - - public native static int rawUncompressFloat(byte[] input, int inputOffset, int inputLength, float[] output, - int outputOffset) throws SnappyException; - // Returns the maximal size of the compressed representation of // input data that is "source_bytes" bytes in length; - public native static int maxCompressedLength(int source_bytes); + native static int maxCompressedLength(int source_bytes); // This operation takes O(1) time. - public native static int uncompressedLength(ByteBuffer compressed, int offset, int len) throws SnappyException; + native static int uncompressedLength(ByteBuffer compressed, int offset, int len) throws SnappyException; - public native static int uncompressedLength(byte[] input, int offset, int len) throws SnappyException; + native static int uncompressedLength(Object input, int offset, int len) throws SnappyException; - public native static boolean isValidCompressedBuffer(ByteBuffer compressed, int offset, int len) - throws SnappyException; + native static boolean isValidCompressedBuffer(ByteBuffer compressed, int offset, int len) throws SnappyException; - public native static boolean isValidCompressedBuffer(byte[] input, int offset, int len) throws SnappyException; + native static boolean isValidCompressedBuffer(Object input, int offset, int len) throws SnappyException; - public static void throw_error(int errorCode) throws SnappyException { + protected static void throw_error(int errorCode) throws SnappyException { throw new SnappyException(errorCode); } diff --git a/src/main/resources/org/xerial/snappy/native/Windows/amd64/snappy.dll b/src/main/resources/org/xerial/snappy/native/Windows/amd64/snappy.dll index 3cbef77..d26d978 100755 Binary files a/src/main/resources/org/xerial/snappy/native/Windows/amd64/snappy.dll and b/src/main/resources/org/xerial/snappy/native/Windows/amd64/snappy.dll differ diff --git a/src/test/java/org/xerial/snappy/SnappyTest.java b/src/test/java/org/xerial/snappy/SnappyTest.java index 2ab1cd8..51e6d81 100755 --- a/src/test/java/org/xerial/snappy/SnappyTest.java +++ b/src/test/java/org/xerial/snappy/SnappyTest.java @@ -222,4 +222,20 @@ public class SnappyTest assertArrayEquals(data, result, 0.0f); } + @Test + public void doubleArray() throws Exception { + double[] data = new double[] { 1.0, -0.3, 1.3, 234.4, 34 }; + byte[] compressed = Snappy.compress(data); + double[] result = Snappy.uncompressDouble(compressed); + assertArrayEquals(data, result, 0.0f); + } + + @Test + public void longArray() throws Exception { + long[] data = new long[] { 2, 3, 15, 4234, 43251531412342342L, 23423422342L }; + byte[] compressed = Snappy.compress(data); + long[] result = Snappy.uncompressLong(compressed); + assertArrayEquals(data, result); + } + }