81 this(in, StandardCharsets.UTF_8);
82 }
83
84 /**
85 * Creates a new ZIP input stream.
86 *
87 * @param in the actual input stream
88 *
89 * @param charset
90 * The {@linkplain java.nio.charset.Charset charset} to be
91 * used to decode the ZIP entry name (ignored if the
92 * <a href="package-summary.html#lang_encoding"> language
93 * encoding bit</a> of the ZIP entry's general purpose bit
94 * flag is set).
95 *
96 * @since 1.7
97 */
98 public ZipInputStream(InputStream in, Charset charset) {
99 super(new PushbackInputStream(in, 512), new Inflater(true), 512);
100 usesDefaultInflater = true;
101 if(in == null) {
102 throw new NullPointerException("in is null");
103 }
104 if (charset == null)
105 throw new NullPointerException("charset is null");
106 this.zc = ZipCoder.get(charset);
107 }
108
109 /**
110 * Reads the next ZIP file entry and positions the stream at the
111 * beginning of the entry data.
112 * @return the next ZIP file entry, or null if there are no more entries
113 * @exception ZipException if a ZIP file error has occurred
114 * @exception IOException if an I/O error has occurred
115 */
116 public ZipEntry getNextEntry() throws IOException {
117 ensureOpen();
118 if (entry != null) {
119 closeEntry();
120 }
121 crc.reset();
266 if (!closed) {
267 super.close();
268 closed = true;
269 }
270 }
271
272 private byte[] b = new byte[256];
273
274 /*
275 * Reads local file (LOC) header for next entry.
276 */
277 private ZipEntry readLOC() throws IOException {
278 try {
279 readFully(tmpbuf, 0, LOCHDR);
280 } catch (EOFException e) {
281 return null;
282 }
283 if (get32(tmpbuf, 0) != LOCSIG) {
284 return null;
285 }
286 // get flag first, we need check EFS.
287 flag = get16(tmpbuf, LOCFLG);
288 // get the entry name and create the ZipEntry first
289 int len = get16(tmpbuf, LOCNAM);
290 int blen = b.length;
291 if (len > blen) {
292 do {
293 blen = blen * 2;
294 } while (len > blen);
295 b = new byte[blen];
296 }
297 readFully(b, 0, len);
298 // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8
299 ZipEntry e = createZipEntry(((flag & EFS) != 0)
300 ? zc.toStringUTF8(b, len)
301 : zc.toString(b, len));
302 // now get the remaining fields for the entry
303 if ((flag & 1) == 1) {
304 throw new ZipException("encrypted ZIP entry not supported");
305 }
306 e.method = get16(tmpbuf, LOCHOW);
307 e.xdostime = get32(tmpbuf, LOCTIM);
308 if ((flag & 8) == 8) {
309 /* "Data Descriptor" present */
310 if (e.method != DEFLATED) {
311 throw new ZipException(
312 "only DEFLATED entries can have EXT descriptor");
313 }
314 } else {
315 e.crc = get32(tmpbuf, LOCCRC);
316 e.csize = get32(tmpbuf, LOCSIZ);
317 e.size = get32(tmpbuf, LOCLEN);
318 }
319 len = get16(tmpbuf, LOCEXT);
|
81 this(in, StandardCharsets.UTF_8);
82 }
83
84 /**
85 * Creates a new ZIP input stream.
86 *
87 * @param in the actual input stream
88 *
89 * @param charset
90 * The {@linkplain java.nio.charset.Charset charset} to be
91 * used to decode the ZIP entry name (ignored if the
92 * <a href="package-summary.html#lang_encoding"> language
93 * encoding bit</a> of the ZIP entry's general purpose bit
94 * flag is set).
95 *
96 * @since 1.7
97 */
98 public ZipInputStream(InputStream in, Charset charset) {
99 super(new PushbackInputStream(in, 512), new Inflater(true), 512);
100 usesDefaultInflater = true;
101 if (in == null) {
102 throw new NullPointerException("in is null");
103 }
104 if (charset == null)
105 throw new NullPointerException("charset is null");
106 this.zc = ZipCoder.get(charset);
107 }
108
109 /**
110 * Reads the next ZIP file entry and positions the stream at the
111 * beginning of the entry data.
112 * @return the next ZIP file entry, or null if there are no more entries
113 * @exception ZipException if a ZIP file error has occurred
114 * @exception IOException if an I/O error has occurred
115 */
116 public ZipEntry getNextEntry() throws IOException {
117 ensureOpen();
118 if (entry != null) {
119 closeEntry();
120 }
121 crc.reset();
266 if (!closed) {
267 super.close();
268 closed = true;
269 }
270 }
271
272 private byte[] b = new byte[256];
273
274 /*
275 * Reads local file (LOC) header for next entry.
276 */
277 private ZipEntry readLOC() throws IOException {
278 try {
279 readFully(tmpbuf, 0, LOCHDR);
280 } catch (EOFException e) {
281 return null;
282 }
283 if (get32(tmpbuf, 0) != LOCSIG) {
284 return null;
285 }
286 // get flag first, we need check USE_UTF8.
287 flag = get16(tmpbuf, LOCFLG);
288 // get the entry name and create the ZipEntry first
289 int len = get16(tmpbuf, LOCNAM);
290 int blen = b.length;
291 if (len > blen) {
292 do {
293 blen = blen * 2;
294 } while (len > blen);
295 b = new byte[blen];
296 }
297 readFully(b, 0, len);
298 // Force to use UTF-8 if the USE_UTF8 bit is ON
299 ZipEntry e = createZipEntry(((flag & USE_UTF8) != 0)
300 ? zc.toStringUTF8(b, len)
301 : zc.toString(b, len));
302 // now get the remaining fields for the entry
303 if ((flag & 1) == 1) {
304 throw new ZipException("encrypted ZIP entry not supported");
305 }
306 e.method = get16(tmpbuf, LOCHOW);
307 e.xdostime = get32(tmpbuf, LOCTIM);
308 if ((flag & 8) == 8) {
309 /* "Data Descriptor" present */
310 if (e.method != DEFLATED) {
311 throw new ZipException(
312 "only DEFLATED entries can have EXT descriptor");
313 }
314 } else {
315 e.crc = get32(tmpbuf, LOCCRC);
316 e.csize = get32(tmpbuf, LOCSIZ);
317 e.size = get32(tmpbuf, LOCLEN);
318 }
319 len = get16(tmpbuf, LOCEXT);
|