[Git][java-team/zstd-jni-java][master] 3 commits: New upstream version 1.5.4-2+ds

sun min (@sunmin) gitlab at salsa.debian.org
Wed Mar 22 04:56:02 GMT 2023



sun min pushed to branch master at Debian Java Maintainers / zstd-jni-java


Commits:
4e257179 by sun min at 2023-03-22T12:38:18+08:00
New upstream version 1.5.4-2+ds
- - - - -
356f1cd6 by sun min at 2023-03-22T12:38:18+08:00
Update upstream source from tag 'upstream/1.5.4-2+ds'

Update to upstream version '1.5.4-2+ds'
with Debian dir 42f740154585198bb6cc6c9b28a2bc9808d06b9f
- - - - -
79fc1256 by sun min at 2023-03-22T12:55:09+08:00
Update debian/*.symbols

- - - - -


17 changed files:

- README.md
- build.sbt
- debian/libzstd-jni1.symbols
- + src/main/java/com/github/luben/zstd/BaseZstdBufferDecompressingStreamNoFinalizer.java
- src/main/java/com/github/luben/zstd/Zstd.java
- + src/main/java/com/github/luben/zstd/ZstdBufferDecompressingStream.java
- + src/main/java/com/github/luben/zstd/ZstdBufferDecompressingStreamNoFinalizer.java
- src/main/java/com/github/luben/zstd/ZstdCompressCtx.java
- src/main/java/com/github/luben/zstd/ZstdDecompressCtx.java
- src/main/java/com/github/luben/zstd/ZstdDirectBufferDecompressingStreamNoFinalizer.java
- + src/main/java/com/github/luben/zstd/ZstdFrameProgression.java
- src/main/java/com/github/luben/zstd/util/Native.java
- + src/main/native/jni_bufferdecompress_zstd.c
- src/main/native/jni_directbufferdecompress_zstd.c
- src/main/native/jni_fast_zstd.c
- src/main/native/jni_zstd.c
- version


Changes:

=====================================
README.md
=====================================
@@ -3,9 +3,7 @@ Zstd-jni
 
 [![CI](https://github.com/luben/zstd-jni/workflows/CI/badge.svg)](https://github.com/luben/zstd-jni/actions)
 [![codecov.io](http://codecov.io/github/luben/zstd-jni/coverage.svg?branch=master)](http://codecov.io/github/luben/zstd-jni?branch=master)
-[![Code Quality: C](https://img.shields.io/lgtm/grade/cpp/g/luben/zstd-jni.svg?logo=lgtm&logoWidth=18&label=C)](https://lgtm.com/projects/g/luben/zstd-jni/context:cpp)
-[![Code Quality: Java](https://img.shields.io/lgtm/grade/java/g/luben/zstd-jni.svg?logo=lgtm&logoWidth=18&label=Java)](https://lgtm.com/projects/g/luben/zstd-jni/context:java)
-[![Total Alerts](https://img.shields.io/lgtm/alerts/g/luben/zstd-jni.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/luben/zstd-jni/alerts)
+[![CodeQL](https://github.com/luben/zstd-jni/actions/workflows/codeql-analysis.yml/badge.svg?branch=master)](https://github.com/luben/zstd-jni/actions/workflows/codeql-analysis.yml)
 [![Maven Central](https://img.shields.io/maven-central/v/com.github.luben/zstd-jni.svg?label=Maven%20Central)](https://search.maven.org/artifact/com.github.luben/zstd-jni/)
 [![Javadocs](https://www.javadoc.io/badge/com.github.luben/zstd-jni.svg)](https://www.javadoc.io/doc/com.github.luben/zstd-jni)
 


=====================================
build.sbt
=====================================
@@ -43,7 +43,8 @@ jniNativeClasses := Seq(
   "com.github.luben.zstd.ZstdOutputStreamNoFinalizer",
   "com.github.luben.zstd.ZstdInputStreamNoFinalizer",
   "com.github.luben.zstd.ZstdDirectBufferDecompressingStreamNoFinalizer",
-  "com.github.luben.zstd.ZstdDirectBufferCompressingStreamNoFinalizer"
+  "com.github.luben.zstd.ZstdDirectBufferCompressingStreamNoFinalizer",
+  "com.github.luben.zstd.ZstdBufferDecompressingStreamNoFinalizer"
 )
 
 jniLibSuffix := (System.getProperty("os.name").toLowerCase match {


=====================================
debian/libzstd-jni1.symbols
=====================================
@@ -1,9 +1,15 @@
 libzstd-jni.so.1 libzstd-jni1 #MINVER#
 * Build-Depends-Package: libzstd-jni1
+ Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_createDStreamNative at Base 1.5.4-2
+ Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_decompressStreamNative at Base 1.5.4-2
+ Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_freeDStreamNative at Base 1.5.4-2
+ Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_initDStreamNative at Base 1.5.4-2
+ Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_recommendedDOutSizeNative at Base 1.5.4-2
  Java_com_github_luben_zstd_ZstdCompressCtx_compressByteArray0 at Base 1.5.2-5+ds
  Java_com_github_luben_zstd_ZstdCompressCtx_compressDirectByteBuffer0 at Base 1.5.2-5+ds
  Java_com_github_luben_zstd_ZstdCompressCtx_compressDirectByteBufferStream0 at Base 1.5.2-5+ds
  Java_com_github_luben_zstd_ZstdCompressCtx_free at Base 1.5.2-5+ds
+ Java_com_github_luben_zstd_ZstdCompressCtx_getFrameProgression0 at Base 1.5.4-2
  Java_com_github_luben_zstd_ZstdCompressCtx_init at Base 1.5.2-5+ds
  Java_com_github_luben_zstd_ZstdCompressCtx_loadCDict0 at Base 1.5.2-5+ds
  Java_com_github_luben_zstd_ZstdCompressCtx_loadCDictFast0 at Base 1.5.2-5+ds
@@ -34,11 +40,16 @@ libzstd-jni.so.1 libzstd-jni1 #MINVER#
  Java_com_github_luben_zstd_ZstdDirectBufferCompressingStreamNoFinalizer_initCStreamWithDict at Base 1.5.2-5+ds
  Java_com_github_luben_zstd_ZstdDirectBufferCompressingStreamNoFinalizer_initCStreamWithFastDict at Base 1.5.2-5+ds
  Java_com_github_luben_zstd_ZstdDirectBufferCompressingStreamNoFinalizer_recommendedCOutSize at Base 1.5.2-5+ds
- Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_createDStream at Base 1.5.2-5+ds
- Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_decompressStream at Base 1.5.2-5+ds
- Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_freeDStream at Base 1.5.2-5+ds
- Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_initDStream at Base 1.5.2-5+ds
- Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_recommendedDOutSize at Base 1.5.2-5+ds
+#MISSING: 1.5.4-2# Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_createDStream at Base 1.5.2-5+ds
+ Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_createDStreamNative at Base 1.5.4-2
+#MISSING: 1.5.4-2# Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_decompressStream at Base 1.5.2-5+ds
+ Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_decompressStreamNative at Base 1.5.4-2
+#MISSING: 1.5.4-2# Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_freeDStream at Base 1.5.2-5+ds
+ Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_freeDStreamNative at Base 1.5.4-2
+#MISSING: 1.5.4-2# Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_initDStream at Base 1.5.2-5+ds
+ Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_initDStreamNative at Base 1.5.4-2
+#MISSING: 1.5.4-2# Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_recommendedDOutSize at Base 1.5.2-5+ds
+ Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_recommendedDOutSizeNative at Base 1.5.4-2
  Java_com_github_luben_zstd_ZstdInputStreamNoFinalizer_createDStream at Base 1.5.2-5+ds
  Java_com_github_luben_zstd_ZstdInputStreamNoFinalizer_decompressStream at Base 1.5.2-5+ds
  Java_com_github_luben_zstd_ZstdInputStreamNoFinalizer_freeDStream at Base 1.5.2-5+ds


=====================================
src/main/java/com/github/luben/zstd/BaseZstdBufferDecompressingStreamNoFinalizer.java
=====================================
@@ -0,0 +1,118 @@
+package com.github.luben.zstd;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public abstract class BaseZstdBufferDecompressingStreamNoFinalizer implements Closeable {
+    protected long stream;
+    protected ByteBuffer source;
+    protected boolean closed = false;
+    private boolean finishedFrame = false;
+    private boolean streamEnd = false;
+    private int consumed;
+    private int produced;
+
+    BaseZstdBufferDecompressingStreamNoFinalizer(ByteBuffer source) {
+        this.source = source;
+    }
+
+    /**
+     * Override this method in case the byte buffer passed to the constructor might not contain the full compressed stream
+     *
+     * @param toRefill current buffer
+     * @return either the current buffer (but refilled and flipped if there was new content) or a new buffer.
+     */
+    protected ByteBuffer refill(ByteBuffer toRefill) {
+        return toRefill;
+    }
+
+    public boolean hasRemaining() {
+        return !streamEnd && (source.hasRemaining() || !finishedFrame);
+    }
+
+    public BaseZstdBufferDecompressingStreamNoFinalizer setDict(byte[] dict) throws IOException {
+        long size = Zstd.loadDictDecompress(stream, dict, dict.length);
+        if (Zstd.isError(size)) {
+            throw new ZstdIOException(size);
+        }
+        return this;
+    }
+
+    public BaseZstdBufferDecompressingStreamNoFinalizer setDict(ZstdDictDecompress dict) throws IOException {
+        dict.acquireSharedLock();
+        try {
+            long size = Zstd.loadFastDictDecompress(stream, dict);
+            if (Zstd.isError(size)) {
+                throw new ZstdIOException(size);
+            }
+        } finally {
+            dict.releaseSharedLock();
+        }
+        return this;
+    }
+
+    public BaseZstdBufferDecompressingStreamNoFinalizer setLongMax(int windowLogMax) throws IOException {
+        long size = Zstd.setDecompressionLongMax(stream, windowLogMax);
+        if (Zstd.isError(size)) {
+            throw new ZstdIOException(size);
+        }
+        return this;
+    }
+
+    int readInternal(ByteBuffer target, boolean isDirectBufferRequired) throws IOException {
+        if (closed) {
+            throw new IOException("Stream closed");
+        }
+        if (streamEnd) {
+            return 0;
+        }
+
+        long remaining = decompressStream(stream, target, target.position(), target.remaining(), source, source.position(), source.remaining());
+        if (Zstd.isError(remaining)) {
+            throw new ZstdIOException(remaining);
+        }
+
+        source.position(source.position() + consumed);
+        target.position(target.position() + produced);
+
+        if (!source.hasRemaining()) {
+            source = refill(source);
+            if (!isDirectBufferRequired && source.isDirect()) {
+                throw new IllegalArgumentException("Source buffer should be a non-direct buffer");
+            }
+            if (isDirectBufferRequired && !source.isDirect()) {
+                throw new IllegalArgumentException("Source buffer should be a direct buffer");
+            }
+        }
+
+        finishedFrame = remaining == 0;
+        if (finishedFrame) {
+            // nothing left, so at end of the stream
+            streamEnd = !source.hasRemaining();
+        }
+
+        return produced;
+    }
+
+    @Override
+    public void close() {
+        if (!closed) {
+            try {
+                freeDStream(stream);
+            } finally {
+                closed = true;
+                source = null; // help GC with realizing the buffer can be released
+            }
+        }
+    }
+    public abstract int read(ByteBuffer target) throws IOException;
+
+    abstract long createDStream();
+
+    abstract long freeDStream(long stream);
+
+    abstract long initDStream(long stream);
+
+    abstract long decompressStream(long stream, ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize);
+}


