/**
  * Writes bytes to ZIP entry.
  * @param b the byte array to write
  * @param offset the start position to write from
  * @param length the number of bytes to write
  * @throws IOException on error
  */
 public override void write(byte[] b, int offset, int length) //throws IOException
 {
     ZipUtil.checkRequestedFeatures(entry);
     if (entry.getMethod() == DEFLATED)
     {
         if (length > 0)
         {
             if (!def.finished())
             {
                 if (length <= DEFLATER_BLOCK_SIZE)
                 {
                     def.setInput(b, offset, length);
                     deflateUntilInputIsNeeded();
                 }
                 else
                 {
                     int fullblocks = length / DEFLATER_BLOCK_SIZE;
                     for (int i = 0; i < fullblocks; i++)
                     {
                         def.setInput(b, offset + i * DEFLATER_BLOCK_SIZE,
                                      DEFLATER_BLOCK_SIZE);
                         deflateUntilInputIsNeeded();
                     }
                     int done = fullblocks * DEFLATER_BLOCK_SIZE;
                     if (done < length)
                     {
                         def.setInput(b, offset + done, length - done);
                         deflateUntilInputIsNeeded();
                     }
                 }
             }
         }
     }
     else
     {
         writeOut(b, offset, length);
         written += length;
     }
     crc.update(b, offset, length);
     count(length);
 }
 /**
  * Set the extra field data in central directory.
  * @param data the data to use
  */
 public virtual void setCentralDirectoryData(byte[] data)
 {
     centralData = ZipUtil.copy(data);
 }
 /**
  * Get the local data.
  * @return the local data
  */
 public virtual byte[] getLocalFileDataData()
 {
     return(ZipUtil.copy(localData));
 }
 /**
  * Set the extra field data in the local file data -
  * without Header-ID or length specifier.
  * @param data the field data to use
  */
 public virtual void setLocalFileDataData(byte[] data)
 {
     localData = ZipUtil.copy(data);
 }
