/**
         * Closes the current {@code ZipEntry}. Any entry terminal data is written
         * to the underlying stream.
         *
         * @throws IOException
         *             If an error occurs closing the entry.
         */
        public void closeEntry()
        {
            // throws IOException {
            if (cDir == null) {
                throw new java.io.IOException("Stream is closed"); //$NON-NLS-1$
            }
            if (currentEntry == null) {
                return;
            }
            if (currentEntry.getMethod() == DEFLATED) {
                base.finish();
            }

            // Verify values for STORED types
            if (currentEntry.getMethod() == STORED) {
                if (crc.getValue() != currentEntry.crc) {
                    throw new ZipException("Crc mismatch"); //$NON-NLS-1$
                }
                if (currentEntry.size != crc.tbytes) {
                    throw new ZipException("Size mismatch"); //$NON-NLS-1$
                }
            }
            curOffset = ZipFile.LOCHDR;

            // Write the DataDescriptor
            if (currentEntry.getMethod() != STORED) {
                curOffset += ZipFile.EXTHDR;
                writeLong(outJ, ZipFile.EXTSIG);
                writeLong(outJ, currentEntry.crc = crc.getValue());
                writeLong(outJ, currentEntry.compressedSize = def.getTotalOut());
                writeLong(outJ, currentEntry.size = def.getTotalIn());
            }
            // Update the CentralDirectory
            writeLong(cDir, ZipFile.CENSIG);
            writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version created
            writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version to extract
            writeShort(cDir, currentEntry.getMethod() == STORED ? 0
                    : ZIPDataDescriptorFlag);
            writeShort(cDir, currentEntry.getMethod());
            writeShort(cDir, currentEntry.time);
            writeShort(cDir, currentEntry.modDate);
            writeLong(cDir, crc.getValue());
            if (currentEntry.getMethod() == DEFLATED) {
                curOffset += (int) writeLong(cDir, def.getTotalOut());
                writeLong(cDir, def.getTotalIn());
            } else {
                curOffset += (int) writeLong(cDir, crc.tbytes);
                writeLong(cDir, crc.tbytes);
            }
            curOffset += writeShort(cDir, nameLength);
            if (currentEntry.extra != null) {
                curOffset += (int) writeShort(cDir, currentEntry.extra.Length);
            } else {
                writeShort(cDir, 0);
            }
            String c;
            if ((c = currentEntry.getComment()) != null) {
                writeShort(cDir, c.length());
            } else {
                writeShort(cDir, 0);
            }
            writeShort(cDir, 0); // Disk Start
            writeShort(cDir, 0); // Internal File Attributes
            writeLong(cDir, 0); // External File Attributes
            writeLong(cDir, offset);
            cDir.write(nameBytes);
            nameBytes = null;
            if (currentEntry.extra != null) {
                cDir.write(currentEntry.extra);
            }
            offset += curOffset;
            if (c != null) {
                cDir.write(c.getBytes());
            }
            currentEntry = null;
            crc.reset();
            def.reset();
            done = false;
        }
        /**
         * Writes entry information to the underlying stream. Data associated with
         * the entry can then be written using {@code write()}. After data is
         * written {@code closeEntry()} must be called to complete the writing of
         * the entry to the underlying stream.
         *
         * @param ze
         *            the {@code ZipEntry} to store.
         * @throws IOException
         *             If an error occurs storing the entry.
         * @see #write
         */
        public void putNextEntry(ZipEntry ze)
        {
            //throws java.io.IOException {
            if (currentEntry != null) {
                closeEntry();
            }
            if (ze.getMethod() == STORED
                    || (compressMethod == STORED && ze.getMethod() == -1)) {
                if (ze.crc == -1) {
                    /* [MSG "archive.20", "Crc mismatch"] */
                    throw new ZipException("Crc mismatch"); //$NON-NLS-1$
                }
                if (ze.size == -1 && ze.compressedSize == -1) {
                    /* [MSG "archive.21", "Size mismatch"] */
                    throw new ZipException("Size mismatch"); //$NON-NLS-1$
                }
                if (ze.size != ze.compressedSize && ze.compressedSize != -1
                        && ze.size != -1) {
                    /* [MSG "archive.21", "Size mismatch"] */
                    throw new ZipException("Size mismatch"); //$NON-NLS-1$
                }
            }
            /* [MSG "archive.1E", "Stream is closed"] */
            if (cDir == null) {
                throw new java.io.IOException("Stream is closed"); //$NON-NLS-1$
            }
            if (entries.contains(ze.name)) {
                /* [MSG "archive.29", "Entry already exists: {0}"] */
                throw new ZipException("Entry already exists: "+ ze.name); //$NON-NLS-1$
            }
            nameLength = utf8Count(ze.name);
            if (nameLength > 0xffff) {
                /* [MSG "archive.2A", "Name too long: {0}"] */
                throw new java.lang.IllegalArgumentException("Name too long: "+ ze.name); //$NON-NLS-1$
            }

            def.setLevel(compressLevel);
            currentEntry = ze;
            entries.add(currentEntry.name);
            if (currentEntry.getMethod() == -1) {
                currentEntry.setMethod(compressMethod);
            }
            writeLong(outJ, ZipFile.LOCSIG); // Entry header
            writeShort(outJ, ZIPLocalHeaderVersionNeeded); // Extraction version
            writeShort(outJ, currentEntry.getMethod() == STORED ? 0
                    : ZIPDataDescriptorFlag);
            writeShort(outJ, currentEntry.getMethod());
            if (currentEntry.getTime() == -1) {
                currentEntry.setTime(java.lang.SystemJ.currentTimeMillis());
            }
            writeShort(outJ, currentEntry.time);
            writeShort(outJ, currentEntry.modDate);

            if (currentEntry.getMethod() == STORED) {
                if (currentEntry.size == -1) {
                    currentEntry.size = currentEntry.compressedSize;
                } else if (currentEntry.compressedSize == -1) {
                    currentEntry.compressedSize = currentEntry.size;
                }
                writeLong(outJ, currentEntry.crc);
                writeLong(outJ, currentEntry.size);
                writeLong(outJ, currentEntry.size);
            } else {
                writeLong(outJ, 0);
                writeLong(outJ, 0);
                writeLong(outJ, 0);
            }
            writeShort(outJ, nameLength);
            if (currentEntry.extra != null) {
                writeShort(outJ, currentEntry.extra.Length);
            } else {
                writeShort(outJ, 0);
            }
            nameBytes = toUTF8Bytes(currentEntry.name, nameLength);
            outJ.write(nameBytes);
            if (currentEntry.extra != null) {
                outJ.write(currentEntry.extra);
            }
        }
