Beispiel #1
0
        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));
            }
        }
Beispiel #2
0
        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();
            }
        }