Esempio n. 5
0
        /**
         * Reads the central directory of the given archive and populates
         * the internal tables with ZipArchiveEntry instances.
         *
         * <p>The ZipArchiveEntrys will know all data that can be obtained from
         * the central directory alone, but not the data that requires the
         * local file header or additional data to be read.</p>
         *
         * @return a Map&lt;ZipArchiveEntry, NameAndComment>&gt; of
         * zipentries that didn't have the language encoding flag set when
         * read.
         */
        private java.util.Map <ZipArchiveEntry, IAC_NameAndComment> populateFromCentralDirectory()
        //throws IOException
        {
            java.util.HashMap <ZipArchiveEntry, IAC_NameAndComment> noUTF8Flag = new java.util.HashMap <ZipArchiveEntry, IAC_NameAndComment>();

            positionAtCentralDirectory();

            byte[] cfh = new byte[CFH_LEN];

            byte[] signatureBytes = new byte[WORD];
            archive.readFully(signatureBytes);
            long sig    = ZipLong.getValue(signatureBytes);
            long cfhSig = ZipLong.getValue(ZipArchiveOutputStream.CFH_SIG);

            if (sig != cfhSig && startsWithLocalFileHeader())
            {
                throw new java.io.IOException("central directory is empty, can't expand"
                                              + " corrupt archive.");
            }
            while (sig == cfhSig)
            {
                archive.readFully(cfh);
                int             off = 0;
                ZipArchiveEntry ze  = new ZipArchiveEntry();

                int versionMadeBy = ZipShort.getValue(cfh, off);
                off += SHORT;
                ze.setPlatform((versionMadeBy >> BYTE_SHIFT) & NIBLET_MASK);

                off += SHORT; // skip version info

                GeneralPurposeBit gpFlag  = GeneralPurposeBit.parse(cfh, off);
                bool        hasUTF8Flag   = gpFlag.usesUTF8ForNames();
                ZipEncoding entryEncoding =
                    hasUTF8Flag ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding;
                ze.setGeneralPurposeBit(gpFlag);

                off += SHORT;

                ze.setMethod(ZipShort.getValue(cfh, off));
                off += SHORT;

                // FIXME this is actually not very cpu cycles friendly as we are converting from
                // dos to java while the underlying Sun implementation will convert
                // from java to dos time for internal storage...
                long time = ZipUtil.dosToJavaTime(ZipLong.getValue(cfh, off));
                ze.setTime(time);
                off += WORD;

                ze.setCrc(ZipLong.getValue(cfh, off));
                off += WORD;

                ze.setCompressedSize(ZipLong.getValue(cfh, off));
                off += WORD;

                ze.setSize(ZipLong.getValue(cfh, off));
                off += WORD;

                int fileNameLen = ZipShort.getValue(cfh, off);
                off += SHORT;

                int extraLen = ZipShort.getValue(cfh, off);
                off += SHORT;

                int commentLen = ZipShort.getValue(cfh, off);
                off += SHORT;

                off += SHORT; // disk number

                ze.setInternalAttributes(ZipShort.getValue(cfh, off));
                off += SHORT;

                ze.setExternalAttributes(ZipLong.getValue(cfh, off));
                off += WORD;

                byte[] fileName = new byte[fileNameLen];
                archive.readFully(fileName);
                ze.setName(entryEncoding.decode(fileName));

                // LFH offset,
                IAC_OffsetEntry offset = new IAC_OffsetEntry();
                offset.headerOffset = ZipLong.getValue(cfh, off);
                // data offset will be filled later
                entries.put(ze, offset);

                nameMap.put(ze.getName(), ze);

                byte[] cdExtraData = new byte[extraLen];
                archive.readFully(cdExtraData);
                ze.setCentralDirectoryExtra(cdExtraData);

                byte[] comment = new byte[commentLen];
                archive.readFully(comment);
                ze.setComment(entryEncoding.decode(comment));

                archive.readFully(signatureBytes);
                sig = ZipLong.getValue(signatureBytes);

                if (!hasUTF8Flag && useUnicodeExtraFields)
                {
                    noUTF8Flag.put(ze, new IAC_NameAndComment(fileName, comment));
                }
            }
            return(noUTF8Flag);
        }
