From e7b724c6ba5cc17a001d68a42c110c3010cf3444 Mon Sep 17 00:00:00 2001 From: Davide Angelocola Date: Fri, 26 Jun 2026 20:51:26 +0200 Subject: [PATCH 1/2] refactor: make NativeCall.requireNative return void Every caller uses it as a guard statement and discards the returned segment, so the fluent return was dead. Drop it. Co-Authored-By: Claude Opus 4.8 --- zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java b/zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java index 71181b8..463e0a9 100644 --- a/zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java +++ b/zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java @@ -59,12 +59,11 @@ private static String errorName(long code) { /// Guards a zero-copy entry point: the segment handed to zstd must be backed /// by native (off-heap) memory, since its address is dereferenced in C. Fails /// fast with a clear message instead of the FFM linker's cryptic error. - static MemorySegment requireNative(MemorySegment seg, String name) { + static void requireNative(MemorySegment seg, String name) { if (!seg.isNative()) { throw new IllegalArgumentException( name + " must be a native (off-heap) MemorySegment; got a heap segment"); } - return seg; } /// Rethrows any `Throwable` as if unchecked, laundering the checked From 611817e496b30baf74a9ee728f16e962baee5878 Mon Sep 17 00:00:00 2001 From: Davide Angelocola Date: Fri, 26 Jun 2026 20:56:08 +0200 Subject: [PATCH 2/2] feat: expose Zstd.versionNumber() Wire up the previously-unused VERSION_NUMBER binding as a public int Zstd.versionNumber() (MAJOR*10000 + MINOR*100 + PATCH, e.g. 10507 for 1.5.7), paralleling version() for programmatic version checks. Test asserts it stays consistent with the version() string. Co-Authored-By: Claude Opus 4.8 --- zstd/src/main/java/io/github/dfa1/zstd/Zstd.java | 12 ++++++++++++ .../test/java/io/github/dfa1/zstd/ZstdTest.java | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/zstd/src/main/java/io/github/dfa1/zstd/Zstd.java b/zstd/src/main/java/io/github/dfa1/zstd/Zstd.java index 5020e6f..5385de7 100644 --- a/zstd/src/main/java/io/github/dfa1/zstd/Zstd.java +++ b/zstd/src/main/java/io/github/dfa1/zstd/Zstd.java @@ -227,6 +227,18 @@ public static String version() { } } + /// Runtime zstd version as a single number for programmatic comparison, + /// encoded `MAJOR * 10000 + MINOR * 100 + PATCH` — e.g. `10507` for `1.5.7`. + /// + /// @return the linked zstd library version number + public static int versionNumber() { + try { + return (int) Bindings.VERSION_NUMBER.invokeExact(); + } catch (Throwable t) { + throw NativeCall.rethrow(t); + } + } + // --- package-private helpers shared with the context classes --- // Native-call status checking and segment guards live in NativeCall. diff --git a/zstd/src/test/java/io/github/dfa1/zstd/ZstdTest.java b/zstd/src/test/java/io/github/dfa1/zstd/ZstdTest.java index 1a81f6a..d46e27f 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/ZstdTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/ZstdTest.java @@ -135,5 +135,20 @@ void reportsSemanticVersion() { // When the runtime version is read / Then it is an x.y.z string assertThat(Zstd.version()).matches("\\d+\\.\\d+\\.\\d+"); } + + @Test + void reportsVersionNumberConsistentWithTheString() { + // Given the x.y.z version string split into its parts + String[] parts = Zstd.version().split("\\."); + int expected = Integer.parseInt(parts[0]) * 10000 + + Integer.parseInt(parts[1]) * 100 + + Integer.parseInt(parts[2]); + + // When the numeric version is read + int number = Zstd.versionNumber(); + + // Then it encodes MAJOR * 10000 + MINOR * 100 + PATCH + assertThat(number).isEqualTo(expected); + } } }