Beispiel #1
0
        internal void Reset()
        {
            Codec.TotalBytesIn = Codec.TotalBytesOut = 0;
            Codec.Message      = null;

            PendingCount = 0;
            NextPending  = 0;

            _rfc1950BytesEmitted = false;

            Status         = WantRfc1950HeaderBytes ? InitState : BusyState;
            Codec._Adler32 = Adler.Adler32(0, null, 0, 0);

            LastFlush = (int)FlushType.None;

            InitializeTreeData();
            _InitializeLazyMatch();
        }
Beispiel #2
0
        internal int SetDictionary(byte[] dictionary)
        {
            var length = dictionary.Length;
            var index  = 0;

            if (dictionary == null || Status != InitState)
            {
                throw new ZlibException("Stream error.");
            }

            Codec._Adler32 = Adler.Adler32(Codec._Adler32, dictionary, 0, dictionary.Length);

            if (length < MinMatch)
            {
                return(ZlibConstants.ZOk);
            }

            if (length > WSize - MinLookahead)
            {
                length = WSize - MinLookahead;
                index  = dictionary.Length - length;
            }

            Array.Copy(dictionary, index, Window, 0, length);
            Strstart   = length;
            BlockStart = length;

            InsH = Window[0] & 0xff;
            InsH = ((InsH << HashShift) ^ (Window[1] & 0xff)) & HashMask;

            for (var n = 0; n <= length - MinMatch; n++)
            {
                InsH            = ((InsH << HashShift) ^ (Window[n + (MinMatch - 1)] & 0xff)) & HashMask;
                Prev[n & WMask] = Head[InsH];
                Head[InsH]      = (short)n;
            }

            return(ZlibConstants.ZOk);
        }
Beispiel #3
0
        internal int Read_buf(byte[] buf, int start, int size)
        {
            var len = AvailableBytesIn;

            if (len > size)
            {
                len = size;
            }
            if (len == 0)
            {
                return(0);
            }

            AvailableBytesIn -= len;

            if (Dstate.WantRfc1950HeaderBytes)
            {
                _Adler32 = Adler.Adler32(_Adler32, InputBuffer, NextIn, len);
            }
            Array.Copy(InputBuffer, NextIn, buf, start, len);
            NextIn       += len;
            TotalBytesIn += len;
            return(len);
        }
Beispiel #4
0
        internal int Deflate(FlushType flush)
        {
            if (Codec.OutputBuffer == null ||
                Codec.InputBuffer == null && Codec.AvailableBytesIn != 0 ||
                Status == FinishState && flush != FlushType.Finish)
            {
                Codec.Message = ErrorMessage[ZlibConstants.ZNeedDict - ZlibConstants.ZStreamError];
                throw new ZlibException($"Something is fishy. [{Codec.Message}]");
            }

            if (Codec.AvailableBytesOut == 0)
            {
                Codec.Message = ErrorMessage[ZlibConstants.ZNeedDict - ZlibConstants.ZBufError];
                throw new ZlibException("OutputBuffer is full (AvailableBytesOut == 0)");
            }

            var oldFlush = LastFlush;

            LastFlush = (int)flush;

            if (Status == InitState)
            {
                var header     = (ZDeflated + ((WBits - 8) << 4)) << 8;
                var levelFlags = (((int)CompressionLevel - 1) & 0xff) >> 1;

                if (levelFlags > 3)
                {
                    levelFlags = 3;
                }
                header |= levelFlags << 6;
                if (Strstart != 0)
                {
                    header |= PresetDict;
                }
                header += 31 - header % 31;

                Status = BusyState;
                unchecked
                {
                    Pending[PendingCount++] = (byte)(header >> 8);
                    Pending[PendingCount++] = (byte)header;
                }

                if (Strstart != 0)
                {
                    Pending[PendingCount++] = (byte)((Codec._Adler32 & 0xFF000000) >> 24);
                    Pending[PendingCount++] = (byte)((Codec._Adler32 & 0x00FF0000) >> 16);
                    Pending[PendingCount++] = (byte)((Codec._Adler32 & 0x0000FF00) >> 8);
                    Pending[PendingCount++] = (byte)(Codec._Adler32 & 0x000000FF);
                }

                Codec._Adler32 = Adler.Adler32(0, null, 0, 0);
            }

            if (PendingCount != 0)
            {
                Codec.Flush_pending();
                if (Codec.AvailableBytesOut == 0)
                {
                    LastFlush = -1;
                    return(ZlibConstants.ZOk);
                }
            }
            else if (Codec.AvailableBytesIn == 0 &&
                     (int)flush <= oldFlush &&
                     flush != FlushType.Finish)
            {
                return(ZlibConstants.ZOk);
            }

            if (Status == FinishState && Codec.AvailableBytesIn != 0)
            {
                Codec.Message = ErrorMessage[ZlibConstants.ZNeedDict - ZlibConstants.ZBufError];
                throw new ZlibException("status == FINISH_STATE && _codec.AvailableBytesIn != 0");
            }

            if (Codec.AvailableBytesIn != 0 || Lookahead != 0 || flush != FlushType.None && Status != FinishState)
            {
                var bstate = _deflateFunction(flush);

                if (bstate == BlockState.FinishStarted || bstate == BlockState.FinishDone)
                {
                    Status = FinishState;
                }
                switch (bstate)
                {
                case BlockState.NeedMore:
                case BlockState.FinishStarted:
                {
                    if (Codec.AvailableBytesOut == 0)
                    {
                        LastFlush = -1;
                    }
                    return(ZlibConstants.ZOk);
                }

                case BlockState.BlockDone:
                {
                    if (flush == FlushType.Partial)
                    {
                        Tr_align();
                    }
                    else
                    {
                        Tr_stored_block(0, 0, false);
                        if (flush == FlushType.Full)
                        {
                            for (var i = 0; i < HashSize; i++)
                            {
                                Head[i] = 0;
                            }
                        }
                    }

                    Codec.Flush_pending();
                    if (Codec.AvailableBytesOut == 0)
                    {
                        LastFlush = -1;
                        return(ZlibConstants.ZOk);
                    }

                    break;
                }
                }
            }

            if (flush != FlushType.Finish)
            {
                return(ZlibConstants.ZOk);
            }

            if (!WantRfc1950HeaderBytes || _rfc1950BytesEmitted)
            {
                return(ZlibConstants.ZStreamEnd);
            }

            Pending[PendingCount++] = (byte)((Codec._Adler32 & 0xFF000000) >> 24);
            Pending[PendingCount++] = (byte)((Codec._Adler32 & 0x00FF0000) >> 16);
            Pending[PendingCount++] = (byte)((Codec._Adler32 & 0x0000FF00) >> 8);
            Pending[PendingCount++] = (byte)(Codec._Adler32 & 0x000000FF);

            Codec.Flush_pending();

            _rfc1950BytesEmitted = true;

            return(PendingCount != 0 ? ZlibConstants.ZOk : ZlibConstants.ZStreamEnd);
        }