Created
May 28, 2011 19:20
-
-
Save LordJZ/997133 to your computer and use it in GitHub Desktop.
StreamHandler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Runtime.InteropServices; | |
namespace WhatIf | |
{ | |
/// <summary> | |
/// A class to manipulate data inside a stream. | |
/// </summary> | |
public class StreamHandler : IDisposable | |
{ | |
private static IEnumerable<byte> m_newLineBytes = Environment.NewLine.ToCharArray().Select(c => (byte)c); | |
#region Properties | |
private Encoding m_encoding; | |
private Encoder m_encoder; | |
private Decoder m_decoder; | |
private bool m_2BytesPerChar; | |
private byte[] m_buffer; | |
private byte[] m_charBytes; | |
private char[] m_singleChar; | |
/// <summary> | |
/// Holds the underlying stream. | |
/// </summary> | |
protected Stream m_stream; | |
/// <summary> | |
/// Gets the underlying stream of the <see cref="WhatIf.StreamHandler"/>. | |
/// </summary> | |
public Stream BaseStream | |
{ | |
get | |
{ | |
this.Flush(); | |
return this.m_stream; | |
} | |
} | |
/// <summary> | |
/// Gets the number of bytes from the current position of the stream to the end of the stream. | |
/// </summary> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// Methods were called after the stream was closed. | |
/// </exception> | |
/// <exception cref="System.NotSupportedException"> | |
/// The stream does not support seeking. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public long RemainingLength | |
{ | |
get | |
{ | |
this.Flush(); | |
return m_stream.Length - m_stream.Position; | |
} | |
} | |
/// <summary> | |
/// Gets the value indicating whether the current stream was fully read and no bytes can be read currently. | |
/// </summary> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// Methods were called after the stream was closed. | |
/// </exception> | |
/// <exception cref="System.NotSupportedException"> | |
/// The stream does not support seeking. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public bool IsRead | |
{ | |
get | |
{ | |
return RemainingLength == 0; | |
} | |
} | |
#endregion | |
#region Constructors | |
/// <summary> | |
/// Initializes a new instance of the <see cref="WhatIf.StreamHandler"/> class | |
/// based on the supplied stream and a specific character encoding. | |
/// </summary> | |
/// <param name="output">The output stream.</param> | |
/// <param name="encoding">The character encoding.</param> | |
/// <exception cref="System.ArgumentException"> | |
/// The stream does not support writing, or the stream is already closed. | |
/// </exception> | |
/// <exception cref="System.ArgumentNullException"> | |
/// output or encoding is null. | |
/// </exception> | |
public StreamHandler(Stream output, Encoding encoding) | |
{ | |
if (output == null) | |
throw new ArgumentNullException("output"); | |
if (encoding == null) | |
throw new ArgumentNullException("encoding"); | |
this.m_stream = output; | |
this.m_buffer = new byte[0x10]; | |
this.m_encoding = encoding; | |
this.m_encoder = this.m_encoding.GetEncoder(); | |
this.m_decoder = this.m_encoding.GetDecoder(); | |
this.m_2BytesPerChar = encoding is UnicodeEncoding; | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="WhatIf.StreamHandler"/> class | |
/// based on the supplied stream and using UTF-8 as the encoding for strings. | |
/// </summary> | |
/// <param name="output">The output stream.</param> | |
/// <exception cref="System.ArgumentException"> | |
/// The stream does not support writing, or the stream is already closed. | |
/// </exception> | |
/// <exception cref="System.ArgumentNullException"> | |
/// output is null. | |
/// </exception> | |
public StreamHandler(Stream output) | |
: this(output, new UTF8Encoding(false, true)) | |
{ | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="WhatIf.StreamHandler"/> class | |
/// using a new resizeable <see cref="System.IO.MemoryStream"/> and using UTF-8 as the encoding for strings. | |
/// </summary> | |
public StreamHandler() | |
: this(new MemoryStream(), new UTF8Encoding(false, true)) | |
{ | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="WhatIf.StreamHandler"/> class | |
/// using a new <see cref="System.IO.FileStream"/> in reading or writing mode | |
/// and using UTF-8 as the encoding for strings. | |
/// </summary> | |
/// <param name="path"> | |
/// Name of the file to open. | |
/// </param> | |
public StreamHandler(string path) | |
: this(new FileStream(path, FileMode.OpenOrCreate), new UTF8Encoding(false, true)) | |
{ | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="WhatIf.StreamHandler"/> class | |
/// using a new <see cref="System.IO.FileStream"/> in the specified mode | |
/// and using UTF-8 as the encoding for strings. | |
/// </summary> | |
/// <param name="path"> | |
/// A relative or absolute path for the file that the current | |
/// <see cref="WhatIf.StreamHandler"/> object will encapsulate. | |
/// </param> | |
/// <param name="mode"> | |
/// A <see cref="System.IO.FileMode"/> constant that determines how to open or create the file. | |
/// </param> | |
public StreamHandler(string path, FileMode mode) | |
: this(new FileStream(path, mode), new UTF8Encoding(false, true)) | |
{ | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="WhatIf.StreamHandler"/> class | |
/// using a new <see cref="System.IO.FileStream"/> in the specified mode | |
/// and using the specified encoding for strings. | |
/// </summary> | |
/// <param name="path"> | |
/// A relative or absolute path for the file that the current | |
/// <see cref="WhatIf.StreamHandler"/> object will encapsulate. | |
/// </param> | |
/// <param name="mode"> | |
/// A <see cref="System.IO.FileMode"/> constant that determines how to open or create the file. | |
/// </param> | |
/// <param name="encoding"> | |
/// The character encoding. | |
/// </param> | |
public StreamHandler(string path, FileMode mode, Encoding encoding) | |
: this(new FileStream(path, mode), encoding) | |
{ | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="WhatIf.StreamHandler"/> class | |
/// based on the supplied byte array. | |
/// </summary> | |
/// <param name="buffer">The byte array containing data to be read or to be written into.</param> | |
/// <exception cref="System.ArgumentNullException"> | |
/// buffer is null. | |
/// </exception> | |
public StreamHandler(byte[] buffer) | |
{ | |
this.m_stream = new MemoryStream(buffer); | |
this.m_buffer = new byte[16]; | |
this.m_encoding = new UTF8Encoding(false, true); | |
this.m_encoder = this.m_encoding.GetEncoder(); | |
this.m_decoder = this.m_encoding.GetDecoder(); | |
this.m_2BytesPerChar = false; | |
} | |
#endregion | |
#region Misc Methods | |
/// <summary> | |
/// Closes the current <see cref="WhatIf.StreamHandler"/> and the underlying stream. | |
/// </summary> | |
public virtual void Close() | |
{ | |
this.Dispose(true); | |
} | |
/// <summary> | |
/// Releases the unmanaged resources used by the <see cref="WhatIf.StreamHandler"/> | |
/// and optionally releases the managed resources. | |
/// </summary> | |
/// <param name="disposing"> | |
/// true to release both managed and unmanaged resources; | |
/// false to release only unmanaged resources. | |
/// </param> | |
protected virtual void Dispose(bool disposing) | |
{ | |
if (disposing) | |
this.m_stream.Close(); | |
} | |
/// <summary> | |
/// Releases all resources used by the current instance of the <see cref="WhatIf.StreamHandler"/> class. | |
/// </summary> | |
void IDisposable.Dispose() | |
{ | |
this.Dispose(true); | |
} | |
/// <summary> | |
/// Clears all buffers for the current writer and causes any buffered | |
/// data to be written to the underlying device. | |
/// </summary> | |
public void Flush() | |
{ | |
this.m_stream.Flush(); | |
} | |
/// <summary> | |
/// Gets the value indicating whether you can read the provided number of bytes. | |
/// </summary> | |
/// <param name="bytes">Number of bytes to read.</param> | |
/// <returns>true if the provided number of bytes can be read; otherwise, false.</returns> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// Methods were called after the stream was closed. | |
/// </exception> | |
/// <exception cref="System.NotSupportedException"> | |
/// The stream does not support seeking. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ArgumentException"> | |
/// bytes is negative. | |
/// </exception> | |
public bool CanRead(long bytes) | |
{ | |
if (bytes < 0) | |
throw new ArgumentException("A non-negative number is required.", "bytes"); | |
return RemainingLength >= bytes; | |
} | |
/// <summary> | |
/// Skips a number of bytes from the current stream. | |
/// </summary> | |
/// <param name="bytes">The number of bytes to skip.</param> | |
/// <returns>true if the provided number of bytes can be read; otherwise, false.</returns> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// Methods were called after the stream was closed. | |
/// </exception> | |
/// <exception cref="System.NotSupportedException"> | |
/// The stream does not support seeking. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ArgumentException"> | |
/// bytes is negative. | |
/// </exception> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// End of stream is reached. | |
/// </exception> | |
public void Skip(long bytes) | |
{ | |
if (!CanRead(bytes)) | |
throw new EndOfStreamException(); | |
this.m_stream.Position += bytes; | |
} | |
#endregion | |
#region Write Methods | |
/// <summary> | |
/// Writes a one-byte Boolean value to the current stream, with 0 representing | |
/// false and 1 representing true. | |
/// </summary> | |
/// <param name="value"> | |
/// The Boolean value to write (0 or 1). | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteBool(bool value) | |
{ | |
this.m_buffer[0] = value ? ((byte)1) : ((byte)0); | |
this.m_stream.Write(this.m_buffer, 0, 1); | |
return this; | |
} | |
/// <summary> | |
/// Writes an unsigned byte to the current stream and advances the stream position | |
/// by one byte. | |
/// </summary> | |
/// <param name="value"> | |
/// The unsigned byte to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteByte(byte value) | |
{ | |
this.m_stream.WriteByte(value); | |
return this; | |
} | |
/// <summary> | |
/// Writes a byte array to the underlying stream. | |
/// </summary> | |
/// <param name="buffer"> | |
/// A byte array containing the data to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.ArgumentNullException"> | |
/// buffer is null. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteBytes(byte[] buffer) | |
{ | |
if (buffer == null) | |
throw new ArgumentNullException("buffer"); | |
this.m_stream.Write(buffer, 0, buffer.Length); | |
return this; | |
} | |
/// <summary> | |
/// Writes a Unicode character to the current stream and advances the current | |
/// position of the stream in accordance with the Encoding used and the specific | |
/// characters being written to the stream. | |
/// </summary> | |
/// <param name="ch"> | |
/// The non-surrogate, Unicode character to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.ArgumentException"> | |
/// ch is a single surrogate character. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public unsafe StreamHandler WriteChar(char ch) | |
{ | |
if (char.IsSurrogate(ch)) | |
throw new ArgumentException("Single surrogate characters are not allowed."); | |
int count = 0; | |
fixed (byte* numRef = this.m_buffer) | |
{ | |
count = this.m_encoder.GetBytes(&ch, 1, numRef, 16, true); | |
} | |
this.m_stream.Write(this.m_buffer, 0, count); | |
return this; | |
} | |
/// <summary> | |
/// Writes a character array to the current stream and advances the current position | |
/// of the stream in accordance with the Encoding used and the specific characters | |
/// being written to the stream. | |
/// </summary> | |
/// <param name="chars"> | |
/// A character array containing the data to write. | |
/// </param> | |
/// <exception cref="System.ArgumentNullException"> | |
/// chars is null. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteChars(char[] chars) | |
{ | |
if (chars == null) | |
throw new ArgumentNullException("chars"); | |
byte[] buffer = this.m_encoding.GetBytes(chars, 0, chars.Length); | |
this.m_stream.Write(buffer, 0, buffer.Length); | |
return this; | |
} | |
/// <summary> | |
/// Writes a decimal value to the current stream and advances the stream position | |
/// by sixteen bytes. | |
/// </summary> | |
/// <param name="value"> | |
/// The decimal value to write. | |
/// </param> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteDecimal(decimal value) | |
{ | |
int[] bits = decimal.GetBits(value); | |
this.WriteInt32(bits[0]); | |
this.WriteInt32(bits[1]); | |
this.WriteInt32(bits[2]); | |
this.WriteInt32(bits[3]); | |
return this; | |
} | |
/// <summary> | |
/// Writes an eight-byte floating-point value to the current stream and advances | |
/// the stream position by eight bytes. | |
/// </summary> | |
/// <param name="value"> | |
/// The eight-byte floating-point value to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public unsafe StreamHandler WriteDouble(double value) | |
{ | |
ulong num = *(ulong*)&value; | |
this.m_buffer[0] = (byte)num; | |
this.m_buffer[1] = (byte)(num >> 8); | |
this.m_buffer[2] = (byte)(num >> 16); | |
this.m_buffer[3] = (byte)(num >> 24); | |
this.m_buffer[4] = (byte)(num >> 32); | |
this.m_buffer[5] = (byte)(num >> 40); | |
this.m_buffer[6] = (byte)(num >> 48); | |
this.m_buffer[7] = (byte)(num >> 56); | |
this.m_stream.Write(this.m_buffer, 0, 8); | |
return this; | |
} | |
/// <summary> | |
/// Writes a four-byte floating-point value to the current stream and advances | |
/// the stream position by four bytes. | |
/// </summary> | |
/// <param name="value"> | |
/// The four-byte floating-point value to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public unsafe StreamHandler WriteFloat(float value) | |
{ | |
uint num = *((uint*)&value); | |
this.m_buffer[0] = (byte)num; | |
this.m_buffer[1] = (byte)(num >> 8); | |
this.m_buffer[2] = (byte)(num >> 16); | |
this.m_buffer[3] = (byte)(num >> 24); | |
this.m_stream.Write(this.m_buffer, 0, 4); | |
return this; | |
} | |
/// <summary> | |
/// Writes a four-byte signed integer to the current stream and advances the | |
/// stream position by four bytes. | |
/// </summary> | |
/// <param name="value"> | |
/// The four-byte signed integer to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteInt32(int value) | |
{ | |
this.m_buffer[0] = (byte)value; | |
this.m_buffer[1] = (byte)(value >> 8); | |
this.m_buffer[2] = (byte)(value >> 16); | |
this.m_buffer[3] = (byte)(value >> 24); | |
this.m_stream.Write(this.m_buffer, 0, 4); | |
return this; | |
} | |
/// <summary> | |
/// Writes an eight-byte signed integer to the current stream and advances the | |
/// stream position by eight bytes. | |
/// </summary> | |
/// <param name="value"> | |
/// The eight-byte signed integer to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteInt64(long value) | |
{ | |
this.m_buffer[0] = (byte)value; | |
this.m_buffer[1] = (byte)(value >> 8); | |
this.m_buffer[2] = (byte)(value >> 0x10); | |
this.m_buffer[3] = (byte)(value >> 0x18); | |
this.m_buffer[4] = (byte)(value >> 0x20); | |
this.m_buffer[5] = (byte)(value >> 40); | |
this.m_buffer[6] = (byte)(value >> 0x30); | |
this.m_buffer[7] = (byte)(value >> 0x38); | |
this.m_stream.Write(this.m_buffer, 0, 8); | |
return this; | |
} | |
/// <summary> | |
/// Writes a signed byte to the current stream and advances the stream position | |
/// by one byte. | |
/// </summary> | |
/// <param name="value"> | |
/// The signed byte to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteSByte(sbyte value) | |
{ | |
this.m_stream.WriteByte((byte)value); | |
return this; | |
} | |
/// <summary> | |
/// Writes a two-byte signed integer to the current stream and advances the stream | |
/// position by two bytes. | |
/// </summary> | |
/// <param name="value"> | |
/// The two-byte signed integer to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteInt16(short value) | |
{ | |
this.m_buffer[0] = (byte)value; | |
this.m_buffer[1] = (byte)(value >> 8); | |
this.m_stream.Write(this.m_buffer, 0, 2); | |
return this; | |
} | |
/// <summary> | |
/// Writes a null-terminated string to the current stream in the current encoding of | |
/// the <see cref="WhatIf.StreamHandler"/>, and advances the current position of the stream | |
/// by the length of the string plus one. | |
/// </summary> | |
/// <param name="value"> | |
/// The string to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ArgumentNullException"> | |
/// value is null. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.ArgumentException"> | |
/// value contains a null character before a not-null character. | |
/// </exception> | |
/// <returns> | |
/// The current instance of <see cref="WhatIf.StreamHandler"/>. | |
/// </returns> | |
public StreamHandler WriteCString(string value) | |
{ | |
if (value == null) | |
throw new ArgumentNullException("value"); | |
value = value.TrimEnd((char)0); | |
if (value.IndexOf((char)0) != -1) | |
throw new ArgumentException("value"); | |
char[] chars = value.ToCharArray(); | |
byte[] buffer = this.m_encoding.GetBytes(chars, 0, chars.Length); | |
this.m_stream.Write(buffer, 0, buffer.Length); | |
this.m_stream.WriteByte(0); | |
return this; | |
} | |
/// <summary> | |
/// Writes a four-byte unsigned integer to the current stream and advances the | |
/// stream position by four bytes. | |
/// </summary> | |
/// <param name="value"> | |
/// The four-byte unsigned integer to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteUInt32(uint value) | |
{ | |
this.m_buffer[0] = (byte)value; | |
this.m_buffer[1] = (byte)(value >> 8); | |
this.m_buffer[2] = (byte)(value >> 0x10); | |
this.m_buffer[3] = (byte)(value >> 0x18); | |
this.m_stream.Write(this.m_buffer, 0, 4); | |
return this; | |
} | |
/// <summary> | |
/// Writes an eight-byte unsigned integer to the current stream and advances | |
/// the stream position by eight bytes. | |
/// </summary> | |
/// <param name="value"> | |
/// The eight-byte unsigned integer to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteUInt64(ulong value) | |
{ | |
this.m_buffer[0] = (byte)value; | |
this.m_buffer[1] = (byte)(value >> 8); | |
this.m_buffer[2] = (byte)(value >> 0x10); | |
this.m_buffer[3] = (byte)(value >> 0x18); | |
this.m_buffer[4] = (byte)(value >> 0x20); | |
this.m_buffer[5] = (byte)(value >> 40); | |
this.m_buffer[6] = (byte)(value >> 0x30); | |
this.m_buffer[7] = (byte)(value >> 0x38); | |
this.m_stream.Write(this.m_buffer, 0, 8); | |
return this; | |
} | |
/// <summary> | |
/// Writes a two-byte unsigned integer to the current stream and advances the | |
/// stream position by two bytes. | |
/// </summary> | |
/// <param name="value"> | |
/// The two-byte unsigned integer to write. | |
/// </param> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteUInt16(ushort value) | |
{ | |
this.m_buffer[0] = (byte)value; | |
this.m_buffer[1] = (byte)(value >> 8); | |
this.m_stream.Write(this.m_buffer, 0, 2); | |
return this; | |
} | |
/// <summary> | |
/// Writes a region of a byte array to the current stream. | |
/// </summary> | |
/// <param name="buffer"> | |
/// A byte array containing the data to write. | |
/// </param> | |
/// <param name="index"> | |
/// The starting point in buffer at which to begin writing. | |
/// </param> | |
/// <param name="count"> | |
/// The number of bytes to write. | |
/// </param> | |
/// <exception cref="System.ArgumentException"> | |
/// The buffer length minus index is less than count. | |
/// </exception> | |
/// <exception cref="System.ArgumentNullException"> | |
/// buffer is null. | |
/// </exception> | |
/// <exception cref="System.ArgumentOutOfRangeException"> | |
/// index or count is negative. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteBytes(byte[] buffer, int index, int count) | |
{ | |
this.m_stream.Write(buffer, index, count); | |
return this; | |
} | |
/// <summary> | |
/// Writes a section of a character array to the current stream, and advances | |
/// the current position of the stream in accordance with the Encoding used and | |
/// perhaps the specific characters being written to the stream. | |
/// </summary> | |
/// <param name="chars"> | |
/// A character array containing the data to write. | |
/// </param> | |
/// <param name="index"> | |
/// The starting point in buffer from which to begin writing. | |
/// </param> | |
/// <param name="count"> | |
/// The number of characters to write. | |
/// </param> | |
/// <exception cref="System.ArgumentException"> | |
/// The buffer length minus index is less than count. | |
/// </exception> | |
/// <exception cref="System.ArgumentNullException"> | |
/// chars is null. | |
/// </exception> | |
/// <exception cref="System.ArgumentOutOfRangeException"> | |
/// index or count is negative. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteChars(char[] chars, int index, int count) | |
{ | |
byte[] buffer = this.m_encoding.GetBytes(chars, index, count); | |
this.m_stream.Write(buffer, 0, buffer.Length); | |
return this; | |
} | |
/// <summary> | |
/// Writes a byte representation of a structure to the current stream. | |
/// </summary> | |
/// <typeparam name="T"> | |
/// Type of a structure. | |
/// </typeparam> | |
/// <param name="structure"> | |
/// A structure to write into the current stream. | |
/// </param> | |
/// <returns>The current instance of <see cref="WhatIf.StreamHandler"/>.</returns> | |
public StreamHandler WriteStruct<T>(T structure) where T : struct | |
{ | |
lock (StructHelper<T>.SyncRoot) | |
{ | |
Marshal.StructureToPtr(structure, StructHelper<T>.UnmanagedDataBank, false); | |
Marshal.Copy(StructHelper<T>.UnmanagedDataBank, StructHelper<T>.ManagedDataBank, 0, StructHelper<T>.Size); | |
WriteBytes(StructHelper<T>.ManagedDataBank); | |
} | |
return this; | |
} | |
#endregion | |
#region Read Methods | |
private int InternalReadOneChar() | |
{ | |
long position = 0L; | |
int num = 0; | |
int byteCount = 0; | |
if (this.m_stream.CanSeek) | |
position = this.m_stream.Position; | |
if (this.m_charBytes == null) | |
this.m_charBytes = new byte[0x80]; | |
if (this.m_singleChar == null) | |
this.m_singleChar = new char[1]; | |
while (num == 0) | |
{ | |
byteCount = this.m_2BytesPerChar ? 2 : 1; | |
int num4 = this.m_stream.ReadByte(); | |
this.m_charBytes[0] = (byte)num4; | |
if (num4 == -1) | |
byteCount = 0; | |
if (byteCount == 2) | |
{ | |
num4 = this.m_stream.ReadByte(); | |
this.m_charBytes[1] = (byte)num4; | |
if (num4 == -1) | |
byteCount = 1; | |
} | |
if (byteCount == 0) | |
return -1; | |
try | |
{ | |
num = this.m_decoder.GetChars(this.m_charBytes, 0, byteCount, this.m_singleChar, 0); | |
continue; | |
} | |
catch | |
{ | |
if (this.m_stream.CanSeek) | |
this.m_stream.Seek(position - this.m_stream.Position, SeekOrigin.Current); | |
throw; | |
} | |
} | |
if (num == 0) | |
return -1; | |
return this.m_singleChar[0]; | |
} | |
private void FillBuffer(int numBytes) | |
{ | |
int offset = 0; | |
int num2 = 0; | |
if (this.m_stream == null) | |
throw new IOException(); | |
if (numBytes == 1) | |
{ | |
num2 = this.m_stream.ReadByte(); | |
if (num2 == -1) | |
throw new IOException(); | |
this.m_buffer[0] = (byte)num2; | |
} | |
else | |
{ | |
do | |
{ | |
num2 = this.m_stream.Read(this.m_buffer, offset, numBytes - offset); | |
if (num2 == 0) | |
throw new IOException(); | |
offset += num2; | |
} | |
while (offset < numBytes); | |
} | |
} | |
/// <summary> | |
/// Returns the next available character and does not advance the byte or character | |
/// position. | |
/// </summary> | |
/// <returns> | |
/// The next available character, or -1 if no more characters are available or | |
/// the stream does not support seeking. | |
/// </returns> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public int PeekChar() | |
{ | |
if (this.m_stream == null) | |
throw new IOException(); | |
if (!this.m_stream.CanSeek) | |
return -1; | |
long position = this.m_stream.Position; | |
int num2 = this.Read(); | |
this.m_stream.Position = position; | |
return num2; | |
} | |
/// <summary> | |
/// Reads characters from the underlying stream and advances the current position | |
/// of the stream in accordance with the Encoding used and the specific character | |
/// being read from the stream. | |
/// </summary> | |
/// <returns> | |
/// The next character from the input stream, or -1 if no characters are currently | |
/// available. | |
/// </returns> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
public int Read() | |
{ | |
if (this.m_stream == null) | |
throw new IOException(); | |
return this.InternalReadOneChar(); | |
} | |
/// <summary> | |
/// Reads the specified number of bytes from the stream, starting from a specified | |
/// point in the byte array. | |
/// </summary> | |
/// <param name="buffer"> | |
/// The buffer to read data into. | |
/// </param> | |
/// <param name="offset"> | |
/// The starting point in the buffer at which to begin reading into the buffer. | |
/// </param> | |
/// <param name="count"> | |
/// The number of bytes to read. | |
/// </param> | |
/// <returns> | |
/// The number of bytes read into buffer. This might be less than the number | |
/// of bytes requested if that many bytes are not available, or it might be zero | |
/// if the end of the stream is reached. | |
/// </returns> | |
/// <exception cref="System.ArgumentException"> | |
/// The sum of offset and count is larger than the buffer length. | |
/// </exception> | |
/// <exception cref="System.ArgumentNullException"> | |
/// buffer is null. | |
/// </exception> | |
/// <exception cref="System.ArgumentOutOfRangeException"> | |
/// offset or count is negative. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.NotSupportedException"> | |
/// The stream does not support reading. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// Methods were called after the stream was closed. | |
/// </exception> | |
public int Read(byte[] buffer, int offset, int count) | |
{ | |
return this.m_stream.Read(buffer, offset, count); | |
} | |
/// <summary> | |
/// Reads the specified number of characters from the stream, starting from a | |
/// specified point in the character array. | |
/// </summary> | |
/// <param name="buffer"> | |
/// The buffer to read data into. | |
/// </param> | |
/// <param name="index"> | |
/// The starting point in the buffer at which to begin reading into the buffer. | |
/// </param> | |
/// <param name="count"> | |
/// The number of characters to read. | |
/// </param> | |
/// <returns> | |
/// The total number of characters read into the buffer. This might be less than | |
/// the number of characters requested if that many characters are not currently | |
/// available, or it might be zero if the end of the stream is reached. | |
/// </returns> | |
/// <exception cref="System.ArgumentException"> | |
/// The buffer length minus index is less than count. -or-The number of decoded | |
/// characters to read is greater than count. This can happen if a Unicode decoder | |
/// returns fallback characters or a surrogate pair. | |
/// </exception> | |
/// <exception cref="System.ArgumentNullException"> | |
/// buffer is null. | |
/// </exception> | |
/// <exception cref="System.ArgumentOutOfRangeException"> | |
/// index or count is negative. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public int Read(char[] buffer, int index, int count) | |
{ | |
if (buffer == null) | |
throw new ArgumentNullException("buffer"); | |
if (index < 0) | |
throw new ArgumentOutOfRangeException("index", "A non-negative number is required."); | |
if (count < 0) | |
throw new ArgumentOutOfRangeException("count", "A non-negative number is required."); | |
if ((buffer.Length - index) < count) | |
throw new ArgumentException("Invalid index and count arguments."); | |
if (this.m_stream == null) | |
throw new IOException(); | |
char[] buf = this.ReadChars(count); | |
Array.Copy(buf, 0, buffer, index, buf.Length); | |
return buf.Length; | |
} | |
/// <summary> | |
/// Reads a Boolean value from the current stream and advances the current position | |
/// of the stream by one byte. | |
/// </summary> | |
/// <returns> | |
/// true if the byte is nonzero; otherwise, false. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public bool ReadBoolean() | |
{ | |
this.FillBuffer(1); | |
return (this.m_buffer[0] != 0); | |
} | |
/// <summary> | |
/// Reads the next byte from the current stream and advances the current position | |
/// of the stream by one byte. | |
/// </summary> | |
/// <returns> | |
/// The next byte read from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public byte ReadByte() | |
{ | |
if (this.m_stream == null) | |
throw new ObjectDisposedException("m_stream"); | |
int num = this.m_stream.ReadByte(); | |
if (num == -1) | |
throw new EndOfStreamException(); | |
return (byte)num; | |
} | |
/// <summary> | |
/// Reads the specified number of bytes from the current stream into a byte array | |
/// and advances the current position by that number of bytes. | |
/// </summary> | |
/// <param name="count"> | |
/// The number of bytes to read. | |
/// </param> | |
/// <returns> | |
/// A byte array containing data read from the underlying stream. This might | |
/// be less than the number of bytes requested if the end of the stream is reached. | |
/// </returns> | |
/// <exception cref="System.ArgumentException"> | |
/// The number of decoded characters to read is greater than count. This can | |
/// happen if a Unicode decoder returns fallback characters or a surrogate pair. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.ArgumentOutOfRangeException"> | |
/// count is negative. | |
/// </exception> | |
public byte[] ReadBytes(int count) | |
{ | |
if (count < 0) | |
throw new ArgumentOutOfRangeException("count", "A non-negative number is required."); | |
if (this.m_stream == null) | |
throw new ObjectDisposedException("m_stream"); | |
byte[] buffer = new byte[count]; | |
this.m_stream.Read(buffer, 0, count); | |
return buffer; | |
} | |
/// <summary> | |
/// Reads the next character from the current stream and advances the current | |
/// position of the stream in accordance with the Encoding used and the specific | |
/// character being read from the stream. | |
/// </summary> | |
/// <returns> | |
/// A character read from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ArgumentException"> | |
/// A surrogate character was read. | |
/// </exception> | |
public char ReadChar() | |
{ | |
int num = this.Read(); | |
if (num == -1) | |
throw new EndOfStreamException(); | |
return (char)num; | |
} | |
/// <summary> | |
/// Reads the specified number of characters from the current stream, returns | |
/// the data in a character array, and advances the current position in accordance | |
/// with the Encoding used and the specific character being read from the stream. | |
/// </summary> | |
/// <param name="count"> | |
/// The number of characters to read. | |
/// </param> | |
/// <returns> | |
/// A character array containing data read from the underlying stream. This might | |
/// be less than the number of characters requested if the end of the stream | |
/// is reached. | |
/// </returns> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ArgumentOutOfRangeException"> | |
/// count is negative. | |
/// </exception> | |
public char[] ReadChars(int count) | |
{ | |
if (count < 0) | |
throw new ArgumentOutOfRangeException("count", "A non-negative number is required."); | |
if (this.m_stream == null) | |
throw new ObjectDisposedException("m_stream"); | |
List<char> buffer = new List<char>(count); | |
for (int i = 0; i < count; ++i) | |
buffer.Add(this.ReadChar()); | |
return buffer.ToArray(); | |
} | |
/// <summary> | |
/// Reads a decimal value from the current stream and advances the current position | |
/// of the stream by sixteen bytes. | |
/// </summary> | |
/// <returns> | |
/// A decimal value read from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public decimal ReadDecimal() | |
{ | |
this.FillBuffer(16); | |
int lo = ((m_buffer[0] | (m_buffer[1] << 8)) | (m_buffer[2] << 16)) | (m_buffer[3] << 24); | |
int mid = ((m_buffer[4] | (m_buffer[5] << 8)) | (m_buffer[6] << 16)) | (m_buffer[7] << 24); | |
int hi = ((m_buffer[8] | (m_buffer[9] << 8)) | (m_buffer[10] << 16)) | (m_buffer[11] << 24); | |
return new decimal(new int[] { lo, mid, hi, | |
((m_buffer[12] | (m_buffer[13] << 8)) | (m_buffer[14] << 16)) | (m_buffer[15] << 24) }); | |
} | |
/// <summary> | |
/// Reads an 8-byte floating point value from the current stream and advances | |
/// the current position of the stream by eight bytes. | |
/// </summary> | |
/// <returns> | |
/// An 8-byte floating point value read from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public unsafe double ReadDouble() | |
{ | |
this.FillBuffer(8); | |
uint num = (uint)(m_buffer[0] | (m_buffer[1] << 8) | (m_buffer[2] << 16) | (m_buffer[3] << 24)); | |
uint num2 = (uint)(m_buffer[4] | (m_buffer[5] << 8) | (m_buffer[6] << 16) | (m_buffer[7] << 24)); | |
ulong num3 = (num2 << 0x20) | num; | |
return *(((double*)&num3)); | |
} | |
/// <summary> | |
/// Reads a 2-byte signed integer from the current stream and advances the current | |
/// position of the stream by two bytes. | |
/// </summary> | |
/// <returns> | |
/// A 2-byte signed integer read from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public short ReadInt16() | |
{ | |
this.FillBuffer(2); | |
return (short)(this.m_buffer[0] | (this.m_buffer[1] << 8)); | |
} | |
/// <summary> | |
/// Reads a 4-byte signed integer from the current stream and advances the current | |
/// position of the stream by four bytes. | |
/// </summary> | |
/// <returns> | |
/// A 4-byte signed integer read from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public int ReadInt32() | |
{ | |
this.FillBuffer(4); | |
return (m_buffer[0] | (m_buffer[1] << 8) | (m_buffer[2] << 16) | (m_buffer[3] << 24)); | |
} | |
/// <summary> | |
/// Reads an 8-byte signed integer from the current stream and advances the current | |
/// position of the stream by eight bytes. | |
/// </summary> | |
/// <returns> | |
/// An 8-byte signed integer read from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public long ReadInt64() | |
{ | |
this.FillBuffer(8); | |
uint num = (uint)(m_buffer[0] | (m_buffer[1] << 8) | (m_buffer[2] << 16) | (m_buffer[3] << 24)); | |
uint num2 = (uint)(m_buffer[4] | (m_buffer[5] << 8) | (m_buffer[6] << 16) | (m_buffer[7] << 24)); | |
return (long)((num2 << 0x20) | num); | |
} | |
/// <summary> | |
/// Reads a signed byte from this stream and advances the current position of | |
/// the stream by one byte. | |
/// </summary> | |
/// <returns> | |
/// A signed byte read from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public sbyte ReadSByte() | |
{ | |
this.FillBuffer(1); | |
return (sbyte)this.m_buffer[0]; | |
} | |
/// <summary> | |
/// Reads a 4-byte floating point value from the current stream and advances | |
/// the current position of the stream by four bytes. | |
/// </summary> | |
/// <returns> | |
/// A 4-byte floating point value read from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public unsafe float ReadSingle() | |
{ | |
this.FillBuffer(4); | |
uint num = (uint)(m_buffer[0] | (m_buffer[1] << 8) | (m_buffer[2] << 16) | (m_buffer[3] << 24)); | |
return *(((float*)&num)); | |
} | |
/// <summary> | |
/// Reads a null-terminated string from the current stream. | |
/// </summary> | |
/// <returns> | |
/// The string being read. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public string ReadCString() | |
{ | |
const int allocationCount = 100; | |
long left = RemainingLength; | |
if (left == 0) | |
throw new EndOfStreamException(); | |
var list = new List<byte>((int)Math.Min(left, allocationCount)); | |
byte b; | |
bool caretReturn = false; | |
bool terminatorFound = false; | |
do | |
{ | |
b = ReadByte(); | |
switch (b) | |
{ | |
case 0: | |
terminatorFound = true; | |
break; | |
case (byte)'\r': | |
caretReturn = true; | |
break; | |
case (byte)'\n': | |
if (list.Count == list.Capacity) | |
list.Capacity += allocationCount; | |
list.AddRange(m_newLineBytes); | |
caretReturn = false; | |
break; | |
default: | |
if (list.Count == list.Capacity) | |
list.Capacity += allocationCount; | |
if (caretReturn) | |
{ | |
list.AddRange(m_newLineBytes); | |
caretReturn = false; | |
} | |
list.Add(b); | |
break; | |
} | |
} while (!terminatorFound && !IsRead); | |
return m_encoding.GetString(list.ToArray()); | |
} | |
/// <summary> | |
/// Reads a 2-byte unsigned integer from the current stream using little-endian | |
/// encoding and advances the position of the stream by two bytes. | |
/// </summary> | |
/// <returns> | |
/// A 2-byte unsigned integer read from this stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public ushort ReadUInt16() | |
{ | |
this.FillBuffer(2); | |
return (ushort)(this.m_buffer[0] | (this.m_buffer[1] << 8)); | |
} | |
/// <summary> | |
/// Reads a 4-byte unsigned integer from the current stream and advances the | |
/// position of the stream by four bytes. | |
/// </summary> | |
/// <returns> | |
/// A 4-byte unsigned integer read from this stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
public uint ReadUInt32() | |
{ | |
this.FillBuffer(4); | |
return (uint)(m_buffer[0] | (m_buffer[1] << 8) | (m_buffer[2] << 16) | (m_buffer[3] << 24)); | |
} | |
/// <summary> | |
/// Reads an 8-byte unsigned integer from the current stream and advances the | |
/// position of the stream by eight bytes. | |
/// </summary> | |
/// <returns> | |
/// An 8-byte unsigned integer read from this stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
public ulong ReadUInt64() | |
{ | |
this.FillBuffer(8); | |
uint num = (uint)(m_buffer[0] | (m_buffer[1] << 8) | (m_buffer[2] << 16) | (m_buffer[3] << 24)); | |
uint num2 = (uint)(m_buffer[4] | (m_buffer[5] << 8) | (m_buffer[6] << 16) | (m_buffer[7] << 24)); | |
return ((num2 << 0x20) | num); | |
} | |
/// <summary> | |
/// Reads all bytes from the current stream, not advancing the current position. | |
/// </summary> | |
/// <returns> | |
/// The byte array that contains all bytes from the current stream. | |
/// </returns> | |
/// <exception cref="System.IO.EndOfStreamException"> | |
/// The end of the stream is reached. | |
/// </exception> | |
/// <exception cref="System.IO.IOException"> | |
/// An I/O error occurs. | |
/// </exception> | |
/// <exception cref="System.ObjectDisposedException"> | |
/// The stream is closed. | |
/// </exception> | |
public byte[] ReadAllBytes() | |
{ | |
long pos = this.m_stream.Position; | |
this.m_stream.Position = 0; | |
byte[] buffer = new byte[this.m_stream.Length]; | |
this.m_stream.Read(buffer, 0, (int)this.m_stream.Length); | |
this.m_stream.Position = pos; | |
return buffer; | |
} | |
/// <summary> | |
/// Reads a structure from the current stream, advancing | |
/// the current position by the number of bytes in the structure. | |
/// </summary> | |
/// <typeparam name="T"> | |
/// Type of the structure. | |
/// </typeparam> | |
/// <returns> | |
/// A structure read from the stream. | |
/// </returns> | |
public T ReadStruct<T>() where T : struct | |
{ | |
lock (StructHelper<T>.SyncRoot) | |
{ | |
m_stream.Read(StructHelper<T>.ManagedDataBank, 0, StructHelper<T>.Size); | |
Marshal.Copy(StructHelper<T>.ManagedDataBank, 0, StructHelper<T>.UnmanagedDataBank, StructHelper<T>.Size); | |
return (T)Marshal.PtrToStructure(StructHelper<T>.UnmanagedDataBank, typeof(T)); | |
} | |
} | |
#endregion | |
#region DoAt Methods | |
/// <summary> | |
/// Runs the given function temporary setting the current stream's position to the specified value. | |
/// </summary> | |
/// <typeparam name="TArg">Type of the function argument.</typeparam> | |
/// <typeparam name="TResult">The return type of the function.</typeparam> | |
/// <param name="position">The position to run the function at.</param> | |
/// <param name="func">The function to run at the given position.</param> | |
/// <param name="arg">The argument passed to the function.</param> | |
/// <returns>The result of the function.</returns> | |
public TResult DoAt<TArg, TResult>(long position, Func<TArg, TResult> func, TArg arg) | |
{ | |
long old_position = this.BaseStream.Position; | |
this.BaseStream.Position = position; | |
TResult result = func(arg); | |
this.BaseStream.Position = old_position; | |
return result; | |
} | |
/// <summary> | |
/// Runs the given function temporary setting the current stream's position to the specified value. | |
/// </summary> | |
/// <typeparam name="TResult">The return type of the function.</typeparam> | |
/// <param name="position">The position to run the function at.</param> | |
/// <param name="func">The function to run at the given position.</param> | |
/// <returns>The result of the function.</returns> | |
public TResult DoAt<TResult>(long position, Func<TResult> func) | |
{ | |
long old_position = this.BaseStream.Position; | |
this.BaseStream.Position = position; | |
TResult result = func(); | |
this.BaseStream.Position = old_position; | |
return result; | |
} | |
/// <summary> | |
/// Runs the given function temporary setting the current stream's position to the specified value. | |
/// </summary> | |
/// <typeparam name="TArg">Type of the function argument.</typeparam> | |
/// <param name="position">The position to run the function at.</param> | |
/// <param name="func">The function to run at the given position.</param> | |
/// <param name="arg">The argument passed to the function.</param> | |
public void DoAt<TArg>(long position, Action<TArg> func, TArg arg) | |
{ | |
long old_position = this.BaseStream.Position; | |
this.BaseStream.Position = position; | |
func(arg); | |
this.BaseStream.Position = old_position; | |
} | |
/// <summary> | |
/// Runs the given function temporary setting the current stream's position to the specified value. | |
/// </summary> | |
/// <param name="position">The position to run the function at.</param> | |
/// <param name="func">The function to run at the given position.</param> | |
public void DoAt(long position, Action func) | |
{ | |
long old_position = this.BaseStream.Position; | |
this.BaseStream.Position = position; | |
func(); | |
this.BaseStream.Position = old_position; | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment