Exemplo n.º 1
0
        protected DeflateStream(Stream baseStream, ZLibCompressOptions compOpts, Format format)
        {
            ZLibInit.Manager.EnsureLoaded();

            BaseStream = baseStream ?? throw new ArgumentNullException(nameof(baseStream));
            _mode      = Mode.Compress;
            _disposed  = false;

            // Check and set compress options
            _leaveOpen  = compOpts.LeaveOpen;
            _bufferSize = CheckBufferSize(compOpts.BufferSize);
            _workBuf    = new byte[_bufferSize];
            int formatWindowBits = CheckFormatWindowBits(compOpts.WindowBits, _mode, format);

            CheckMemLevel(compOpts.MemLevel);

            // Prepare and init ZStream
            switch (ZLibInit.Lib.PlatformLongSize)
            {
            case PlatformLongSize.Long32:
            {
                _zs32  = new ZStreamL32();
                _zsPin = GCHandle.Alloc(_zs32, GCHandleType.Pinned);

                ZLibRet ret = ZLibInit.Lib.L32.DeflateInit(_zs32, compOpts.Level, formatWindowBits, compOpts.MemLevel);
                ZLibException.CheckReturnValue(ret, _zs32);
                break;
            }

            case PlatformLongSize.Long64:
            {
                _zs64  = new ZStreamL64();
                _zsPin = GCHandle.Alloc(_zs64, GCHandleType.Pinned);

                ZLibRet ret = ZLibInit.Lib.L64.DeflateInit(_zs64, compOpts.Level, formatWindowBits, compOpts.MemLevel);
                ZLibException.CheckReturnValue(ret, _zs64);
                break;
            }

            default:
                throw new PlatformNotSupportedException();
            }
        }
Exemplo n.º 2
0
        public unsafe void Write(ReadOnlySpan <byte> span)
#endif
        {
            if (_mode != Mode.Compress)
            {
                throw new NotSupportedException("Write() not supported on decompression");
            }

            TotalIn += span.Length;

            fixed(byte *readPtr = span)      // [In] Compressed
            fixed(byte *writePtr = _workBuf) // [Out] Will-be-decompressed
            {
                switch (ZLibInit.Lib.PlatformLongSize)
                {
                case PlatformLongSize.Long32:
                {
                    _zs32.NextIn   = readPtr;
                    _zs32.AvailIn  = (uint)span.Length;
                    _zs32.NextOut  = writePtr + _workBufPos;
                    _zs32.AvailOut = (uint)(_workBuf.Length - _workBufPos);

                    while (_zs32.AvailIn != 0)
                    {
                        uint    outCount = _zs32.AvailOut;
                        ZLibRet ret      = ZLibInit.Lib.L32.Deflate(_zs32, ZLibFlush.NoFlush);
                        _workBufPos += (int)(outCount - _zs32.AvailOut);

                        if (_zs32.AvailOut == 0)
                        {
                            BaseStream.Write(_workBuf, 0, _workBuf.Length);
                            TotalOut += _workBuf.Length;

                            _workBufPos    = 0;
                            _zs32.NextOut  = writePtr;
                            _zs32.AvailOut = (uint)_workBuf.Length;
                        }

                        ZLibException.CheckReturnValue(ret, _zs32);
                    }
                    break;
                }

                case PlatformLongSize.Long64:
                {
                    _zs64.NextIn   = readPtr;
                    _zs64.AvailIn  = (uint)span.Length;
                    _zs64.NextOut  = writePtr + _workBufPos;
                    _zs64.AvailOut = (uint)(_workBuf.Length - _workBufPos);

                    while (_zs64.AvailIn != 0)
                    {
                        uint    outCount = _zs64.AvailOut;
                        ZLibRet ret      = ZLibInit.Lib.L64.Deflate(_zs64, ZLibFlush.NoFlush);
                        _workBufPos += (int)(outCount - _zs64.AvailOut);

                        if (_zs64.AvailOut == 0)
                        {
                            BaseStream.Write(_workBuf, 0, _workBuf.Length);
                            TotalOut += _workBuf.Length;

                            _workBufPos    = 0;
                            _zs64.NextOut  = writePtr;
                            _zs64.AvailOut = (uint)_workBuf.Length;
                        }

                        ZLibException.CheckReturnValue(ret, _zs64);
                    }
                    break;
                }
                }
            }
        }
Exemplo n.º 3
0
        public unsafe int Read(Span <byte> span)
#endif
        { // For Decompress
            if (_mode != Mode.Decompress)
            {
                throw new NotSupportedException("Read() not supported on compression");
            }

            if (_workBufPos == ReadDone)
            {
                return(0);
            }

            int readSize = 0;

            fixed(byte *readPtr = _workBuf) // [In] Compressed
            fixed(byte *writePtr = span)    // [Out] Will-be-decompressed
            {
                switch (ZLibInit.Lib.PlatformLongSize)
                {
                case PlatformLongSize.Long32:
                {
                    _zs32.NextIn   = readPtr + _workBufPos;
                    _zs32.NextOut  = writePtr;
                    _zs32.AvailOut = (uint)span.Length;

                    while (0 < _zs32.AvailOut)
                    {
                        if (_zs32.AvailIn == 0)
                        {         // Compressed Data is no longer available in array, so read more from _stream
                            int baseReadSize = BaseStream.Read(_workBuf, 0, _workBuf.Length);

                            _workBufPos   = 0;
                            _zs32.NextIn  = readPtr;
                            _zs32.AvailIn = (uint)baseReadSize;
                            TotalIn      += baseReadSize;
                        }

                        uint inCount  = _zs32.AvailIn;
                        uint outCount = _zs32.AvailOut;

                        // flush method for inflate has no effect
                        ZLibRet ret = ZLibInit.Lib.L32.Inflate(_zs32, ZLibFlush.NoFlush);

                        _workBufPos += (int)(inCount - _zs32.AvailIn);
                        readSize    += (int)(outCount - _zs32.AvailOut);

                        if (ret == ZLibRet.StreamEnd)
                        {
                            _workBufPos = ReadDone;         // magic for StreamEnd
                            break;
                        }

                        ZLibException.CheckReturnValue(ret, _zs32);
                    }
                }
                break;

                case PlatformLongSize.Long64:
                {
                    _zs64.NextIn   = readPtr + _workBufPos;
                    _zs64.NextOut  = writePtr;
                    _zs64.AvailOut = (uint)span.Length;

                    while (0 < _zs64.AvailOut)
                    {
                        if (_zs64.AvailIn == 0)
                        {         // Compressed Data is no longer available in array, so read more from _stream
                            int baseReadSize = BaseStream.Read(_workBuf, 0, _workBuf.Length);

                            _workBufPos   = 0;
                            _zs64.NextIn  = readPtr;
                            _zs64.AvailIn = (uint)baseReadSize;
                            TotalIn      += baseReadSize;
                        }

                        uint inCount  = _zs64.AvailIn;
                        uint outCount = _zs64.AvailOut;

                        // flush method for inflate has no effect
                        ZLibRet ret = ZLibInit.Lib.L64.Inflate(_zs64, ZLibFlush.NoFlush);

                        _workBufPos += (int)(inCount - _zs64.AvailIn);
                        readSize    += (int)(outCount - _zs64.AvailOut);

                        if (ret == ZLibRet.StreamEnd)
                        {
                            _workBufPos = ReadDone;         // magic for StreamEnd
                            break;
                        }

                        ZLibException.CheckReturnValue(ret, _zs64);
                    }
                }
                break;
                }
            }

            TotalOut += readSize;
            return(readSize);
        }