public ZStreamWriter(Stream stream, int level, uint bufferSize)
        {
            if (!stream.CanWrite)
            {
                throw new ArgumentException("Stream not writable");
            }
            if (bufferSize == 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize", "must be greater zero");
            }

            baseStream = stream;

            zstream = new zlib.z_stream();

            switch (zlib.deflateInit(zstream, level))
            {
            case zlib.Z_OK: break;

            case zlib.Z_MEM_ERROR:
            case zlib.Z_STREAM_ERROR: throw new Exception("zlib memory error");

            default: throw new Exception("Unknown zlib error");
            }

            zstream.out_buf   = new byte[bufferSize];
            zstream.next_out  = 0;
            zstream.avail_out = bufferSize;
        }
        public ZLibStreamReader(Stream stream, uint bufferSize)
        {
            if (!stream.CanRead)
            {
                throw new ArgumentException("Stream not readable.", "stream");
            }
            if (bufferSize == 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize", "must be greater zero");
            }

            baseStream = stream;

            zstream = new zlib.z_stream();

            switch (zlib.inflateInit(zstream))
            {
            case zlib.Z_OK: break;

            case zlib.Z_MEM_ERROR:
            case zlib.Z_STREAM_ERROR: throw new Exception("zlib memory error");

            default: throw new Exception("Unknown zlib error");
            }

            zstream.in_buf   = new byte[bufferSize];
            zstream.next_in  = 0;
            zstream.avail_in = (uint)baseStream.Read(zstream.in_buf, (int)zstream.next_in, (int)bufferSize);
        }
        public override void Close()
        {
            if (baseStream != null)
            {
                baseStream.Close();
            }
            baseStream = null;

            if (zstream != null)
            {
                zlib.inflateEnd(zstream);
            }
            zstream = null;

            base.Close();
        }
        public void WriteToEnd()
        {
            if (baseStream == null)
            {
                throw new ObjectDisposedException(null, "File closed");
            }

            int ret;

            do
            {
                ret = zlib.deflate(zstream, zlib.Z_FINISH);
                if (ret == zlib.Z_OK)
                {
                    if (zstream.avail_out == 0)
                    {
                        baseStream.Write(zstream.out_buf, 0, zstream.next_out);
                        zstream.next_out  = 0;
                        zstream.avail_out = (uint)zstream.out_buf.Length;
                    }
                }
                else if (ret != zlib.Z_STREAM_END)
                {
                    if (zstream.msg != null && zstream.msg.Length > 0)
                    {
                        throw new Exception(zstream.msg);
                    }
                    throw new Exception("zlib error");
                }
            } while(ret != zlib.Z_STREAM_END);

            if (zstream.next_out > 0)
            {
                baseStream.Write(zstream.out_buf, 0, zstream.next_out);
                zstream.next_out  = 0;
                zstream.avail_out = (uint)zstream.out_buf.Length;
            }

            if (zstream != null)
            {
                zlib.deflateEnd(zstream);
            }
            zstream = null;
        }
		public ZStreamWriter(Stream stream, int level, uint bufferSize)
		{
			if(!stream.CanWrite) throw new ArgumentException("Stream not writable");
			if(bufferSize==0) throw new ArgumentOutOfRangeException("bufferSize", "must be greater zero");

			baseStream=stream;

			zstream=new zlib.z_stream();

			switch(zlib.deflateInit(zstream, level))
			{
				case zlib.Z_OK: break;
				case zlib.Z_MEM_ERROR:
				case zlib.Z_STREAM_ERROR: throw new Exception("zlib memory error");
				default: throw new Exception("Unknown zlib error");
			}

			zstream.out_buf=new byte[bufferSize];
			zstream.next_out=0;
			zstream.avail_out=bufferSize;
		}
		public ZLibStreamReader(Stream stream, uint bufferSize)
		{
			if(!stream.CanRead) throw new ArgumentException("Stream not readable.", "stream");
			if(bufferSize==0) throw new ArgumentOutOfRangeException("bufferSize", "must be greater zero");

			baseStream=stream;

			zstream=new zlib.z_stream();

			switch(zlib.inflateInit(zstream))
			{
				case zlib.Z_OK: break;
				case zlib.Z_MEM_ERROR:
				case zlib.Z_STREAM_ERROR: throw new Exception("zlib memory error");
				default: throw new Exception("Unknown zlib error");
			}

			zstream.in_buf=new byte[bufferSize];
			zstream.next_in=0;
			zstream.avail_in=(uint)baseStream.Read(zstream.in_buf, (int)zstream.next_in, (int)bufferSize);
		}
		public void WriteToEnd()
		{
			if(baseStream==null) throw new ObjectDisposedException(null, "File closed");

			int ret;
			do
			{
				ret=zlib.deflate(zstream, zlib.Z_FINISH);
				if(ret==zlib.Z_OK)
				{
					if(zstream.avail_out==0)
					{
						baseStream.Write(zstream.out_buf, 0, zstream.next_out);
						zstream.next_out=0;
						zstream.avail_out=(uint)zstream.out_buf.Length;
					}
				}
				else if(ret!=zlib.Z_STREAM_END)
				{
					if(zstream.msg!=null&&zstream.msg.Length>0) throw new Exception(zstream.msg);
					throw new Exception("zlib error");
				}
			} while(ret!=zlib.Z_STREAM_END);

			if(zstream.next_out>0)
			{
				baseStream.Write(zstream.out_buf, 0, zstream.next_out);
				zstream.next_out=0;
				zstream.avail_out=(uint)zstream.out_buf.Length;
			}

			if(zstream!=null) zlib.deflateEnd(zstream);
			zstream=null;
		}
		public override void Close()
		{
			if(baseStream!=null) baseStream.Close();
			baseStream=null;

			if(zstream!=null) zlib.inflateEnd(zstream);
			zstream=null;

			base.Close();
		}