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)); } }
internal PkgArchiveEntry(PkgArchive archive, PkgArchiveEntryInfo info) { this.archive = archive; this.info = info; }