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 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); + } } }