예제 #1
0
        /// <summary>
        /// Read the header from a stream. This method advances the stream by
        /// the length of the header but doesn't close the stream.
        /// </summary>
        /// <param name="stream">The stream to read the header from</param>
        /// <returns>Sii file header information</returns>
        public static SiiHeader FromStream(Stream stream)
        {
            SiiHeader header = new SiiHeader();

            using (BinaryReader br = new BinaryReader(stream, Encoding.UTF8, true)) {
                header.Signature            = br.ReadUInt32();
                header.Hmac                 = br.ReadBytes(32);
                header.InitializationVector = br.ReadBytes(16);
                header.DecompressedUnitSize = br.ReadUInt32();
            }

            return(header);
        }
예제 #2
0
        /// <summary>
        /// Read a Sii binary file.
        /// </summary>
        /// <param name="stream">Stream containing the sii binary data</param>
        /// <returns>The root Sii object representing the unit</returns>
        public async Task <Object> ReadFromBinary(Stream stream)
        {
            SiiHeader header = SiiHeader.FromStream(stream);

            using (MemoryStream plainStream = new MemoryStream()) {
                if (header.Signature != SII_CRYPTO_UNIT_SIGNATURE) // Not a valid encrypted unit
                {
                    throw new InvalidSiiFileException();
                }

                await SiiEncryption.Decrypt(stream, plainStream, header.InitializationVector);

                plainStream.Position = 0;
                byte[] plainSig   = new byte[SII_TEXT_UNIT_SIGNATURE.Length];
                byte[] txtSig     = Encoding.UTF8.GetBytes(SII_TEXT_UNIT_SIGNATURE);
                bool   compressed = false;

                plainStream.Read(plainSig, 0, plainSig.Length);
                plainStream.Position = 0;

                for (int i = 0; i < txtSig.Length; i++)
                {
                    if (txtSig[i] != plainSig[i])
                    {
                        compressed = true;
                        break;
                    }
                }

                Stream decompressedStream;

                if (compressed)
                {
                    decompressedStream = new MemoryStream();

                    await SiiCompression.Decompress(plainStream, decompressedStream);

                    decompressedStream.Position = 0;
                }
                else
                {
                    decompressedStream = plainStream;
                }


                return(await ReadFromText(decompressedStream));
            }
        }