Esempio n. 6
0
 /**
  * Whether this class is able to read the given entry.
  *
  * <p>May return false if it is set up to use encryption or a
  * compression method that hasn't been implemented yet.</p>
  * @since Apache Commons Compress 1.1
  */
 public bool canReadEntryData(ZipArchiveEntry ze)
 {
     return(ZipUtil.canHandleEntryData(ze));
 }
        /**
         * Writes the central file header entry.
         * @param ze the entry to write
         * @throws IOException on error
         */
        protected void writeCentralFileHeader(ZipArchiveEntry ze) //throws IOException
        {
            writeOut(CFH_SIG);
            written += WORD;

            // version made by
            // CheckStyle:MagicNumber OFF
            writeOut(ZipShort.getBytes((ze.getPlatform() << 8) | 20));
            written += SHORT;

            int  zipMethod = ze.getMethod();
            bool encodable = zipEncoding.canEncode(ze.getName());

            writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod,
                                                             !encodable &&
                                                             fallbackToUTF8);
            written += WORD;

            // compression method
            writeOut(ZipShort.getBytes(zipMethod));
            written += SHORT;

            // last mod. time and date
            writeOut(ZipUtil.toDosTime(ze.getTime()));
            written += WORD;

            // CRC
            // compressed length
            // uncompressed length
            writeOut(ZipLong.getBytes(ze.getCrc()));
            writeOut(ZipLong.getBytes(ze.getCompressedSize()));
            writeOut(ZipLong.getBytes(ze.getSize()));
            // CheckStyle:MagicNumber OFF
            written += 12;
            // CheckStyle:MagicNumber ON

            // file name length
            ZipEncoding entryEncoding;

            if (!encodable && fallbackToUTF8)
            {
                entryEncoding = ZipEncodingHelper.UTF8_ZIP_ENCODING;
            }
            else
            {
                entryEncoding = zipEncoding;
            }

            java.nio.ByteBuffer name = entryEncoding.encode(ze.getName());

            writeOut(ZipShort.getBytes(name.limit()));
            written += SHORT;

            // extra field length
            byte[] extra = ze.getCentralDirectoryExtra();
            writeOut(ZipShort.getBytes(extra.Length));
            written += SHORT;

            // file comment length
            String comm = ze.getComment();

            if (comm == null)
            {
                comm = "";
            }

            java.nio.ByteBuffer commentB = entryEncoding.encode(comm);

            writeOut(ZipShort.getBytes(commentB.limit()));
            written += SHORT;

            // disk number start
            writeOut(ZERO);
            written += SHORT;

            // internal file attributes
            writeOut(ZipShort.getBytes(ze.getInternalAttributes()));
            written += SHORT;

            // external file attributes
            writeOut(ZipLong.getBytes(ze.getExternalAttributes()));
            written += WORD;

            // relative offset of LFH
            writeOut((byte[])offsets.get(ze));
            written += WORD;

            // file name
            writeOut((byte[])name.array(), name.arrayOffset(), name.limit());
            written += name.limit();

            // extra field
            writeOut(extra);
            written += extra.Length;

            // file comment
            writeOut((byte[])commentB.array(), commentB.arrayOffset(), commentB.limit());
            written += commentB.limit();
        }
        /**
         * Writes the local file header entry
         * @param ze the entry to write
         * @throws IOException on error
         */
        protected void writeLocalFileHeader(ZipArchiveEntry ze) //throws IOException
        {
            bool encodable = zipEncoding.canEncode(ze.getName());

            ZipEncoding entryEncoding;

            if (!encodable && fallbackToUTF8)
            {
                entryEncoding = ZipEncodingHelper.UTF8_ZIP_ENCODING;
            }
            else
            {
                entryEncoding = zipEncoding;
            }

            java.nio.ByteBuffer name = entryEncoding.encode(ze.getName());

            if (createUnicodeExtraFields != UnicodeExtraFieldPolicy.NEVER)
            {
                if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS ||
                    !encodable)
                {
                    ze.addExtraField(new UnicodePathExtraField(ze.getName(),
                                                               (byte[])name.array(),
                                                               name.arrayOffset(),
                                                               name.limit()));
                }

                String comm = ze.getComment();
                if (comm != null && !"".equals(comm))
                {
                    bool commentEncodable = this.zipEncoding.canEncode(comm);

                    if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS ||
                        !commentEncodable)
                    {
                        java.nio.ByteBuffer commentB = entryEncoding.encode(comm);
                        ze.addExtraField(new UnicodeCommentExtraField(comm,
                                                                      (byte[])commentB.array(),
                                                                      commentB.arrayOffset(),
                                                                      commentB.limit())
                                         );
                    }
                }
            }

            offsets.put(ze, ZipLong.getBytes(written));

            writeOut(LFH_SIG);
            written += WORD;

            //store method in local variable to prevent multiple method calls
            int zipMethod = ze.getMethod();

            writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod,
                                                             !encodable &&
                                                             fallbackToUTF8);
            written += WORD;

            // compression method
            writeOut(ZipShort.getBytes(zipMethod));
            written += SHORT;

            // last mod. time and date
            writeOut(ZipUtil.toDosTime(ze.getTime()));
            written += WORD;

            // CRC
            // compressed length
            // uncompressed length
            localDataStart = written;
            if (zipMethod == DEFLATED || raf != null)
            {
                writeOut(LZERO);
                writeOut(LZERO);
                writeOut(LZERO);
            }
            else
            {
                writeOut(ZipLong.getBytes(ze.getCrc()));
                writeOut(ZipLong.getBytes(ze.getSize()));
                writeOut(ZipLong.getBytes(ze.getSize()));
            }
            // CheckStyle:MagicNumber OFF
            written += 12;
            // CheckStyle:MagicNumber ON

            // file name length
            writeOut(ZipShort.getBytes(name.limit()));
            written += SHORT;

            // extra field length
            byte[] extra = ze.getLocalFileDataExtra();
            writeOut(ZipShort.getBytes(extra.Length));
            written += SHORT;

            // file name
            writeOut((byte[])name.array(), name.arrayOffset(), name.limit());
            written += name.limit();

            // extra field
            writeOut(extra);
            written += extra.Length;

            dataStart = written;
        }
        /**
         * Writes all necessary data for this entry.
         * @throws IOException on error
         */
        public override void closeArchiveEntry() //throws IOException
        {
            if (finished)
            {
                throw new java.io.IOException("Stream has already been finished");
            }

            if (entry == null)
            {
                throw new java.io.IOException("No current entry to close");
            }

            long realCrc = crc.getValue();

            crc.reset();

            if (entry.getMethod() == DEFLATED)
            {
                def.finish();
                while (!def.finished())
                {
                    deflate();
                }

                entry.setSize(ZipUtil.adjustToLong(def.getTotalIn()));
                entry.setCompressedSize(ZipUtil.adjustToLong(def.getTotalOut()));
                entry.setCrc(realCrc);

                def.reset();

                written += entry.getCompressedSize();
            }
            else if (raf == null)
            {
                if (entry.getCrc() != realCrc)
                {
                    throw new java.util.zip.ZipException("bad CRC checksum for entry "
                                                         + entry.getName() + ": "
                                                         + java.lang.Long.toHexString(entry.getCrc())
                                                         + " instead of "
                                                         + java.lang.Long.toHexString(realCrc));
                }

                if (entry.getSize() != written - dataStart)
                {
                    throw new java.util.zip.ZipException("bad size for entry "
                                                         + entry.getName() + ": "
                                                         + entry.getSize()
                                                         + " instead of "
                                                         + (written - dataStart));
                }
            }
            else     /* method is STORED and we used RandomAccessFile */
            {
                long size = written - dataStart;

                entry.setSize(size);
                entry.setCompressedSize(size);
                entry.setCrc(realCrc);
            }

            // If random access output, write the local file header containing
            // the correct CRC and compressed/uncompressed sizes
            if (raf != null)
            {
                long save = raf.getFilePointer();

                raf.seek(localDataStart);
                writeOut(ZipLong.getBytes(entry.getCrc()));
                writeOut(ZipLong.getBytes(entry.getCompressedSize()));
                writeOut(ZipLong.getBytes(entry.getSize()));
                raf.seek(save);
            }

            writeDataDescriptor(entry);
            entry = null;
        }
