protected override FileIndexEntry[] ReadEntries() { var entries = new List <FileIndexEntry>(); var length = (int)(_fileInfo.Length / 3 / 4); using var index = new FileStream(_indexPath, FileMode.Open, FileAccess.Read, FileShare.Read); var binaryReader = new BinaryReader(index); var count = (int)(index.Length / 12); for (var i = 0; i < count && i < length; ++i) { var entry = new FileIndexEntry { Lookup = binaryReader.ReadInt32(), Length = binaryReader.ReadInt32(), Extra = binaryReader.ReadInt32() }; entries.Add(entry); } for (var i = count; i < length; ++i) { var entry = new FileIndexEntry { Lookup = -1, Length = -1, Extra = -1 }; entries.Add(entry); } return(entries.ToArray()); }
protected override FileIndexEntry[] ReadEntries() { var length = Length; var dataPath = DataPath; var entries = new FileIndexEntry[length]; for (var i = 0; i < entries.Length; i++) { entries[i].Lookup = -1; } using var index = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read); var fileInfo = new FileInfo(dataPath); var uopPattern = Path.GetFileNameWithoutExtension(fileInfo.Name).ToLowerInvariant(); using var binaryReader = new BinaryReader(index); binaryReader.BaseStream.Seek(0, SeekOrigin.Begin); if (binaryReader.ReadInt32() != UOP_MAGIC_NUMBER) { throw new ArgumentException("Bad UOP file."); } binaryReader.ReadInt64(); // version + signature var nextBlock = binaryReader.ReadInt64(); binaryReader.ReadInt32(); // block capacity var count = binaryReader.ReadInt32(); var hashes = new Dictionary <ulong, int>(); for (var i = 0; i < length; i++) { var entryName = $"build/{uopPattern}/{i:D8}{_extension}"; var hash = CreateHash(entryName); if (!hashes.ContainsKey(hash)) { hashes.Add(hash, i); } } binaryReader.BaseStream.Seek(nextBlock, SeekOrigin.Begin); do { var filesCount = binaryReader.ReadInt32(); nextBlock = binaryReader.ReadInt64(); for (var i = 0; i < filesCount; i++) { var offset = binaryReader.ReadInt64(); var headerLength = binaryReader.ReadInt32(); var compressedLength = binaryReader.ReadInt32(); var decompressedLength = binaryReader.ReadInt32(); var hash = binaryReader.ReadUInt64(); binaryReader.ReadUInt32(); // Adler32 var flag = binaryReader.ReadInt16(); var entryLength = flag == 1 ? compressedLength : decompressedLength; if (offset == 0) { continue; } if (hashes.TryGetValue(hash, out var idx)) { if (idx < 0 || idx > entries.Length) { throw new IndexOutOfRangeException("hashes dictionary and files collection have different count of entries!"); } entries[idx].Lookup = (int)(offset + headerLength); entries[idx].Length = entryLength; if (_hasExtra) { var cursorPosition = binaryReader.BaseStream.Position; binaryReader.BaseStream.Seek(offset + headerLength, SeekOrigin.Begin); var extra = binaryReader.ReadBytes(8); var extra1 = (ushort)((extra[3] << 24) | (extra[2] << 16) | (extra[1] << 8) | extra[0]); var extra2 = (ushort)((extra[7] << 24) | (extra[6] << 16) | (extra[5] << 8) | extra[4]); entries[idx].Lookup += 8; entries[idx].Extra = extra1 << 16 | extra2; binaryReader.BaseStream.Seek(cursorPosition, SeekOrigin.Begin); } } } }while (binaryReader.BaseStream.Seek(nextBlock, SeekOrigin.Begin) != 0); return(entries); }