Skip to content

Commit 005749b

Browse files
committed
Bump minimum required JDK to 22, migrate API to MemorySegment
1 parent b2555f6 commit 005749b

35 files changed

+293
-978
lines changed

pom.xml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,9 @@
9797
<plugin>
9898
<groupId>org.apache.maven.plugins</groupId>
9999
<artifactId>maven-compiler-plugin</artifactId>
100-
<!-- When attempting to compile on higher Java versions, you may encounter
101-
some issues with Unsafe. In Intellij unset the 'use -release' under the
102-
javac compiler page and it'll happily compile once again
103-
-->
104100
<configuration>
105-
<source>1.8</source>
106-
<target>1.8</target>
101+
<source>22</source>
102+
<target>22</target>
107103
</configuration>
108104
</plugin>
109105
<plugin>

src/main/java/software/coley/lljzip/ZipIO.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
import software.coley.lljzip.format.model.EndOfCentralDirectory;
55
import software.coley.lljzip.format.model.ZipArchive;
66
import software.coley.lljzip.format.read.*;
7-
import software.coley.lljzip.util.BufferData;
8-
import software.coley.lljzip.util.ByteData;
9-
import software.coley.lljzip.util.FileMapUtil;
107

118
import java.io.FileNotFoundException;
129
import java.io.IOException;
10+
import java.lang.foreign.Arena;
11+
import java.lang.foreign.MemorySegment;
12+
import java.nio.channels.FileChannel;
1313
import java.nio.file.Files;
1414
import java.nio.file.Path;
1515
import java.util.zip.ZipFile;
@@ -21,7 +21,7 @@
2121
* <li>For regular ZIP files use {@link ForwardScanZipReader}.</li>
2222
* <li>For ZIP files without {@link CentralDirectoryFileHeader} or {@link EndOfCentralDirectory} items, use {@link NaiveLocalFileZipReader}</li>
2323
* </ul>
24-
* You can fully control zip parsing via {@link #read(ByteData, ZipReader)} by passing a customized reader implementation.
24+
* You can fully control zip parsing via {@link #read(MemorySegment, ZipReader)} by passing a customized reader implementation.
2525
*
2626
* @author Matt Coley
2727
*/
@@ -37,7 +37,7 @@ public class ZipIO {
3737
* @throws IOException
3838
* When the archive bytes cannot be read from, usually indicating a malformed zip.
3939
*/
40-
public static ZipArchive readStandard(ByteData data) throws IOException {
40+
public static ZipArchive readStandard(MemorySegment data) throws IOException {
4141
return read(data, new ForwardScanZipReader());
4242
}
4343

@@ -82,7 +82,7 @@ public static ZipArchive readStandard(Path data) throws IOException {
8282
* @throws IOException
8383
* When the archive bytes cannot be read from, usually indicating a malformed zip.
8484
*/
85-
public static ZipArchive readNaive(ByteData data) throws IOException {
85+
public static ZipArchive readNaive(MemorySegment data) throws IOException {
8686
return read(data, new NaiveLocalFileZipReader());
8787
}
8888

@@ -128,7 +128,7 @@ public static ZipArchive readNaive(Path data) throws IOException {
128128
* @throws IOException
129129
* When the archive bytes cannot be read from, usually indicating a malformed zip.
130130
*/
131-
public static ZipArchive readJvm(ByteData data) throws IOException {
131+
public static ZipArchive readJvm(MemorySegment data) throws IOException {
132132
return read(data, new JvmZipReader());
133133
}
134134

@@ -194,7 +194,7 @@ public static ZipArchive readAdaptingIO(Path path) throws IOException {
194194
public static ZipArchive read(byte[] data, ZipReader strategy) throws IOException {
195195
if (data == null)
196196
throw new IOException("Data is null!");
197-
return read(BufferData.wrap(data), strategy);
197+
return read(MemorySegment.ofArray(data), strategy);
198198
}
199199

200200
/**
@@ -213,7 +213,23 @@ public static ZipArchive read(Path path, ZipReader strategy) throws IOException
213213
throw new IOException("Data is null!");
214214
if (!Files.isRegularFile(path))
215215
throw new FileNotFoundException(path.toString());
216-
return read(FileMapUtil.map(path), strategy);
216+
FileChannel fc = FileChannel.open(path);
217+
try {
218+
long size = fc.size();
219+
// The fixed size elements of a CDFH is 22 bytes (plus the variable size bits which can be 0)
220+
// - Even if we only want to read local/central file entries, those are even larger at a minimum
221+
if (size < 22)
222+
throw new IOException("Not enough bytes to read Central-Directory-File-Header, minimum=22");
223+
224+
ZipArchive zip = new ZipArchive(fc);
225+
strategy.read(zip, fc.map(FileChannel.MapMode.READ_ONLY, 0L, size, Arena.ofAuto()));
226+
fc = null;
227+
return zip;
228+
} finally {
229+
if (fc != null) {
230+
fc.close();
231+
}
232+
}
217233
}
218234

219235
/**
@@ -227,17 +243,17 @@ public static ZipArchive read(Path path, ZipReader strategy) throws IOException
227243
* @throws IOException
228244
* When the archive bytes cannot be read from, usually indicating a malformed zip.
229245
*/
230-
public static ZipArchive read(ByteData data, ZipReader strategy) throws IOException {
246+
public static ZipArchive read(MemorySegment data, ZipReader strategy) throws IOException {
231247
if (data == null)
232248
throw new IOException("Data is null!");
233249

234250
// The fixed size elements of a CDFH is 22 bytes (plus the variable size bits which can be 0)
235251
// - Even if we only want to read local/central file entries, those are even larger at a minimum
236-
if (data.length() < 22)
252+
if (data.byteSize() < 22)
237253
throw new IOException("Not enough bytes to read Central-Directory-File-Header, minimum=22");
238254

239255
// Create instance
240-
ZipArchive zip = new ZipArchive(data);
256+
ZipArchive zip = new ZipArchive();
241257
strategy.read(zip, data);
242258
return zip;
243259
}

src/main/java/software/coley/lljzip/format/ZipPatterns.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import software.coley.lljzip.format.model.CentralDirectoryFileHeader;
44
import software.coley.lljzip.format.model.EndOfCentralDirectory;
55
import software.coley.lljzip.format.model.LocalFileHeader;
6-
import software.coley.lljzip.util.ByteDataUtil;
6+
import software.coley.lljzip.util.MemorySegmentUtil;
77

88
/**
9-
* Patterns for usage in {@link ByteDataUtil} methods.
9+
* Patterns for usage in {@link MemorySegmentUtil} methods.
1010
*
1111
* @author Matt Coley
1212
*/

src/main/java/software/coley/lljzip/format/compression/Decompressor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package software.coley.lljzip.format.compression;
22

33
import software.coley.lljzip.format.model.LocalFileHeader;
4-
import software.coley.lljzip.util.ByteData;
54

65
import java.io.IOException;
6+
import java.lang.foreign.MemorySegment;
77

88
/**
99
* Outlines decompression of {@link LocalFileHeader#getFileData()}.
@@ -22,5 +22,5 @@ public interface Decompressor {
2222
* @throws IOException
2323
* Decompression failure.
2424
*/
25-
ByteData decompress(LocalFileHeader header, ByteData bytes) throws IOException;
25+
MemorySegment decompress(LocalFileHeader header, MemorySegment bytes) throws IOException;
2626
}

src/main/java/software/coley/lljzip/format/compression/DeflateDecompressor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package software.coley.lljzip.format.compression;
22

33
import software.coley.lljzip.format.model.LocalFileHeader;
4-
import software.coley.lljzip.util.ByteData;
54
import software.coley.lljzip.util.FastWrapOutputStream;
65

76
import java.io.IOException;
7+
import java.lang.foreign.MemorySegment;
88
import java.util.zip.DataFormatException;
99
import java.util.zip.Inflater;
1010
import java.util.zip.ZipException;
@@ -22,23 +22,24 @@ private DeflateDecompressor() {
2222
}
2323

2424
@Override
25-
public ByteData decompress(LocalFileHeader header, ByteData data) throws IOException {
25+
public MemorySegment decompress(LocalFileHeader header, MemorySegment data) throws IOException {
2626
if (header.getCompressionMethod() != ZipCompressions.DEFLATED)
2727
throw new IOException("LocalFileHeader contents not using 'Deflated'!");
2828
Inflater inflater = new Inflater(true);
2929
FastWrapOutputStream out = new FastWrapOutputStream();
3030
try {
3131
byte[] output = new byte[1024];
3232
byte[] buffer = new byte[1024];
33+
MemorySegment bufferSegment = MemorySegment.ofArray(buffer);
3334
long position = 0L;
34-
long length = data.length();
35+
long length = data.byteSize();
3536
do {
3637
if (inflater.needsInput()) {
3738
int remaining = (int) Math.min(buffer.length, length);
3839
if (remaining == 0) {
3940
break;
4041
}
41-
data.get(position, buffer, 0, remaining);
42+
MemorySegment.copy(data, position, bufferSegment, 0, remaining);
4243
length -= remaining;
4344
position += remaining;
4445
inflater.setInput(buffer, 0, remaining);

src/main/java/software/coley/lljzip/format/compression/UnsafeDeflateDecompressor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package software.coley.lljzip.format.compression;
22

33
import software.coley.lljzip.format.model.LocalFileHeader;
4-
import software.coley.lljzip.util.ByteData;
54
import software.coley.lljzip.util.FastWrapOutputStream;
65
import software.coley.lljzip.util.InflaterHackery;
76

87
import java.io.IOException;
8+
import java.lang.foreign.MemorySegment;
99
import java.util.ArrayDeque;
1010
import java.util.Deque;
1111
import java.util.zip.DataFormatException;
@@ -38,7 +38,7 @@ private UnsafeDeflateDecompressor() {
3838
}
3939

4040
@Override
41-
public ByteData decompress(LocalFileHeader header, ByteData data) throws IOException {
41+
public MemorySegment decompress(LocalFileHeader header, MemorySegment data) throws IOException {
4242
if (header.getCompressionMethod() != ZipCompressions.DEFLATED)
4343
throw new IOException("LocalFileHeader contents not using 'Deflated'!");
4444
FastWrapOutputStream out = new FastWrapOutputStream();
@@ -55,16 +55,17 @@ public ByteData decompress(LocalFileHeader header, ByteData data) throws IOExcep
5555
try {
5656
byte[] output = entry.decompress;
5757
byte[] buffer = entry.buffer;
58+
MemorySegment bufferSegment = MemorySegment.ofArray(buffer);
5859
Inflater inflater = entry.inflater;
5960
long position = 0L;
60-
long length = data.length();
61+
long length = data.byteSize();
6162
int remaining = 0;
6263
boolean needsInput = true;
6364
do {
6465
if (needsInput) {
6566
remaining = (int) Math.min(buffer.length, length);
6667
if (remaining != 0) {
67-
data.get(position, buffer, 0, remaining);
68+
MemorySegment.copy(data, position, bufferSegment, 0, remaining);
6869
length -= remaining;
6970
position += remaining;
7071
inflater.setInput(buffer, 0, remaining);

src/main/java/software/coley/lljzip/format/compression/ZipCompressions.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package software.coley.lljzip.format.compression;
22

33
import software.coley.lljzip.format.model.LocalFileHeader;
4-
import software.coley.lljzip.util.ByteData;
54

65
import java.io.IOException;
6+
import java.lang.foreign.MemorySegment;
77

88
/**
99
* Constants for {@link LocalFileHeader#getCompressionMethod()}.
@@ -202,7 +202,7 @@ static String getName(int method) {
202202
* @throws IOException
203203
* When the decompression failed.
204204
*/
205-
static ByteData decompress(LocalFileHeader header) throws IOException {
205+
static MemorySegment decompress(LocalFileHeader header) throws IOException {
206206
int method = header.getCompressionMethod();
207207
switch (method) {
208208
case STORED:

src/main/java/software/coley/lljzip/format/model/AbstractZipFileHeader.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
import software.coley.lljzip.format.compression.Decompressor;
44
import software.coley.lljzip.format.compression.ZipCompressions;
5-
import software.coley.lljzip.util.ByteData;
6-
import software.coley.lljzip.util.ByteDataUtil;
5+
import software.coley.lljzip.util.MemorySegmentUtil;
76
import software.coley.lljzip.util.lazy.LazyByteData;
87
import software.coley.lljzip.util.lazy.LazyInt;
98
import software.coley.lljzip.util.lazy.LazyLong;
109

1110
import javax.annotation.Nonnull;
1211
import javax.annotation.Nullable;
12+
import java.lang.foreign.MemorySegment;
1313

1414
/**
1515
* Common base for shared elements of {@link CentralDirectoryFileHeader} and {@link LocalFileHeader}.
@@ -35,7 +35,7 @@ public abstract class AbstractZipFileHeader implements ZipPart, ZipRead {
3535
protected transient long offset = -1L;
3636

3737
// Data source that contents were read from.
38-
protected transient ByteData data;
38+
protected transient MemorySegment data;
3939

4040
// String cache values
4141
private transient String fileNameCache;
@@ -45,7 +45,7 @@ public abstract class AbstractZipFileHeader implements ZipPart, ZipRead {
4545
* @return The associated backing data that this file header was read from.
4646
*/
4747
@Nullable
48-
public ByteData getBackingData() {
48+
public MemorySegment getBackingData() {
4949
return data;
5050
}
5151

@@ -55,7 +55,7 @@ public long offset() {
5555
}
5656

5757
@Override
58-
public void read(@Nonnull ByteData data, long offset) {
58+
public void read(@Nonnull MemorySegment data, long offset) {
5959
this.data = data;
6060
this.offset = offset;
6161
}
@@ -230,15 +230,15 @@ public void setExtraFieldLength(int extraFieldLength) {
230230
*
231231
* @return File name.
232232
*/
233-
public ByteData getFileName() {
233+
public MemorySegment getFileName() {
234234
return fileName.get();
235235
}
236236

237237
/**
238238
* @param fileName
239239
* File name.
240240
*/
241-
public void setFileName(ByteData fileName) {
241+
public void setFileName(MemorySegment fileName) {
242242
this.fileName.set(fileName);
243243
fileNameCache = null;
244244
}
@@ -252,7 +252,7 @@ public void setFileName(ByteData fileName) {
252252
public String getFileNameAsString() {
253253
String fileNameCache = this.fileNameCache;
254254
if (fileNameCache == null && fileName != null) {
255-
return this.fileNameCache = ByteDataUtil.toString(fileName.get());
255+
return this.fileNameCache = MemorySegmentUtil.toString(fileName.get());
256256
}
257257
return fileNameCache;
258258
}
@@ -261,15 +261,15 @@ public String getFileNameAsString() {
261261
* @return May be used for extra compression information,
262262
* depending on the {@link #getCompressionMethod() compression method} used.
263263
*/
264-
public ByteData getExtraField() {
264+
public MemorySegment getExtraField() {
265265
return extraField.get();
266266
}
267267

268268
/**
269269
* @param extraField
270270
* Extra field bytes.
271271
*/
272-
public void setExtraField(ByteData extraField) {
272+
public void setExtraField(MemorySegment extraField) {
273273
this.extraField.set(extraField);
274274
}
275275

@@ -279,7 +279,7 @@ public void setExtraField(ByteData extraField) {
279279
public String getExtraFieldAsString() {
280280
String fileCommentCache = this.extraFieldCache;
281281
if (fileCommentCache == null && extraField != null) {
282-
return this.extraFieldCache = ByteDataUtil.toString(extraField.get());
282+
return this.extraFieldCache = MemorySegmentUtil.toString(extraField.get());
283283
}
284284
return fileCommentCache;
285285
}

src/main/java/software/coley/lljzip/format/model/AdaptingLocalFileHeader.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package software.coley.lljzip.format.model;
22

3-
import software.coley.lljzip.util.BufferData;
4-
import software.coley.lljzip.util.NoopByteData;
53
import software.coley.lljzip.util.lazy.LazyByteData;
64
import software.coley.lljzip.util.lazy.LazyInt;
75
import software.coley.lljzip.util.lazy.LazyLong;
@@ -10,6 +8,7 @@
108
import java.io.ByteArrayOutputStream;
119
import java.io.IOException;
1210
import java.io.InputStream;
11+
import java.lang.foreign.MemorySegment;
1312
import java.util.zip.ZipEntry;
1413
import java.util.zip.ZipFile;
1514

@@ -45,20 +44,20 @@ public AdaptingLocalFileHeader(@Nonnull ZipFile archive, @Nonnull ZipEntry entry
4544
lastModFileTime = new LazyInt(() -> 0);
4645
lastModFileDate = new LazyInt(() -> 0);
4746
fileNameLength = new LazyInt(entryName::length);
48-
fileName = new LazyByteData(() -> BufferData.wrap(entryName.getBytes()));
47+
fileName = new LazyByteData(() -> MemorySegment.ofArray(entryName.getBytes()));
4948
fileDataLength = new LazyLong(() -> entryData.length);
50-
fileData = new LazyByteData(() -> BufferData.wrap(entryData));
49+
fileData = new LazyByteData(() -> MemorySegment.ofArray(entryData));
5150
compressionMethod = new LazyInt(() -> 0);
5251
uncompressedSize = new LazyLong(() -> entryData.length);
5352
compressedSize = new LazyLong(() -> entryData.length);
5453
crc32 = new LazyInt(() -> (int) entry.getCrc());
5554
if (extra != null) {
5655
extraFieldLength = new LazyInt(() -> extra.length);
57-
extraField = new LazyByteData(() -> BufferData.wrap(extra));
56+
extraField = new LazyByteData(() -> MemorySegment.ofArray(extra));
5857
} else {
5958
extraFieldLength = new LazyInt(() -> 0);
60-
extraField = new LazyByteData(() -> NoopByteData.INSTANCE);
59+
extraField = new LazyByteData(() -> MemorySegment.ofArray(new byte[0]));
6160
}
62-
data = NoopByteData.INSTANCE;
61+
data = MemorySegment.ofArray(new byte[0]);
6362
}
6463
}

0 commit comments

Comments
 (0)