Esempio n. 10
0
        public override int read(byte[] buffer, int start, int length) //throws IOException
        {
            if (closed)
            {
                throw new java.io.IOException("The stream is closed");
            }
            if (inf.finished() || current == null)
            {
                return(-1);
            }

            // avoid int overflow, check null buffer
            if (start <= buffer.Length && length >= 0 && start >= 0 &&
                buffer.Length - start >= length)
            {
                ZipUtil.checkRequestedFeatures(current);
                if (!supportsDataDescriptorFor(current))
                {
                    throw new UnsupportedZipFeatureException(Feature.DATA_DESCRIPTOR, current);
                }

                if (current.getMethod() == ZipArchiveOutputStream.STORED)
                {
                    if (hasDataDescriptor)
                    {
                        if (lastStoredEntry == null)
                        {
                            readStoredEntry();
                        }
                        return(lastStoredEntry.read(buffer, start, length));
                    }

                    int csize = (int)current.getSize();
                    if (readBytesOfEntry >= csize)
                    {
                        return(-1);
                    }
                    if (offsetInBuffer >= lengthOfLastRead)
                    {
                        offsetInBuffer = 0;
                        if ((lengthOfLastRead = inJ.read(buf)) == -1)
                        {
                            return(-1);
                        }
                        count(lengthOfLastRead);
                        bytesReadFromStream += lengthOfLastRead;
                    }
                    int toRead = length > lengthOfLastRead
                        ? lengthOfLastRead - offsetInBuffer
                        : length;
                    if ((csize - readBytesOfEntry) < toRead)
                    {
                        toRead = csize - readBytesOfEntry;
                    }
                    java.lang.SystemJ.arraycopy(buf, offsetInBuffer, buffer, start, toRead);
                    offsetInBuffer   += toRead;
                    readBytesOfEntry += toRead;
                    crc.update(buffer, start, toRead);
                    return(toRead);
                }

                if (inf.needsInput())
                {
                    fill();
                    if (lengthOfLastRead > 0)
                    {
                        bytesReadFromStream += lengthOfLastRead;
                    }
                }
                int read = 0;
                try {
                    read = inf.inflate(buffer, start, length);
                } catch (java.util.zip.DataFormatException e) {
                    throw new java.util.zip.ZipException(e.getMessage());
                }
                if (read == 0)
                {
                    if (inf.finished())
                    {
                        return(-1);
                    }
                    else if (lengthOfLastRead == -1)
                    {
                        throw new java.io.IOException("Truncated ZIP file");
                    }
                }
                crc.update(buffer, start, read);
                return(read);
            }
            throw new java.lang.ArrayIndexOutOfBoundsException();
        }
