diff --git a/src/main/java/org/xerial/snappy/Snappy.java b/src/main/java/org/xerial/snappy/Snappy.java index 113feb3..8cd4cd7 100755 --- a/src/main/java/org/xerial/snappy/Snappy.java +++ b/src/main/java/org/xerial/snappy/Snappy.java @@ -40,12 +40,14 @@ public class Snappy } /** - * Compress the content of the given input buffer + * Compress the content in the given input buffer. After the compression, + * you can retrieve the compressed data from the output buffer [pos() ... + * limit()) (compressed data size = limit() - pos() = remaining()) * * @param uncompressed - * input is at buffer[pos() ... limit()) + * buffer[pos() ... limit()) containing the input data * @param compressed - * output compressed data to buffer[pos()..] + * output of the compressed data. Uses range [pos()..]. * @return byte size of the compressed data. * * @throws SnappyError @@ -72,13 +74,13 @@ public class Snappy } /** - * Uncompress the content of the input buffer. The result is dumped to the + * Uncompress the content in the input buffer. The result is dumped to the * specified output buffer * * @param compressed - * input is at buffer[pos() ... limit()) + * buffer[pos() ... limit()) containing the input data * @param uncompressed - * output the uncompressed data to buffer[pot()) + * output of the the uncompressed data. It uses buffer[pot()..] * @return uncompressed data size * * @throws SnappyException @@ -106,7 +108,7 @@ public class Snappy } /** - * Get the uncompressed size of the given compressed input + * Get the uncompressed byte size of the given compressed input. * * @param compressed * input data [pos() ... limit()) @@ -124,7 +126,8 @@ public class Snappy } /** - * Get the maximum size of the compressed data of a given byte size + * Get the maximum byte size needed for compressing a data of the given byte + * size. * * @param byteSize * byte size of the data to compress @@ -134,4 +137,14 @@ public class Snappy return SnappyNative.maxCompressedLength(byteSize); } + /** + * Returns true iff the contents of compressed buffer [pos() ... limit()) + * can be uncompressed successfully. Does not return the uncompressed data. + * Takes time proportional to compressed_length, but is usually at least a + * factor of four faster than actual decompression. + */ + public static boolean isValidCompressedBuffer(ByteBuffer compressed) { + return SnappyNative.isValidCompressedBuffer(compressed, compressed.position(), compressed.remaining()); + } + } diff --git a/src/main/java/org/xerial/snappy/SnappyNative.cpp b/src/main/java/org/xerial/snappy/SnappyNative.cpp index 34b004d..a871c53 100755 --- a/src/main/java/org/xerial/snappy/SnappyNative.cpp +++ b/src/main/java/org/xerial/snappy/SnappyNative.cpp @@ -102,4 +102,12 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength return (jint) result; } +JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer + (JNIEnv * env, jclass self, jobject compressed, jint cpos, jint clen) +{ + char* compressedBuffer = (char*) env->GetDirectBufferAddress(compressed) + cpos; + bool ret = snappy::IsValidCompressedBuffer(compressedBuffer, (size_t) clen); + return ret; +} + diff --git a/src/main/java/org/xerial/snappy/SnappyNative.h b/src/main/java/org/xerial/snappy/SnappyNative.h index 96ba375..7044c80 100755 --- a/src/main/java/org/xerial/snappy/SnappyNative.h +++ b/src/main/java/org/xerial/snappy/SnappyNative.h @@ -47,6 +47,14 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_maxCompressedLength JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength (JNIEnv *, jclass, jobject, jint, jint); +/* + * Class: org_xerial_snappy_SnappyNative + * Method: isValidCompressedBuffer + * Signature: (Ljava/nio/ByteBuffer;II)Z + */ +JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer + (JNIEnv *, jclass, jobject, jint, jint); + #ifdef __cplusplus } #endif diff --git a/src/main/java/org/xerial/snappy/SnappyNative.java b/src/main/java/org/xerial/snappy/SnappyNative.java index 95b0821..ee8a565 100755 --- a/src/main/java/org/xerial/snappy/SnappyNative.java +++ b/src/main/java/org/xerial/snappy/SnappyNative.java @@ -56,6 +56,8 @@ public class SnappyNative // This operation takes O(1) time. public native static int uncompressedLength(ByteBuffer compressed, int offset, int len) throws SnappyException; + public native static boolean isValidCompressedBuffer(ByteBuffer compressed, int offset, int len); + public 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 b79c774..310be6c 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 2738c22..2ed60e2 100755 --- a/src/test/java/org/xerial/snappy/SnappyTest.java +++ b/src/test/java/org/xerial/snappy/SnappyTest.java @@ -82,6 +82,8 @@ public class SnappyTest int compressedSize = Snappy.compress(src, compressed); _logger.info("compressed length: " + compressedSize); + assertTrue(Snappy.isValidCompressedBuffer(compressed)); + assertEquals(0, src.position()); assertEquals(orig.length, src.remaining()); assertEquals(orig.length, src.limit()); @@ -123,6 +125,7 @@ public class SnappyTest ByteBuffer compressed = ByteBuffer.allocateDirect(maxCompressedLength + offset2); compressed.position(offset2); Snappy.compress(input, compressed); + assertTrue(Snappy.isValidCompressedBuffer(compressed)); // uncompress final int offset3 = 80;