Пример #1
0
        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>();
                }
            }
        }
Пример #2
0
        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>();
                }
            }
        }