=====================================
src/main/java/com/github/luben/zstd/Zstd.java
=====================================
@@ -604,7 +604,7 @@ public class Zstd {
     public static long decompressedSize(byte[] src, int srcPosition, int srcSize) {
         return decompressedSize(src, srcPosition, srcSize, false);
     }
-    
+
     /**
      * Return the original size of a compressed buffer (if known)
      *
@@ -639,7 +639,7 @@ public class Zstd {
      *         0 if the original size is not known
      */
     public static native long decompressedDirectByteBufferSize(ByteBuffer src, int srcPosition, int srcSize, boolean magicless);
-    
+
     /**
      * Return the original size of a compressed buffer (if known)
      *
@@ -1087,7 +1087,9 @@ public class Zstd {
      * Decompress data
      *
      * @param src the source buffer
-     * @param originalSize the maximum size of the uncompressed data
+     * @param originalSize the maximum size of the uncompressed data.
+     *                  If originaSize is greater than the actuall uncompressed size, additional memory copy going to happen.
+     *                  If originalSize is smaller than the uncompressed size, ZstdExeption will be thrown.
      * @return byte array with the decompressed data
      */
     public static byte[] decompress(byte[] src, int originalSize) {


=====================================
src/main/java/com/github/luben/zstd/ZstdBufferDecompressingStream.java
=====================================
@@ -0,0 +1,87 @@
+package com.github.luben.zstd;
+
+import com.github.luben.zstd.util.Native;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class ZstdBufferDecompressingStream implements Closeable {
+
+    static {
+        Native.load();
+    }
+
+    /**
+     * Override this method in case the byte buffer passed to the constructor might not contain the full compressed stream
+     *
+     * @param toRefill current buffer
+     * @return either the current buffer (but refilled and flipped if there was new content) or a new buffer.
+     */
+    protected ByteBuffer refill(ByteBuffer toRefill) {
+        return toRefill;
+    }
+
+    private final ZstdBufferDecompressingStreamNoFinalizer inner;
+    private boolean finalize = true;
+
+    public ZstdBufferDecompressingStream(ByteBuffer source) {
+        inner = new ZstdBufferDecompressingStreamNoFinalizer(source) {
+            @Override
+            protected ByteBuffer refill(ByteBuffer toRefill) {
+                return ZstdBufferDecompressingStream.this.refill(toRefill);
+            }
+        };
+    }
+
+    /**
+     * Enable or disable class finalizers
+     * <p>
+     * If finalizers are disabled the responsibility fir calling the `close` method is on the consumer.
+     *
+     * @param finalize default `true` - finalizers are enabled
+     */
+    public void setFinalize(boolean finalize) {
+        this.finalize = finalize;
+    }
+
+    public synchronized boolean hasRemaining() {
+        return inner.hasRemaining();
+    }
+
+    public static int recommendedTargetBufferSize() {
+        return ZstdBufferDecompressingStreamNoFinalizer.recommendedTargetBufferSize();
+    }
+
+    public synchronized ZstdBufferDecompressingStream setDict(byte[] dict) throws IOException {
+        inner.setDict(dict);
+        return this;
+    }
+
+    public synchronized ZstdBufferDecompressingStream setDict(ZstdDictDecompress dict) throws IOException {
+        inner.setDict(dict);
+        return this;
+    }
+
+    public ZstdBufferDecompressingStream setLongMax(int windowLogMax) throws IOException {
+        inner.setLongMax(windowLogMax);
+        return this;
+    }
+
+
+    public synchronized int read(ByteBuffer target) throws IOException {
+        return inner.read(target);
+    }
+
+    @Override
+    public synchronized void close() throws IOException {
+        inner.close();
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        if (finalize) {
+            close();
+        }
+    }
+}


=====================================
src/main/java/com/github/luben/zstd/ZstdBufferDecompressingStreamNoFinalizer.java
=====================================
@@ -0,0 +1,66 @@
+package com.github.luben.zstd;
+
+import com.github.luben.zstd.util.Native;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class ZstdBufferDecompressingStreamNoFinalizer extends BaseZstdBufferDecompressingStreamNoFinalizer {
+    static {
+        Native.load();
+    }
+
+    public ZstdBufferDecompressingStreamNoFinalizer(ByteBuffer source) {
+        super(source);
+        if (source.isDirect()) {
+            throw new IllegalArgumentException("Source buffer should be a non-direct buffer");
+        }
+        stream = createDStreamNative();
+        initDStreamNative(stream);
+    }
+
+    @Override
+    public int read(ByteBuffer target) throws IOException {
+        if (target.isDirect()) {
+            throw new IllegalArgumentException("Target buffer should be a non-direct buffer");
+        }
+        return readInternal(target, false);
+    }
+
+    @Override
+    long createDStream() {
+        return createDStreamNative();
+    }
+
+    @Override
+    long freeDStream(long stream) {
+        return freeDStreamNative(stream);
+    }
+
+    @Override
+    long initDStream(long stream) {
+        return initDStreamNative(stream);
+    }
+
+    @Override
+    long decompressStream(long stream, ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize) {
+        byte[] targetArr = Zstd.extractArray(dst);
+        byte[] sourceArr = Zstd.extractArray(source);
+
+        return decompressStreamNative(stream, targetArr, dstOffset, dstSize, sourceArr, srcOffset, srcSize);
+    }
+
+    public static int recommendedTargetBufferSize() {
+        return (int) recommendedDOutSizeNative();
+    }
+
+    private native long createDStreamNative();
+
+    private native long freeDStreamNative(long stream);
+
+    private native long initDStreamNative(long stream);
+
+    private native long decompressStreamNative(long stream, byte[] dst, int dstOffset, int dstSize, byte[] src, int srcOffset, int srcSize);
+
+    private static native long recommendedDOutSizeNative();
+}


=====================================
src/main/java/com/github/luben/zstd/ZstdCompressCtx.java
=====================================
@@ -16,76 +16,77 @@ public class ZstdCompressCtx extends AutoCloseBase {
 
     private ZstdDictCompress compression_dict = null;
 
-    private native void init();
+    private static native long init();
 
-    private native void free();
+    private static native void free(long ptr);
 
     /**
      * Create a context for faster compress operations
      * One such context is required for each thread - put this in a ThreadLocal.
      */
     public ZstdCompressCtx() {
-        init();
+        nativePtr = init();
         if (0 == nativePtr) {
             throw new IllegalStateException("ZSTD_createCompressCtx failed");
         }
         storeFence();
     }
 
-    void  doClose() {
+    void doClose() {
         if (nativePtr != 0) {
-            free();
+            free(nativePtr);
             nativePtr = 0;
         }
     }
 
+    private void ensureOpen() {
+        if (nativePtr == 0) {
+            throw new IllegalStateException("Compression context is closed");
+        }
+    }
+
     /**
      * Set compression level
      * @param level compression level, default: {@link Zstd#defaultCompressionLevel()}
      */
     public ZstdCompressCtx setLevel(int level) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
-        setLevel0(level);
+        setLevel0(nativePtr, level);
         releaseSharedLock();
         return this;
     }
 
-    private native void setLevel0(int level);
+    private static native void setLevel0(long ptr, int level);
 
     /**
      * Enable or disable magicless frames
      * @param magiclessFlag A 32-bits magic number is written at start of frame, default: false
      */
     public ZstdCompressCtx setMagicless(boolean magiclessFlag) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
         Zstd.setCompressionMagicless(nativePtr, magiclessFlag);
         releaseSharedLock();
         return this;
     }
-    
+
     /**
      * Enable or disable compression checksums
      * @param checksumFlag A 32-bits checksum of content is written at end of frame, default: false
      */
     public ZstdCompressCtx setChecksum(boolean checksumFlag) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
-        setChecksum0(checksumFlag);
+        setChecksum0(nativePtr, checksumFlag);
         releaseSharedLock();
         return this;
     }
-    private native void setChecksum0(boolean checksumFlag);
+    private static native void setChecksum0(long ptr, boolean checksumFlag);
 
 
     public ZstdCompressCtx setWorkers(int workers) {
+        ensureOpen();
         acquireSharedLock();
         Zstd.setCompressionWorkers(nativePtr, workers);
         releaseSharedLock();
@@ -97,30 +98,26 @@ public class ZstdCompressCtx extends AutoCloseBase {
      * @param contentSizeFlag Content size will be written into frame header _whenever known_, default: true
      */
     public ZstdCompressCtx setContentSize(boolean contentSizeFlag) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
-        setContentSize0(contentSizeFlag);
+        setContentSize0(nativePtr, contentSizeFlag);
         releaseSharedLock();
         return this;
     }
-    private native void setContentSize0(boolean contentSizeFlag);
+    private static native void setContentSize0(long ptr, boolean contentSizeFlag);
 
     /**
      * Enable or disable dictID
      * @param dictIDFlag When applicable, dictionary's ID is written into frame header, default: true
      */
     public ZstdCompressCtx setDictID(boolean dictIDFlag) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
-        setDictID0(dictIDFlag);
+        setDictID0(nativePtr, dictIDFlag);
         releaseSharedLock();
         return this;
     }
-    private native void setDictID0(boolean dictIDFlag);
+    private static native void setDictID0(long ptr, boolean dictIDFlag);
 
     /**
      * Enable or disable LongDistanceMatching and set the window size
@@ -132,9 +129,7 @@ public class ZstdCompressCtx extends AutoCloseBase {
      *                  0 disables LDM.
      */
     public ZstdCompressCtx setLong(int windowLog) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
         Zstd.setCompressionLong(nativePtr, windowLog);
         releaseSharedLock();
@@ -147,14 +142,11 @@ public class ZstdCompressCtx extends AutoCloseBase {
      * @param dict the dictionary or `null` to remove loaded dictionary
      */
     public ZstdCompressCtx loadDict(ZstdDictCompress dict) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
-
+        ensureOpen();
         acquireSharedLock();
         dict.acquireSharedLock();
         try {
-            long result = loadCDictFast0(dict);
+            long result = loadCDictFast0(nativePtr, dict);
             if (Zstd.isError(result)) {
                 throw new ZstdException(result);
             }
@@ -166,7 +158,7 @@ public class ZstdCompressCtx extends AutoCloseBase {
         }
         return this;
     }
-    private native long loadCDictFast0(ZstdDictCompress dict);
+    private native long loadCDictFast0(long ptr, ZstdDictCompress dict);
 
     /**
      * Load compression dictionary to be used for subsequently compressed frames.
@@ -174,12 +166,10 @@ public class ZstdCompressCtx extends AutoCloseBase {
      * @param dict the dictionary or `null` to remove loaded dictionary
      */
     public ZstdCompressCtx loadDict(byte[] dict) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
         try {
-            long result = loadCDict0(dict);
+            long result = loadCDict0(nativePtr, dict);
             if (Zstd.isError(result)) {
                 throw new ZstdException(result);
             }
@@ -189,13 +179,17 @@ public class ZstdCompressCtx extends AutoCloseBase {
         }
         return this;
     }
-    private native long loadCDict0(byte[] dict);
+    private native long loadCDict0(long ptr, byte[] dict);
 
-    private void ensureOpen() {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+    /**
+     * Tells how much data has been ingested (read from input),
+     * consumed (input actually compressed) and produced (output) for current frame.
+     */
+    public ZstdFrameProgression getFrameProgression() {
+        ensureOpen();
+        return getFrameProgression0(nativePtr);
     }
+    private static native ZstdFrameProgression getFrameProgression0(long ptr);
 
     /**
      * Clear all state and parameters from the compression context. This leaves the object in a
@@ -203,12 +197,12 @@ public class ZstdCompressCtx extends AutoCloseBase {
      */
     public void reset() {
         ensureOpen();
-        long result = reset0();
+        long result = reset0(nativePtr);
         if (Zstd.isError(result)) {
             throw new ZstdException(result);
         }
     }
-    private native long reset0();
+    private static native long reset0(long ptr);
 
     /**
      * Promise to compress a certain number of source bytes. Knowing the number of bytes to compress
@@ -220,12 +214,12 @@ public class ZstdCompressCtx extends AutoCloseBase {
      */
     public void setPledgedSrcSize(long srcSize) {
         ensureOpen();
-        long result = setPledgedSrcSize0(srcSize);
+        long result = setPledgedSrcSize0(nativePtr, srcSize);
         if (Zstd.isError(result)) {
             throw new ZstdException(result);
         }
     }
-    private native long setPledgedSrcSize0(long srcSize);
+    private static native long setPledgedSrcSize0(long ptr, long srcSize);
 
     /**
      * Compress as much of the <code>src</code> {@link ByteBuffer} into the <code>dst</code> {@link
@@ -238,7 +232,7 @@ public class ZstdCompressCtx extends AutoCloseBase {
      */
     public boolean compressDirectByteBufferStream(ByteBuffer dst, ByteBuffer src, EndDirective endOp) {
         ensureOpen();
-        long result = compressDirectByteBufferStream0(dst, dst.position(), dst.limit(), src, src.position(), src.limit(), endOp.value());
+        long result = compressDirectByteBufferStream0(nativePtr, dst, dst.position(), dst.limit(), src, src.position(), src.limit(), endOp.value());
         if ((result & 0x80000000L) != 0) {
             long code = result & 0xFF;
             throw new ZstdException(code, Zstd.getErrorName(code));
@@ -255,7 +249,7 @@ public class ZstdCompressCtx extends AutoCloseBase {
      * bit is set if an error occurred. If an error occurred, the lowest 31 bits encode a zstd error
      * code. Otherwise, the lowest 31 bits are the new position of the source buffer.
      */
-    private native long compressDirectByteBufferStream0(ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcSize, int srcOffset, int endOp);
+    private static native long compressDirectByteBufferStream0(long ptr, ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcSize, int srcOffset, int endOp);
 
     /**
      * Compresses buffer 'srcBuff' into buffer 'dstBuff' reusing this ZstdCompressCtx.
@@ -274,9 +268,7 @@ public class ZstdCompressCtx extends AutoCloseBase {
      * @return  the number of bytes written into buffer 'dstBuff'.
      */
     public int compressDirectByteBuffer(ByteBuffer dstBuff, int dstOffset, int dstSize, ByteBuffer srcBuff, int srcOffset, int srcSize) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         if (!srcBuff.isDirect()) {
             throw new IllegalArgumentException("srcBuff must be a direct buffer");
         }
@@ -287,7 +279,7 @@ public class ZstdCompressCtx extends AutoCloseBase {
         acquireSharedLock();
 
         try {
-            long size = compressDirectByteBuffer0(dstBuff, dstOffset, dstSize, srcBuff, srcOffset, srcSize);
+            long size = compressDirectByteBuffer0(nativePtr, dstBuff, dstOffset, dstSize, srcBuff, srcOffset, srcSize);
             if (Zstd.isError(size)) {
                 throw new ZstdException(size);
             }
@@ -300,7 +292,7 @@ public class ZstdCompressCtx extends AutoCloseBase {
         }
     }
 
-    private native long compressDirectByteBuffer0(ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize);
+    private static native long compressDirectByteBuffer0(long ptr, ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize);
 
     /**
      * Compresses byte array 'srcBuff' into byte array 'dstBuff' reusing this ZstdCompressCtx.
@@ -318,14 +310,11 @@ public class ZstdCompressCtx extends AutoCloseBase {
      * @return  the number of bytes written into buffer 'dstBuff'.
      */
     public int compressByteArray(byte[] dstBuff, int dstOffset, int dstSize, byte[] srcBuff, int srcOffset, int srcSize) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
-
+        ensureOpen();
         acquireSharedLock();
 
         try {
-            long size = compressByteArray0(dstBuff, dstOffset, dstSize, srcBuff, srcOffset, srcSize);
+            long size = compressByteArray0(nativePtr, dstBuff, dstOffset, dstSize, srcBuff, srcOffset, srcSize);
             if (Zstd.isError(size)) {
                 throw new ZstdException(size);
             }
@@ -338,7 +327,7 @@ public class ZstdCompressCtx extends AutoCloseBase {
         }
     }
 
-    private native long compressByteArray0(byte[] dst, int dstOffset, int dstSize, byte[] src, int srcOffset, int srcSize);
+    private static native long compressByteArray0(long ptr, byte[] dst, int dstOffset, int dstSize, byte[] src, int srcOffset, int srcSize);
 
     /* Convenience methods */
 


=====================================
src/main/java/com/github/luben/zstd/ZstdDecompressCtx.java
=====================================
@@ -15,16 +15,16 @@ public class ZstdDecompressCtx extends AutoCloseBase {
     private long nativePtr = 0;
     private ZstdDictDecompress decompression_dict = null;
 
-    private native void init();
+    private static native long init();
 
-    private native void free();
+    private static native void free(long nativePtr);
 
     /**
      * Create a context for faster compress operations
      * One such context is required for each thread - put this in a ThreadLocal.
      */
     public ZstdDecompressCtx() {
-        init();
+        nativePtr = init();
         if (0 == nativePtr) {
             throw new IllegalStateException("ZSTD_createDeCompressCtx failed");
         }
@@ -33,7 +33,7 @@ public class ZstdDecompressCtx extends AutoCloseBase {
 
     void doClose() {
         if (nativePtr != 0) {
-            free();
+            free(nativePtr);
             nativePtr = 0;
         }
     }
@@ -43,28 +43,24 @@ public class ZstdDecompressCtx extends AutoCloseBase {
      * @param magiclessFlag A 32-bits checksum of content is written at end of frame, default: false
      */
     public ZstdDecompressCtx setMagicless(boolean magiclessFlag) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
         Zstd.setDecompressionMagicless(nativePtr, magiclessFlag);
         releaseSharedLock();
         return this;
     }
-    
+
     /**
      * Load decompression dictionary
      *
      * @param dict the dictionary or `null` to remove loaded dictionary
      */
     public ZstdDecompressCtx loadDict(ZstdDictDecompress dict) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Decompression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
         dict.acquireSharedLock();
         try {
-            long result = loadDDictFast0(dict);
+            long result = loadDDictFast0(nativePtr, dict);
             if (Zstd.isError(result)) {
                 throw new ZstdException(result);
             }
@@ -76,7 +72,7 @@ public class ZstdDecompressCtx extends AutoCloseBase {
         }
         return this;
     }
-    private native long loadDDictFast0(ZstdDictDecompress dict);
+    private static native long loadDDictFast0(long nativePtr, ZstdDictDecompress dict);
 
     /**
      * Load decompression dictionary.
@@ -84,12 +80,10 @@ public class ZstdDecompressCtx extends AutoCloseBase {
      * @param dict the dictionary or `null` to remove loaded dictionary
      */
     public ZstdDecompressCtx loadDict(byte[] dict) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Compression context is closed");
-        }
+        ensureOpen();
         acquireSharedLock();
         try {
-            long result = loadDDict0(dict);
+            long result = loadDDict0(nativePtr, dict);
             if (Zstd.isError(result)) {
                 throw new ZstdException(result);
             }
@@ -99,7 +93,7 @@ public class ZstdDecompressCtx extends AutoCloseBase {
         }
         return this;
     }
-    private native long loadDDict0(byte[] dict);
+    private static native long loadDDict0(long nativePtr, byte[] dict);
 
     /**
      * Clear all state and parameters from the decompression context. This leaves the object in a
@@ -107,9 +101,9 @@ public class ZstdDecompressCtx extends AutoCloseBase {
      */
     public void reset() {
         ensureOpen();
-        reset0();
+        reset0(nativePtr);
     }
-    private native void reset0();
+    private static native void reset0(long nativePtr);
 
     private void ensureOpen() {
         if (nativePtr == 0) {
@@ -127,7 +121,7 @@ public class ZstdDecompressCtx extends AutoCloseBase {
      */
     public boolean decompressDirectByteBufferStream(ByteBuffer dst, ByteBuffer src) {
         ensureOpen();
-        long result = decompressDirectByteBufferStream0(dst, dst.position(), dst.limit(), src, src.position(), src.limit());
+        long result = decompressDirectByteBufferStream0(nativePtr, dst, dst.position(), dst.limit(), src, src.position(), src.limit());
         if ((result & 0x80000000L) != 0) {
             long code = result & 0xFF;
             throw new ZstdException(code, Zstd.getErrorName(code));
@@ -144,7 +138,7 @@ public class ZstdDecompressCtx extends AutoCloseBase {
      * bit is set if an error occurred. If an error occurred, the lowest 31 bits encode a zstd error
      * code. Otherwise, the lowest 31 bits are the new position of the source buffer.
      */
-    private native long decompressDirectByteBufferStream0(ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize);
+    private static native long decompressDirectByteBufferStream0(long nativePtr, ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize);
 
     /**
      * Decompresses buffer 'srcBuff' into buffer 'dstBuff' using this ZstdDecompressCtx.
@@ -162,9 +156,7 @@ public class ZstdDecompressCtx extends AutoCloseBase {
      * @return the number of bytes decompressed into destination buffer (originalSize)
      */
     public int decompressDirectByteBuffer(ByteBuffer dstBuff, int dstOffset, int dstSize, ByteBuffer srcBuff, int srcOffset, int srcSize) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Decompression context is closed");
-        }
+        ensureOpen();
         if (!srcBuff.isDirect()) {
             throw new IllegalArgumentException("srcBuff must be a direct buffer");
         }
@@ -175,7 +167,7 @@ public class ZstdDecompressCtx extends AutoCloseBase {
         acquireSharedLock();
 
         try {
-            long size = decompressDirectByteBuffer0(dstBuff, dstOffset, dstSize, srcBuff, srcOffset, srcSize);
+            long size = decompressDirectByteBuffer0(nativePtr, dstBuff, dstOffset, dstSize, srcBuff, srcOffset, srcSize);
             if (Zstd.isError(size)) {
                 throw new ZstdException(size);
             }
@@ -188,7 +180,7 @@ public class ZstdDecompressCtx extends AutoCloseBase {
         }
     }
 
-    private native long decompressDirectByteBuffer0(ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize);
+    private static native long decompressDirectByteBuffer0(long nativePtr, ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize);
 
     /**
      * Decompresses byte array 'srcBuff' into byte array 'dstBuff' using this ZstdDecompressCtx.
@@ -204,14 +196,11 @@ public class ZstdDecompressCtx extends AutoCloseBase {
      * @return the number of bytes decompressed into destination buffer (originalSize)
      */
     public int decompressByteArray(byte[] dstBuff, int dstOffset, int dstSize, byte[] srcBuff, int srcOffset, int srcSize) {
-        if (nativePtr == 0) {
-            throw new IllegalStateException("Decompression context is closed");
-        }
-
+        ensureOpen();
         acquireSharedLock();
 
         try {
-            long size = decompressByteArray0(dstBuff, dstOffset, dstSize, srcBuff, srcOffset, srcSize);
+            long size = decompressByteArray0(nativePtr, dstBuff, dstOffset, dstSize, srcBuff, srcOffset, srcSize);
             if (Zstd.isError(size)) {
                 throw new ZstdException(size);
             }
@@ -224,7 +213,7 @@ public class ZstdDecompressCtx extends AutoCloseBase {
         }
     }
 
-    private native long decompressByteArray0(byte[] dst, int dstOffset, int dstSize, byte[] src, int srcOffset, int srcSize);
+    private static native long decompressByteArray0(long nativePtr, byte[] dst, int dstOffset, int dstSize, byte[] src, int srcOffset, int srcSize);
 
     /* Covenience methods */
 
@@ -273,7 +262,19 @@ public class ZstdDecompressCtx extends AutoCloseBase {
         return decompressByteArray(dst, 0, dst.length, src, 0, src.length);
     }
 
+    /**
+    * Decompress data
+    *
+    * @param src the source buffer
+    * @param originalSize the maximum size of the uncompressed data.
+    *                  If originaSize is greater than the actuall uncompressed size, additional memory copy going to happen.
+    *                  If originalSize is smaller than the uncompressed size, ZstdExeption will be thrown.
+    * @return byte array with the decompressed data
+    */
     public byte[] decompress(byte[] src, int originalSize) throws ZstdException {
+        if (originalSize < 0) {
+            throw new ZstdException(Zstd.errGeneric(), "Original size should not be negative");
+        }
         byte[] dst = new byte[originalSize];
         int size = decompress(dst, src);
         if (size != originalSize) {


=====================================
src/main/java/com/github/luben/zstd/ZstdDirectBufferDecompressingStreamNoFinalizer.java
=====================================
@@ -2,131 +2,63 @@ package com.github.luben.zstd;
 
 import com.github.luben.zstd.util.Native;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 
-public class ZstdDirectBufferDecompressingStreamNoFinalizer implements Closeable {
-
+public class ZstdDirectBufferDecompressingStreamNoFinalizer extends BaseZstdBufferDecompressingStreamNoFinalizer {
     static {
         Native.load();
     }
 
-    /**
-     * Override this method in case the byte buffer passed to the constructor might not contain the full compressed stream
-     * @param toRefill current buffer
-     * @return either the current buffer (but refilled and flipped if there was new content) or a new buffer.
-     */
-    protected ByteBuffer refill(ByteBuffer toRefill) {
-        return toRefill;
-    }
-
-    private ByteBuffer source;
-    private final long stream;
-    private boolean finishedFrame = false;
-    private boolean closed = false;
-    private boolean streamEnd = false;
-
-    private static native long recommendedDOutSize();
-    private static native long createDStream();
-    private static native long freeDStream(long stream);
-    private native long initDStream(long stream);
-    private native long decompressStream(long stream, ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize);
-
     public ZstdDirectBufferDecompressingStreamNoFinalizer(ByteBuffer source) {
+        super(source);
         if (!source.isDirect()) {
             throw new IllegalArgumentException("Source buffer should be a direct buffer");
         }
         this.source = source;
-        stream = createDStream();
-        initDStream(stream);
+        stream = createDStreamNative();
+        initDStreamNative(stream);
     }
 
-    public boolean hasRemaining() {
-        return !streamEnd && (source.hasRemaining() || !finishedFrame);
+    @Override
+    public int read(ByteBuffer target) throws IOException {
+        if (!target.isDirect()) {
+            throw new IllegalArgumentException("Target buffer should be a direct buffer");
+        }
+        return readInternal(target, true);
     }
 
-    public static int recommendedTargetBufferSize() {
-        return (int) recommendedDOutSize();
+    @Override
+    long createDStream() {
+        return createDStreamNative();
     }
 
-    public ZstdDirectBufferDecompressingStreamNoFinalizer setDict(byte[] dict) throws IOException {
-        long size = Zstd.loadDictDecompress(stream, dict, dict.length);
-        if (Zstd.isError(size)) {
-            throw new ZstdIOException(size);
-        }
-        return this;
+    @Override
+    long freeDStream(long stream) {
+        return freeDStreamNative(stream);
     }
 
-    public ZstdDirectBufferDecompressingStreamNoFinalizer setDict(ZstdDictDecompress dict) throws IOException {
-        dict.acquireSharedLock();
-        try {
-            long size = Zstd.loadFastDictDecompress(stream, dict);
-            if (Zstd.isError(size)) {
-                throw new ZstdIOException(size);
-            }
-        } finally {
-            dict.releaseSharedLock();
-        }
-        return this;
+    @Override
+    long initDStream(long stream) {
+        return initDStreamNative(stream);
     }
 
-    public ZstdDirectBufferDecompressingStreamNoFinalizer setLongMax(int windowLogMax) throws IOException {
-        long size = Zstd.setDecompressionLongMax(stream, windowLogMax);
-        if (Zstd.isError(size)) {
-            throw new ZstdIOException(size);
-        }
-        return this;
+    @Override
+    long decompressStream(long stream, ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize) {
+        return decompressStreamNative(stream, dst, dstOffset, dstSize, src, srcOffset, srcSize);
     }
 
-    private int consumed;
-    private int produced;
-    public int read(ByteBuffer target) throws IOException {
-        if (!target.isDirect()) {
-            throw new IllegalArgumentException("Target buffer should be a direct buffer");
-        }
-        if (closed) {
-            throw new IOException("Stream closed");
-        }
-        if (streamEnd) {
-            return 0;
-        }
-
-        long remaining = decompressStream(stream, target, target.position(), target.remaining(), source, source.position(), source.remaining());
-        if (Zstd.isError(remaining)) {
-            throw new ZstdIOException(remaining);
-        }
-
-        source.position(source.position() + consumed);
-        target.position(target.position() + produced);
+    public static int recommendedTargetBufferSize() {
+        return (int) recommendedDOutSizeNative();
+    }
 
-        if (!source.hasRemaining()) {
-            source = refill(source);
-            if (!source.isDirect()) {
-                throw new IllegalArgumentException("Source buffer should be a direct buffer");
-            }
-        }
+    private static native long createDStreamNative();
 
-        finishedFrame = remaining == 0;
-        if (finishedFrame) {
-            // nothing left, so at end of the stream
-            streamEnd = !source.hasRemaining();
-        }
+    private static native long freeDStreamNative(long stream);
 
-        return produced;
-    }
+    private native long initDStreamNative(long stream);
 
+    private native long decompressStreamNative(long stream, ByteBuffer dst, int dstOffset, int dstSize, ByteBuffer src, int srcOffset, int srcSize);
 
-    @Override
-    public void close() {
-        if (!closed) {
-            try {
-                freeDStream(stream);
-            }
-            finally {
-                closed = true;
-                source = null; // help GC with realizing the buffer can be released
-            }
-        }
-    }
+    private static native long recommendedDOutSizeNative();
 }


=====================================
src/main/java/com/github/luben/zstd/ZstdFrameProgression.java
=====================================
@@ -0,0 +1,65 @@
+package com.github.luben.zstd;
+
+public class ZstdFrameProgression {
+
+    private long ingested;
+    private long consumed;
+    private long produced;
+    private long flushed;
+    private int currentJobID;
+    private int nbActiveWorkers;
+
+    public ZstdFrameProgression(long ingested, long consumed, long produced, long flushed, int currentJobID,
+            int nbActiveWorkers) {
+        this.ingested = ingested;
+        this.consumed = consumed;
+        this.produced = produced;
+        this.flushed = flushed;
+        this.currentJobID = currentJobID;
+        this.nbActiveWorkers = nbActiveWorkers;
+    }
+
+    /**
+     * The number of input bytes read and buffered.
+     */
+    public long getIngested() {
+        return ingested;
+    }
+
+    /**
+     * The number of input bytes actually compressed.
+     * Note: ingested - consumed = amount of input data buffered internally, not yet compressed.
+     */
+    public long getConsumed() {
+        return consumed;
+    }
+
+    /**
+     * The number of compressed bytes generated and buffered.
+     */
+    public long getProduced() {
+        return produced;
+    }
+
+    /**
+     * The number of compressed bytes flushed.
+     */
+    public long getFlushed() {
+        return flushed;
+    }
+
+    /**
+     * The last started job number. Only applicable if multi-threading is enabled.
+     */
+    public int getCurrentJobID() {
+        return currentJobID;
+    }
+
+    /**
+     * The number of workers actively compressing. Only applicable if multi-threading is enabled.
+     */
+    public int getNbActiveWorkers() {
+        return nbActiveWorkers;
+    }
+
+}


=====================================
src/main/java/com/github/luben/zstd/util/Native.java
=====================================
@@ -5,6 +5,8 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.UnsatisfiedLinkError;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 public enum Native {
     ;
@@ -61,6 +63,24 @@ public enum Native {
         return loaded;
     }
 
+    private static void loadLibrary(final String libName) {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+          public Void run() {
+            System.loadLibrary(libName);
+            return null;
+          }
+        });
+    }
+
+    private static void loadLibraryFile(final String libFileName) {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+          public Void run() {
+            System.load(libFileName);
+            return null;
+          }
+        });
+    }
+
     public static synchronized void load() {
         load(null);
     }
@@ -74,7 +94,7 @@ public enum Native {
         String overridePath = System.getProperty(nativePathOverride);
         if (overridePath != null) {
             // Do not fall back to auto-discovery - consumers know better
-            System.load(overridePath);
+            loadLibraryFile(overridePath);
             loaded = true;
             return;
         }
@@ -82,7 +102,7 @@ public enum Native {
         // try to load the shared library directly from the JAR
         try {
             Class.forName("org.osgi.framework.BundleEvent"); // Simple OSGI env. check
-            System.loadLibrary(libname);
+            loadLibrary(libname);
             loaded = true;
             return;
         } catch (Throwable e) {
@@ -94,7 +114,7 @@ public enum Native {
             // fallback to loading the zstd-jni from the system library path.
             // It also covers loading on Android.
             try {
-                System.loadLibrary(libnameShort);
+                loadLibrary(libnameShort);
                 loaded = true;
                 return;
             } catch (UnsatisfiedLinkError e) {
@@ -127,11 +147,11 @@ public enum Native {
                 // ignore
             }
             try {
-                System.load(tempLib.getAbsolutePath());
+                loadLibraryFile(tempLib.getAbsolutePath());
             } catch (UnsatisfiedLinkError e) {
                 // fall-back to loading the zstd-jni from the system library path
                 try {
-                    System.loadLibrary(libnameShort);
+                    loadLibrary(libnameShort);
                 } catch (UnsatisfiedLinkError e1) {
                     // display error in case problem with loading from temp folder
                     // and from system library path - concatenate both messages


=====================================
src/main/native/jni_bufferdecompress_zstd.c
=====================================
@@ -0,0 +1,86 @@
+#include <jni.h>
+#include <zstd.h>
+#include <zstd_errors.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+/* field IDs can't change in the same VM */
+static jfieldID consumed_id;
+static jfieldID produced_id;
+
+/*
+ * Class:     com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer
+ * Method:    recommendedDOutSizeNative
+ */
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_recommendedDOutSizeNative
+  (JNIEnv *env, jclass obj) {
+    return ZSTD_DStreamOutSize();
+}
+
+/*
+ * Class:     com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer
+ * Method:    createDStreamNative
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_createDStreamNative
+  (JNIEnv *env, jclass obj) {
+    return (jlong)(intptr_t) ZSTD_createDStream();
+}
+
+/*
+ * Class:     com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer
+ * Method:    freeDStreamNative
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_freeDStreamNative
+  (JNIEnv *env, jclass obj, jlong stream) {
+    return ZSTD_freeDCtx((ZSTD_DCtx *)(intptr_t) stream);
+}
+
+/*
+ * Class:     com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer
+ * Method:    initDStreamNative
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_initDStreamNative
+  (JNIEnv *env, jclass obj, jlong stream) {
+    jclass clazz = (*env)->GetObjectClass(env, obj);
+    consumed_id = (*env)->GetFieldID(env, clazz, "consumed", "I");
+    produced_id = (*env)->GetFieldID(env, clazz, "produced", "I");
+    return ZSTD_initDStream((ZSTD_DCtx *)(intptr_t) stream);
+}
+
+/*
+ * Class:     com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer
+ * Method:    decompressStreamNative
+ * Signature: (JLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)I
+ */
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdBufferDecompressingStreamNoFinalizer_decompressStreamNative
+  (JNIEnv *env, jclass obj, jlong stream, jbyteArray dst, jint dst_offset, jint dst_size, jbyteArray src, jint src_offset, jint src_size) {
+    // input validation
+    if (NULL == dst) return -ZSTD_error_dstSize_tooSmall;
+    if (NULL == src) return -ZSTD_error_srcSize_wrong;
+    if (0 > dst_offset) return -ZSTD_error_dstSize_tooSmall;
+    if (0 > src_offset) return -ZSTD_error_srcSize_wrong;
+    if (0 > src_size) return -ZSTD_error_srcSize_wrong;
+    if (0 > dst_size) return -ZSTD_error_dstSize_tooSmall;
+    if (src_offset + src_size > (*env)->GetArrayLength(env, src)) return -ZSTD_error_srcSize_wrong;
+    if (dst_offset + dst_size > (*env)->GetArrayLength(env, dst)) return -ZSTD_error_dstSize_tooSmall;
+
+    size_t size = -ZSTD_error_memory_allocation;
+    char *dst_buf_ptr = (char*)(*env)->GetPrimitiveArrayCritical(env, dst, NULL);
+    if (dst_buf_ptr == NULL) goto E1;
+    char *src_buf_ptr = (char*)(*env)->GetPrimitiveArrayCritical(env, src, NULL);
+    if (src_buf_ptr == NULL) goto E2;
+
+    ZSTD_outBuffer output = { dst_buf_ptr + dst_offset, dst_size, 0};
+    ZSTD_inBuffer input = { src_buf_ptr + src_offset, src_size, 0};
+
+    size = ZSTD_decompressStream((ZSTD_DCtx *)(intptr_t) stream, &output, &input);
+
+    (*env)->ReleasePrimitiveArrayCritical(env, src, src_buf_ptr, JNI_ABORT);
+E2: (*env)->ReleasePrimitiveArrayCritical(env, dst, dst_buf_ptr, 0);
+    (*env)->SetIntField(env, obj, consumed_id, input.pos);
+    (*env)->SetIntField(env, obj, produced_id, output.pos);
+E1: return size;
+}


=====================================
src/main/native/jni_directbufferdecompress_zstd.c
=====================================
@@ -10,39 +10,39 @@ static jfieldID produced_id;
 
 /*
  * Class:     com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer
- * Method:    recommendedDOutSize
+ * Method:    recommendedDOutSizeNative
  */
-JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_recommendedDOutSize
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_recommendedDOutSizeNative
   (JNIEnv *env, jclass obj) {
     return ZSTD_DStreamOutSize();
 }
 
 /*
  * Class:     com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer
- * Method:    createDStream
+ * Method:    createDStreamNative
  * Signature: ()J
  */
-JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_createDStream
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_createDStreamNative
   (JNIEnv *env, jclass obj) {
     return (jlong)(intptr_t) ZSTD_createDStream();
 }
 
 /*
  * Class:     com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer
- * Method:    freeDStream
+ * Method:    freeDStreamNative
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_freeDStream
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_freeDStreamNative
   (JNIEnv *env, jclass obj, jlong stream) {
     return ZSTD_freeDCtx((ZSTD_DCtx *)(intptr_t) stream);
 }
 
 /*
  * Class:     com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer
- * Method:    initDStream
+ * Method:    initDStreamNative
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_initDStream
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_initDStreamNative
   (JNIEnv *env, jclass obj, jlong stream) {
     jclass clazz = (*env)->GetObjectClass(env, obj);
     consumed_id = (*env)->GetFieldID(env, clazz, "consumed", "I");
@@ -52,10 +52,10 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressing
 
 /*
  * Class:     com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer
- * Method:    decompressStream
+ * Method:    decompressStreamNative
  * Signature: (JLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)I
  */
-JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_decompressStream
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDirectBufferDecompressingStreamNoFinalizer_decompressStreamNative
   (JNIEnv *env, jclass obj, jlong stream, jobject dst_buf, jint dst_offset, jint dst_size, jobject src_buf, jint src_offset, jint src_size) {
     size_t size = -ZSTD_error_memory_allocation;
 


=====================================
src/main/native/jni_fast_zstd.c
=====================================
@@ -1,3 +1,6 @@
+#ifndef ZSTD_STATIC_LINKING_ONLY
+#define ZSTD_STATIC_LINKING_ONLY
+#endif
 #include <jni.h>
 #include <zstd.h>
 #include <zstd_errors.h>
@@ -6,9 +9,6 @@
 // They can't change in the same VM
 static jfieldID compress_dict = 0;
 static jfieldID decompress_dict = 0;
-static jfieldID compress_ctx_nativePtr = 0;
-static jfieldID decompress_ctx_nativePtr = 0;
-
 
 /*
  * Class:     com_github_luben_zstd_ZstdDictCompress
@@ -201,94 +201,84 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_Zstd_decompressDirectByteBuff
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    init
- * Signature: ()V
+ * Signature: ()J
  */
-JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_init
-  (JNIEnv *env, jobject obj)
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_init
+  (JNIEnv *env, jclass clazz)
 {
-    if (compress_ctx_nativePtr == 0) {
-        jclass clazz = (*env)->GetObjectClass(env, obj);
-        compress_ctx_nativePtr = (*env)->GetFieldID(env, clazz, "nativePtr", "J");
-    }
     ZSTD_CCtx* cctx = ZSTD_createCCtx();
-    (*env)->SetLongField(env, obj, compress_ctx_nativePtr, (jlong)(intptr_t) cctx);
+    return (jlong)(intptr_t) cctx;
 }
 
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    free
- * Signature: ()V
+ * Signature: (J)V
  */
 JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_free
-  (JNIEnv *env, jobject obj)
+  (JNIEnv *env, jclass clazz, jlong ptr)
 {
-    if (compress_ctx_nativePtr == 0) return;
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, obj, compress_ctx_nativePtr);
-    if (NULL == cctx) return;
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
     ZSTD_freeCCtx(cctx);
 }
 
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    setLevel0
- * Signature: (I)V
+ * Signature: (JI)V
  */
 JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_setLevel0
-  (JNIEnv *env, jobject obj, jint level)
+  (JNIEnv *env, jclass clazz, jlong ptr, jint level)
 {
-    if (compress_ctx_nativePtr == 0) return;
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, obj, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
     ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, level);
 }
 
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    setChecksum0
- * Signature: (I)V
+ * Signature: (JI)V
  */
 JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_setChecksum0
-  (JNIEnv *env, jobject obj, jboolean checksumFlag)
+  (JNIEnv *env, jclass clazz, jlong ptr, jboolean checksumFlag)
 {
-    if (compress_ctx_nativePtr == 0) return;
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, obj, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
     ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, (checksumFlag == JNI_TRUE));
 }
 
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    setContentSize0
- * Signature: (I)V
+ * Signature: (JI)V
  */
 JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_setContentSize0
-  (JNIEnv *env, jobject obj, jboolean contentSizeFlag)
+  (JNIEnv *env, jclass clazz, jlong ptr, jboolean contentSizeFlag)
 {
-    if (compress_ctx_nativePtr == 0) return;
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, obj, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
     ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, (contentSizeFlag == JNI_TRUE));
 }
 
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    setDictID0
- * Signature: (I)V
+ * Signature: (JI)V
  */
 JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_setDictID0
-  (JNIEnv *env, jobject obj, jboolean dictIDFlag)
+  (JNIEnv *env, jclass clazz, jlong ptr, jboolean dictIDFlag)
 {
-    if (compress_ctx_nativePtr == 0) return;
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, obj, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
     ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, (dictIDFlag == JNI_TRUE));
 }
 
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    loadCDictFast0
- * Signature: (Lcom/github/luben/zstd/ZstdDictCompress)J
+ * Signature: (JLcom/github/luben/zstd/ZstdDictCompress)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_loadCDictFast0
-  (JNIEnv *env, jobject obj, jobject dict)
+  (JNIEnv *env, jclass clazz, jlong ptr, jobject dict)
 {
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, obj, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
     if (dict == NULL) {
         // remove dictionary
         return ZSTD_CCtx_refCDict(cctx, NULL);
@@ -301,12 +291,12 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_loadCDictFast
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    loadCDict0
- * Signature: ([B)J
+ * Signature: (J[B)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_loadCDict0
-  (JNIEnv *env, jobject obj, jbyteArray dict)
+  (JNIEnv *env, jclass clazz, jlong ptr, jbyteArray dict)
 {
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, obj, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
     if (dict == NULL) {
         // remove dictionary
         return ZSTD_CCtx_loadDictionary(cctx, NULL, 0);
@@ -322,25 +312,38 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_loadCDict0
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    reset0
- * Signature: (L)J
+ * Signature: (J)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_reset0
-  (JNIEnv *env, jclass jctx) {
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, jctx, compress_ctx_nativePtr);
+  (JNIEnv *env, jclass jctx, jlong ptr) {
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
     return ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters);
 }
 
+JNIEXPORT jobject JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_getFrameProgression0
+  (JNIEnv *env, jclass jctx, jlong ptr) {
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
+    ZSTD_frameProgression native_progression = ZSTD_getFrameProgression(cctx);
+
+    jclass frame_progression_class = (*env)->FindClass(env, "com/github/luben/zstd/ZstdFrameProgression");
+    jmethodID frame_progression_constructor = (*env)->GetMethodID(env, frame_progression_class, "<init>", "(JJJJII)V");
+    return (*env)->NewObject(
+            env, frame_progression_class, frame_progression_constructor, native_progression.ingested,
+            native_progression.consumed, native_progression.produced, native_progression.flushed,
+            native_progression.currentJobID, native_progression.nbActiveWorkers);
+}
+
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_setPledgedSrcSize0
-  (JNIEnv *env, jclass jctx, jlong src_size) {
+  (JNIEnv *env, jclass jctx, jlong ptr, jlong src_size) {
     if (src_size < 0) {
         return -ZSTD_error_srcSize_wrong;
     }
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, jctx, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
     return ZSTD_CCtx_setPledgedSrcSize(cctx, (unsigned long long)src_size);
 }
 
 static size_t compress_direct_buffer_stream
-  (JNIEnv *env, jclass jctx, jobject dst, jint *dst_offset, jint dst_size, jobject src, jint *src_offset, jint src_size, jint end_op) {
+  (JNIEnv *env, jclass jctx, jlong ptr, jobject dst, jint *dst_offset, jint dst_size, jobject src, jint *src_offset, jint src_size, jint end_op) {
     if (NULL == dst) return -ZSTD_error_dstSize_tooSmall;
     if (NULL == src) return -ZSTD_error_srcSize_wrong;
     if (0 > *dst_offset) return -ZSTD_error_dstSize_tooSmall;
@@ -351,7 +354,7 @@ static size_t compress_direct_buffer_stream
     if (dst_size > dst_cap) return -ZSTD_error_dstSize_tooSmall;
     jsize src_cap = (*env)->GetDirectBufferCapacity(env, src);
     if (src_size > src_cap) return -ZSTD_error_srcSize_wrong;
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, jctx, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
 
     ZSTD_outBuffer out;
     out.pos = *dst_offset;
@@ -373,11 +376,11 @@ static size_t compress_direct_buffer_stream
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    compressDirectByteBufferStream0
- * Signature: (Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;III)J
+ * Signature: (JLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;III)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_compressDirectByteBufferStream0
-  (JNIEnv *env, jclass jctx, jobject dst, jint dst_offset, jint dst_size, jobject src, jint src_offset, jint src_size, jint end_op) {
-    size_t result = compress_direct_buffer_stream(env, jctx, dst, &dst_offset, dst_size, src, &src_offset, src_size, end_op);
+  (JNIEnv *env, jclass jctx, jlong ptr, jobject dst, jint dst_offset, jint dst_size, jobject src, jint src_offset, jint src_size, jint end_op) {
+    size_t result = compress_direct_buffer_stream(env, jctx, ptr, dst, &dst_offset, dst_size, src, &src_offset, src_size, end_op);
     if (ZSTD_isError(result)) {
         return (1ULL << 31) | ZSTD_getErrorCode(result);
     }
@@ -391,10 +394,10 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_compressDirec
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    compressDirectByteBuffer0
- * Signature: (Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)J
+ * Signature: (JLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_compressDirectByteBuffer0
-  (JNIEnv *env, jclass jctx, jobject dst, jint dst_offset, jint dst_size, jobject src, jint src_offset, jint src_size) {
+  (JNIEnv *env, jclass jctx, jlong ptr, jobject dst, jint dst_offset, jint dst_size, jobject src, jint src_offset, jint src_size) {
     if (NULL == dst) return -ZSTD_error_dstSize_tooSmall;
     if (NULL == src) return -ZSTD_error_srcSize_wrong;
     if (0 > dst_offset) return -ZSTD_error_dstSize_tooSmall;
@@ -406,7 +409,7 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_compressDirec
     jsize src_cap = (*env)->GetDirectBufferCapacity(env, src);
     if (src_offset + src_size > src_cap) return -ZSTD_error_srcSize_wrong;
 
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, jctx, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
 
     char *dst_buff = (char*)(*env)->GetDirectBufferAddress(env, dst);
     if (dst_buff == NULL) return -ZSTD_error_memory_allocation;
@@ -420,10 +423,10 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_compressDirec
 /*
  * Class:     com_github_luben_zstd_ZstdCompressCtx
  * Method:    compressByteArray0
- * Signature: (B[IIB[II)J
+ * Signature: (JB[IIB[II)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_compressByteArray0
-  (JNIEnv *env, jclass jctx, jbyteArray dst, jint dst_offset, jint dst_size, jbyteArray src, jint src_offset, jint src_size) {
+  (JNIEnv *env, jclass jctx, jlong ptr, jbyteArray dst, jint dst_offset, jint dst_size, jbyteArray src, jint src_offset, jint src_size) {
     size_t size = -ZSTD_error_memory_allocation;
 
     if (0 > dst_offset) return -ZSTD_error_dstSize_tooSmall;
@@ -433,7 +436,7 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdCompressCtx_compressByteA
     if (src_offset + src_size > (*env)->GetArrayLength(env, src)) return -ZSTD_error_srcSize_wrong;
     if (dst_offset + dst_size > (*env)->GetArrayLength(env, dst)) return -ZSTD_error_dstSize_tooSmall;
 
-    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t)(*env)->GetLongField(env, jctx, compress_ctx_nativePtr);
+    ZSTD_CCtx* cctx = (ZSTD_CCtx*)(intptr_t) ptr;
 
     void *dst_buff = (*env)->GetPrimitiveArrayCritical(env, dst, NULL);
     if (dst_buff == NULL) goto E1;
@@ -453,17 +456,13 @@ E1: return size;
 /*
  * Class:     com_github_luben_zstd_ZstdDecompressCtx
  * Method:    init
- * Signature: ()V
+ * Signature: ()J
  */
-JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_init
-  (JNIEnv *env, jobject obj)
+JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_init
+  (JNIEnv *env, jclass clazz)
 {
-    if (decompress_ctx_nativePtr == 0) {
-        jclass clazz = (*env)->GetObjectClass(env, obj);
-        decompress_ctx_nativePtr = (*env)->GetFieldID(env, clazz, "nativePtr", "J");
-    }
     ZSTD_DCtx* dctx = ZSTD_createDCtx();
-    (*env)->SetLongField(env, obj, decompress_ctx_nativePtr, (jlong)(intptr_t) dctx);
+    return (jlong)(intptr_t) dctx;
 }
 
 /*
@@ -472,10 +471,9 @@ JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_init
  * Signature: ()V
  */
 JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_free
-  (JNIEnv *env, jobject obj)
+  (JNIEnv *env, jclass clazz, jlong ptr)
 {
-    if (decompress_ctx_nativePtr == 0) return;
-    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)(*env)->GetLongField(env, obj, decompress_ctx_nativePtr);
+    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)ptr;
     if (NULL == dctx) return;
     ZSTD_freeDCtx(dctx);
 }
@@ -483,12 +481,12 @@ JNIEXPORT void JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_free
 /*
  * Class:     com_github_luben_zstd_ZstdDecompressCtx
  * Method:    loadDDictFast0
- * Signature: (Lcom/github/luben/zstd/ZstdDictDecompress)J
+ * Signature: (JLcom/github/luben/zstd/ZstdDictDecompress;)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_loadDDictFast0
-  (JNIEnv *env, jobject obj, jobject dict)
+  (JNIEnv *env, jclass clazz, jlong ptr, jobject dict)
 {
-    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)(*env)->GetLongField(env, obj, decompress_ctx_nativePtr);
+    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)ptr;
     if (dict == NULL) {
         // remove dictionary
         return ZSTD_DCtx_refDDict(dctx, NULL);
@@ -501,12 +499,12 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_loadDDictFa
 /*
  * Class:     com_github_luben_zstd_ZstdDecompressCtx
  * Method:    loadDDict0
- * Signature: ([B)J
+ * Signature: (J[B)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_loadDDict0
-  (JNIEnv *env, jobject obj, jbyteArray dict)
+  (JNIEnv *env, jclass clazz, jlong ptr, jbyteArray dict)
 {
-    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)(*env)->GetLongField(env, obj, decompress_ctx_nativePtr);
+    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)ptr;
     if (dict == NULL) {
         // remove dictionary
         return ZSTD_DCtx_loadDictionary(dctx, NULL, 0);
@@ -522,16 +520,16 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_loadDDict0
 /*
  * Class:     com_github_luben_zstd_ZstdDecompressCtx
  * Method:    reset0
- * Signature: (L)J
+ * Signature: (J)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_reset0
-  (JNIEnv *env, jclass jctx) {
-    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)(*env)->GetLongField(env, jctx, compress_ctx_nativePtr);
+  (JNIEnv *env, jclass clazz, jlong ptr) {
+    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)ptr;
     return ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters);
 }
 
 static size_t decompress_direct_buffer_stream
-  (JNIEnv *env, jclass jctx, jobject dst, jint *dst_offset, jint dst_size, jobject src, jint *src_offset, jint src_size)
+  (JNIEnv *env, jlong ptr, jobject dst, jint *dst_offset, jint dst_size, jobject src, jint *src_offset, jint src_size)
 {
     if (NULL == dst) return -ZSTD_error_dstSize_tooSmall;
     if (NULL == src) return -ZSTD_error_srcSize_wrong;
@@ -545,7 +543,7 @@ static size_t decompress_direct_buffer_stream
     jsize src_cap = (*env)->GetDirectBufferCapacity(env, src);
     if (src_size > src_cap) return -ZSTD_error_srcSize_wrong;
 
-    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)(*env)->GetLongField(env, jctx, decompress_ctx_nativePtr);
+    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)ptr;
 
     ZSTD_outBuffer out;
     out.pos = *dst_offset;
@@ -567,12 +565,12 @@ static size_t decompress_direct_buffer_stream
 /*
  * Class:     com_github_luben_zstd_ZstdDecompressCtx
  * Method:    decompressDirectByteBufferStream0
- * Signature: (Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)J
+ * Signature: (JLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_decompressDirectByteBufferStream0
-  (JNIEnv *env, jclass jctx, jobject dst, jint dst_offset, jint dst_size, jobject src, jint src_offset, jint src_size)
+  (JNIEnv *env, jclass jclazz, jlong ptr, jobject dst, jint dst_offset, jint dst_size, jobject src, jint src_offset, jint src_size)
 {
-    size_t result = decompress_direct_buffer_stream(env, jctx, dst, &dst_offset, dst_size, src, &src_offset, src_size);
+    size_t result = decompress_direct_buffer_stream(env, ptr, dst, &dst_offset, dst_size, src, &src_offset, src_size);
     if (ZSTD_isError(result)) {
         return (1ULL << 31) | ZSTD_getErrorCode(result);
     }
@@ -587,10 +585,10 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_decompressD
 /*
  * Class:     com_github_luben_zstd_ZstdDecompressCtx
  * Method:    decompressDirectByteBuffer0
- * Signature: (Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)J
+ * Signature: (JLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_decompressDirectByteBuffer0
-(JNIEnv *env, jclass jctx, jobject dst, jint dst_offset, jint dst_size, jobject src, jint src_offset, jint src_size)
+(JNIEnv *env, jclass jclazz, jlong ptr, jobject dst, jint dst_offset, jint dst_size, jobject src, jint src_offset, jint src_size)
 {
     if (NULL == dst) return -ZSTD_error_dstSize_tooSmall;
     if (NULL == src) return -ZSTD_error_srcSize_wrong;
@@ -603,7 +601,7 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_decompressD
     jsize src_cap = (*env)->GetDirectBufferCapacity(env, src);
     if (src_offset + src_size > src_cap) return -ZSTD_error_srcSize_wrong;
 
-    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)(*env)->GetLongField(env, jctx, decompress_ctx_nativePtr);
+    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)ptr;
 
     char *dst_buff = (char*)(*env)->GetDirectBufferAddress(env, dst);
     if (dst_buff == NULL) return -ZSTD_error_memory_allocation;
@@ -620,7 +618,7 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_decompressD
  * Signature: (B[IIB[II)J
  */
 JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_decompressByteArray0
-  (JNIEnv *env, jclass jctx, jbyteArray dst, jint dst_offset, jint dst_size, jbyteArray src, jint src_offset, jint src_size) {
+  (JNIEnv *env, jclass jclazz, jlong ptr, jbyteArray dst, jint dst_offset, jint dst_size, jbyteArray src, jint src_offset, jint src_size) {
     size_t size = -ZSTD_error_memory_allocation;
 
     if (0 > dst_offset) return -ZSTD_error_dstSize_tooSmall;
@@ -630,7 +628,7 @@ JNIEXPORT jlong JNICALL Java_com_github_luben_zstd_ZstdDecompressCtx_decompressB
     if (src_offset + src_size > (*env)->GetArrayLength(env, src)) return -ZSTD_error_srcSize_wrong;
     if (dst_offset + dst_size > (*env)->GetArrayLength(env, dst)) return -ZSTD_error_dstSize_tooSmall;
 
-    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)(*env)->GetLongField(env, jctx, decompress_ctx_nativePtr);
+    ZSTD_DCtx* dctx = (ZSTD_DCtx*)(intptr_t)ptr;
 
     void *dst_buff = (*env)->GetPrimitiveArrayCritical(env, dst, NULL);
     if (dst_buff == NULL) goto E1;


=====================================
src/main/native/jni_zstd.c
=====================================
@@ -39,7 +39,7 @@ static size_t JNI_ZSTD_decompressedSize(const void* buf, size_t bufSize, jboolea
         return frameHeader.frameContentSize;
     }
 
-    return ZSTD_getDecompressedSize(buf, bufSize);
+    return ZSTD_getFrameContentSize(buf, bufSize);
 }
 
 /*


=====================================
version
=====================================
@@ -1 +1 @@
-1.5.2-5
+1.5.4-2



View it on GitLab: https://salsa.debian.org/java-team/zstd-jni-java/-/compare/733908b4416e27802b52597868ab7ff590f84754...79fc125696536faea375de411b1ca21d2c3e7966

-- 
View it on GitLab: https://salsa.debian.org/java-team/zstd-jni-java/-/compare/733908b4416e27802b52597868ab7ff590f84754...79fc125696536faea375de411b1ca21d2c3e7966
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20230322/49c44c23/attachment.htm>


More information about the pkg-java-commits mailing list