Пример #1
0
        private static Stream GetStream(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            var position = stream.Position;

            var parse = RNCHeader.TryParse(stream, out var header);

            stream.Position = position; // restore position in case of not-RNC

            if (!parse)
            {
                return(stream);
            }

            var input  = new byte[stream.Length];
            var output = new byte[header.UncompressedSize];

            var read = stream.Read(input, 0, input.Length);

            if (read != input.Length)
            {
                throw new EndOfStreamException("Couldn't read entire stream.");
            }

            var p1 = Marshal.AllocHGlobal(input.Length);
            var p2 = Marshal.AllocHGlobal(output.Length);

            Marshal.Copy(input, 0, p1, input.Length);
            Marshal.Copy(output, 0, p2, output.Length);

            var status = Unpack(p1, p2);

            if (status == RNCStatus.Ok)
            {
                Marshal.Copy(p2, output, 0, output.Length);
            }

            Marshal.FreeHGlobal(p1);
            Marshal.FreeHGlobal(p2);

            if (status != RNCStatus.Ok)
            {
                throw new InvalidOperationException($"Error while unpacking: '{status}'.");
            }

            return(new MemoryStream(output));
        }
Пример #2
0
        /// <summary>
        ///     Tries to parse an instance from a stream.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="result"></param>
        /// <returns>
        ///     <c>true</c> if a header was found and compression scheme is supported.
        /// </returns>
        public static bool TryParse(Stream stream, out RNCHeader result)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            result = default(RNCHeader);

            var reader = new BinaryReader(stream);

            var signature = Encoding.ASCII.GetString(reader.ReadBytes(3));

            if (signature != "RNC")
            {
                return(false);
            }

            var compression = (RNCCompression)reader.ReadByte();

            if (compression != RNCCompression.Method1)
            {
                return(false);
            }

            var uncompressedSize = ReadUInt32BE(reader);
            var compressedSize   = ReadUInt32BE(reader);
            var uncompressedSum  = ReadUInt16BE(reader);
            var compressedSum    = ReadUInt16BE(reader);
            var leeway           = reader.ReadByte();
            var packChunks       = reader.ReadByte();

            result = new RNCHeader(
                signature, compression, uncompressedSize, compressedSize,
                uncompressedSum, compressedSum, leeway, packChunks
                );

            return(true);
        }