Esempio n. 11
0
        public ZipArchiveEntry getNextZipEntry() //throws IOException
        {
            if (closed || hitCentralDirectory)
            {
                return(null);
            }
            if (current != null)
            {
                closeEntry();
            }
            byte[] lfh = new byte[LFH_LEN];
            try {
                readFully(lfh);
            } catch (java.io.EOFException) {
                return(null);
            }
            ZipLong sig = new ZipLong(lfh);

            if (sig.equals(ZipLong.CFH_SIG))
            {
                hitCentralDirectory = true;
                return(null);
            }
            if (!sig.equals(ZipLong.LFH_SIG))
            {
                return(null);
            }

            int off = WORD;

            current = new ZipArchiveEntry();

            int versionMadeBy = ZipShort.getValue(lfh, off);

            off += SHORT;
            current.setPlatform((versionMadeBy >> ZipFile.BYTE_SHIFT)
                                & ZipFile.NIBLET_MASK);

            GeneralPurposeBit gpFlag  = GeneralPurposeBit.parse(lfh, off);
            bool        hasUTF8Flag   = gpFlag.usesUTF8ForNames();
            ZipEncoding entryEncoding =
                hasUTF8Flag ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding;

            hasDataDescriptor = gpFlag.usesDataDescriptor();
            current.setGeneralPurposeBit(gpFlag);

            off += SHORT;

            current.setMethod(ZipShort.getValue(lfh, off));
            off += SHORT;

            long time = ZipUtil.dosToJavaTime(ZipLong.getValue(lfh, off));

            current.setTime(time);
            off += WORD;

            if (!hasDataDescriptor)
            {
                current.setCrc(ZipLong.getValue(lfh, off));
                off += WORD;

                current.setCompressedSize(ZipLong.getValue(lfh, off));
                off += WORD;

                current.setSize(ZipLong.getValue(lfh, off));
                off += WORD;
            }
            else
            {
                off += 3 * WORD;
            }

            int fileNameLen = ZipShort.getValue(lfh, off);

            off += SHORT;

            int extraLen = ZipShort.getValue(lfh, off);

            off += SHORT;

            byte[] fileName = new byte[fileNameLen];
            readFully(fileName);
            current.setName(entryEncoding.decode(fileName));

            byte[] extraData = new byte[extraLen];
            readFully(extraData);
            current.setExtra(extraData);

            if (!hasUTF8Flag && useUnicodeExtraFields)
            {
                ZipUtil.setNameAndCommentFromExtraFields(current, fileName, null);
            }
            return(current);
        }
 /**
  * The actual data to put into central directory.
  *
  * @return The CentralDirectoryData value
  */
 public byte[] getCentralDirectoryData()
 {
     return(centralDirectoryData == null
         ? getLocalFileDataData() : ZipUtil.copy(centralDirectoryData));
 }