nativepackedoutputstream.java

来自「java调用ie浏览器demo源码,可以用在windows或者linux」· Java 代码 · 共 438 行 · 第 1/2 页

JAVA
438
字号
        public void setLevel(int level) {

            this.level = level;

        }



        /**

         * Begins writing a new CAB file entry and positions the stream to the

         * start of the entry data. Closes the current entry if still active.

         * The default compression method will be used if no compression method

         * was specified for the entry, and the current time will be used if

         * the entry has no set modification time.

         * @param e the ZIP entry to be written

         * @exception java.util.zip.ZipException if a ZIP format error has occurred

         * @exception IOException if an I/O error has occurred

         */        

        @Override

        public void putNextEntry(ZipEntry e) throws IOException {

            checkValid();

            if( null!= entry ){

                closeEntry();	// close previous entry

            }

            

            if( null==e || e.toString().isEmpty() ){

                return;

            }



            String en = e.getName();

            if(File.separatorChar!='/'){

                en.replace(File.separatorChar, '/');

            }

            if( names.containsKey(en) ) {

                throw new ZipException("duplicate entry: " + en);

            }



            entry = e;

            ZipEntryAccessor.setName(entry, en);

            if( -1 == entry.getTime()  ){

                entry.setTime(System.currentTimeMillis());

            }



            //re-code DEFLATED const for compatibility reason

            int emethod = entry.getMethod();

            if( -1==emethod || DEFLATED==emethod ){

                setMethod(entry, method); // use default method

            }

            switch( entry.getMethod() ) {

            case METHOD_NONE:

            case METHOD_MSZIP:

            case METHOD_QUANTUM:

            case METHOD_LZX:

            case DEFLATED:

                break;

            default:

                throw new ZipException("unsupported compression method");

            }

            names.put(en, entry);

            putNextEntryNative(osNative, entry, level);

        }

        private static native void putNextEntryNative(long osNative, ZipEntry e, int level);



        /**

         * Closes the current CAB entry and positions the stream for writing

         * the next entry.

         * @exception ZipException if a CAB format error has occurred

         * @exception IOException if an I/O error has occurred

         */        

        @Override

        public void closeEntry() throws IOException {

            if (null != entry && 0 != osNative) {

                long newCrc = crc.getValue();

                crc.reset();



                //Not cheking now due to different packing algorithms.

                //Due to "solid" packing algorithm the packed size can be equal to 0 or

                //greater than unpacked size.

                

                long newCSize = closeEntryNative( osNative, newCrc );

                entry.setCompressedSize(newCSize);



                long newSize = actualUncomressedSize;

                actualUncomressedSize = 0;

                

                long oldSize = entry.getSize();

                entry.setSize(newSize);



                long oldCrc = entry.getCrc();

                entry.setCrc(newCrc);



                entry = null;



                if( -1!=oldSize && newSize != oldSize ){

                    throw new ZipException(

                        "invalid entry size (expected " + oldSize +

                        ", but got " + newSize + " bytes)");

                }

                

                //in 0xffffffffL "L" suffix is VERY critical!

                if(  (0xffffffffL != (oldCrc & 0xffffffffL)) && (newCrc!=oldCrc) ){

                    throw new ZipException(

                         "invalid entry crc-32 (expected 0x" +

                         Long.toHexString(oldCrc) + ", but got 0x" +

                         Long.toHexString(newCrc) + ")");

                }



            }

        }

        

        /**

         * @param osNative native handler to stream processor

         * @param crc Java-calculated CRC

         * @return the count of bytes were written to base output stream (compressed size)

         */

        private static native long closeEntryNative(long osNative, long crc);



        /**

         * Callback from native code that reserves space for crc and compressed 

         * size that are not natively supported in OS DLL.

         * @return length-model for final {@link #getEntrySuffix} call 

         */

        protected String getEntrySuffixStub()

        {

            //call ones to reserve additional bytes in file name

            //for storing extended attribytes

            return "{01234567-01234567}";

        }

        

        /**

         * Callback from native code that stores real crc and compressed size 

         * values that are not natively supported in OS DLL.

         * @param entryName CAB entry name for modification

         * @return modified CAB entry name

         * @throws java.io.IOException

         */

        protected String getEntrySuffix(String entryName) throws IOException

        {

            ZipEntry ze = names.get(entryName);

            if( null == ze){

                return null;

            }



            Formatter f = new Formatter();

            f.format("{%08x-%08x}", ze.getCrc(), ze.getCompressedSize());

            String ret = f.toString();

            if( ret.length() > getEntrySuffixStub().length() ){

                throw new ZipException(

                    "no room for extended attributes (reserved:" +

                    getEntrySuffixStub() + ", but stored " +

                    ret + ")");

            }

            return f.toString();

        }



        /**

         * Writes an array of bytes to the current CAB entry data. This method

         * will block until all the bytes are written.

         * @param b the data to be written

         * @param off the start offset in the data

         * @param len the number of bytes that are written

         * @exception ZipException if a CAB file error has occurred

         * @exception IOException if an I/O error has occurred

         */        

        @Override

        public synchronized void write(byte[] b, int off, int len)

            throws IOException

        {

            checkValid();

            if (off < 0 || len < 0 || off > b.length - len) {

                throw new IndexOutOfBoundsException();

            } else if (len == 0) {

                return;

            }

            if (null == entry) {

                throw new ZipException("no current ZIP entry");

            }

            writeNativeBytes(osNative, b, off, len);

            actualUncomressedSize += len;

            //System.out.println(actualUncomressedSize);

            crc.update(b, off, len);

        }

        private static native void writeNativeBytes(long osNative, byte[] b, int off, int len) throws IOException;



        /**

         * Finishes writing the content of the CAB output stream without closing

         * the underlying stream. Use this method when applying multiple filters

         * in succession to the same output stream.

         * @exception ZipException if a CAB file error has occurred

         * @exception IOException if an I/O exception has occurred

         */        

        @Override

        public void finish() throws IOException {

            checkValid();

            if (null != entry) {

                closeEntry();

            }

            finishNative(osNative);

        }

        private static native void finishNative(long osNative) throws IOException;



        /**

         * Closes the CAB output stream as well as the stream being filtered.

         * @exception ZipException if a CAB file error has occurred

         * @exception IOException if an I/O error has occurred

         */        

        @Override

        public void close() throws IOException {

            //this call are in super:

            // finish();

            // if(null != os)

            //      os.close();

            try{

                super.close();

            } finally {

                if(0 != osNative) {

                    closeNative(osNative);

                    osNative = 0;

                }

            }                

        }

        private static native void closeNative(long osNative);

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?