public MTARC(Stream input) { _stream = input; using (var br = new BinaryReaderX(input, true, ByteOrder)) { // Set endianess if (br.PeekString() == "\0CRA" || br.PeekString() == "\0SFH") { br.ByteOrder = ByteOrder = ByteOrder.BigEndian; HeaderLength = 8; System = Platform.PS3; } // HFSHeader if (br.PeekString() == "HFS" || br.PeekString() == "\0SFH") { HFSHeader = br.ReadStruct <HFSHeader>(); HFSHeaderLength = HFSHeader.Type == 0 ? 0x20000 : 0x10; } // Header Header = br.ReadStruct <Header>(); switch (Header.Version) { case 0x7: HeaderLength = 8; break; } if (ByteOrder == ByteOrder.LittleEndian && Header.Version != 7) { br.ReadInt32(); } // Files var entries = br.ReadMultiple <FileMetadata>(Header.EntryCount); Files.AddRange(entries.Select(metadata => { br.BaseStream.Position = metadata.Offset + HFSHeaderLength; var level = (System == Platform.CTR ? metadata.CompressedSize != (metadata.UncompressedSize & 0x00FFFFFF) : metadata.CompressedSize != (metadata.UncompressedSize >> 3)) ? CompressionLevel.Optimal : CompressionLevel.NoCompression; br.BaseStream.Position += metadata.CompressedSize; return(new MTArcFileInfo { Metadata = metadata, CompressionLevel = level, System = System, FileData = new SubStream(br.BaseStream, metadata.Offset + HFSHeaderLength, metadata.CompressedSize), FileName = metadata.FileName + (ArcShared.ExtensionMap.ContainsKey(metadata.ExtensionHash) ? ArcShared.ExtensionMap[metadata.ExtensionHash] : "." + metadata.ExtensionHash.ToString("X8")), State = ArchiveFileState.Archived }); })); // HFSFooter if (HFSHeader != null) { br.SeekAlignment(); HFSFooter = br.ReadStruct <HFSFooter>(); } } }
public MTARC(Stream input) { _stream = input; using (var br = new BinaryReaderX(input, true, ByteOrder)) { // Set endianess if (br.PeekString() == "\0CRA" || br.PeekString() == "\0SFH") { br.ByteOrder = ByteOrder = ByteOrder.BigEndian; HeaderLength = 8; System = Platform.PS3; } // HFSHeader if (br.PeekString() == "HFS" || br.PeekString() == "\0SFH") { HFSHeader = br.ReadStruct <HFSHeader>(); HFSHeaderLength = HFSHeader.Type == 0 ? 0x20000 : 0x10; } // Header Header = br.ReadStruct <Header>(); switch (Header.Version) { case 0x9: System = Platform.Switch; HeaderLength = 8; break; case 0x7: HeaderLength = 8; break; } if (ByteOrder == ByteOrder.LittleEndian && Header.Version != 7 && Header.Version != 9) { br.ReadInt32(); } // Files if (Header.Version == 9) { var entries = br.ReadMultiple <FileMetadataSwitch>(Header.EntryCount); Files.AddRange(entries.Select(metadata => { //it seems every file is compressed with ZLib on Switch //example file game.arc contains of at least one file "om120a" where compressed and uncompressed size are equal but the file is still compressed //the decompressed file is really the same size; comparing with other entries no clear differences were found, that would indicate a //compression flag br.BaseStream.Position = metadata.Offset; var level = CompressionLevel.Optimal; br.BaseStream.Position += metadata.CompressedSize; return(new MTArcFileInfo { SwitchMetadata = metadata, CompressionLevel = level, System = System, FileData = new SubStream(br.BaseStream, metadata.Offset, metadata.CompressedSize), FileName = metadata.FileName + (ArcShared.ExtensionMap.ContainsKey(metadata.ExtensionHash) ? ArcShared.ExtensionMap[metadata.ExtensionHash] : "." + metadata.ExtensionHash.ToString("X8")), State = ArchiveFileState.Archived }); })); } else { var entries = br.ReadMultiple <FileMetadata>(Header.EntryCount); Files.AddRange(entries.Select(metadata => { br.BaseStream.Position = metadata.Offset + HFSHeaderLength; var level = (System == Platform.CTR ? metadata.CompressedSize != (metadata.UncompressedSize & 0x00FFFFFF) : System == Platform.Switch ? metadata.CompressedSize != metadata.UncompressedSize : metadata.CompressedSize != (metadata.UncompressedSize >> 3)) ? CompressionLevel.Optimal : CompressionLevel.NoCompression; br.BaseStream.Position += metadata.CompressedSize; return(new MTArcFileInfo { Metadata = metadata, CompressionLevel = level, System = System, FileData = new SubStream(br.BaseStream, metadata.Offset + HFSHeaderLength, metadata.CompressedSize), FileName = metadata.FileName + (ArcShared.ExtensionMap.ContainsKey(metadata.ExtensionHash) ? ArcShared.ExtensionMap[metadata.ExtensionHash] : "." + metadata.ExtensionHash.ToString("X8")), State = ArchiveFileState.Archived }); })); } // HFSFooter if (HFSHeader != null) { br.SeekAlignment(); HFSFooter = br.ReadStruct <HFSFooter>(); } } }