2016-11-27 14:47:09 +11:00

78 lines
2.2 KiB
C#

// Originally copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
// See license.txt, section Ionic.Zlib license
#if __MonoCS__
using System;
using System.IO;
using ClassicalSharp;
namespace Ionic.Zlib {
internal class DeflateStream : ReadOnlyStream {
ZlibCodec z;
bool _leaveOpen;
byte[] workBuffer;
Stream _stream;
public DeflateStream(Stream stream, bool leaveOpen) {
_stream = stream;
_leaveOpen = leaveOpen;
workBuffer = new byte[16384]; // TODO: 1024 bytes?
z = new ZlibCodec();
}
public override void Close() {
z.EndInflate();
z = null;
if (!_leaveOpen)
_stream.Dispose();
_stream = null;
}
public override void Flush() { }
public override int Read(byte[] buffer, int offset, int count) {
// According to MS documentation, any implementation of the IO.Stream.Read function must:
// (a) throw an exception if offset & count reference an invalid part of the buffer,
// or if count < 0, or if buffer is null
// (b) return 0 only upon EOF, or if count = 0
// (c) if not EOF, then return at least 1 byte, up to <count> bytes
if (count == 0) return 0;
int rc = 0;
// set up the output of the deflate/inflate codec:
z.OutputBuffer = buffer;
z.NextOut = offset;
z.AvailableBytesOut = count;
z.InputBuffer = workBuffer;
bool endOfInput = false;
do {
// need data in _workingBuffer in order to deflate/inflate. Here, we check if we have any.
if (z.AvailableBytesIn == 0 && !endOfInput) {
// No data available, so try to Read data from the captive stream.
z.NextIn = 0;
z.AvailableBytesIn = _stream.Read(workBuffer, 0, workBuffer.Length);
if (z.AvailableBytesIn == 0)
endOfInput = true;
}
rc = z.Inflate();
if (endOfInput && rc == RCode.BufferError)
return 0;
if (rc != RCode.Okay && rc != RCode.StreamEnd)
throw new InvalidDataException("inflating: rc=" + rc);
if ((endOfInput || rc == RCode.StreamEnd) && z.AvailableBytesOut == count)
break; // nothing more to read
} while (z.AvailableBytesOut > 0 && !endOfInput && rc == RCode.Okay);
return count - z.AvailableBytesOut;
}
}
}
#endif