/// <summary> /// Gets the decompressed length of the compressed data and length. /// </summary> /// <param name="compressed">The compressed data.</param> /// <param name="compressedLength">The actual length of the compressed data.</param> /// <returns>The length of the compressed data.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="compressed"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="compressedLength"/> is less than zero. /// </exception> /// <exception cref="ZlibException"> /// A Zlib error occurred, or the resulting length was greater than <see cref="int.MaxValue"/>. /// </exception> public static int DecompressedLength(byte[] compressed, int compressedLength) { if (compressed == null) { throw new ArgumentNullException(nameof(compressed)); } if (compressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(compressedLength), compressedLength, 0, true); } int decompressedLength = 0; ZResult result = UncompressNative(new byte[0], ref decompressedLength, compressed, compressedLength); if (result != ZResult.OK && result != ZResult.BufferError) { throw new ZlibException(result, false, compressed, new byte[0]); } if (decompressedLength < 0) { throw new ZlibException($"Decompressed length of {nameof(compressedLength)} is greater " + $"than {nameof(Int32)}.{nameof(int.MaxValue)}!"); } return(decompressedLength); }
/// <summary> /// Gets the compressed length of the decompressed data and length. /// </summary> /// <param name="decompressed">The decompressed data.</param> /// <param name="decompressedLength">The actual length of the decompressed data.</param> /// <returns>The length of the compressed data.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="decompressed"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="decompressedLength"/> is less than zero. /// </exception> /// <exception cref="ZlibException"> /// A Zlib error occurred, or the resulting length was greater than <see cref="int.MaxValue"/>. /// </exception> public static int CompressedLength(byte[] decompressed, int decompressedLength) { if (decompressed == null) { throw new ArgumentNullException(nameof(decompressed)); } if (decompressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(decompressedLength), decompressedLength, 0, true); } int compressedLength = CompressedBounds(decompressedLength); byte[] compressed = new byte[compressedLength]; ZResult result = CompressNative(compressed, ref compressedLength, decompressed, decompressedLength); if (result != ZResult.OK) // && result != ZResult.BufferError) { throw new ZlibException(result, true, decompressed, compressed); } if (compressedLength < 0) { throw new ZlibException($"Compressed length of {nameof(decompressedLength)} is greater " + $"than {nameof(Int32)}.{nameof(int.MaxValue)}!"); } return(compressedLength); }
public BlowfishInputStream(Blowfish blowfish, Stream stream, int length, int bufferSize, bool leaveOpen) { Blowfish = blowfish ?? throw new ArgumentNullException(nameof(blowfish)); this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); if (length < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(length), length, 0, true); } if (bufferSize < 8) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(bufferSize), bufferSize, 8, true); } if (bufferSize % 8 != 0) { throw new ArgumentException($"{nameof(bufferSize)} must be a multiple of 8!"); } if (!stream.CanRead) { throw new ArgumentException($"{nameof(BlowfishInputStream)} only supports streams that can read!"); } decryptedBuffer = new byte[bufferSize]; decryptedLength = 0; decryptedPosition = 0; virtualPosition = 0; virtualLength = length; cutoffLength = length - length % 8; zeroPosition = stream.Position; this.leaveOpen = leaveOpen; }
/// <summary> /// Decompresses the compressed data and length to the output decompression buffer and length. /// </summary> /// <param name="decompressed">The decompression buffer.</param> /// <param name="decompressedLength">The actual length of the decompression buffer.</param> /// <param name="compressed">The compressed data.</param> /// <param name="compressedLength">The actual length of the compressed data.</param> /// /// <exception cref="ArgumentNullException"> /// <paramref name="decompressed"/> or <paramref name="compressed"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="decompressedLength"/> or <paramref name="compressedLength"/> is less than zero. /// </exception> /// <exception cref="ZlibException"> /// A Zlib error occurred, or the resulting length was greater than <see cref="int.MaxValue"/>. /// </exception> public static void Decompress(byte[] decompressed, ref int decompressedLength, byte[] compressed, int compressedLength) { if (decompressed == null) { throw new ArgumentNullException(nameof(decompressed)); } if (compressed == null) { throw new ArgumentNullException(nameof(compressed)); } if (decompressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(decompressedLength), decompressedLength, 0, true); } if (compressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(compressedLength), compressedLength, 0, true); } ZResult result = UncompressNative(decompressed, ref decompressedLength, compressed, compressedLength); if (result != ZResult.OK) { throw new ZlibException(result, false, compressed, decompressed); } }
/// <summary> /// Decrypts the buffer with the specified length and starting index. /// </summary> /// <param name="buffer">The buffer to decrypt.</param> /// <param name="index">The index to start decrypting the buffer at.</param> /// <param name="bufferLength">The buffer length which must be a multiple of 8.</param> /// /// <exception cref="ArgumentNullException"> /// <paramref name="buffer"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="index"/> or <paramref name="bufferLength"/> is less than zero.-or- /// <paramref name="index"/> + <paramref name="bufferLength"/> is greater than the length of /// <paramref name="buffer"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="bufferLength"/> is not a multiple of 8. /// </exception> public void Decrypt(byte[] buffer, int index, int bufferLength) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (index < 0) throw ArgumentOutOfRangeUtils.OutsideMin(nameof(index), index, 0, true); }
/// <summary> /// Constructs the animation command attribute with the specified command, parameter length, and other /// settings. /// </summary> /// <param name="command">The name of the command. Null if there is no command name.</param> /// <param name="count">The maximum number of parameters in the command.</param> /// <param name="isRange">The command's last parameter is optional if it is the same as the previous.</param> /// <param name="isJump">The command is a jump, making the last parameter a potential label.</param> /// /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="count"/> is less than zero. /// </exception> public AnimationCommandAttribute(string command, int count, bool isRange = false, bool isJump = false) : base(command) { if (count < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(count), count, 0, true); } Count = count; IsRange = isRange; IsJump = isJump; }
private static void ThrowIfInvalidDimensions(int width, int height) { if (width < 0) { throw new HgxException(ArgumentOutOfRangeUtils.OutsideMin("width", width, 0, false)); } if (height < 0) { throw new HgxException(ArgumentOutOfRangeUtils.OutsideMin("height", height, 0, false)); } }
/// <summary> /// Reads the compressed data from the binary reader and returns the decompressed data. /// </summary> /// <param name="reader">The <see cref="BinaryReader"/> to read with.</param> /// <param name="compressedLength">The length of the compressed data to read.</param> /// /// <exception cref="ArgumentNullException"> /// <paramref name="reader"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="compressedLength"/> is less than zero. /// </exception> /// <exception cref="ZlibException"> /// A Zlib error occurred, or the resulting length was greater than <see cref="int.MaxValue"/>. /// </exception> public static byte[] Decompress(BinaryReader reader, int compressedLength) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (compressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(compressedLength), compressedLength, 0, true); } return(Decompress(reader.ReadBytes(compressedLength))); }
/// <summary> /// Reads a string from the current stream. The string is of the specified fixed length. /// </summary> /// <param name="reader">The <see cref="BinaryReader"/> to read with.</param> /// <param name="length">The length of the string to read.</param> /// <returns>The string that was read from the stream.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="reader"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="length"/> is negative. /// </exception> /// <exception cref="ArgumentException"> /// The number of decoded characters to read is greater than <paramref name="length"/>. This can happen if a /// Unicode decoder returns fallback characters or a surrogate pair. /// </exception> /// <exception cref="ObjectDisposedException"> /// The stream is closed. /// </exception> /// <exception cref="IOException"> /// An I/O error occured. /// </exception> public static string ReadFixedString(this BinaryReader reader, int length) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (length < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(length), length, 0, true); } return(new string(reader.ReadChars(length))); }
/// <summary> /// Encrypts the buffer with the specified length. /// </summary> /// <param name="buffer">The buffer to encrypt.</param> /// <param name="bufferLength">The buffer length which must be a multiple of 8.</param> /// /// <exception cref="ArgumentNullException"> /// <paramref name="buffer"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="bufferLength"/> is less than zero or greater than the length of <paramref name="buffer"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="bufferLength"/> is not a multiple of 8. /// </exception> public void Encrypt(byte[] buffer, int bufferLength) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (bufferLength < 0 || bufferLength > buffer.Length) { throw ArgumentOutOfRangeUtils.OutsideRange(nameof(bufferLength), bufferLength, 0, $"{nameof(buffer)}.{nameof(buffer.Length)}", buffer.Length, true, true); } fixed(byte *pBuffer = buffer) Encrypt(pBuffer, bufferLength); }
/// <summary> /// Reads the compressed data from the input stream and returns the decompressed data. /// </summary> /// <param name="stream">The input <see cref="Stream"/> to read with.</param> /// <param name="compressedLength">The length of the compressed data to read.</param> /// /// <exception cref="ArgumentNullException"> /// <paramref name="stream"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="compressedLength"/> is less than zero. /// </exception> /// <exception cref="ZlibException"> /// A Zlib error occurred, or the resulting length was greater than <see cref="int.MaxValue"/>. /// </exception> public static byte[] Decompress(Stream stream, int compressedLength) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (compressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(compressedLength), compressedLength, 0, true); } byte[] compressed = new byte[compressedLength]; stream.Read(compressed, 0, compressedLength); return(Decompress(compressed)); }
/// <summary> /// Reads an array of 1-byte signed integers from the current stream and advances the current position of the /// stream by <paramref name="count"/> bytes. /// </summary> /// <param name="reader">The <see cref="BinaryReader"/> to read with.</param> /// <param name="count">The number of values to read.</param> /// <returns>An array of 1-byte signed integers read from the current stream.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="reader"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="count"/> is negative. /// </exception> /// <exception cref="EndOfStreamException"> /// The end of the stream is reached. /// </exception> /// <exception cref="IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="NotSupportedException"> /// The stream does not support reading. /// </exception> /// <exception cref="ObjectDisposedException"> /// The stream is closed. /// </exception> public static sbyte[] ReadSBytes(this BinaryReader reader, int count) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (count < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(count), count, 0, true); } sbyte[] values = new sbyte[count]; byte[] buffer = reader.ReadBytes(count); Buffer.BlockCopy(buffer, 0, values, 0, count); return(values); }
/// <summary> /// Reads an array of decimal-floating points from the current stream and advances the current position of the /// stream by sixteen bytes times <paramref name="count"/>. /// </summary> /// <param name="reader">The <see cref="BinaryReader"/> to read with.</param> /// <param name="count">The number of values to read.</param> /// <returns>An array of decimal-floating points read from the current stream.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="reader"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="count"/> is negative. /// </exception> /// <exception cref="EndOfStreamException"> /// The end of the stream is reached. /// </exception> /// <exception cref="IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="NotSupportedException"> /// The stream does not support reading. /// </exception> /// <exception cref="ObjectDisposedException"> /// The stream is closed. /// </exception> /// <exception cref="OverflowException"> /// The number of bytes to read is greater than <see cref="int.MaxValue"/>. /// </exception> public static decimal[] ReadDecimals(this BinaryReader reader, int count) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (count < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(count), count, 0, true); } int bufferSize = count * sizeof(decimal); decimal[] values = new decimal[count]; byte[] buffer = reader.ReadBytes(bufferSize); Buffer.BlockCopy(buffer, 0, values, 0, bufferSize); return(values); }
/// <summary> /// Reads the compressed data from the binary reader and returns the decompressed data. /// </summary> /// <param name="reader">The <see cref="BinaryReader"/> to read with.</param> /// <param name="compressedLength">The length of the compressed data to read.</param> /// <param name="decompressedLength">The length of the decompression data.</param> /// /// <exception cref="ArgumentNullException"> /// <paramref name="reader"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="compressedLength"/> or <paramref name="decompressedLength"/> is less than zero. /// </exception> /// <exception cref="ZlibException"> /// A Zlib error occurred. /// </exception> public static byte[] Decompress(BinaryReader reader, int compressedLength, int decompressedLength) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (compressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(compressedLength), compressedLength, 0, true); } if (decompressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(decompressedLength), decompressedLength, 0, true); } byte[] compressed = reader.ReadBytes(compressedLength); byte[] decompressed = new byte[decompressedLength]; Decompress(decompressed, ref decompressedLength, compressed, compressedLength); return(decompressed); }
/// <summary> /// Reads a string from the current stream. The string is of the specified fixed length and ends with the /// <paramref name="padding"/> character. /// </summary> /// <param name="reader">The <see cref="BinaryReader"/> to read with.</param> /// <param name="length">The length of the string to read.</param> /// <param name="padding">The character to trim from the end of the string.</param> /// <returns>The string that was read from the stream.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="reader"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="length"/> is negative. /// </exception> /// <exception cref="ArgumentException"> /// The number of decoded characters to read is greater than <paramref name="length"/>. This can happen if a /// Unicode decoder returns fallback characters or a surrogate pair. /// </exception> /// <exception cref="ObjectDisposedException"> /// The stream is closed. /// </exception> /// <exception cref="IOException"> /// An I/O error occured. /// </exception> public static string ReadFixedString(this BinaryReader reader, int length, char padding) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (length < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(length), length, 0, true); } string fullString = new string(reader.ReadChars(length)); int paddingIndex = fullString.IndexOf(padding); if (paddingIndex != -1) { return(fullString.Substring(paddingIndex)); } return(fullString); }
/// <summary> /// Advances the position in the stream to conform to a padding amount with the supplied additional offset. /// </summary> /// <param name="stream">The stream to advance.</param> /// <param name="padding">The padding to conform to.</param> /// <param name="offset">The additional offset before the padding is calculated.</param> /// <returns>The amount of bytes skipped.</returns> /// /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="padding"/> is less than or equal to zero.-or- <paramref name="offset"/> is less than zero /// or greater than or equal to <paramref name="padding"/>. /// </exception> /// <exception cref="IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="NotSupportedException"> /// The stream does not support seeking or reading. /// </exception> /// <exception cref="ObjectDisposedException"> /// The stream is closed. /// </exception> public static int SkipPadding(this Stream stream, int padding, int offset) { if (padding <= 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(padding), padding, 1, false); } if (offset < 0 || offset >= padding) { throw ArgumentOutOfRangeUtils.OutsideRange(nameof(offset), padding, 0, nameof(padding), padding, true, false); } int count = (int)((stream.Position + (padding - offset)) % padding); if (count != 0) { count = (padding - count); stream.Skip(count); } return(0); }
/// <summary> /// Reads an array of unmanaged structs from the stream. /// </summary> /// <param name="reader">The <see cref="BinaryReader"/> to read with.</param> /// <param name="type">The unmanaged type.</param> /// <param name="length">The length of the array to read.</param> /// <returns>The array of unmanaged objects as a managed objects.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="reader"/> or <paramref name="type"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="length"/> is negative. /// </exception> /// <exception cref="IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ObjectDisposedException"> /// The stream is closed. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="type"/> is a reference type that is not a formatted class. /// </exception> public static Array ReadUnmanagedArray(this BinaryReader reader, Type type, int length) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (type == null) { throw new ArgumentNullException(nameof(type)); } if (length < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(length), length, 0, true); } Array result = Array.CreateInstance(type, length); if (length == 0) { return(result); } int size = Marshal.SizeOf(type); byte[] buffer = reader.ReadBytes(size * length); GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); try { IntPtr ptr = handle.AddrOfPinnedObject(); for (int i = 0; i < length; i++) { result.SetValue(Marshal.PtrToStructure(ptr, type), i); ptr = new IntPtr(ptr.ToInt64() + size); } return(result); } finally { handle.Free(); } }
/// <summary> /// Compresses the decompressed data and length and writes the compressed data to the binary writer. /// </summary> /// <param name="writer">The <see cref="BinaryWriter"/> to write with.</param> /// <param name="decompressed">The decompressed data to compress.</param> /// <param name="decompressedLength">The length of the decompressed data to read.</param> /// <param name="compressedLength">The length of the compressed data.</param> /// <returns>The actual compressed length of the decompressed data.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="writer"/> or <paramref name="decompressed"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="decompressedLength"/> is less than zero. /// </exception> /// <exception cref="ZlibException"> /// A Zlib error occurred. /// </exception> public static int Compress(BinaryWriter writer, byte[] decompressed, int decompressedLength) { if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (decompressed == null) { throw new ArgumentNullException(nameof(decompressed)); } if (decompressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(decompressedLength), decompressedLength, 0, true); } int compressedLength = CompressedBounds(decompressedLength); byte[] compressed = new byte[compressedLength]; Compress(compressed, ref compressedLength, decompressed, decompressedLength); writer.Write(compressed, 0, compressedLength); return(compressed.Length); }
/// <summary> /// Compresses the decompressed data and length and writes the compressed data to the output stream. /// </summary> /// <param name="stream">The output <see cref="Stream"/> to read with.</param> /// <param name="decompressed">The decompressed data to compress.</param> /// <param name="decompressedLength">The length of the decompressed data to read.</param> /// <param name="compressedLength">The length of the compressed data.</param> /// <returns>The actual compressed length of the decompressed data.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="reader"/> or <paramref name="decompressed"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="decompressedLength"/> is less than zero. /// </exception> /// <exception cref="ZlibException"> /// A Zlib error occurred. /// </exception> public static int Compress(Stream stream, byte[] decompressed, int decompressedLength) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (decompressed == null) { throw new ArgumentNullException(nameof(decompressed)); } if (decompressedLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(decompressedLength), decompressedLength, 0, true); } int compressedLength = CompressedBounds(decompressedLength); byte[] compressed = new byte[compressedLength]; Compress(compressed, ref compressedLength, decompressed, decompressedLength); stream.Write(compressed, 0, compressedLength); return(decompressedLength); }
public BlowfishOutputStream(Blowfish blowfish, Stream stream, int bufferSize, bool leaveOpen) { Blowfish = blowfish ?? throw new ArgumentNullException(nameof(blowfish)); this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); if (bufferSize < 8) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(bufferSize), bufferSize, 8, true); } if (bufferSize % 8 != 0) { throw new ArgumentException($"{nameof(bufferSize)} must be a multiple of 8!"); } if (!stream.CanWrite) { throw new ArgumentException($"{nameof(BlowfishOutputStream)} only supports streams that can write!"); } decryptedBuffer = new byte[bufferSize]; virtualPosition = 0; this.leaveOpen = leaveOpen; }
/// <summary> /// Encrypts the buffer with the specified length. /// </summary> /// <param name="buffer">The buffer to encrypt.</param> /// <param name="index">The index to start encrypting the buffer at.</param> /// <param name="bufferLength">The buffer length which must be a multiple of 8.</param> /// /// <exception cref="ArgumentNullException"> /// <paramref name="buffer"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="index"/> or <paramref name="bufferLength"/> is less than zero.-or- /// <paramref name="index"/> + <paramref name="bufferLength"/> is greater than the length of /// <paramref name="buffer"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="bufferLength"/> is not a multiple of 8. /// </exception> public void Encrypt(byte[] buffer, int index, int bufferLength) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (index < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(index), index, 0, true); } if (bufferLength < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(bufferLength), bufferLength, 0, true); } if (index + bufferLength > buffer.Length) { throw ArgumentOutOfRangeUtils.OutsideRange($"{nameof(index)} + {nameof(bufferLength)}", index + bufferLength, 0, $"{nameof(buffer)}.{nameof(Array.Length)}", buffer.Length, true, false); } fixed(byte *pBuffer = buffer) Encrypt(pBuffer + index, bufferLength); }
/// <summary> /// Skips <paramref name="count"/> number of bytes in the stream. /// </summary> /// <param name="stream">The stream to skip through.</param> /// <param name="count">The number of bytes to skip.</param> /// <param name="bufferSize"> /// The size of the buffer to read bytes into at a time when <see cref="Stream.CanSeek"/> is false. /// </param> /// <returns>The number of bytes, actually skipped.</returns> /// /// <remarks> /// This method utilizes <see cref="Stream.Seek(long, SeekOrigin)"/> if it's <see cref="Stream.CanSeek"/> is /// true. Otherwise it reads bytes to a buffer of size <paramref name="bufferSize"/> until /// <paramref name="count"/> is reached. /// </remarks> /// /// <exception cref="ArgumentNullException"> /// <paramref name="stream"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="count"/> is less than zero or <paramref name="bufferSize"/> is less than 1. /// </exception> /// <exception cref="IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="NotSupportedException"> /// The stream does not support seeking or reading. /// </exception> /// <exception cref="ObjectDisposedException"> /// The stream is closed. /// </exception> public static int Skip(this Stream stream, int count, int bufferSize) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (count < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(count), count, 0, true); } if (bufferSize < 1) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(bufferSize), bufferSize, 1, true); } if (stream.CanSeek) { // Use a faster method of skipping if possible long oldPosition = stream.Position; return((int)(stream.Seek(count, SeekOrigin.Current) - oldPosition)); } else { bufferSize = Math.Min(count, bufferSize); byte[] buffer = new byte[bufferSize]; int totalRead = 0; while (totalRead < count) { int read = stream.Read(buffer, 0, Math.Min(count - totalRead, bufferSize)); if (read == 0) { return(totalRead); } totalRead += read; } return(totalRead); } }
/// <summary> /// Reads an array of unmanaged structs from the stream. /// </summary> /// <typeparam name="T">The unmanaged type.</typeparam> /// <param name="reader">The <see cref="BinaryReader"/> to read with.</param> /// <param name="length">The length of the array.</param> /// <returns>The array of unmanaged objects as a managed objects.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="reader"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="length"/> is negative. /// </exception> /// <exception cref="IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ObjectDisposedException"> /// The stream is closed. /// </exception> /// <exception cref="ArgumentException"> /// <typeparamref name="T"/> is a reference type that is not a formatted class. /// </exception> public static T[] ReadUnmanagedArray <T>(this BinaryReader reader, int length) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (length < 0) { throw ArgumentOutOfRangeUtils.OutsideMin(nameof(length), length, 0, true); } T[] result = new T[length]; if (length == 0) { return(result); } int size = Marshal.SizeOf <T>(); byte[] buffer = reader.ReadBytes(size * length); GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); try { IntPtr ptr = handle.AddrOfPinnedObject(); for (int i = 0; i < length; i++) { result[i] = Marshal.PtrToStructure <T>(ptr); ptr = new IntPtr(ptr.ToInt64() + size); } return(result); } finally { handle.Free(); } }
private static byte[] ProcessImage(BinaryReader reader, int width, int height, int depthBits, HGXIMGDATA data) { if (data.CompressedDataLength <= 0) { throw new HgxException(ArgumentOutOfRangeUtils.OutsideMin(nameof(data.CompressedDataLength), data.CompressedDataLength, 0, false)); } int depthBytes = (depthBits + 7) / 8; int stride = (width * depthBytes + 3) & ~3; byte[] dataBuffer = Zlib.Decompress(reader, data.CompressedDataLength, data.DecompressedDataLength); byte[] cmdBuffer = Zlib.Decompress(reader, data.CompressedCmdLength, data.DecompressedCmdLength); if (depthBits != 24 && depthBits != 32) { throw new HgxException($"Unsupported depthBits! must be either 24 or 32, got {depthBits}."); } if (width <= 0) { throw new HgxException(ArgumentOutOfRangeUtils.OutsideMin("width", width, 0, false)); } if (height <= 0) { throw new HgxException(ArgumentOutOfRangeUtils.OutsideMin("height", height, 0, false)); } if (stride * height > Asmodean.MaxRgbaLength) { throw new HgxException("Image dimensions are too large!"); } //ThrowIfUnsupportedDepthBytes(depthBits); //ThrowIfInvalidDimensions(width, height); //ThrowIfDimensionsTooLarge(height, stride); byte[] rgbaBuffer; if (CatDebug.SpeedTestHgx) { CatDebug.HgxWatch.Start(); } #if NATIVE_ASMODEAN if (CatDebug.NativeHgx) { // Minimum unrle buffer size is 1024 bytes rgbaBuffer = new byte[Math.Max(stride * height, 1024)]; // Perform heavy processing that's faster in native code ReturnCode result = Asmodean.ProcessImageNative( dataBuffer, dataBuffer.Length, cmdBuffer, cmdBuffer.Length, rgbaBuffer, rgbaBuffer.Length, width, height, depthBytes, stride); switch (result) { case ReturnCode.Success: break; case ReturnCode.UnrleDataIsCorrupt: throw new HgxException("dataBuffer, cmdBuffer, or unrleBuffer ran out of data!"); case ReturnCode.DataBufferTooSmall: throw new HgxException("dataBuffer is too small!"); case ReturnCode.CmdBufferTooSmall: throw new HgxException("cmdBuffer is too small!"); case ReturnCode.RgbaBufferTooSmall: throw new HgxException("rgbaBuffer is too small!"); case ReturnCode.UnrleBufferTooSmall: throw new HgxException("unrleBuffer is too small!"); case ReturnCode.DimensionsTooLarge: throw new HgxException("Image dimensions are too large!"); case ReturnCode.InvalidDimensions: if (width <= 0) { throw new HgxException(ArgumentOutOfRangeUtils.OutsideMin("width", width, 0, false)); } else { throw new HgxException(ArgumentOutOfRangeUtils.OutsideMin("height", height, 0, false)); } case ReturnCode.InvalidDepthBytes: throw new HgxException($"Unsupported depthBits! must be either 24 or 32, got {depthBits}."); case ReturnCode.DataBufferIsNull: throw new ArgumentNullException("dataBuffer"); case ReturnCode.CmdBufferIsNull: throw new ArgumentNullException("cmdBuffer"); case ReturnCode.RgbaBufferIsNull: throw new ArgumentNullException("rgbaBuffer"); case ReturnCode.AllocationFailed: throw new HgxException("A memory allocation while processing the HG-X image failed!"); default: throw new HgxException($"Unexpected return code {result}!"); } } else #endif { rgbaBuffer = ProcessImageManaged( dataBuffer, cmdBuffer, width, height, depthBytes, stride); } if (CatDebug.SpeedTestHgx) { CatDebug.HgxWatch.Stop(); } return(rgbaBuffer); }