19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util.zip;
27
28 import java.io.Closeable;
29 import java.io.InputStream;
30 import java.io.IOException;
31 import java.io.EOFException;
32 import java.io.File;
33 import java.nio.charset.Charset;
34 import java.nio.charset.StandardCharsets;
35 import java.util.ArrayDeque;
36 import java.util.Deque;
37 import java.util.Enumeration;
38 import java.util.HashMap;
39 import java.util.Map;
40 import java.util.NoSuchElementException;
41 import java.util.WeakHashMap;
42 import java.security.AccessController;
43 import sun.security.action.GetPropertyAction;
44 import static java.util.zip.ZipConstants64.*;
45
46 /**
47 * This class is used to read entries from a zip file.
48 *
49 * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
50 * or method in this class will cause a {@link NullPointerException} to be
51 * thrown.
52 *
53 * @author David Connelly
54 */
55 public
56 class ZipFile implements ZipConstants, Closeable {
57 private long jzfile; // address of jzfile data
58 private String name; // zip file name
59 private int total; // total number of entries
60 private volatile boolean closeRequested = false;
61
62 private static final int STORED = ZipEntry.STORED;
63 private static final int DEFLATED = ZipEntry.DEFLATED;
454 private void releaseInflater(Inflater inf) {
455 if (false == inf.ended()) {
456 inf.reset();
457 synchronized (inflaterCache) {
458 inflaterCache.add(inf);
459 }
460 }
461 }
462
463 // List of available Inflater objects for decompression
464 private Deque<Inflater> inflaterCache = new ArrayDeque<>();
465
466 /**
467 * Returns the path name of the ZIP file.
468 * @return the path name of the ZIP file
469 */
470 public String getName() {
471 return name;
472 }
473
474 /**
475 * Returns an enumeration of the ZIP file entries.
476 * @return an enumeration of the ZIP file entries
477 * @throws IllegalStateException if the zip file has been closed
478 */
479 public Enumeration<? extends ZipEntry> entries() {
480 ensureOpen();
481 return new Enumeration<ZipEntry>() {
482 private int i = 0;
483 public boolean hasMoreElements() {
484 synchronized (ZipFile.this) {
485 ensureOpen();
486 return i < total;
487 }
488 }
489 public ZipEntry nextElement() throws NoSuchElementException {
490 synchronized (ZipFile.this) {
491 ensureOpen();
492 if (i >= total) {
493 throw new NoSuchElementException();
494 }
495 long jzentry = getNextEntry(jzfile, i++);
496 if (jzentry == 0) {
497 String message;
498 if (closeRequested) {
499 message = "ZipFile concurrently closed";
500 } else {
501 message = getZipMessage(ZipFile.this.jzfile);
502 }
503 throw new ZipError("jzentry == 0" +
504 ",\n jzfile = " + ZipFile.this.jzfile +
505 ",\n total = " + ZipFile.this.total +
506 ",\n name = " + ZipFile.this.name +
507 ",\n i = " + i +
508 ",\n message = " + message
509 );
510 }
511 ZipEntry ze = getZipEntry(null, jzentry);
512 freeEntry(jzfile, jzentry);
513 return ze;
514 }
515 }
516 };
517 }
518
519 private ZipEntry getZipEntry(String name, long jzentry) {
520 ZipEntry e = new ZipEntry();
521 e.flag = getEntryFlag(jzentry); // get the flag first
522 if (name != null) {
523 e.name = name;
524 } else {
525 byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME);
526 if (!zc.isUTF8() && (e.flag & EFS) != 0) {
527 e.name = zc.toStringUTF8(bname, bname.length);
528 } else {
529 e.name = zc.toString(bname, bname.length);
530 }
531 }
532 e.time = getEntryTime(jzentry);
533 e.crc = getEntryCrc(jzentry);
534 e.size = getEntrySize(jzentry);
535 e. csize = getEntryCSize(jzentry);
536 e.method = getEntryMethod(jzentry);
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util.zip;
27
28 import java.io.Closeable;
29 import java.io.InputStream;
30 import java.io.IOException;
31 import java.io.EOFException;
32 import java.io.File;
33 import java.nio.charset.Charset;
34 import java.nio.charset.StandardCharsets;
35 import java.util.ArrayDeque;
36 import java.util.Deque;
37 import java.util.Enumeration;
38 import java.util.HashMap;
39 import java.util.Iterator;
40 import java.util.Map;
41 import java.util.NoSuchElementException;
42 import java.util.Spliterator;
43 import java.util.Spliterators;
44 import java.util.WeakHashMap;
45 import java.util.stream.Stream;
46 import java.util.stream.StreamSupport;
47
48 import static java.util.zip.ZipConstants64.*;
49
50 /**
51 * This class is used to read entries from a zip file.
52 *
53 * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
54 * or method in this class will cause a {@link NullPointerException} to be
55 * thrown.
56 *
57 * @author David Connelly
58 */
59 public
60 class ZipFile implements ZipConstants, Closeable {
61 private long jzfile; // address of jzfile data
62 private String name; // zip file name
63 private int total; // total number of entries
64 private volatile boolean closeRequested = false;
65
66 private static final int STORED = ZipEntry.STORED;
67 private static final int DEFLATED = ZipEntry.DEFLATED;
458 private void releaseInflater(Inflater inf) {
459 if (false == inf.ended()) {
460 inf.reset();
461 synchronized (inflaterCache) {
462 inflaterCache.add(inf);
463 }
464 }
465 }
466
467 // List of available Inflater objects for decompression
468 private Deque<Inflater> inflaterCache = new ArrayDeque<>();
469
470 /**
471 * Returns the path name of the ZIP file.
472 * @return the path name of the ZIP file
473 */
474 public String getName() {
475 return name;
476 }
477
478 protected class ZipEntryIterator implements Enumeration<ZipEntry>, Iterator<ZipEntry> {
479 private int i = 0;
480
481 public ZipEntryIterator() {
482 ensureOpen();
483 }
484
485 public boolean hasMoreElements() {
486 return hasNext();
487 }
488
489 public boolean hasNext() {
490 synchronized (ZipFile.this) {
491 ensureOpen();
492 return i < total;
493 }
494 }
495
496 public ZipEntry nextElement() {
497 return next();
498 }
499
500 public ZipEntry next() {
501 synchronized (ZipFile.this) {
502 ensureOpen();
503 if (i >= total) {
504 throw new NoSuchElementException();
505 }
506 long jzentry = getNextEntry(jzfile, i++);
507 if (jzentry == 0) {
508 String message;
509 if (closeRequested) {
510 message = "ZipFile concurrently closed";
511 } else {
512 message = getZipMessage(ZipFile.this.jzfile);
513 }
514 throw new ZipError("jzentry == 0" +
515 ",\n jzfile = " + ZipFile.this.jzfile +
516 ",\n total = " + ZipFile.this.total +
517 ",\n name = " + ZipFile.this.name +
518 ",\n i = " + i +
519 ",\n message = " + message
520 );
521 }
522 ZipEntry ze = getZipEntry(null, jzentry);
523 freeEntry(jzfile, jzentry);
524 return ze;
525 }
526 }
527 }
528
529 /**
530 * Returns an enumeration of the ZIP file entries.
531 * @return an enumeration of the ZIP file entries
532 * @throws IllegalStateException if the zip file has been closed
533 */
534 public Enumeration<? extends ZipEntry> entries() {
535 return new ZipEntryIterator();
536 }
537
538 /**
539 * Return a {@code Stream} of the ZIP file entries.
540 *
541 * @return a {@code Stream} of entries in this ZIP file
542 * @throws IllegalStateException if the zip file has been closed
543 * @since 1.8
544 */
545 public Stream<? extends ZipEntry> stream() {
546 return StreamSupport.stream(Spliterators.spliterator(
547 new ZipEntryIterator(), size(),
548 Spliterator.DISTINCT | Spliterator.IMMUTABLE | Spliterator.NONNULL));
549 }
550
551 private ZipEntry getZipEntry(String name, long jzentry) {
552 ZipEntry e = new ZipEntry();
553 e.flag = getEntryFlag(jzentry); // get the flag first
554 if (name != null) {
555 e.name = name;
556 } else {
557 byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME);
558 if (!zc.isUTF8() && (e.flag & EFS) != 0) {
559 e.name = zc.toStringUTF8(bname, bname.length);
560 } else {
561 e.name = zc.toString(bname, bname.length);
562 }
563 }
564 e.time = getEntryTime(jzentry);
565 e.crc = getEntryCrc(jzentry);
566 e.size = getEntrySize(jzentry);
567 e. csize = getEntryCSize(jzentry);
568 e.method = getEntryMethod(jzentry);
|