Skip to content

Commit 99020a8

Browse files
committed
Support files that are larget than 2GB
1 parent 4d38c8a commit 99020a8

27 files changed

+583
-258
lines changed

src/main/java/software/coley/llzip/ZipCompressions.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import software.coley.llzip.part.LocalFileHeader;
44
import software.coley.llzip.strategy.DeflateDecompressor;
5+
import software.coley.llzip.util.ByteData;
56

67
import java.io.IOException;
78
import java.nio.ByteBuffer;
@@ -203,7 +204,7 @@ static String getName(int method) {
203204
* @throws IOException
204205
* When the decompression failed.
205206
*/
206-
static ByteBuffer decompress(LocalFileHeader header) throws IOException {
207+
static ByteData decompress(LocalFileHeader header) throws IOException {
207208
int method = header.getCompressionMethod();
208209
switch (method) {
209210
case STRORED:

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

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
import software.coley.llzip.strategy.DefaultZipReaderStrategy;
44
import software.coley.llzip.strategy.JvmZipReaderStrategy;
55
import software.coley.llzip.strategy.ZipReaderStrategy;
6+
import software.coley.llzip.util.BufferData;
7+
import software.coley.llzip.util.ByteData;
8+
import software.coley.llzip.util.FileMapUtil;
69

710
import java.io.FileNotFoundException;
811
import java.io.IOException;
9-
import java.nio.ByteBuffer;
10-
import java.nio.ByteOrder;
11-
import java.nio.channels.FileChannel;
1212
import java.nio.file.Files;
1313
import java.nio.file.Path;
14-
import java.nio.file.StandardOpenOption;
1514

1615
/**
1716
* IO wrappers for reading {@link ZipArchive} contents.
@@ -30,7 +29,7 @@ public class ZipIO {
3029
* @throws IOException
3130
* When the archive bytes cannot be read from, usually indicating a malformed zip.
3231
*/
33-
public static ZipArchive readStandard(ByteBuffer data) throws IOException {
32+
public static ZipArchive readStandard(ByteData data) throws IOException {
3433
return read(data, new DefaultZipReaderStrategy());
3534
}
3635

@@ -48,6 +47,7 @@ public static ZipArchive readStandard(ByteBuffer data) throws IOException {
4847
public static ZipArchive readStandard(byte[] data) throws IOException {
4948
return read(data, new DefaultZipReaderStrategy());
5049
}
50+
5151
/**
5252
* Creates an archive using the {@link DefaultZipReaderStrategy}.
5353
*
@@ -75,7 +75,7 @@ public static ZipArchive readStandard(Path data) throws IOException {
7575
* @throws IOException
7676
* When the archive bytes cannot be read from, usually indicating a malformed zip.
7777
*/
78-
public static ZipArchive readJvm(ByteBuffer data) throws IOException {
78+
public static ZipArchive readJvm(ByteData data) throws IOException {
7979
return read(data, new JvmZipReaderStrategy());
8080
}
8181

@@ -122,11 +122,11 @@ public static ZipArchive readJvm(Path path) throws IOException {
122122
* @throws IOException
123123
* When the archive bytes cannot be read from, usually indicating a malformed zip.
124124
*/
125-
public static ZipArchive read(ByteBuffer data, ZipReaderStrategy strategy) throws IOException {
125+
public static ZipArchive read(ByteData data, ZipReaderStrategy strategy) throws IOException {
126126
if (data == null)
127127
throw new IOException("Data is null!");
128128
// The fixed size elements of a CDFH is 22 bytes (plus the variable size bits which can be 0)
129-
if (data.remaining() < 22)
129+
if (data.length() < 22)
130130
throw new IOException("Not enough bytes to read Central-Directory-File-Header, minimum=22");
131131
// Create instance
132132
ZipArchive zip = new ZipArchive();
@@ -148,7 +148,7 @@ public static ZipArchive read(ByteBuffer data, ZipReaderStrategy strategy) throw
148148
public static ZipArchive read(byte[] data, ZipReaderStrategy strategy) throws IOException {
149149
if (data == null)
150150
throw new IOException("Data is null!");
151-
return read(ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN), strategy);
151+
return read(BufferData.wrap(data), strategy);
152152
}
153153

154154
/**
@@ -167,10 +167,6 @@ public static ZipArchive read(Path path, ZipReaderStrategy strategy) throws IOEx
167167
throw new IOException("Data is null!");
168168
if (!Files.isRegularFile(path))
169169
throw new FileNotFoundException(path.toString());
170-
ByteBuffer buffer;
171-
try (FileChannel fc = FileChannel.open(path, StandardOpenOption.READ)) {
172-
buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0L, fc.size());
173-
}
174-
return read(buffer.order(ByteOrder.LITTLE_ENDIAN), strategy);
170+
return read(FileMapUtil.map(path), strategy);
175171
}
176172
}

src/main/java/software/coley/llzip/ZipPatterns.java

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

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

src/main/java/software/coley/llzip/part/CentralDirectoryFileHeader.java

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

33
import software.coley.llzip.ZipCompressions;
44
import software.coley.llzip.strategy.Decompressor;
5-
import software.coley.llzip.util.Buffers;
5+
import software.coley.llzip.util.ByteData;
6+
import software.coley.llzip.util.ByteDataUtil;
67

7-
import java.nio.ByteBuffer;
88
import java.util.Objects;
99

1010
/**
@@ -13,7 +13,7 @@
1313
* @author Matt Coley
1414
*/
1515
public class CentralDirectoryFileHeader implements ZipPart, ZipRead {
16-
private transient int offset = -1;
16+
private transient long offset = -1L;
1717
private transient LocalFileHeader linkedFileHeader;
1818
// Zip spec elements
1919
private int versionMadeBy;
@@ -32,40 +32,40 @@ public class CentralDirectoryFileHeader implements ZipPart, ZipRead {
3232
private int internalFileAttributes;
3333
private int externalFileAttributes;
3434
private int relativeOffsetOfLocalHeader;
35-
private ByteBuffer fileName;
36-
private ByteBuffer extraField;
37-
private ByteBuffer fileComment;
35+
private ByteData fileName;
36+
private ByteData extraField;
37+
private ByteData fileComment;
3838

3939
private transient String fileNameCache;
4040
private transient String fileCommentCache;
4141

4242
@Override
43-
public void read(ByteBuffer data, int offset) {
43+
public void read(ByteData data, long offset) {
4444
this.offset = offset;
45-
versionMadeBy = Buffers.readWord(data, offset + 4);
46-
versionNeededToExtract = Buffers.readWord(data, offset + 6);
47-
generalPurposeBitFlag = Buffers.readWord(data, offset + 8);
48-
compressionMethod = Buffers.readWord(data, offset + 10);
49-
lastModFileTime = Buffers.readWord(data, offset + 12);
50-
lastModFileDate = Buffers.readWord(data, offset + 14);
51-
crc32 = Buffers.readQuad(data, offset + 16);
52-
compressedSize = Buffers.readQuad(data, offset + 20);
53-
uncompressedSize = Buffers.readQuad(data, offset + 24);
54-
fileNameLength = Buffers.readWord(data, offset + 28);
55-
extraFieldLength = Buffers.readWord(data, offset + 30);
56-
fileCommentLength = Buffers.readWord(data, offset + 32);
57-
diskNumberStart = Buffers.readWord(data, offset + 34);
58-
internalFileAttributes = Buffers.readWord(data, offset + 36);
59-
externalFileAttributes = Buffers.readQuad(data, offset + 38);
60-
relativeOffsetOfLocalHeader = Buffers.readQuad(data, offset + 42);
61-
fileName = Buffers.slice(data, offset + 46, fileNameLength);
62-
extraField = Buffers.slice(data, offset + 46 + fileNameLength, extraFieldLength);
63-
fileComment = Buffers.slice(data, offset + 46 + fileNameLength + extraFieldLength, fileCommentLength);
45+
versionMadeBy = ByteDataUtil.readWord(data, offset + 4);
46+
versionNeededToExtract = ByteDataUtil.readWord(data, offset + 6);
47+
generalPurposeBitFlag = ByteDataUtil.readWord(data, offset + 8);
48+
compressionMethod = ByteDataUtil.readWord(data, offset + 10);
49+
lastModFileTime = ByteDataUtil.readWord(data, offset + 12);
50+
lastModFileDate = ByteDataUtil.readWord(data, offset + 14);
51+
crc32 = ByteDataUtil.readQuad(data, offset + 16);
52+
compressedSize = ByteDataUtil.readQuad(data, offset + 20);
53+
uncompressedSize = ByteDataUtil.readQuad(data, offset + 24);
54+
fileNameLength = ByteDataUtil.readWord(data, offset + 28);
55+
extraFieldLength = ByteDataUtil.readWord(data, offset + 30);
56+
fileCommentLength = ByteDataUtil.readWord(data, offset + 32);
57+
diskNumberStart = ByteDataUtil.readWord(data, offset + 34);
58+
internalFileAttributes = ByteDataUtil.readWord(data, offset + 36);
59+
externalFileAttributes = ByteDataUtil.readQuad(data, offset + 38);
60+
relativeOffsetOfLocalHeader = ByteDataUtil.readQuad(data, offset + 42);
61+
fileName = data.sliceOf(offset + 46, fileNameLength);
62+
extraField = data.sliceOf(offset + 46 + fileNameLength, extraFieldLength);
63+
fileComment = data.sliceOf(offset + 46 + fileNameLength + extraFieldLength, fileCommentLength);
6464
}
6565

6666
@Override
6767
public int length() {
68-
return 46 + Buffers.length(fileName) + Buffers.length(extraField) + Buffers.length(fileComment);
68+
return 46 + (int) fileName.length() + (int) extraField.length() + (int) fileComment.length();
6969
}
7070

7171
@Override
@@ -74,7 +74,7 @@ public PartType type() {
7474
}
7575

7676
@Override
77-
public int offset() {
77+
public long offset() {
7878
return offset;
7979
}
8080

@@ -366,15 +366,15 @@ public void setRelativeOffsetOfLocalHeader(int relativeOffsetOfLocalHeader) {
366366
*
367367
* @return File name.
368368
*/
369-
public ByteBuffer getFileName() {
369+
public ByteData getFileName() {
370370
return fileName;
371371
}
372372

373373
/**
374374
* @param fileName
375375
* File name.
376376
*/
377-
public void setFileName(ByteBuffer fileName) {
377+
public void setFileName(ByteData fileName) {
378378
this.fileName = fileName;
379379
}
380380

@@ -387,7 +387,7 @@ public void setFileName(ByteBuffer fileName) {
387387
public String getFileNameAsString() {
388388
String fileNameCache = this.fileNameCache;
389389
if (fileNameCache == null) {
390-
return this.fileNameCache = Buffers.toString(fileName);
390+
return this.fileNameCache = ByteDataUtil.toString(fileName);
391391
}
392392
return fileNameCache;
393393
}
@@ -396,30 +396,30 @@ public String getFileNameAsString() {
396396
* @return May be used for extra compression information,
397397
* depending on the {@link #getCompressionMethod() compression method} used.
398398
*/
399-
public ByteBuffer getExtraField() {
399+
public ByteData getExtraField() {
400400
return extraField;
401401
}
402402

403403
/**
404404
* @param extraField
405405
* Extra field bytes.
406406
*/
407-
public void setExtraField(ByteBuffer extraField) {
407+
public void setExtraField(ByteData extraField) {
408408
this.extraField = extraField;
409409
}
410410

411411
/**
412412
* @return File comment.
413413
*/
414-
public ByteBuffer getFileComment() {
414+
public ByteData getFileComment() {
415415
return fileComment;
416416
}
417417

418418
/**
419419
* @param fileComment
420420
* File comment.
421421
*/
422-
public void setFileComment(ByteBuffer fileComment) {
422+
public void setFileComment(ByteData fileComment) {
423423
this.fileComment = fileComment;
424424
}
425425

@@ -429,7 +429,7 @@ public void setFileComment(ByteBuffer fileComment) {
429429
public String getFileCommentAsString() {
430430
String fileCommentCache = this.fileCommentCache;
431431
if (fileCommentCache == null) {
432-
return this.fileCommentCache = Buffers.toString(fileComment);
432+
return this.fileCommentCache = ByteDataUtil.toString(fileComment);
433433
}
434434
return fileCommentCache;
435435
}
@@ -454,7 +454,7 @@ public String toString() {
454454
", externalFileAttributes=" + externalFileAttributes +
455455
", relativeOffsetOfLocalHeader=" + relativeOffsetOfLocalHeader +
456456
", fileName='" + fileName + '\'' +
457-
", extraField=" + Buffers.toString(extraField) +
457+
", extraField=" + ByteDataUtil.toString(extraField) +
458458
", fileComment='" + fileComment + '\'' +
459459
'}';
460460
}
@@ -483,7 +483,7 @@ public boolean equals(Object o) {
483483
relativeOffsetOfLocalHeader == that.relativeOffsetOfLocalHeader &&
484484
Objects.equals(linkedFileHeader, that.linkedFileHeader) &&
485485
fileName.equals(that.fileName) &&
486-
Buffers.equals(extraField, that.extraField) &&
486+
ByteDataUtil.equals(extraField, that.extraField) &&
487487
fileComment.equals(that.fileComment);
488488
}
489489

0 commit comments

Comments
 (0)