public static SinHeader Read(BinaryReader r) { var h = new SinHeader(); h.Init(r, r.ReadInt32BE()); return(h); }
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); } }