1 /*
2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
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
44 public
45 class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
46
47 /**
48 * Whether to use ZIP64 for zip files with more than 64k entries.
49 * Until ZIP64 support in zip implementations is ubiquitous, this
50 * system property allows the creation of zip files which can be
51 * read by legacy zip implementations which tolerate "incorrect"
52 * total entry count fields, such as the ones in jdk6, and even
53 * some in jdk7.
54 */
55 private static final boolean inhibitZip64 =
56 Boolean.parseBoolean(
57 java.security.AccessController.doPrivileged(
58 new sun.security.action.GetPropertyAction(
59 "jdk.util.zip.inhibitZip64", "false")));
60
61 private static class XEntry {
62 final ZipEntry entry;
63 final long offset;
64 long dostime; // last modification time in msdos format
65 public XEntry(ZipEntry entry, long offset) {
66 this.entry = entry;
67 this.offset = offset;
68 }
69 }
70
71 private XEntry current;
72 private Vector<XEntry> xentries = new Vector<>();
73 private HashSet<String> names = new HashSet<>();
74 private CRC32 crc = new CRC32();
75 private long written = 0;
76 private long locoff = 0;
77 private byte[] comment;
78 private int method = DEFLATED;
79 private boolean finished;
80
81 private boolean closed = false;
82
83 private final ZipCoder zc;
84
175 */
176 public void setLevel(int level) {
177 def.setLevel(level);
178 }
179
180 /**
181 * Begins writing a new ZIP file entry and positions the stream to the
182 * start of the entry data. Closes the current entry if still active.
183 * The default compression method will be used if no compression method
184 * was specified for the entry, and the current time will be used if
185 * the entry has no set modification time.
186 * @param e the ZIP entry to be written
187 * @exception ZipException if a ZIP format error has occurred
188 * @exception IOException if an I/O error has occurred
189 */
190 public void putNextEntry(ZipEntry e) throws IOException {
191 ensureOpen();
192 if (current != null) {
193 closeEntry(); // close previous entry
194 }
195 if (e.time == -1) {
196 // by default, do NOT use extended timestamps in extra
197 // data, for now.
198 e.setTime(System.currentTimeMillis());
199 }
200 if (e.method == -1) {
201 e.method = method; // use default method
202 }
203 // store size, compressed size, and crc-32 in LOC header
204 e.flag = 0;
205 switch (e.method) {
206 case DEFLATED:
207 // store size, compressed size, and crc-32 in data descriptor
208 // immediately following the compressed entry data
209 if (e.size == -1 || e.csize == -1 || e.crc == -1)
210 e.flag = 8;
211
212 break;
213 case STORED:
214 // compressed size, uncompressed size, and crc-32 must all be
215 // set for entries using STORED compression method
372 * Closes the ZIP output stream as well as the stream being filtered.
373 * @exception ZipException if a ZIP file error has occurred
374 * @exception IOException if an I/O error has occurred
375 */
376 public void close() throws IOException {
377 if (!closed) {
378 super.close();
379 closed = true;
380 }
381 }
382
383 /*
384 * Writes local file (LOC) header for specified entry.
385 */
386 private void writeLOC(XEntry xentry) throws IOException {
387 ZipEntry e = xentry.entry;
388 int flag = e.flag;
389 boolean hasZip64 = false;
390 int elen = getExtraLen(e.extra);
391
392 // keep a copy of dostime for writeCEN(), otherwise the tz
393 // sensitive local time entries in loc and cen might be
394 // different if the default tz get changed during writeLOC()
395 // and writeCEN()
396 xentry.dostime = javaToDosTime(e.time);
397
398 writeInt(LOCSIG); // LOC header signature
399 if ((flag & 8) == 8) {
400 writeShort(version(e)); // version needed to extract
401 writeShort(flag); // general purpose bit flag
402 writeShort(e.method); // compression method
403 writeInt(xentry.dostime); // last modification time
404 // store size, uncompressed size, and crc-32 in data descriptor
405 // immediately following compressed entry data
406 writeInt(0);
407 writeInt(0);
408 writeInt(0);
409 } else {
410 if (e.csize >= ZIP64_MAGICVAL || e.size >= ZIP64_MAGICVAL) {
411 hasZip64 = true;
412 writeShort(45); // ver 4.5 for zip64
413 } else {
414 writeShort(version(e)); // version needed to extract
415 }
416 writeShort(flag); // general purpose bit flag
417 writeShort(e.method); // compression method
418 writeInt(xentry.dostime); // last modification time
419 writeInt(e.crc); // crc-32
420 if (hasZip64) {
421 writeInt(ZIP64_MAGICVAL);
422 writeInt(ZIP64_MAGICVAL);
423 elen += 20; //headid(2) + size(2) + size(8) + csize(8)
424 } else {
425 writeInt(e.csize); // compressed size
426 writeInt(e.size); // uncompressed size
427 }
428 }
429 byte[] nameBytes = zc.getBytes(e.name);
430 writeShort(nameBytes.length);
431
432 int elenEXTT = 0; // info-zip extended timestamp
433 int flagEXTT = 0;
434 if (e.mtime != null) {
435 elenEXTT += 4;
436 flagEXTT |= EXTT_FLAG_LMT;
437 }
438 if (e.atime != null) {
505 if (e.size >= ZIP64_MAGICVAL) {
506 size = ZIP64_MAGICVAL; // size(8)
507 elenZIP64 += 8;
508 hasZip64 = true;
509 }
510 if (xentry.offset >= ZIP64_MAGICVAL) {
511 offset = ZIP64_MAGICVAL;
512 elenZIP64 += 8; // offset(8)
513 hasZip64 = true;
514 }
515 writeInt(CENSIG); // CEN header signature
516 if (hasZip64) {
517 writeShort(45); // ver 4.5 for zip64
518 writeShort(45);
519 } else {
520 writeShort(version); // version made by
521 writeShort(version); // version needed to extract
522 }
523 writeShort(flag); // general purpose bit flag
524 writeShort(e.method); // compression method
525 // use the copy in xentry, which has been converted
526 // from e.time in writeLOC()
527 writeInt(xentry.dostime); // last modification time
528 writeInt(e.crc); // crc-32
529 writeInt(csize); // compressed size
530 writeInt(size); // uncompressed size
531 byte[] nameBytes = zc.getBytes(e.name);
532 writeShort(nameBytes.length);
533
534 int elen = getExtraLen(e.extra);
535 if (hasZip64) {
536 elen += (elenZIP64 + 4);// + headid(2) + datasize(2)
537 }
538 // cen info-zip extended timestamp only outputs mtime
539 // but set the flag for a/ctime, if present in loc
540 int flagEXTT = 0;
541 if (e.mtime != null) {
542 elen += 4; // + mtime(4)
543 flagEXTT |= EXTT_FLAG_LMT;
544 }
545 if (e.atime != null) {
546 flagEXTT |= EXTT_FLAG_LAT;
547 }
|
1 /*
2 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
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
44 public
45 class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
46
47 /**
48 * Whether to use ZIP64 for zip files with more than 64k entries.
49 * Until ZIP64 support in zip implementations is ubiquitous, this
50 * system property allows the creation of zip files which can be
51 * read by legacy zip implementations which tolerate "incorrect"
52 * total entry count fields, such as the ones in jdk6, and even
53 * some in jdk7.
54 */
55 private static final boolean inhibitZip64 =
56 Boolean.parseBoolean(
57 java.security.AccessController.doPrivileged(
58 new sun.security.action.GetPropertyAction(
59 "jdk.util.zip.inhibitZip64", "false")));
60
61 private static class XEntry {
62 final ZipEntry entry;
63 final long offset;
64 public XEntry(ZipEntry entry, long offset) {
65 this.entry = entry;
66 this.offset = offset;
67 }
68 }
69
70 private XEntry current;
71 private Vector<XEntry> xentries = new Vector<>();
72 private HashSet<String> names = new HashSet<>();
73 private CRC32 crc = new CRC32();
74 private long written = 0;
75 private long locoff = 0;
76 private byte[] comment;
77 private int method = DEFLATED;
78 private boolean finished;
79
80 private boolean closed = false;
81
82 private final ZipCoder zc;
83
174 */
175 public void setLevel(int level) {
176 def.setLevel(level);
177 }
178
179 /**
180 * Begins writing a new ZIP file entry and positions the stream to the
181 * start of the entry data. Closes the current entry if still active.
182 * The default compression method will be used if no compression method
183 * was specified for the entry, and the current time will be used if
184 * the entry has no set modification time.
185 * @param e the ZIP entry to be written
186 * @exception ZipException if a ZIP format error has occurred
187 * @exception IOException if an I/O error has occurred
188 */
189 public void putNextEntry(ZipEntry e) throws IOException {
190 ensureOpen();
191 if (current != null) {
192 closeEntry(); // close previous entry
193 }
194 if (e.xdostime == -1) {
195 // by default, do NOT use extended timestamps in extra
196 // data, for now.
197 e.setTime(System.currentTimeMillis());
198 }
199 if (e.method == -1) {
200 e.method = method; // use default method
201 }
202 // store size, compressed size, and crc-32 in LOC header
203 e.flag = 0;
204 switch (e.method) {
205 case DEFLATED:
206 // store size, compressed size, and crc-32 in data descriptor
207 // immediately following the compressed entry data
208 if (e.size == -1 || e.csize == -1 || e.crc == -1)
209 e.flag = 8;
210
211 break;
212 case STORED:
213 // compressed size, uncompressed size, and crc-32 must all be
214 // set for entries using STORED compression method
371 * Closes the ZIP output stream as well as the stream being filtered.
372 * @exception ZipException if a ZIP file error has occurred
373 * @exception IOException if an I/O error has occurred
374 */
375 public void close() throws IOException {
376 if (!closed) {
377 super.close();
378 closed = true;
379 }
380 }
381
382 /*
383 * Writes local file (LOC) header for specified entry.
384 */
385 private void writeLOC(XEntry xentry) throws IOException {
386 ZipEntry e = xentry.entry;
387 int flag = e.flag;
388 boolean hasZip64 = false;
389 int elen = getExtraLen(e.extra);
390
391 writeInt(LOCSIG); // LOC header signature
392 if ((flag & 8) == 8) {
393 writeShort(version(e)); // version needed to extract
394 writeShort(flag); // general purpose bit flag
395 writeShort(e.method); // compression method
396 writeInt(e.xdostime); // last modification time
397 // store size, uncompressed size, and crc-32 in data descriptor
398 // immediately following compressed entry data
399 writeInt(0);
400 writeInt(0);
401 writeInt(0);
402 } else {
403 if (e.csize >= ZIP64_MAGICVAL || e.size >= ZIP64_MAGICVAL) {
404 hasZip64 = true;
405 writeShort(45); // ver 4.5 for zip64
406 } else {
407 writeShort(version(e)); // version needed to extract
408 }
409 writeShort(flag); // general purpose bit flag
410 writeShort(e.method); // compression method
411 writeInt(e.xdostime); // last modification time
412 writeInt(e.crc); // crc-32
413 if (hasZip64) {
414 writeInt(ZIP64_MAGICVAL);
415 writeInt(ZIP64_MAGICVAL);
416 elen += 20; //headid(2) + size(2) + size(8) + csize(8)
417 } else {
418 writeInt(e.csize); // compressed size
419 writeInt(e.size); // uncompressed size
420 }
421 }
422 byte[] nameBytes = zc.getBytes(e.name);
423 writeShort(nameBytes.length);
424
425 int elenEXTT = 0; // info-zip extended timestamp
426 int flagEXTT = 0;
427 if (e.mtime != null) {
428 elenEXTT += 4;
429 flagEXTT |= EXTT_FLAG_LMT;
430 }
431 if (e.atime != null) {
498 if (e.size >= ZIP64_MAGICVAL) {
499 size = ZIP64_MAGICVAL; // size(8)
500 elenZIP64 += 8;
501 hasZip64 = true;
502 }
503 if (xentry.offset >= ZIP64_MAGICVAL) {
504 offset = ZIP64_MAGICVAL;
505 elenZIP64 += 8; // offset(8)
506 hasZip64 = true;
507 }
508 writeInt(CENSIG); // CEN header signature
509 if (hasZip64) {
510 writeShort(45); // ver 4.5 for zip64
511 writeShort(45);
512 } else {
513 writeShort(version); // version made by
514 writeShort(version); // version needed to extract
515 }
516 writeShort(flag); // general purpose bit flag
517 writeShort(e.method); // compression method
518 writeInt(e.xdostime); // last modification time
519 writeInt(e.crc); // crc-32
520 writeInt(csize); // compressed size
521 writeInt(size); // uncompressed size
522 byte[] nameBytes = zc.getBytes(e.name);
523 writeShort(nameBytes.length);
524
525 int elen = getExtraLen(e.extra);
526 if (hasZip64) {
527 elen += (elenZIP64 + 4);// + headid(2) + datasize(2)
528 }
529 // cen info-zip extended timestamp only outputs mtime
530 // but set the flag for a/ctime, if present in loc
531 int flagEXTT = 0;
532 if (e.mtime != null) {
533 elen += 4; // + mtime(4)
534 flagEXTT |= EXTT_FLAG_LMT;
535 }
536 if (e.atime != null) {
537 flagEXTT |= EXTT_FLAG_LAT;
538 }
|