22
33import software .coley .llzip .ZipCompressions ;
44import software .coley .llzip .strategy .Decompressor ;
5- import software .coley .llzip .util .Array ;
5+ import software .coley .llzip .util .Buffers ;
66
7- import java .util . Arrays ;
7+ import java .nio . ByteBuffer ;
88import java .util .Objects ;
99
1010/**
@@ -32,37 +32,40 @@ public class CentralDirectoryFileHeader implements ZipPart, ZipRead {
3232 private int internalFileAttributes ;
3333 private int externalFileAttributes ;
3434 private int relativeOffsetOfLocalHeader ;
35- private String fileName ;
36- private byte [] extraField ;
37- private String fileComment ;
35+ private ByteBuffer fileName ;
36+ private ByteBuffer extraField ;
37+ private ByteBuffer fileComment ;
38+
39+ private transient String fileNameCache ;
40+ private transient String fileCommentCache ;
3841
3942 @ Override
40- public void read (byte [] data , int offset ) {
43+ public void read (ByteBuffer data , int offset ) {
4144 this .offset = offset ;
42- versionMadeBy = Array .readWord (data , offset + 4 );
43- versionNeededToExtract = Array .readWord (data , offset + 6 );
44- generalPurposeBitFlag = Array .readWord (data , offset + 8 );
45- compressionMethod = Array .readWord (data , offset + 10 );
46- lastModFileTime = Array .readWord (data , offset + 12 );
47- lastModFileDate = Array .readWord (data , offset + 14 );
48- crc32 = Array .readQuad (data , offset + 16 );
49- compressedSize = Array .readQuad (data , offset + 20 );
50- uncompressedSize = Array .readQuad (data , offset + 24 );
51- fileNameLength = Array .readWord (data , offset + 28 );
52- extraFieldLength = Array .readWord (data , offset + 30 );
53- fileCommentLength = Array .readWord (data , offset + 32 );
54- diskNumberStart = Array .readWord (data , offset + 34 );
55- internalFileAttributes = Array .readWord (data , offset + 36 );
56- externalFileAttributes = Array .readQuad (data , offset + 38 );
57- relativeOffsetOfLocalHeader = Array .readQuad (data , offset + 42 );
58- fileName = Array . readString (data , offset + 46 , fileNameLength );
59- extraField = Array . readArray (data , offset + 46 + fileNameLength , extraFieldLength );
60- fileComment = Array . readString (data , offset + 46 + fileNameLength + extraFieldLength , fileCommentLength );
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 );
6164 }
6265
6366 @ Override
6467 public int length () {
65- return 46 + fileName .length () + extraField .length + fileComment .length ();
68+ return 46 + Buffers .length (fileName ) + Buffers .length ( extraField ) + Buffers .length (fileComment );
6669 }
6770
6871 @ Override
@@ -363,49 +366,74 @@ public void setRelativeOffsetOfLocalHeader(int relativeOffsetOfLocalHeader) {
363366 *
364367 * @return File name.
365368 */
366- public String getFileName () {
369+ public ByteBuffer getFileName () {
367370 return fileName ;
368371 }
369372
370373 /**
371374 * @param fileName
372375 * File name.
373376 */
374- public void setFileName (String fileName ) {
377+ public void setFileName (ByteBuffer fileName ) {
375378 this .fileName = fileName ;
376379 }
377380
381+ /**
382+ * Should match {@link CentralDirectoryFileHeader#getFileName()} but is not a strict requirement.
383+ * If they do not match, the central directory file name should be trusted instead.
384+ *
385+ * @return File name.
386+ */
387+ public String getFileNameAsString () {
388+ String fileNameCache = this .fileNameCache ;
389+ if (fileNameCache == null ) {
390+ return this .fileNameCache = Buffers .toString (fileName );
391+ }
392+ return fileNameCache ;
393+ }
394+
378395 /**
379396 * @return May be used for extra compression information,
380397 * depending on the {@link #getCompressionMethod() compression method} used.
381398 */
382- public byte [] getExtraField () {
399+ public ByteBuffer getExtraField () {
383400 return extraField ;
384401 }
385402
386403 /**
387404 * @param extraField
388405 * Extra field bytes.
389406 */
390- public void setExtraField (byte [] extraField ) {
407+ public void setExtraField (ByteBuffer extraField ) {
391408 this .extraField = extraField ;
392409 }
393410
394411 /**
395412 * @return File comment.
396413 */
397- public String getFileComment () {
414+ public ByteBuffer getFileComment () {
398415 return fileComment ;
399416 }
400417
401418 /**
402419 * @param fileComment
403420 * File comment.
404421 */
405- public void setFileComment (String fileComment ) {
422+ public void setFileComment (ByteBuffer fileComment ) {
406423 this .fileComment = fileComment ;
407424 }
408425
426+ /**
427+ * @return File comment.
428+ */
429+ public String getFileCommentAsString () {
430+ String fileCommentCache = this .fileCommentCache ;
431+ if (fileCommentCache == null ) {
432+ return this .fileCommentCache = Buffers .toString (fileComment );
433+ }
434+ return fileCommentCache ;
435+ }
436+
409437 @ Override
410438 public String toString () {
411439 return "CentralDirectoryFileHeader{" +
@@ -426,7 +454,7 @@ public String toString() {
426454 ", externalFileAttributes=" + externalFileAttributes +
427455 ", relativeOffsetOfLocalHeader=" + relativeOffsetOfLocalHeader +
428456 ", fileName='" + fileName + '\'' +
429- ", extraField=" + Arrays .toString (extraField ) +
457+ ", extraField=" + Buffers .toString (extraField ) +
430458 ", fileComment='" + fileComment + '\'' +
431459 '}' ;
432460 }
@@ -455,7 +483,7 @@ public boolean equals(Object o) {
455483 relativeOffsetOfLocalHeader == that .relativeOffsetOfLocalHeader &&
456484 Objects .equals (linkedFileHeader , that .linkedFileHeader ) &&
457485 fileName .equals (that .fileName ) &&
458- Arrays .equals (extraField , that .extraField ) &&
486+ Buffers .equals (extraField , that .extraField ) &&
459487 fileComment .equals (that .fileComment );
460488 }
461489
@@ -465,7 +493,7 @@ public int hashCode() {
465493 compressionMethod , lastModFileTime , lastModFileDate , crc32 , compressedSize , uncompressedSize ,
466494 fileNameLength , extraFieldLength , fileCommentLength , diskNumberStart , internalFileAttributes ,
467495 externalFileAttributes , relativeOffsetOfLocalHeader , fileName , fileComment );
468- result = 31 * result + Arrays .hashCode (extraField );
496+ result = 31 * result + extraField .hashCode ();
469497 return result ;
470498 }
471499}
0 commit comments