using System;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Messaging;
namespace System.IO.Compression
{
/// Provides methods and properties for compressing and decompressing streams using the Deflate algorithm.
// Token: 0x02000109 RID: 265
public class DeflateStream : Stream
{
/// Initializes a new instance of the class using the specified stream and value.
/// The stream to compress or decompress.
/// One of the values that indicates the action to take.
///
/// is null.
///
/// access right is ReadOnly and value is Compress.
///
/// is not a valid value.-or- is and is false.-or- is and is false.
// Token: 0x06000988 RID: 2440 RVA: 0x00019184 File Offset: 0x00017384
public DeflateStream(Stream compressedStream, CompressionMode mode)
: this(compressedStream, mode, false, false)
{
}
/// Initializes a new instance of the class using the specified stream and value, and a value that specifies whether to leave the stream open.
/// The stream to compress or decompress.
/// One of the values that indicates the action to take.
/// true to leave the stream open; otherwise, false.
///
/// is null.
///
/// access right is ReadOnly and value is Compress.
///
/// is not a valid value.-or- is and is false.-or- is and is false.
// Token: 0x06000989 RID: 2441 RVA: 0x00019190 File Offset: 0x00017390
public DeflateStream(Stream compressedStream, CompressionMode mode, bool leaveOpen)
: this(compressedStream, mode, leaveOpen, false)
{
}
// Token: 0x0600098A RID: 2442 RVA: 0x0001919C File Offset: 0x0001739C
internal DeflateStream(Stream compressedStream, CompressionMode mode, bool leaveOpen, bool gzip)
{
if (compressedStream == null)
{
throw new ArgumentNullException("compressedStream");
}
if (mode != CompressionMode.Compress && mode != CompressionMode.Decompress)
{
throw new ArgumentException("mode");
}
this.data = GCHandle.Alloc(this);
this.base_stream = compressedStream;
this.feeder = ((mode != CompressionMode.Compress) ? new DeflateStream.UnmanagedReadOrWrite(DeflateStream.UnmanagedRead) : new DeflateStream.UnmanagedReadOrWrite(DeflateStream.UnmanagedWrite));
this.z_stream = DeflateStream.CreateZStream(mode, gzip, this.feeder, GCHandle.ToIntPtr(this.data));
if (this.z_stream == IntPtr.Zero)
{
this.base_stream = null;
this.feeder = null;
throw new NotImplementedException("Failed to initialize zlib. You probably have an old zlib installed. Version 1.2.0.4 or later is required.");
}
this.mode = mode;
this.leaveOpen = leaveOpen;
}
/// Releases the unmanaged resources used by the and optionally releases the managed resources.
/// true to release both managed and unmanaged resources; false to release only unmanaged resources.
// Token: 0x0600098B RID: 2443 RVA: 0x00019270 File Offset: 0x00017470
protected override void Dispose(bool disposing)
{
if (disposing && !this.disposed)
{
this.disposed = true;
IntPtr intPtr = this.z_stream;
this.z_stream = IntPtr.Zero;
int num = 0;
if (intPtr != IntPtr.Zero)
{
num = DeflateStream.CloseZStream(intPtr);
}
this.io_buffer = null;
if (!this.leaveOpen)
{
Stream stream = this.base_stream;
if (stream != null)
{
stream.Close();
}
this.base_stream = null;
}
DeflateStream.CheckResult(num, "Dispose");
}
if (this.data.IsAllocated)
{
this.data.Free();
this.data = default(GCHandle);
}
base.Dispose(disposing);
}
// Token: 0x0600098C RID: 2444 RVA: 0x00019328 File Offset: 0x00017528
private static int UnmanagedRead(IntPtr buffer, int length, IntPtr data)
{
DeflateStream deflateStream = GCHandle.FromIntPtr(data).Target as DeflateStream;
if (deflateStream == null)
{
return -1;
}
return deflateStream.UnmanagedRead(buffer, length);
}
// Token: 0x0600098D RID: 2445 RVA: 0x0001935C File Offset: 0x0001755C
private unsafe int UnmanagedRead(IntPtr buffer, int length)
{
int num = 0;
int num2 = 1;
while (length > 0 && num2 > 0)
{
if (this.io_buffer == null)
{
this.io_buffer = new byte[4096];
}
int num3 = Math.Min(length, this.io_buffer.Length);
num2 = this.base_stream.Read(this.io_buffer, 0, num3);
if (num2 > 0)
{
Marshal.Copy(this.io_buffer, 0, buffer, num2);
buffer = new IntPtr((void*)((byte*)buffer.ToPointer() + num2));
length -= num2;
num += num2;
}
}
return num;
}
// Token: 0x0600098E RID: 2446 RVA: 0x000193F0 File Offset: 0x000175F0
private static int UnmanagedWrite(IntPtr buffer, int length, IntPtr data)
{
DeflateStream deflateStream = GCHandle.FromIntPtr(data).Target as DeflateStream;
if (deflateStream == null)
{
return -1;
}
return deflateStream.UnmanagedWrite(buffer, length);
}
// Token: 0x0600098F RID: 2447 RVA: 0x00019424 File Offset: 0x00017624
private unsafe int UnmanagedWrite(IntPtr buffer, int length)
{
int num = 0;
while (length > 0)
{
if (this.io_buffer == null)
{
this.io_buffer = new byte[4096];
}
int num2 = Math.Min(length, this.io_buffer.Length);
Marshal.Copy(buffer, this.io_buffer, 0, num2);
this.base_stream.Write(this.io_buffer, 0, num2);
buffer = new IntPtr((void*)((byte*)buffer.ToPointer() + num2));
length -= num2;
num += num2;
}
return num;
}
// Token: 0x06000990 RID: 2448 RVA: 0x000194A4 File Offset: 0x000176A4
private unsafe int ReadInternal(byte[] array, int offset, int count)
{
if (count == 0)
{
return 0;
}
int num;
fixed (byte* ptr = (ref array != null && array.Length != 0 ? ref array[0] : ref *null))
{
IntPtr intPtr = new IntPtr((void*)(ptr + offset));
num = DeflateStream.ReadZStream(this.z_stream, intPtr, count);
}
DeflateStream.CheckResult(num, "ReadInternal");
return num;
}
/// Reads a specified number of compressed or decompressed bytes into the specified byte array.
/// The number of bytes that were read into the byte array.
/// The buffer to store the compressed or decompressed bytes.
/// The location in the array to begin reading.
/// The number of compressed or decompressed bytes to read.
///
/// is null.
/// The value was Compress when the object was created.- or - The underlying stream does not support reading.
///
/// or is less than zero.-or- length minus the index starting point is less than .
/// The data is in an invalid format.
/// The stream is closed.
// Token: 0x06000991 RID: 2449 RVA: 0x00019500 File Offset: 0x00017700
public override int Read(byte[] dest, int dest_offset, int count)
{
if (this.disposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
if (dest == null)
{
throw new ArgumentNullException("Destination array is null.");
}
if (!this.CanRead)
{
throw new InvalidOperationException("Stream does not support reading.");
}
int num = dest.Length;
if (dest_offset < 0 || count < 0)
{
throw new ArgumentException("Dest or count is negative.");
}
if (dest_offset > num)
{
throw new ArgumentException("destination offset is beyond array size");
}
if (dest_offset + count > num)
{
throw new ArgumentException("Reading would overrun buffer");
}
return this.ReadInternal(dest, dest_offset, count);
}
// Token: 0x06000992 RID: 2450 RVA: 0x0001959C File Offset: 0x0001779C
private unsafe void WriteInternal(byte[] array, int offset, int count)
{
if (count == 0)
{
return;
}
int num;
fixed (byte* ptr = (ref array != null && array.Length != 0 ? ref array[0] : ref *null))
{
IntPtr intPtr = new IntPtr((void*)(ptr + offset));
num = DeflateStream.WriteZStream(this.z_stream, intPtr, count);
}
DeflateStream.CheckResult(num, "WriteInternal");
}
/// Writes compressed or decompressed bytes to the underlying stream from the specified byte array.
/// The buffer that contains the data to compress or decompress.
/// The byte offset in at which the read bytes will be placed.
/// The maximum number of bytes to compress.
// Token: 0x06000993 RID: 2451 RVA: 0x000195F8 File Offset: 0x000177F8
public override void Write(byte[] src, int src_offset, int count)
{
if (this.disposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
if (src == null)
{
throw new ArgumentNullException("src");
}
if (src_offset < 0)
{
throw new ArgumentOutOfRangeException("src_offset");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count");
}
if (!this.CanWrite)
{
throw new NotSupportedException("Stream does not support writing");
}
this.WriteInternal(src, src_offset, count);
}
// Token: 0x06000994 RID: 2452 RVA: 0x00019678 File Offset: 0x00017878
private static void CheckResult(int result, string where)
{
if (result >= 0)
{
return;
}
string text;
switch (result + 11)
{
case 0:
text = "IO error";
goto IL_A7;
case 1:
text = "Invalid argument(s)";
goto IL_A7;
case 5:
text = "Invalid version";
goto IL_A7;
case 6:
text = "Internal error (no progress possible)";
goto IL_A7;
case 7:
text = "Not enough memory";
goto IL_A7;
case 8:
text = "Corrupted data";
goto IL_A7;
case 9:
text = "Internal error";
goto IL_A7;
case 10:
text = "Unknown error";
goto IL_A7;
}
text = "Unknown error";
IL_A7:
throw new IOException(text + " " + where);
}
/// Flushes the contents of the internal buffer of the current stream object to the underlying stream.
/// The stream is closed.
///
///
///
// Token: 0x06000995 RID: 2453 RVA: 0x00019740 File Offset: 0x00017940
public override void Flush()
{
if (this.disposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
if (this.CanWrite)
{
int num = DeflateStream.Flush(this.z_stream);
DeflateStream.CheckResult(num, "Flush");
}
}
/// Begins an asynchronous read operation.
/// An object that represents the asynchronous read, which could still be pending.
/// The byte array to read the data into.
/// The byte offset in at which to begin writing data read from the stream.
/// The maximum number of bytes to read.
/// An optional asynchronous callback, to be called when the read is complete.
/// A user-provided object that distinguishes this particular asynchronous read request from other requests.
/// An asynchronous read past the end of the stream was attempted, or a disk error occurred.
/// One or more of the arguments is invalid.
/// Methods were called after the stream was closed.
/// The current implementation does not support the read operation.
/// This call cannot be completed.
// Token: 0x06000996 RID: 2454 RVA: 0x0001978C File Offset: 0x0001798C
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state)
{
if (this.disposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
if (!this.CanRead)
{
throw new NotSupportedException("This stream does not support reading");
}
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count", "Must be >= 0");
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException("offset", "Must be >= 0");
}
if (count + offset > buffer.Length)
{
throw new ArgumentException("Buffer too small. count/offset wrong.");
}
DeflateStream.ReadMethod readMethod = new DeflateStream.ReadMethod(this.ReadInternal);
return readMethod.BeginInvoke(buffer, offset, count, cback, state);
}
/// Begins an asynchronous write operation.
/// An object that represents the asynchronous write, which could still be pending.
/// The buffer to write data from.
/// The byte offset in to begin writing from.
/// The maximum number of bytes to write.
/// An optional asynchronous callback, to be called when the write is complete.
/// A user-provided object that distinguishes this particular asynchronous write request from other requests.
/// An asynchronous write past the end of the stream was attempted, or a disk error occurred.
/// One or more of the arguments is invalid.
/// Methods were called after the stream was closed.
/// The current implementation does not support the write operation.
/// The write operation cannot be performed because the stream is closed.
// Token: 0x06000997 RID: 2455 RVA: 0x0001983C File Offset: 0x00017A3C
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback cback, object state)
{
if (this.disposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
if (!this.CanWrite)
{
throw new InvalidOperationException("This stream does not support writing");
}
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count", "Must be >= 0");
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException("offset", "Must be >= 0");
}
if (count + offset > buffer.Length)
{
throw new ArgumentException("Buffer too small. count/offset wrong.");
}
DeflateStream.WriteMethod writeMethod = new DeflateStream.WriteMethod(this.WriteInternal);
return writeMethod.BeginInvoke(buffer, offset, count, cback, state);
}
/// Waits for the pending asynchronous read to complete.
/// The number of bytes read from the stream, between zero (0) and the number of bytes you requested. returns zero (0) only at the end of the stream; otherwise, it blocks until at least one byte is available.
/// The reference to the pending asynchronous request to finish.
///
/// is null.
///
/// did not originate from a method on the current stream.
/// An exception was thrown during a call to .
/// The end call is invalid because asynchronous read operations for this stream are not yet complete.
/// The stream is null.
// Token: 0x06000998 RID: 2456 RVA: 0x000198EC File Offset: 0x00017AEC
public override int EndRead(IAsyncResult async_result)
{
if (async_result == null)
{
throw new ArgumentNullException("async_result");
}
AsyncResult asyncResult = async_result as AsyncResult;
if (asyncResult == null)
{
throw new ArgumentException("Invalid IAsyncResult", "async_result");
}
DeflateStream.ReadMethod readMethod = asyncResult.AsyncDelegate as DeflateStream.ReadMethod;
if (readMethod == null)
{
throw new ArgumentException("Invalid IAsyncResult", "async_result");
}
return readMethod.EndInvoke(async_result);
}
/// Ends an asynchronous write operation.
/// A reference to the outstanding asynchronous I/O request.
///
/// is null.
///
/// did not originate from a method on the current stream.
/// An exception was thrown during a call to .
/// The stream is null.
/// The end write call is invalid.
// Token: 0x06000999 RID: 2457 RVA: 0x00019950 File Offset: 0x00017B50
public override void EndWrite(IAsyncResult async_result)
{
if (async_result == null)
{
throw new ArgumentNullException("async_result");
}
AsyncResult asyncResult = async_result as AsyncResult;
if (asyncResult == null)
{
throw new ArgumentException("Invalid IAsyncResult", "async_result");
}
DeflateStream.WriteMethod writeMethod = asyncResult.AsyncDelegate as DeflateStream.WriteMethod;
if (writeMethod == null)
{
throw new ArgumentException("Invalid IAsyncResult", "async_result");
}
writeMethod.EndInvoke(async_result);
}
/// This operation is not supported and always throws a .
/// A long value.
/// The location in the stream.
/// One of the values.
/// This property is not supported on this stream.
// Token: 0x0600099A RID: 2458 RVA: 0x000199B4 File Offset: 0x00017BB4
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
/// This operation is not supported and always throws a .
/// The length of the stream.
/// This property is not supported on this stream.
// Token: 0x0600099B RID: 2459 RVA: 0x000199BC File Offset: 0x00017BBC
public override void SetLength(long value)
{
throw new NotSupportedException();
}
/// Gets a reference to the underlying stream.
/// A stream object that represents the underlying stream.
/// The underlying stream is closed.
// Token: 0x1700027F RID: 639
// (get) Token: 0x0600099C RID: 2460 RVA: 0x000199C4 File Offset: 0x00017BC4
public Stream BaseStream
{
get
{
return this.base_stream;
}
}
/// Gets a value indicating whether the stream supports reading while decompressing a file.
/// true if the value is Decompress, and the underlying stream is opened and supports reading; otherwise, false.
// Token: 0x17000280 RID: 640
// (get) Token: 0x0600099D RID: 2461 RVA: 0x000199CC File Offset: 0x00017BCC
public override bool CanRead
{
get
{
return !this.disposed && this.mode == CompressionMode.Decompress && this.base_stream.CanRead;
}
}
/// Gets a value indicating whether the stream supports seeking.
/// false in all cases.
// Token: 0x17000281 RID: 641
// (get) Token: 0x0600099E RID: 2462 RVA: 0x00019A00 File Offset: 0x00017C00
public override bool CanSeek
{
get
{
return false;
}
}
/// Gets a value indicating whether the stream supports writing.
/// true if the value is Compress, and the underlying stream supports writing and is not closed; otherwise, false.
// Token: 0x17000282 RID: 642
// (get) Token: 0x0600099F RID: 2463 RVA: 0x00019A04 File Offset: 0x00017C04
public override bool CanWrite
{
get
{
return !this.disposed && this.mode == CompressionMode.Compress && this.base_stream.CanWrite;
}
}
/// This property is not supported and always throws a .
/// A long value.
/// This property is not supported on this stream.
///
///
///
// Token: 0x17000283 RID: 643
// (get) Token: 0x060009A0 RID: 2464 RVA: 0x00019A2C File Offset: 0x00017C2C
public override long Length
{
get
{
throw new NotSupportedException();
}
}
/// This property is not supported and always throws a .
/// A long value.
/// This property is not supported on this stream.
///
///
///
// Token: 0x17000284 RID: 644
// (get) Token: 0x060009A1 RID: 2465 RVA: 0x00019A34 File Offset: 0x00017C34
// (set) Token: 0x060009A2 RID: 2466 RVA: 0x00019A3C File Offset: 0x00017C3C
public override long Position
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
// Token: 0x060009A3 RID: 2467
[DllImport("MonoPosixHelper", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateZStream(CompressionMode compress, bool gzip, DeflateStream.UnmanagedReadOrWrite feeder, IntPtr data);
// Token: 0x060009A4 RID: 2468
[DllImport("MonoPosixHelper", CallingConvention = CallingConvention.Cdecl)]
private static extern int CloseZStream(IntPtr stream);
// Token: 0x060009A5 RID: 2469
[DllImport("MonoPosixHelper", CallingConvention = CallingConvention.Cdecl)]
private static extern int Flush(IntPtr stream);
// Token: 0x060009A6 RID: 2470
[DllImport("MonoPosixHelper", CallingConvention = CallingConvention.Cdecl)]
private static extern int ReadZStream(IntPtr stream, IntPtr buffer, int length);
// Token: 0x060009A7 RID: 2471
[DllImport("MonoPosixHelper", CallingConvention = CallingConvention.Cdecl)]
private static extern int WriteZStream(IntPtr stream, IntPtr buffer, int length);
// Token: 0x0400031F RID: 799
private const int BufferSize = 4096;
// Token: 0x04000320 RID: 800
private const string LIBNAME = "MonoPosixHelper";
// Token: 0x04000321 RID: 801
private Stream base_stream;
// Token: 0x04000322 RID: 802
private CompressionMode mode;
// Token: 0x04000323 RID: 803
private bool leaveOpen;
// Token: 0x04000324 RID: 804
private bool disposed;
// Token: 0x04000325 RID: 805
private DeflateStream.UnmanagedReadOrWrite feeder;
// Token: 0x04000326 RID: 806
private IntPtr z_stream;
// Token: 0x04000327 RID: 807
private byte[] io_buffer;
// Token: 0x04000328 RID: 808
private GCHandle data;
// Token: 0x02000309 RID: 777
// (Invoke) Token: 0x06001BFD RID: 7165
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int UnmanagedReadOrWrite(IntPtr buffer, int length, IntPtr data);
// Token: 0x0200030A RID: 778
// (Invoke) Token: 0x06001C01 RID: 7169
private delegate int ReadMethod(byte[] array, int offset, int count);
// Token: 0x0200030B RID: 779
// (Invoke) Token: 0x06001C05 RID: 7173
private delegate void WriteMethod(byte[] array, int offset, int count);
}
}