public void Deserialize(Stream input) { var magic = input.ReadValueU32(Endian.Little); if (magic != 0x53464152 && // SFAR magic.Swap() != 0x53464152) { throw new FormatException(); } var endian = magic == 0x53464152 ? Endian.Little : Endian.Big; var version = input.ReadValueU32(endian); if (version != 0x00010000) { throw new FormatException(); } var dataOffset = input.ReadValueU32(endian); var fileTableOffset = input.ReadValueU32(endian); var fileTableCount = input.ReadValueU32(endian); var blockSizeTableOffset = input.ReadValueU32(endian); this.MaximumBlockSize = input.ReadValueU32(endian); this.CompressionScheme = input .ReadValueEnum<SFXArchive.CompressionScheme>(endian); if (fileTableOffset != 0x20) { throw new FormatException(); } if (this.MaximumBlockSize != 0x010000) { throw new FormatException(); } /* if (this.CompressionScheme != SFXArchive.CompressionScheme.None && this.CompressionScheme != SFXArchive.CompressionScheme.LZMA && this.CompressionScheme != SFXArchive.CompressionScheme.LZX) { throw new FormatException(); } */ input.Seek(blockSizeTableOffset, SeekOrigin.Begin); var blockSizeTableSize = dataOffset - fileTableOffset; var blockSizeTableCount = blockSizeTableSize / 2; this.BlockSizes.Clear(); for (uint i = 0; i < blockSizeTableCount; i++) { this.BlockSizes.Add(input.ReadValueU16(endian)); } input.Seek(fileTableOffset, SeekOrigin.Begin); for (uint i = 0; i < fileTableCount; i++) { // ReSharper disable UseObjectOrCollectionInitializer var entry = new SFXArchive.Entry(); // ReSharper restore UseObjectOrCollectionInitializer entry.NameHash = input.ReadFileNameHash(); entry.BlockSizeIndex = input.ReadValueS32(endian); entry.UncompressedSize = input.ReadValueU32(endian); entry.UncompressedSize |= ((long)input.ReadValueU8()) << 32; entry.Offset = input.ReadValueU32(endian); entry.Offset |= ((long)input.ReadValueU8()) << 32; this.Entries.Add(entry); } }
public void Deserialize(Stream input) { var magic = input.ReadValueU32(Endian.Little); if (magic != 0x53464152 && // SFAR magic.Swap() != 0x53464152) { throw new FormatException(); } var endian = magic == 0x53464152 ? Endian.Little : Endian.Big; var version = input.ReadValueU32(endian); if (version != 0x00010000) { throw new FormatException(); } var dataOffset = input.ReadValueU32(endian); bool firstDataOffset = true; uint minDataOffset = dataOffset; //Console.WriteLine("Data Offset: {0:X8}",dataOffset); var fileTableOffset = input.ReadValueU32(endian); //Console.WriteLine("File Table Offset: {0:X8}",fileTableOffset); var fileTableCount = input.ReadValueU32(endian); //Console.WriteLine("File Table Count: {0:X8}",fileTableCount); var blockSizeTableOffset = input.ReadValueU32(endian); //Console.WriteLine("Block Size Table Offset: {0:X8}",blockSizeTableOffset); this.MaximumBlockSize = input.ReadValueU32(endian); this.CompressionScheme = input .ReadValueEnum <SFXArchive.CompressionScheme>(endian); if (fileTableOffset != 0x20) { throw new FormatException(); } if (this.MaximumBlockSize != 0x010000) { throw new FormatException(); } /* * if (this.CompressionScheme != SFXArchive.CompressionScheme.None && * this.CompressionScheme != SFXArchive.CompressionScheme.LZMA && * this.CompressionScheme != SFXArchive.CompressionScheme.LZX) * { * throw new FormatException(); * } */ input.Seek(fileTableOffset, SeekOrigin.Begin); for (uint i = 0; i < fileTableCount; i++) { // ReSharper disable UseObjectOrCollectionInitializer var entry = new SFXArchive.Entry(); entry.entryOffset = input.Position; // ReSharper restore UseObjectOrCollectionInitializer entry.nameHash = input.ReadFileNameHash(); //Console.WriteLine("FileNameHash: {0}",entry.NameHash.ToString()); entry.blockSizeIndex = input.ReadValueS32(endian); //Console.WriteLine("Begin position: {0:X8}",input.Position); entry.uncompressedSize = input.ReadValueU32(endian); entry.uncompressedSize |= ((long)input.ReadValueU8()) << 32; //Console.WriteLine(" End position: {0:X8}",input.Position); entry.dataOffset = input.ReadValueU32(endian); entry.dataOffset |= ((long)input.ReadValueU8()) << 32; if (firstDataOffset) { minDataOffset = (uint)entry.dataOffset; firstDataOffset = false; } else { if (minDataOffset > entry.dataOffset) { minDataOffset = (uint)entry.dataOffset; } } //if(entry.NameHash.Equals (fileNameListNameHash))Console.WriteLine("Offset: {0:X10}, UncSize {1:X10}",entry.Offset,entry.UncompressedSize); this.Entries.Add(entry); } if (minDataOffset > dataOffset) { dataOffset = minDataOffset; } input.Seek(blockSizeTableOffset, SeekOrigin.Begin); var blockSizeTableSize = dataOffset - blockSizeTableOffset; var blockSizeTableCount = blockSizeTableSize / 2; //ushort aux; //Console.WriteLine("dataOffset: {0:X8}\nfileTableOffset: {1:X8}\nBlockSizeTableSize: {2:X8}\nblockSizeTableOffset: {3:X8}", dataOffset,fileTableOffset,blockSizeTableSize,blockSizeTableOffset); this.BlockSizes.Clear(); //Console.WriteLine("initial position: {0:X8}",input.Position); //Console.WriteLine("blockSizeTableCount: {0}",blockSizeTableCount); for (uint i = 0; i < blockSizeTableCount; i++) { this.BlockSizes.Add(input.ReadValueU16(endian)); } //Console.WriteLine("final position: {0:X8}",input.Position); //Console.WriteLine("number of repetitions: {0}",blockSizeTableCount); //var fileNameListNameHash = new FileNameHash( // new byte[] { 0xB5, 0x50, 0x19, 0xCB, 0xF9, 0xD3, 0xDA, 0x65, 0xD5, 0x5B, 0x32, 0x1C, 0x00, 0x19, 0x69, 0x7C, }); }
private void getStructure(Stream input) { var magic = input.ReadValueU32(Endian.Little); if (magic != sfarHeader && // SFAR magic.Swap() != sfarHeader) { throw new FormatException("Not a valid sfar file."); } var endian = magic == sfarHeader ? Endian.Little : Endian.Big; var version = input.ReadValueU32(endian); if (version != 0x00010000) { throw new FormatException("Not supported version."); } dataOffset = input.ReadValueU32(endian); uint minDataOffset = dataOffset; entryOffset = input.ReadValueU32(endian); var fileTableCount = numOfFiles = input.ReadValueU32(endian); blockTableOffset = input.ReadValueU32(endian); MaximumBlockSize = input.ReadValueU32(endian); this.CompressionScheme = input.ReadValueEnum <CompressionScheme>(endian); if (entryOffset != 0x20) { throw new FormatException(); } if (MaximumBlockSize != 0x010000) { throw new FormatException(); } if (this.CompressionScheme != CompressionScheme.None && this.CompressionScheme != CompressionScheme.Lzma && this.CompressionScheme != CompressionScheme.Lzx) { throw new FormatException(); } input.Seek(entryOffset, SeekOrigin.Begin); for (uint i = 0; i < fileTableCount; i++) { sfarFile entry = new sfarFile(); entry.entryOffset = input.Position; entry.nameHash = input.ReadFileNameHash(); entry.blockSizeIndex = input.ReadValueS32(endian); entry.uncompressedSize = input.ReadValueU32(endian); entry.uncompressedSize |= ((long)input.ReadValueU8()) << 32; totalUncSize += entry.uncompressedSize; if (entry.blockSizeIndex == -1) { entry.dataOffset = new long[1]; entry.dataOffset[0] = input.ReadValueU32(endian); entry.dataOffset[0] |= ((long)input.ReadValueU8()) << 32; totalComprSize += entry.uncompressedSize; } else { int numBlocks = (int)Math.Ceiling(entry.uncompressedSize / (double)MaximumBlockSize); entry.dataOffset = new long[numBlocks]; entry.blockSizeArray = new ushort[numBlocks]; entry.dataOffset[0] = input.ReadValueU32(endian); entry.dataOffset[0] |= ((long)input.ReadValueU8()) << 32; long lastPosition = input.Position; input.Seek(getBlockOffset(entry.blockSizeIndex, entryOffset, fileTableCount), 0); entry.blockSizeArray[0] = input.ReadValueU16(); for (int j = 1; j < numBlocks; j++) { entry.blockSizeArray[j] = input.ReadValueU16(); entry.dataOffset[j] = entry.dataOffset[j - 1] + entry.blockSizeArray[j]; totalComprSize += entry.blockSizeArray[j]; } input.Seek(lastPosition, 0); } fileList.Add(entry); }// end of foreach }
public void Deserialize(Stream input) { var magic = input.ReadValueU32(Endian.Little); if (magic != 0x53464152 && // SFAR magic.Swap() != 0x53464152) { throw new FormatException(); } var endian = magic == 0x53464152 ? Endian.Little : Endian.Big; var version = input.ReadValueU32(endian); if (version != 0x00010000) { throw new FormatException(); } var dataOffset = input.ReadValueU32(endian); bool firstDataOffset = true; uint minDataOffset = dataOffset; //Console.WriteLine("Data Offset: {0:X8}",dataOffset); var fileTableOffset = input.ReadValueU32(endian); //Console.WriteLine("File Table Offset: {0:X8}",fileTableOffset); var fileTableCount = input.ReadValueU32(endian); //Console.WriteLine("File Table Count: {0:X8}",fileTableCount); var blockSizeTableOffset = input.ReadValueU32(endian); //Console.WriteLine("Block Size Table Offset: {0:X8}",blockSizeTableOffset); this.MaximumBlockSize = input.ReadValueU32(endian); this.CompressionScheme = input .ReadValueEnum<SFXArchive.CompressionScheme>(endian); if (fileTableOffset != 0x20) { throw new FormatException(); } if (this.MaximumBlockSize != 0x010000) { throw new FormatException(); } /* if (this.CompressionScheme != SFXArchive.CompressionScheme.None && this.CompressionScheme != SFXArchive.CompressionScheme.LZMA && this.CompressionScheme != SFXArchive.CompressionScheme.LZX) { throw new FormatException(); } */ input.Seek(fileTableOffset, SeekOrigin.Begin); for (uint i = 0; i < fileTableCount; i++) { // ReSharper disable UseObjectOrCollectionInitializer var entry = new SFXArchive.Entry(); entry.entryOffset = input.Position; // ReSharper restore UseObjectOrCollectionInitializer entry.nameHash = input.ReadFileNameHash(); //Console.WriteLine("FileNameHash: {0}",entry.NameHash.ToString()); entry.blockSizeIndex = input.ReadValueS32(endian); //Console.WriteLine("Begin position: {0:X8}",input.Position); entry.uncompressedSize = input.ReadValueU32(endian); entry.uncompressedSize |= ((long)input.ReadValueU8()) << 32; //Console.WriteLine(" End position: {0:X8}",input.Position); entry.dataOffset = input.ReadValueU32(endian); entry.dataOffset |= ((long)input.ReadValueU8()) << 32; if(firstDataOffset) { minDataOffset = (uint)entry.dataOffset; firstDataOffset = false; } else { if(minDataOffset > entry.dataOffset) minDataOffset = (uint)entry.dataOffset; } //if(entry.NameHash.Equals (fileNameListNameHash))Console.WriteLine("Offset: {0:X10}, UncSize {1:X10}",entry.Offset,entry.UncompressedSize); this.Entries.Add(entry); } if(minDataOffset > dataOffset) dataOffset = minDataOffset; input.Seek(blockSizeTableOffset, SeekOrigin.Begin); var blockSizeTableSize = dataOffset - blockSizeTableOffset; var blockSizeTableCount = blockSizeTableSize / 2; //ushort aux; //Console.WriteLine("dataOffset: {0:X8}\nfileTableOffset: {1:X8}\nBlockSizeTableSize: {2:X8}\nblockSizeTableOffset: {3:X8}", dataOffset,fileTableOffset,blockSizeTableSize,blockSizeTableOffset); this.BlockSizes.Clear(); //Console.WriteLine("initial position: {0:X8}",input.Position); //Console.WriteLine("blockSizeTableCount: {0}",blockSizeTableCount); for (uint i = 0; i < blockSizeTableCount; i++) { this.BlockSizes.Add(input.ReadValueU16(endian)); } //Console.WriteLine("final position: {0:X8}",input.Position); //Console.WriteLine("number of repetitions: {0}",blockSizeTableCount); //var fileNameListNameHash = new FileNameHash( // new byte[] { 0xB5, 0x50, 0x19, 0xCB, 0xF9, 0xD3, 0xDA, 0x65, 0xD5, 0x5B, 0x32, 0x1C, 0x00, 0x19, 0x69, 0x7C, }); }
public void Deserialize(Stream input) { var magic = input.ReadValueU32(Endian.Little); if (magic != 0x53464152 && // SFAR magic.Swap() != 0x53464152) { throw new FormatException(); } var endian = magic == 0x53464152 ? Endian.Little : Endian.Big; var version = input.ReadValueU32(endian); if (version != 0x00010000) { throw new FormatException(); } var dataOffset = input.ReadValueU32(endian); var fileTableOffset = input.ReadValueU32(endian); var fileTableCount = input.ReadValueU32(endian); var blockSizeTableOffset = input.ReadValueU32(endian); this.MaximumBlockSize = input.ReadValueU32(endian); this.CompressionScheme = input .ReadValueEnum <SFXArchive.CompressionScheme>(endian); if (fileTableOffset != 0x20) { throw new FormatException(); } if (this.MaximumBlockSize != 0x010000) { throw new FormatException(); } /* * if (this.CompressionScheme != SFXArchive.CompressionScheme.None && * this.CompressionScheme != SFXArchive.CompressionScheme.LZMA && * this.CompressionScheme != SFXArchive.CompressionScheme.LZX) * { * throw new FormatException(); * } */ input.Seek(blockSizeTableOffset, SeekOrigin.Begin); var blockSizeTableSize = dataOffset - fileTableOffset; var blockSizeTableCount = blockSizeTableSize / 2; this.BlockSizes.Clear(); for (uint i = 0; i < blockSizeTableCount; i++) { this.BlockSizes.Add(input.ReadValueU16(endian)); } input.Seek(fileTableOffset, SeekOrigin.Begin); for (uint i = 0; i < fileTableCount; i++) { // ReSharper disable UseObjectOrCollectionInitializer var entry = new SFXArchive.Entry(); // ReSharper restore UseObjectOrCollectionInitializer entry.NameHash = input.ReadFileNameHash(); entry.BlockSizeIndex = input.ReadValueS32(endian); entry.UncompressedSize = input.ReadValueU32(endian); entry.UncompressedSize |= ((long)input.ReadValueU8()) << 32; entry.Offset = input.ReadValueU32(endian); entry.Offset |= ((long)input.ReadValueU8()) << 32; this.Entries.Add(entry); } }