Пример #1
0
        private void ReadHeaderAndIndexSection()
        {
            // Read file header (16 bytes):
            // 0-3: file signature (0x64)
            // 4-7: number of files
            // 8-11: offset of file name area.
            // 12-15: size of file name area.
            if (reader.ReadInt32() != 0x64)
                throw new InvalidDataException("File signature mismatch.");
            uint numFiles = reader.ReadUInt32();
            uint indexOffset = reader.ReadUInt32();
            uint indexSize = reader.ReadUInt32();

            // Read file names. For each file name entry, the format is:
            // 2 bytes: (X) length of file name, in characters
            // X or 2X bytes: file name (encoded in GBK or UCS2)
            // 4 bytes: all zero; this marks the end of file name
            // 4 bytes: file offset
            // 4 bytes: original file size
            // 4 bytes: file size (packed)
            reader.BaseStream.Seek(indexOffset, SeekOrigin.Begin);
            entries = new List<PkgArchiveEntry>();
            byte[] buffer = new byte[65536 * 2];
            for (uint i = 0; i < numFiles; i++)
            {
                PkgArchiveEntryInfo info = new PkgArchiveEntryInfo();
                info.IndexOffset = (int)reader.BaseStream.Position;
                //PkgArchiveEntry entry = new PkgArchiveEntry();
                //entry.PackagePath = filename;

                ushort length = reader.ReadUInt16();
                if (reader.Read(buffer, 0, length + 4) != length + 4)
                    throw new InvalidDataException("Premature end of file.");
                if (buffer[length] == 0 && buffer[length + 1] == 0 &&
                    buffer[length + 2] == 0 && buffer[length + 3] == 0)
                {
                    // Encoded in GBK
                    info.FileName = Encoding.GetEncoding("GBK").GetString(buffer, 0, length);
                    info.IsFileNameInUnicode = false;
                }
                else
                {
                    // Encoded in UCS-2
                    if (reader.Read(buffer, length + 4, length) != length)
                        throw new InvalidDataException("Premature end of file.");
                    info.FileName = Encoding.Unicode.GetString(buffer, 0, length * 2);
                    info.IsFileNameInUnicode = true;
                }

                info.IndexSize = (int)reader.BaseStream.Position - info.IndexOffset;
                info.ContentOffset = reader.ReadInt32();
                info.OriginalSize = reader.ReadInt32();
                info.ContentSize = reader.ReadInt32();
                entries.Add(new PkgArchiveEntry(this, info));
            }
        }
Пример #2
0
 internal PkgArchiveEntry(PkgArchive archive, PkgArchiveEntryInfo info)
 {
     this.archive = archive;
     this.info = info;
 }