Пример #1
0
            public static SinHeader Read(BinaryReader r)
            {
                var h = new SinHeader();

                h.Init(r, r.ReadInt32BE());
                return(h);
            }
Пример #2
0
        public static void CopyTo(BinaryReader reader, Stream outStream)
        {
            // This implementation uses a BinaryReader without any Seek operation
            // so it can be used with an archive stream

            var header     = SinHeader.Read(reader);
            var dataHeader = MmcfBlock.Read(reader);

            var orderedBlocks = dataHeader.DataBlocks.OrderBy(b => b.DataOffset).ToList();

            var dummy = reader.ReadInt64BE(); // ??
            var pos   = 0L;

            var firstOffset = orderedBlocks.FirstOrDefault()?.DataOffset ?? 0L;

            if (firstOffset > pos)
            {
                reader.ReadBytes((int)firstOffset);  // ??
                pos = firstOffset;
            }

            var totalSize = orderedBlocks.Max(b => b.FileOffset + b.FileLen);

            foreach (var block in orderedBlocks)
            {
                if (pos != block.DataOffset)
                {
                    throw new Exception("Unexpected");
                }

                var data = reader.ReadBytes((int)block.DataLen);
                pos += block.DataLen;

                if (block is AddrBlock)
                {
                    // fall through
                }
                else if (block is LZ4Block lz4Block)
                {
                    var uncompData = new byte[lz4Block.UncompDataLen];
                    LZ4Codec.Decode(data, uncompData);
                    data = uncompData;
                }
                else
                {
                    throw new NotImplementedException();
                }

                FileInfoBase.ReportProgress(outStream.Length, totalSize);

                outStream.Seek(block.FileOffset, SeekOrigin.Begin);
                outStream.Write(data, 0, data.Length);
            }
        }