namespace System.Net.ApiService.Compression.Brotli {
///
///
/// decorator that decompresses brotli data.
/// Not thread-safe.
///
public class BrotliInputStream : System.IO.Stream {
public const int DefaultInternalBufferSize = 16384;
/// Internal buffer used for efficient byte-by-byte reading.
private byte[] buffer;
/// Number of decoded but still unused bytes in internal buffer.
private int remainingBufferBytes;
/// Next unused byte offset.
private int bufferOffset;
/// Decoder state.
private readonly System.Net.ApiService.Compression.Brotli.State state = new System.Net.ApiService.Compression.Brotli.State();
///
/// Creates a
///
/// wrapper that decompresses brotli data.
/// For byte-by-byte reading (
///
/// ) internal buffer with
///
/// size is allocated and used.
///
Will block the thread until first kilobyte of data of source is available.
///
/// underlying data source
/// in case of corrupted data or source stream problems
public BrotliInputStream(System.IO.Stream source)
: this(source, DefaultInternalBufferSize, null) {
}
///
/// Creates a
///
/// wrapper that decompresses brotli data.
/// For byte-by-byte reading (
///
/// ) internal buffer of specified size is
/// allocated and used.
///
Will block the thread until first kilobyte of data of source is available.
///
/// compressed data source
///
/// size of internal buffer used in case of
/// byte-by-byte reading
///
/// in case of corrupted data or source stream problems
public BrotliInputStream(System.IO.Stream source, int byteReadBufferSize)
: this(source, byteReadBufferSize, null) {
}
///
/// Creates a
///
/// wrapper that decompresses brotli data.
/// For byte-by-byte reading (
///
/// ) internal buffer of specified size is
/// allocated and used.
///
Will block the thread until first kilobyte of data of source is available.
///
/// compressed data source
///
/// size of internal buffer used in case of
/// byte-by-byte reading
///
///
/// custom dictionary data;
///
/// if not used
///
/// in case of corrupted data or source stream problems
public BrotliInputStream(System.IO.Stream source, int byteReadBufferSize, byte[] customDictionary) {
if (byteReadBufferSize <= 0) {
throw new System.ArgumentException("Bad buffer size:" + byteReadBufferSize);
} else if (source == null) {
throw new System.ArgumentException("source is null");
}
this.buffer = new byte[byteReadBufferSize];
this.remainingBufferBytes = 0;
this.bufferOffset = 0;
try {
System.Net.ApiService.Compression.Brotli.State.SetInput(state, source);
} catch (System.Net.ApiService.Compression.Brotli.BrotliRuntimeException ex) {
throw new System.IO.IOException("Brotli decoder initialization failed", ex);
}
if (customDictionary != null) {
System.Net.ApiService.Compression.Brotli.Decode.SetCustomDictionary(state, customDictionary);
}
}
///
///
public override void Close() {
System.Net.ApiService.Compression.Brotli.State.Close(state);
}
///
///
public override int ReadByte() {
if (bufferOffset >= remainingBufferBytes) {
remainingBufferBytes = Read(buffer, 0, buffer.Length);
bufferOffset = 0;
if (remainingBufferBytes == -1) {
return -1;
}
}
return buffer[bufferOffset++] & unchecked((int)(0xFF));
}
///
///
public override int Read(byte[] destBuffer, int destOffset, int destLen) {
if (destOffset < 0) {
throw new System.ArgumentException("Bad offset: " + destOffset);
} else if (destLen < 0) {
throw new System.ArgumentException("Bad length: " + destLen);
} else if (destOffset + destLen > destBuffer.Length) {
throw new System.ArgumentException("Buffer overflow: " + (destOffset + destLen) + " > " + destBuffer.Length);
} else if (destLen == 0) {
return 0;
}
int copyLen = System.Math.Max(remainingBufferBytes - bufferOffset, 0);
if (copyLen != 0) {
copyLen = System.Math.Min(copyLen, destLen);
System.Array.Copy(buffer, bufferOffset, destBuffer, destOffset, copyLen);
bufferOffset += copyLen;
destOffset += copyLen;
destLen -= copyLen;
if (destLen == 0) {
return copyLen;
}
}
try {
state.output = destBuffer;
state.outputOffset = destOffset;
state.outputLength = destLen;
state.outputUsed = 0;
System.Net.ApiService.Compression.Brotli.Decode.Decompress(state);
if (state.outputUsed == 0) {
return -1;
}
return state.outputUsed + copyLen;
} catch (System.Net.ApiService.Compression.Brotli.BrotliRuntimeException ex) {
throw new System.IO.IOException("Brotli stream decoding failed", ex);
}
}
// <{[INJECTED CODE]}>
public override bool CanRead {
get {
return true;
}
}
public override bool CanSeek {
get {
return false;
}
}
public override long Length {
get {
throw new System.NotSupportedException();
}
}
public override long Position {
get {
throw new System.NotSupportedException();
}
set {
throw new System.NotSupportedException();
}
}
public override long Seek(long offset, System.IO.SeekOrigin origin) {
throw new System.NotSupportedException();
}
public override void SetLength(long value) {
throw new System.NotSupportedException();
}
public override bool CanWrite {
get {
return false;
}
}
public override System.IAsyncResult BeginWrite(byte[] buffer, int offset,
int count, System.AsyncCallback callback, object state) {
throw new System.NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count) {
throw new System.NotSupportedException();
}
public override void Flush() {
}
}
}