Beispiel #3
0
 /**
  * Constructs a new {@code ZipEntry} using the values obtained from {@code
  * ze}.
  *
  * @param ze
  *            the {@code ZipEntry} from which to obtain values.
  */
 public ZipEntry(ZipEntry ze)
 {
     name = ze.name;
     comment = ze.comment;
     time = ze.time;
     size = ze.size;
     compressedSize = ze.compressedSize;
     crc = ze.crc;
     compressionMethod = ze.compressionMethod;
     modDate = ze.modDate;
     extra = ze.extra;
     nameLen = ze.nameLen;
     mLocalHeaderRelOffset = ze.mLocalHeaderRelOffset;
 }
        /**
         * Reads the next entry from this {@code ZipInputStream} or {@code null} if
         * no more entries are present.
         *
         * @return the next {@code ZipEntry} contained in the input stream.
         * @throws IOException
         *             if an {@code IOException} occurs.
         * @see ZipEntry
         */
        public ZipEntry getNextEntry()
        {
            //throws IOException {
            closeEntry();
            if (entriesEnd) {
                return null;
            }

            int x = 0, count = 0;
            while (count != 4) {
                count += x = inJ.read(hdrBuf, count, 4 - count);
                if (x == -1) {
                    return null;
                }
            }
            long hdr = getLong(hdrBuf, 0);
            if (hdr == ZipFile.CENSIG) {
                entriesEnd = true;
                return null;
            }
            if (hdr != ZipFile.LOCSIG) {
                return null;
            }

            // Read the local header
            count = 0;
            while (count != (ZipFile.LOCHDR - ZipFile.LOCVER)) {
                count += x = inJ.read(hdrBuf, count, (ZipFile.LOCHDR - ZipFile.LOCVER) - count);
                if (x == -1) {
                    throw new java.io.EOFException();
                }
            }
            int version = getShort(hdrBuf, 0) & 0xff;
            if (version > ZIPLocalHeaderVersionNeeded) {
                throw new ZipException("Cannot read version"); //$NON-NLS-1$
            }
            int flags = getShort(hdrBuf, ZipFile.LOCFLG - ZipFile.LOCVER);
            hasDD = ((flags & ZIPDataDescriptorFlag) == ZIPDataDescriptorFlag);
            int cetime = getShort(hdrBuf, ZipFile.LOCTIM - ZipFile.LOCVER);
            int cemodDate = getShort(hdrBuf, ZipFile.LOCTIM - ZipFile.LOCVER + 2);
            int cecompressionMethod = getShort(hdrBuf, ZipFile.LOCHOW - ZipFile.LOCVER);
            long cecrc = 0, cecompressedSize = 0, cesize = -1;
            if (!hasDD) {
                cecrc = getLong(hdrBuf, ZipFile.LOCCRC - ZipFile.LOCVER);
                cecompressedSize = getLong(hdrBuf, ZipFile.LOCSIZ - ZipFile.LOCVER);
                cesize = getLong(hdrBuf, ZipFile.LOCLEN - ZipFile.LOCVER);
            }
            int flen = getShort(hdrBuf,ZipFile.LOCNAM - ZipFile.LOCVER);
            if (flen == 0) {
                throw new ZipException("Entry is not named"); //$NON-NLS-1$
            }
            int elen = getShort(hdrBuf, ZipFile.LOCEXT - ZipFile.LOCVER);

            count = 0;
            if (flen > nameBuf.Length) {
                nameBuf = new byte[flen];
                charBuf = new char[flen];
            }
            while (count != flen) {
                count += x = inJ.read(nameBuf, count, flen - count);
                if (x == -1) {
                    throw new java.io.EOFException();
                }
            }
            currentEntry = createZipEntry(org.apache.harmony.luni.util.Util.convertUTF8WithBuf(nameBuf, charBuf,
                    0, flen));
            currentEntry.time = cetime;
            currentEntry.modDate = cemodDate;
            currentEntry.setMethod(cecompressionMethod);
            if (cesize != -1) {
                currentEntry.setCrc(cecrc);
                currentEntry.setSize(cesize);
                currentEntry.setCompressedSize(cecompressedSize);
            }
            if (elen > 0) {
                count = 0;
                byte[] e = new byte[elen];
                while (count != elen) {
                    count += x = inJ.read(e, count, elen - count);
                    if (x == -1) {
                        throw new java.io.EOFException();
                    }
                }
                currentEntry.setExtra(e);
            }
            return currentEntry;
        }
        /**
         * Closes the current ZIP entry and positions to read the next entry.
         *
         * @throws IOException
         *             if an {@code IOException} occurs.
         */
        public void closeEntry()
        {
            // throws IOException {
            if (closed) {
                throw new java.io.IOException("Stream is closed"); //$NON-NLS-1$
            }
            if (currentEntry == null) {
                return;
            }
            if (currentEntry is java.util.jar.JarEntry) {
                java.util.jar.Attributes temp = ((java.util.jar.JarEntry) currentEntry).getAttributes();
                if (temp != null && temp.containsKey("hidden")) { //$NON-NLS-1$
                    return;
                }
            }

            /*
             * The following code is careful to leave the ZipInputStream in a
             * consistent state, even when close() results in an exception. It does
             * so by:
             *  - pushing bytes back into the source stream
             *  - reading a data descriptor footer from the source stream
             *  - resetting fields that manage the entry being closed
             */

            // Ensure all entry bytes are read
            java.lang.Exception failure = null;
            try {
                skip(java.lang.Long.MAX_VALUE);
            } catch (java.lang.Exception e) {
                failure = e;
            }

            int inB, outJ;
            if (currentEntry.compressionMethod == DEFLATED) {
                inB = inf.getTotalIn();
                outJ = inf.getTotalOut();
            } else {
                inB = inRead;
                outJ = inRead;
            }
            int diff = entryIn - inB;
            // Pushback any required bytes
            if (diff != 0) {
                ((java.io.PushbackInputStream) inJ).unread(buf, len - diff, diff);
            }

            try {
                readAndVerifyDataDescriptor(inB, outJ);
            } catch (java.lang.Exception e) {
                if (failure == null) { // otherwise we're already going to throw
                    failure = e;
                }
            }

            inf.reset();
            lastRead = inRead = entryIn = len = 0;
            crc.reset();
            currentEntry = null;

            if (failure != null) {
                if (failure is java.io.IOException) {
                    throw (java.io.IOException) failure;
                } else if (failure is java.lang.RuntimeException) {
                    throw (java.lang.RuntimeException) failure;
                }
                java.lang.AssertionError error = new java.lang.AssertionError();
                error.initCause(failure);
                throw error;
            }
        }
        /**
         * Reads the next entry from this {@code ZipInputStream} or {@code null} if
         * no more entries are present.
         *
         * @return the next {@code ZipEntry} contained in the input stream.
         * @throws IOException
         *             if an {@code IOException} occurs.
         * @see ZipEntry
         */
        public ZipEntry getNextEntry()  //throws IOException {
        {
            closeEntry();
            if (entriesEnd)
            {
                return(null);
            }

            int x = 0, count = 0;

            while (count != 4)
            {
                count += x = inJ.read(hdrBuf, count, 4 - count);
                if (x == -1)
                {
                    return(null);
                }
            }
            long hdr = getLong(hdrBuf, 0);

            if (hdr == ZipFile.CENSIG)
            {
                entriesEnd = true;
                return(null);
            }
            if (hdr != ZipFile.LOCSIG)
            {
                return(null);
            }

            // Read the local header
            count = 0;
            while (count != (ZipFile.LOCHDR - ZipFile.LOCVER))
            {
                count += x = inJ.read(hdrBuf, count, (ZipFile.LOCHDR - ZipFile.LOCVER) - count);
                if (x == -1)
                {
                    throw new java.io.EOFException();
                }
            }
            int version = getShort(hdrBuf, 0) & 0xff;

            if (version > ZIPLocalHeaderVersionNeeded)
            {
                throw new ZipException("Cannot read version"); //$NON-NLS-1$
            }
            int flags = getShort(hdrBuf, ZipFile.LOCFLG - ZipFile.LOCVER);

            hasDD = ((flags & ZIPDataDescriptorFlag) == ZIPDataDescriptorFlag);
            int  cetime = getShort(hdrBuf, ZipFile.LOCTIM - ZipFile.LOCVER);
            int  cemodDate = getShort(hdrBuf, ZipFile.LOCTIM - ZipFile.LOCVER + 2);
            int  cecompressionMethod = getShort(hdrBuf, ZipFile.LOCHOW - ZipFile.LOCVER);
            long cecrc = 0, cecompressedSize = 0, cesize = -1;

            if (!hasDD)
            {
                cecrc            = getLong(hdrBuf, ZipFile.LOCCRC - ZipFile.LOCVER);
                cecompressedSize = getLong(hdrBuf, ZipFile.LOCSIZ - ZipFile.LOCVER);
                cesize           = getLong(hdrBuf, ZipFile.LOCLEN - ZipFile.LOCVER);
            }
            int flen = getShort(hdrBuf, ZipFile.LOCNAM - ZipFile.LOCVER);

            if (flen == 0)
            {
                throw new ZipException("Entry is not named"); //$NON-NLS-1$
            }
            int elen = getShort(hdrBuf, ZipFile.LOCEXT - ZipFile.LOCVER);

            count = 0;
            if (flen > nameBuf.Length)
            {
                nameBuf = new byte[flen];
                charBuf = new char[flen];
            }
            while (count != flen)
            {
                count += x = inJ.read(nameBuf, count, flen - count);
                if (x == -1)
                {
                    throw new java.io.EOFException();
                }
            }
            currentEntry = createZipEntry(org.apache.harmony.luni.util.Util.convertUTF8WithBuf(nameBuf, charBuf,
                                                                                               0, flen));
            currentEntry.time    = cetime;
            currentEntry.modDate = cemodDate;
            currentEntry.setMethod(cecompressionMethod);
            if (cesize != -1)
            {
                currentEntry.setCrc(cecrc);
                currentEntry.setSize(cesize);
                currentEntry.setCompressedSize(cecompressedSize);
            }
            if (elen > 0)
            {
                count = 0;
                byte[] e = new byte[elen];
                while (count != elen)
                {
                    count += x = inJ.read(e, count, elen - count);
                    if (x == -1)
                    {
                        throw new java.io.EOFException();
                    }
                }
                currentEntry.setExtra(e);
            }
            return(currentEntry);
        }
        /**
         * Closes the current ZIP entry and positions to read the next entry.
         *
         * @throws IOException
         *             if an {@code IOException} occurs.
         */
        public void closeEntry() // throws IOException {
        {
            if (closed)
            {
                throw new java.io.IOException("Stream is closed"); //$NON-NLS-1$
            }
            if (currentEntry == null)
            {
                return;
            }
            if (currentEntry is java.util.jar.JarEntry)
            {
                java.util.jar.Attributes temp = ((java.util.jar.JarEntry)currentEntry).getAttributes();
                if (temp != null && temp.containsKey("hidden"))   //$NON-NLS-1$
                {
                    return;
                }
            }

            /*
             * The following code is careful to leave the ZipInputStream in a
             * consistent state, even when close() results in an exception. It does
             * so by:
             *  - pushing bytes back into the source stream
             *  - reading a data descriptor footer from the source stream
             *  - resetting fields that manage the entry being closed
             */

            // Ensure all entry bytes are read
            java.lang.Exception failure = null;
            try {
                skip(java.lang.Long.MAX_VALUE);
            } catch (java.lang.Exception e) {
                failure = e;
            }

            int inB, outJ;

            if (currentEntry.compressionMethod == DEFLATED)
            {
                inB  = inf.getTotalIn();
                outJ = inf.getTotalOut();
            }
            else
            {
                inB  = inRead;
                outJ = inRead;
            }
            int diff = entryIn - inB;

            // Pushback any required bytes
            if (diff != 0)
            {
                ((java.io.PushbackInputStream)inJ).unread(buf, len - diff, diff);
            }

            try {
                readAndVerifyDataDescriptor(inB, outJ);
            } catch (java.lang.Exception e) {
                if (failure == null)   // otherwise we're already going to throw
                {
                    failure = e;
                }
            }

            inf.reset();
            lastRead = inRead = entryIn = len = 0;
            crc.reset();
            currentEntry = null;

            if (failure != null)
            {
                if (failure is java.io.IOException)
                {
                    throw (java.io.IOException)failure;
                }
                else if (failure is java.lang.RuntimeException)
                {
                    throw (java.lang.RuntimeException)failure;
                }
                java.lang.AssertionError error = new java.lang.AssertionError();
                error.initCause(failure);
                throw error;
            }
        }