/// <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);
        }
Ejemplo n.º 3
0
 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)));
 }
Ejemplo n.º 9
0
        /// <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);
 }
Ejemplo n.º 15
0
        /// <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);
        }
Ejemplo n.º 16
0
        /// <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);
 }
Ejemplo n.º 22
0
        /// <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);
        }