26
26
import java .util .Date ;
27
27
import java .util .Enumeration ;
28
28
import java .util .Hashtable ;
29
+ import java .util .Map ;
29
30
import java .util .zip .Inflater ;
30
31
import java .util .zip .InflaterInputStream ;
31
32
import java .util .zip .ZipException ;
58
59
* <li>close is allowed to throw IOException.</li>
59
60
* </ul>
60
61
*
61
- * @version $Revision$ $Date$
62
+ * @version $Revision: 7140 $ $Date: 2008-01-06 12:50:12 +0100 (dim., 06 janv. 2008) $
62
63
* from org.apache.ant.tools.zip.ZipFile v1.13
63
64
*/
64
- @ SuppressWarnings ("JavaDoc" )
65
- public class ZipFile
66
- implements ArchiveFile
65
+ public class ZipFile implements ArchiveFile
67
66
{
68
67
69
68
/**
@@ -80,7 +79,7 @@ public class ZipFile
80
79
/**
81
80
* Maps ZipEntrys to Longs, recording the offsets of the actual file data.
82
81
*/
83
- private final Hashtable <ZipEntry , Long > dataOffsets = new Hashtable <ZipEntry , Long >();
82
+ private Hashtable <ZipEntry , Long > dataOffsets = new Hashtable <ZipEntry , Long >();
84
83
85
84
/**
86
85
* The encoding to use for filenames and the file comment.
@@ -233,7 +232,8 @@ public void close()
233
232
}
234
233
};
235
234
default :
236
- throw new ZipException ( "Found unsupported compression method " + ze .getMethod () );
235
+ throw new ZipException ( "Found unsupported compression method "
236
+ + ze .getMethod () );
237
237
}
238
238
}
239
239
@@ -279,46 +279,45 @@ private void populateFromCentralDirectory()
279
279
int off = 0 ;
280
280
ZipEntry ze = new ZipEntry ();
281
281
282
- ZipShort versionMadeBy = new ZipShort ( cfh , off );
282
+ ze . setPlatform ( ( ZipShort . convert ( cfh , off ) >> 8 ) & 0x0F );
283
283
off += 2 ;
284
- ze .setPlatform ( ( versionMadeBy .getValue () >> 8 ) & 0x0F );
285
284
286
285
off += 4 ; // skip version info and general purpose byte
287
286
288
- ze .setMethod ( ( new ZipShort ( cfh , off ) ). getValue ( ) );
287
+ ze .setMethod ( ZipShort . convert ( cfh , off ) );
289
288
off += 2 ;
290
289
291
- ze .setTime ( fromDosTime ( new ZipLong ( cfh , off ) ).getTime () );
290
+ ze .setTime ( fromDosTime ( ZipLong . convert ( cfh , off ) ).getTime () );
292
291
off += 4 ;
293
292
294
- ze .setCrc ( ( new ZipLong ( cfh , off ) ). getValue () );
293
+ ze .setCrc ( ZipLong . convert ( cfh , off ));
295
294
off += 4 ;
296
295
297
- ze .setCompressedSize ( ( new ZipLong ( cfh , off ) ). getValue () );
296
+ ze .setCompressedSize ( ZipLong . convert ( cfh , off ));
298
297
off += 4 ;
299
298
300
- ze .setSize ( ( new ZipLong ( cfh , off ) ). getValue ( ) );
299
+ ze .setSize ( ZipLong . convert ( cfh , off ) );
301
300
off += 4 ;
302
301
303
- int fileNameLen = ( new ZipShort ( cfh , off ) ). getValue ( );
302
+ int fileNameLen = ZipShort . convert ( cfh , off );
304
303
off += 2 ;
305
304
306
- int extraLen = ( new ZipShort ( cfh , off ) ). getValue ( );
305
+ int extraLen = ZipShort . convert ( cfh , off );
307
306
off += 2 ;
308
307
309
- int commentLen = ( new ZipShort ( cfh , off ) ). getValue ( );
308
+ int commentLen = ZipShort . convert ( cfh , off );
310
309
off += 2 ;
311
310
312
311
off += 2 ; // disk number
313
312
314
- ze .setInternalAttributes ( ( new ZipShort ( cfh , off ) ). getValue () );
313
+ ze .setInternalAttributes ( ZipShort . convert ( cfh , off ));
315
314
off += 2 ;
316
315
317
- ze .setExternalAttributes ( ( new ZipLong ( cfh , off ) ). getValue ( ) );
316
+ ze .setExternalAttributes ( ZipLong . convert ( cfh , off ) );
318
317
off += 4 ;
319
318
320
319
// LFH offset
321
- entries .put ( ze , ( new ZipLong ( cfh , off )). getValue () );
320
+ entries .put ( ze , new Long ( ZipLong . convert ( cfh , off )) );
322
321
323
322
byte [] fileName = new byte [fileNameLen ];
324
323
archive .readFully ( fileName );
@@ -405,7 +404,7 @@ private void positionAtCentralDirectory()
405
404
archive .seek ( off + CFD_LOCATOR_OFFSET );
406
405
byte [] cfdOffset = new byte [4 ];
407
406
archive .readFully ( cfdOffset );
408
- archive .seek ( ( new ZipLong ( cfdOffset ) ). getValue ( ) );
407
+ archive .seek ( ZipLong . convert ( cfdOffset ) );
409
408
}
410
409
411
410
/**
@@ -433,27 +432,41 @@ private void positionAtCentralDirectory()
433
432
private void resolveLocalFileHeaderData ()
434
433
throws IOException
435
434
{
436
- Enumeration e = getEntries ();
437
- while ( e .hasMoreElements () )
438
- {
439
- ZipEntry ze = (ZipEntry ) e .nextElement ();
440
- long offset = entries .get (ze );
435
+ // Create a sufficiently large HashTable in order to avoid
436
+ // the cost or repeated expansion of the backing array
437
+ // in case of large jars
438
+ dataOffsets = new Hashtable <ZipEntry , Long >(entries .size ());
439
+
440
+ // Allocated array once outside the loop
441
+ final byte [] b = new byte [2 ];
442
+
443
+ // Iterate using the entrySet
444
+ for (Map .Entry <ZipEntry , Long > e : entries .entrySet ()) {
445
+ ZipEntry ze = e .getKey ();
446
+ long offset = e .getValue ();
441
447
archive .seek ( offset + LFH_OFFSET_FOR_FILENAME_LENGTH );
442
- byte [] b = new byte [2 ];
443
448
archive .readFully ( b );
444
- int fileNameLen = ( new ZipShort ( b ) ). getValue ( );
449
+ int fileNameLen = ZipShort . convert ( b );
445
450
archive .readFully ( b );
446
- int extraFieldLen = ( new ZipShort ( b ) ). getValue ( );
451
+ int extraFieldLen = ZipShort . convert ( b );
447
452
archive .skipBytes ( fileNameLen );
448
453
byte [] localExtraData = new byte [extraFieldLen ];
449
454
archive .readFully ( localExtraData );
450
455
ze .setExtra ( localExtraData );
451
- dataOffsets .put ( ze ,
452
- offset + LFH_OFFSET_FOR_FILENAME_LENGTH
453
- + 2 + 2 + fileNameLen + extraFieldLen );
456
+ dataOffsets .put ( ze , offset + LFH_OFFSET_FOR_FILENAME_LENGTH + 2 + 2 + fileNameLen + extraFieldLen );
454
457
}
455
458
}
456
459
460
+ /**
461
+ * Creating a Calendar is relatively expensive. So create on per thread and
462
+ * keep it alive
463
+ */
464
+ static final ThreadLocal threadCalander = new ThreadLocal () {
465
+ protected Object initialValue () {
466
+ return Calendar .getInstance ();
467
+ }
468
+ };
469
+
457
470
/**
458
471
* Convert a DOS date/time field to a Date object.
459
472
*
@@ -463,7 +476,12 @@ private void resolveLocalFileHeaderData()
463
476
protected static Date fromDosTime ( ZipLong l )
464
477
{
465
478
long dosTime = l .getValue ();
466
- Calendar cal = Calendar .getInstance ();
479
+ return fromDosTime (dosTime );
480
+ }
481
+
482
+ protected static Date fromDosTime ( long dosTime )
483
+ {
484
+ Calendar cal = (Calendar ) threadCalander .get ();
467
485
cal .set ( Calendar .YEAR , (int ) ( ( dosTime >> 25 ) & 0x7f ) + 1980 );
468
486
cal .set ( Calendar .MONTH , (int ) ( ( dosTime >> 21 ) & 0x0f ) - 1 );
469
487
cal .set ( Calendar .DATE , (int ) ( dosTime >> 16 ) & 0x1f );
@@ -586,5 +604,4 @@ void addDummy()
586
604
addDummyByte = true ;
587
605
}
588
606
}
589
-
590
607
}
0 commit comments