Skip to content

Commit 6473877

Browse files
dfa1claude
andcommitted
refactor: add NativeCall.createOrThrow for the create-NULL-check pattern
Every native create call (ZSTD_createC/DCtx, ZSTD_createC/DDict) repeated the same invoke + NULL-check + Throwable-laundering. Hoist it into NativeCall.createOrThrow(name, factory), mirroring checkReturnValue's lambda style, and route all ten call sites through it. The 'returned NULL' message now lives in one place. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent e3d33e1 commit 6473877

9 files changed

Lines changed: 35 additions & 76 deletions

zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,27 @@ static long checkReturnValue(ZstdCall c) {
3131
return code;
3232
}
3333

34+
/// A native factory call returning a freshly allocated object pointer.
35+
@FunctionalInterface
36+
interface NativeFactory {
37+
MemorySegment create() throws Throwable;
38+
}
39+
40+
/// Runs a zstd `create`-style call and rejects the `NULL` it returns on
41+
/// allocation failure, raising a {@link ZstdException} that names the call.
42+
static MemorySegment createOrThrow(String what, NativeFactory factory) {
43+
MemorySegment p;
44+
try {
45+
p = factory.create();
46+
} catch (Throwable t) {
47+
throw rethrow(t);
48+
}
49+
if (MemorySegment.NULL.equals(p)) {
50+
throw new ZstdException(what + " returned NULL");
51+
}
52+
return p;
53+
}
54+
3455
static boolean isError(long code) {
3556
try {
3657
return ((int) Bindings.IS_ERROR.invokeExact(code)) != 0;

zstd/src/main/java/io/github/dfa1/zstd/ZstdCompressCtx.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,7 @@ public ZstdCompressCtx() {
2828
}
2929

3030
private static MemorySegment create() {
31-
try {
32-
MemorySegment p = (MemorySegment) Bindings.CREATE_CCTX.invokeExact();
33-
if (MemorySegment.NULL.equals(p)) {
34-
throw new ZstdException("ZSTD_createCCtx returned NULL");
35-
}
36-
return p;
37-
} catch (Throwable t) {
38-
throw NativeCall.rethrow(t);
39-
}
31+
return NativeCall.createOrThrow("ZSTD_createCCtx", () -> (MemorySegment) Bindings.CREATE_CCTX.invokeExact());
4032
}
4133

4234
/// Sets the compression level for subsequent {@link #compress} calls.

zstd/src/main/java/io/github/dfa1/zstd/ZstdCompressDict.java

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,27 +61,15 @@ private static MemorySegment create(ZstdDictionary dict, int level) {
6161
try (Arena arena = Arena.ofConfined()) {
6262
byte[] raw = dict.raw();
6363
MemorySegment d = Zstd.copyIn(arena, raw);
64-
MemorySegment p = (MemorySegment) Bindings.CREATE_CDICT.invokeExact(d, (long) raw.length, level);
65-
if (MemorySegment.NULL.equals(p)) {
66-
throw new ZstdException("ZSTD_createCDict returned NULL");
67-
}
68-
return p;
69-
} catch (Throwable t) {
70-
throw NativeCall.rethrow(t);
64+
return NativeCall.createOrThrow("ZSTD_createCDict",
65+
() -> (MemorySegment) Bindings.CREATE_CDICT.invokeExact(d, (long) raw.length, level));
7166
}
7267
}
7368

7469
private static MemorySegment create(MemorySegment dict, int level) {
7570
NativeCall.requireNative(dict, "dict");
76-
try {
77-
MemorySegment p = (MemorySegment) Bindings.CREATE_CDICT.invokeExact(dict, dict.byteSize(), level);
78-
if (MemorySegment.NULL.equals(p)) {
79-
throw new ZstdException("ZSTD_createCDict returned NULL");
80-
}
81-
return p;
82-
} catch (Throwable t) {
83-
throw NativeCall.rethrow(t);
84-
}
71+
return NativeCall.createOrThrow("ZSTD_createCDict",
72+
() -> (MemorySegment) Bindings.CREATE_CDICT.invokeExact(dict, dict.byteSize(), level));
8573
}
8674

8775
/// The level this dictionary was digested at.

zstd/src/main/java/io/github/dfa1/zstd/ZstdCompressStream.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,7 @@ public ZstdCompressStream(int level, ZstdDictionary dictionary) {
7070
}
7171

7272
private static MemorySegment createCctx() {
73-
try {
74-
MemorySegment cctx = (MemorySegment) Bindings.CREATE_CCTX.invokeExact();
75-
if (MemorySegment.NULL.equals(cctx)) {
76-
throw new ZstdException("ZSTD_createCCtx returned NULL");
77-
}
78-
return cctx;
79-
} catch (Throwable t) {
80-
throw NativeCall.rethrow(t);
81-
}
73+
return NativeCall.createOrThrow("ZSTD_createCCtx", () -> (MemorySegment) Bindings.CREATE_CCTX.invokeExact());
8274
}
8375

8476
private void loadDictionary(ZstdDictionary dictionary) {

zstd/src/main/java/io/github/dfa1/zstd/ZstdDecompressCtx.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,7 @@ public ZstdDecompressCtx() {
1818
}
1919

2020
private static MemorySegment create() {
21-
try {
22-
MemorySegment p = (MemorySegment) Bindings.CREATE_DCTX.invokeExact();
23-
if (MemorySegment.NULL.equals(p)) {
24-
throw new ZstdException("ZSTD_createDCtx returned NULL");
25-
}
26-
return p;
27-
} catch (Throwable t) {
28-
throw NativeCall.rethrow(t);
29-
}
21+
return NativeCall.createOrThrow("ZSTD_createDCtx", () -> (MemorySegment) Bindings.CREATE_DCTX.invokeExact());
3022
}
3123

3224
/// Sets an advanced decompression parameter, sticky across subsequent calls.

zstd/src/main/java/io/github/dfa1/zstd/ZstdDecompressDict.java

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,15 @@ private static MemorySegment create(ZstdDictionary dict) {
3838
try (Arena arena = Arena.ofConfined()) {
3939
byte[] raw = dict.raw();
4040
MemorySegment d = Zstd.copyIn(arena, raw);
41-
MemorySegment p = (MemorySegment) Bindings.CREATE_DDICT.invokeExact(d, (long) raw.length);
42-
if (MemorySegment.NULL.equals(p)) {
43-
throw new ZstdException("ZSTD_createDDict returned NULL");
44-
}
45-
return p;
46-
} catch (Throwable t) {
47-
throw NativeCall.rethrow(t);
41+
return NativeCall.createOrThrow("ZSTD_createDDict",
42+
() -> (MemorySegment) Bindings.CREATE_DDICT.invokeExact(d, (long) raw.length));
4843
}
4944
}
5045

5146
private static MemorySegment create(MemorySegment dict) {
5247
NativeCall.requireNative(dict, "dict");
53-
try {
54-
MemorySegment p = (MemorySegment) Bindings.CREATE_DDICT.invokeExact(dict, dict.byteSize());
55-
if (MemorySegment.NULL.equals(p)) {
56-
throw new ZstdException("ZSTD_createDDict returned NULL");
57-
}
58-
return p;
59-
} catch (Throwable t) {
60-
throw NativeCall.rethrow(t);
61-
}
48+
return NativeCall.createOrThrow("ZSTD_createDDict",
49+
() -> (MemorySegment) Bindings.CREATE_DDICT.invokeExact(dict, dict.byteSize()));
6250
}
6351

6452
/// The dictionary id this dictionary decodes frames for.

zstd/src/main/java/io/github/dfa1/zstd/ZstdDecompressStream.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,7 @@ public ZstdDecompressStream(ZstdDictionary dictionary) {
4444
}
4545

4646
private static MemorySegment createDctx() {
47-
try {
48-
MemorySegment dctx = (MemorySegment) Bindings.CREATE_DCTX.invokeExact();
49-
if (MemorySegment.NULL.equals(dctx)) {
50-
throw new ZstdException("ZSTD_createDCtx returned NULL");
51-
}
52-
return dctx;
53-
} catch (Throwable t) {
54-
throw NativeCall.rethrow(t);
55-
}
47+
return NativeCall.createOrThrow("ZSTD_createDCtx", () -> (MemorySegment) Bindings.CREATE_DCTX.invokeExact());
5648
}
5749

5850
private void loadDictionary(ZstdDictionary dictionary) {

zstd/src/main/java/io/github/dfa1/zstd/ZstdInputStream.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,7 @@ public ZstdInputStream(InputStream in, ZstdDictionary dictionary) {
6565
this.single = new byte[1];
6666
MemorySegment d = null;
6767
try {
68-
d = (MemorySegment) Bindings.CREATE_DCTX.invokeExact();
69-
if (MemorySegment.NULL.equals(d)) {
70-
throw new ZstdException("ZSTD_createDCtx returned NULL");
71-
}
68+
d = NativeCall.createOrThrow("ZSTD_createDCtx", () -> (MemorySegment) Bindings.CREATE_DCTX.invokeExact());
7269
this.dctx = d;
7370
if (dictionary != null) {
7471
loadDictionary(dictionary);

zstd/src/main/java/io/github/dfa1/zstd/ZstdOutputStream.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,7 @@ public ZstdOutputStream(OutputStream out, int level, ZstdDictionary dictionary)
102102
this.single = new byte[1];
103103
MemorySegment c = null;
104104
try {
105-
c = (MemorySegment) Bindings.CREATE_CCTX.invokeExact();
106-
if (MemorySegment.NULL.equals(c)) {
107-
throw new ZstdException("ZSTD_createCCtx returned NULL");
108-
}
105+
c = NativeCall.createOrThrow("ZSTD_createCCtx", () -> (MemorySegment) Bindings.CREATE_CCTX.invokeExact());
109106
this.cctx = c;
110107
NativeCall.checkReturnValue(() -> (long) Bindings.CCTX_SET_PARAMETER.invokeExact(
111108
cctx, ZSTD_C_COMPRESSION_LEVEL, level));

0 commit comments

Comments
 (0)