public Archive(Stream stream) { byte[] header = new byte[4]; stream.Read(header, 0, 4); stream.Seek(-4, SeekOrigin.Current); if (header[0] == 'Y') { archiveFileStream = new Yaz0Stream(stream); } else { archiveFileStream = stream; } using (EndianBinaryReader er = new EndianBinaryReader(archiveFileStream, Encoding.ASCII, true, Endian.Big)) { archiveHeader = new ArchiveHeader(er); sfatHeader = new SFATHeader(er); sfatEntries = new SFATEntry[sfatHeader.NodeCount]; for (int i = 0; i < sfatHeader.NodeCount; i++) { sfatEntries[i] = new SFATEntry(er); } er.Skip(8); // SFNT, 0x00, 0x08, 0x00, 0x00 sfatStringTable = new string[sfatHeader.NodeCount]; for (int i = 0; i < sfatHeader.NodeCount; i++) { // These strings are aligned to 4 bytes. //while (er.PeekReadByte() == 0) // er.ReadByte(); sfatStringTable[i] = Encoding.ASCII.GetString(er.ReadBytesUntil(0)); } } for (int i = 0; i < sfatEntries.Length; i++) { sfatEntries[i].FileName = sfatStringTable[sfatEntries[i].FileNameTableOffset / 4]; } fileDictionary = new Dictionary <string, ArchiveEntry>(sfatEntries.Length); for (int i = 0; i < sfatEntries.Length; i++) { string name = sfatStringTable[sfatEntries[i].FileNameTableOffset / 4]; uint size = sfatEntries[i].DataOffsetEnd - sfatEntries[i].DataOffsetStart; fileDictionary.Add(name, new ArchiveEntry(name, sfatEntries[i].DataOffsetStart + archiveHeader.DataOffset, size, sfatEntries[i].FileType)); } }
public SARC(Stream inputStream) { EndianBinaryReader er = new EndianBinaryReader(inputStream, Endian.Big); try { Header = new SARCHeader(er); SfatHeader = new SFATHeader(er); SfatNodes = new SFATNode[SfatHeader.NodeCount]; for (int i = 0; i < SfatHeader.NodeCount; i++) { SfatNodes[i] = new SFATNode(er); } // Just skip the SFNT_HEADER because it's useless for now ? er.ReadBytes(8); SfatStringTable = new string[SfatHeader.NodeCount]; for (int i = 0; i < SfatHeader.NodeCount; i++) { // These are padded strings, so skip the null bytes padding them while (er.PeekReadByte() == 0) { er.ReadByte(); } SfatStringTable[i] = Encoding.UTF8.GetString(er.ReadBytesUntil(0)); SfatNodes[i].copied_name = SfatStringTable[i]; } // TODO: Maybe we have to pad here too? SfatDataTable = new byte[SfatHeader.NodeCount][]; for (int i = 0; i < SfatHeader.NodeCount; i++) { uint dataLength = SfatNodes[i].NodeDataEndOffset - SfatNodes[i].NodeDataBeginOffset; SfatDataTable[i] = er.ReadBytesAt(Header.DataOffset + SfatNodes[i].NodeDataBeginOffset, (int)dataLength); SfatNodes[i].copied_data = SfatDataTable[i]; } } finally { er.Close(); } }