示例#1
0
        public void DecompressBlock(int decompressSize, int compressedBlockSize, int uncompressedBlockSize, Stream stmIn, Stream stmOut)
        {
            inputStream  = stmIn;
            outputStream = stmOut;

            m_sizeCompressed   = compressedBlockSize;
            m_sizeUncompressed = uncompressedBlockSize;

            switch (m_compressionType)
            {
            case CompressionType.Uncompressed: // uncompressed
                byte[] buffer = new byte[decompressSize];
                decompressSize = stmIn.Read(buffer, 0, decompressSize);
                stmOut.Write(buffer, 0, decompressSize);
                return;

            case CompressionType.MSZIP: // MSZIP
                MspackError err = m_zstm.mszipd_decompress(decompressSize);
                if (err != MspackError.OK)
                {
                    throw new ZipException(err);
                }
                break;

            default:
                throw new NotSupportedException("Only uncompressed and MSZIP cabs are supported");
            }
        }
        internal void mszipd_init(mspack_system system,
                                  int input_buffer_size,
                                  int repair_mode)
        {
            input_buffer_size = (input_buffer_size + 1) & -2;
            if (input_buffer_size == 0)
            {
                throw new Exception();
            }


            /* allocate input buffer */
            this.inbuf = new byte[input_buffer_size];

            /* initialise decompression state */
            this.sys          = system;
            this.inbuf_size   = (uint)input_buffer_size;
            this.error        = MspackError.OK;
            this.repair_mode  = repair_mode;
            this.flush_window = new FlushWindowDelegate(mszipd_flush_window);

            this.i_ptr      = this.i_end = 0;
            this.o_ptr      = this.o_end = -1;
            this.bit_buffer = 0; this.bits_left = 0;
        }
        MspackError zipd_read_input()
        {
            int read = sys.read(inbuf, 0, (int)inbuf_size);

            if (read < 0)
            {
                return(error = MspackError.READ);
            }
            //System.Diagnostics.Debug.WriteLine(string.Format("zip_read_input: read {0:X} bytes", read));
            i_ptr = 0;
            i_end = read;

            return(MspackError.OK);
        }
 public ZipException(MspackError code)
 {
     err = code;
 }
        internal MspackError mszipd_decompress(int out_bytes)
        {
            /* for the bit buffer */
            uint _bit_buffer;
            uint _bits_left;
            int  _i_ptr, _i_end;

            int         i, state;
            MspackError error = MspackError.OK;

            /* easy answers */
            if ((out_bytes < 0))
            {
                return(MspackError.ARGS);
            }
            if (error != MspackError.OK)
            {
                return(error);
            }

            /* flush out any stored-up bytes before we begin */
            i = this.o_end - this.o_ptr;
            if (i > out_bytes)
            {
                i = (int)out_bytes;
            }
            if (i != 0)
            {
                if (this.sys.write(this.window, this.o_ptr, i) != i)
                {
                    return(this.error = MspackError.WRITE);
                }
                this.o_ptr += i;
                out_bytes  -= i;
            }
            if (out_bytes == 0)
            {
                return(MspackError.OK);
            }


            while (out_bytes > 0)
            {
                /* unpack another block */
                RESTORE_BITS(out _i_ptr, out _i_end, out _bit_buffer, out _bits_left);

                /* skip to next read 'CK' header */
                i = (int)_bits_left & 7;
                /* align to bytestream */
                _bit_buffer >>= (i);
                _bits_left   -= (uint)i;

                state = 0;
                do
                {
                    i = (int)READ_BITS(8, ref _i_ptr, ref _i_end, ref _bit_buffer, ref _bits_left);
                    if (i == 'C')
                    {
                        state = 1;
                    }
                    else if ((state == 1) && (i == 'K'))
                    {
                        state = 2;
                    }
                    else
                    {
                        state = 0;
                    }
                } while (state != 2);

                /* inflate a block, repair and realign if necessary */
                this.window_posn  = 0;
                this.bytes_output = 0;
                STORE_BITS(_i_ptr, _i_end, _bit_buffer, _bits_left);
                if ((error = inflate()) != MspackError.OK)
                {
                    //D(("inflate error %d", i))
                    if (this.repair_mode != 0)
                    {
                        //  this.sys->message(NULL, "MSZIP error, %u bytes of data lost.", MSZIP_FRAME_SIZE - this.bytes_output);
                        for (i = this.bytes_output; i < MsZip.FRAME_SIZE; i++)
                        {
                            this.window[i] = 0;
                        }
                        this.bytes_output = (int)MsZip.FRAME_SIZE;
                    }
                    else
                    {
                        return(this.error = (error > 0) ? error : MspackError.DECRUNCH);
                    }
                }
                this.o_ptr = 0;
                this.o_end = this.bytes_output;

                /* write a frame */
                i = (out_bytes < this.bytes_output) ?
                    (int)out_bytes : this.bytes_output;
                if (this.sys.write(this.window, this.o_ptr, i) != i)
                {
                    return(this.error = MspackError.WRITE);
                }

                /* mspack errors (i.e. read errors) are fatal and can't be recovered */
                if ((error > 0) && this.repair_mode != 0)
                {
                    return(error);
                }

                this.o_ptr += i;
                out_bytes  -= i;
            }

            if (out_bytes != 0)
            {
                //D(("bytes left to output"))
                return(this.error = MspackError.DECRUNCH);
            }
            return(MspackError.OK);
        }