public Stream Seek(int index, out int length, out int extra) { if (!FilesExist || index < 0 || index >= _length) { length = extra = 0; return(null); } FileIndexEntry e = _entries[index]; if (e.Lookup < 0 || e.Length <= 0) { length = extra = 0; return(null); } length = e.Length & 0x7FFFFFFF; extra = e.Extra; if (_stream != null && (!_stream.CanRead || !_stream.CanSeek)) { _stream.Dispose(); _stream = null; } if (_stream == null) { _stream = new FileStream(_dataPath, FileMode.Open, FileAccess.Read, FileShare.Read); } _stream.Seek(e.Lookup, SeekOrigin.Begin); return(_stream); }
private FileIndexEntry[] ReadLegacyEntries() { List <FileIndexEntry> entries = new List <FileIndexEntry>(); int length = (int)((new FileInfo(_indexPath).Length / 3) / 4); using (FileStream index = new FileStream(_indexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader bin = new BinaryReader(index); _stream = new FileStream(_mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); int count = (int)(index.Length / 12); for (int i = 0; i < count && i < length; ++i) { FileIndexEntry entry = new FileIndexEntry() { Lookup = bin.ReadInt32(), Length = bin.ReadInt32(), Extra = bin.ReadInt32(), }; entries.Add(entry); } for (int i = count; i < length; ++i) { FileIndexEntry entry = new FileIndexEntry() { Lookup = -1, Length = -1, Extra = -1, }; entries.Add(entry); } } return(entries.ToArray()); }
protected override FileIndexEntry[] ReadEntries() { var entries = new List<FileIndexEntry>(); var length = (int)((new FileInfo(_indexPath).Length / 3) / 4); using(var index = new FileStream(_indexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { var bin = new BinaryReader(index); var count = (int)(index.Length / 12); for(var i = 0; i < count && i < length; ++i) { var entry = new FileIndexEntry { Lookup = bin.ReadInt32(), Length = bin.ReadInt32(), Extra = bin.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 entries = new List <FileIndexEntry>(); var length = (int)((new FileInfo(_indexPath).Length / 3) / 4); using (var index = new FileStream(_indexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { var bin = new BinaryReader(index); var count = (int)(index.Length / 12); for (var i = 0; i < count && i < length; ++i) { var entry = new FileIndexEntry { Lookup = bin.ReadInt32(), Length = bin.ReadInt32(), Extra = bin.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() { int length = Length; string dataPath = DataPath; FileIndexEntry[] entries = new FileIndexEntry[length]; // In the mul file index, we read everything sequentially, and -1 is applied to invalid lookups. // UOP does not do this, so we need to do it ourselves. for (int i = 0; i < entries.Length; i++) entries[i].Lookup = -1; using (FileStream index = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { FileInfo fi = new FileInfo(dataPath); string uopPattern = Path.GetFileNameWithoutExtension(fi.Name).ToLowerInvariant(); using (BinaryReader br = new BinaryReader(index)) { br.BaseStream.Seek(0, SeekOrigin.Begin); if (br.ReadInt32() != UOP_MAGIC_NUMBER) throw new ArgumentException("Bad UOP file."); br.ReadInt64(); // version + signature long nextBlock = br.ReadInt64(); br.ReadInt32(); // block capacity int count = br.ReadInt32(); Dictionary<ulong, int> hashes = new Dictionary<ulong, int>(); for (int i = 0; i < length; i++) { string entryName = string.Format("build/{0}/{1:D8}{2}", uopPattern, i, _extension); ulong hash = CreateHash(entryName); if (!hashes.ContainsKey(hash)) hashes.Add(hash, i); } br.BaseStream.Seek(nextBlock, SeekOrigin.Begin); do { int filesCount = br.ReadInt32(); nextBlock = br.ReadInt64(); for (int i = 0; i < filesCount; i++) { long offset = br.ReadInt64(); int headerLength = br.ReadInt32(); int compressedLength = br.ReadInt32(); int decompressedLength = br.ReadInt32(); ulong hash = br.ReadUInt64(); br.ReadUInt32(); // Adler32 short flag = br.ReadInt16(); int entryLength = flag == 1 ? compressedLength : decompressedLength; if (offset == 0) continue; int idx; if (hashes.TryGetValue(hash, out 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) { long curPos = br.BaseStream.Position; br.BaseStream.Seek(offset + headerLength, SeekOrigin.Begin); byte[] extra = br.ReadBytes(8); ushort extra1 = (ushort)((extra[3] << 24) | (extra[2] << 16) | (extra[1] << 8) | extra[0]); ushort extra2 = (ushort)((extra[7] << 24) | (extra[6] << 16) | (extra[5] << 8) | extra[4]); entries[idx].Lookup += 8; entries[idx].Extra = extra1 << 16 | extra2; br.BaseStream.Seek(curPos, SeekOrigin.Begin); } } } } while (br.BaseStream.Seek(nextBlock, SeekOrigin.Begin) != 0); } } return entries; }
protected override FileIndexEntry[] ReadEntries() { int length = Length; string dataPath = DataPath; FileIndexEntry[] entries = new FileIndexEntry[length]; // In the mul file index, we read everything sequentially, and -1 is applied to invalid lookups. // UOP does not do this, so we need to do it ourselves. for (int i = 0; i < entries.Length; i++) { entries[i].Lookup = -1; } using (FileStream index = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { FileInfo fi = new FileInfo(dataPath); string uopPattern = Path.GetFileNameWithoutExtension(fi.Name).ToLowerInvariant(); using (BinaryReader br = new BinaryReader(index)) { br.BaseStream.Seek(0, SeekOrigin.Begin); if (br.ReadInt32() != UOP_MAGIC_NUMBER) { throw new ArgumentException("Bad UOP file."); } br.ReadInt64(); // version + signature long nextBlock = br.ReadInt64(); br.ReadInt32(); // block capacity int count = br.ReadInt32(); Dictionary <ulong, int> hashes = new Dictionary <ulong, int>(); for (int i = 0; i < length; i++) { string entryName = string.Format("build/{0}/{1:D8}{2}", uopPattern, i, _extension); ulong hash = CreateHash(entryName); if (!hashes.ContainsKey(hash)) { hashes.Add(hash, i); } } br.BaseStream.Seek(nextBlock, SeekOrigin.Begin); do { int filesCount = br.ReadInt32(); nextBlock = br.ReadInt64(); for (int i = 0; i < filesCount; i++) { long offset = br.ReadInt64(); int headerLength = br.ReadInt32(); int compressedLength = br.ReadInt32(); int decompressedLength = br.ReadInt32(); ulong hash = br.ReadUInt64(); br.ReadUInt32(); // Adler32 short flag = br.ReadInt16(); int entryLength = flag == 1 ? compressedLength : decompressedLength; if (offset == 0) { continue; } int idx; if (hashes.TryGetValue(hash, out 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) { long curPos = br.BaseStream.Position; br.BaseStream.Seek(offset + headerLength, SeekOrigin.Begin); byte[] extra = br.ReadBytes(8); ushort extra1 = (ushort)((extra[3] << 24) | (extra[2] << 16) | (extra[1] << 8) | extra[0]); ushort extra2 = (ushort)((extra[7] << 24) | (extra[6] << 16) | (extra[5] << 8) | extra[4]); entries[idx].Lookup += 8; entries[idx].Extra = extra1 << 16 | extra2; br.BaseStream.Seek(curPos, SeekOrigin.Begin); } } } }while (br.BaseStream.Seek(nextBlock, SeekOrigin.Begin) != 0); } } return(entries); }
private FileIndexEntry[] ReadLegacyEntries() { List<FileIndexEntry> entries = new List<FileIndexEntry>(); int length = (int)((new FileInfo(_indexPath).Length / 3) / 4); using (FileStream index = new FileStream(_indexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader bin = new BinaryReader(index); _stream = new FileStream(_mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); int count = (int)(index.Length / 12); for (int i = 0; i < count && i < length; ++i) { FileIndexEntry entry = new FileIndexEntry() { Lookup = bin.ReadInt32(), Length = bin.ReadInt32(), Extra = bin.ReadInt32(), }; entries.Add(entry); } for (int i = count; i < length; ++i) { FileIndexEntry entry = new FileIndexEntry() { Lookup = -1, Length = -1, Extra = -1, }; entries.Add(entry); } } return entries.ToArray(); }
private FileIndexEntry[] ReadUOPEntries() { List<FileIndexEntry> entries = new List<FileIndexEntry>(); _stream = new FileStream(_indexPath, FileMode.Open); using (BinaryReader reader = new BinaryReader(_stream)) { UopHeader header = new UopHeader() { MagicNumber = reader.ReadInt32(), Version = reader.ReadInt32(), Misc = reader.ReadInt32(), StartAddress = reader.ReadInt64(), BlockSize = reader.ReadInt32(), FileCount = reader.ReadInt32(), }; if (header.MagicNumber != UOPMagicNumber) { Tracer.Error("{0} is not a UOP file, magic number not found!", _indexPath); return new FileIndexEntry[0]; } long nextBlockAddress = header.StartAddress; List<UopIndexEntry> uopEntries = new List<UopIndexEntry>(); while (nextBlockAddress != 0L) { _stream.Seek(nextBlockAddress, SeekOrigin.Begin); UopBlock block = new UopBlock() { FileCount = reader.ReadInt32(), NextBlockAddress = reader.ReadInt64() }; for (int i = 0; i < block.FileCount; i++) { UopIndexEntry uopEntry = new UopIndexEntry() { Lookup = reader.ReadInt64(), Length = reader.ReadInt32(), CompressedSize = reader.ReadInt32(), DecompressedSize = reader.ReadInt32(), EntryHash = reader.ReadInt64(), BlockHash = reader.ReadInt32(), IsCompressed = reader.ReadInt16() == 1, }; uopEntries.Add(uopEntry); } nextBlockAddress = block.NextBlockAddress; } foreach (var uopEntry in uopEntries) { FileIndexEntry entry = new FileIndexEntry() { Lookup = (int)uopEntry.Lookup, Length = uopEntry.DecompressedSize }; entries.Add(entry); } } return entries.ToArray(); }
private FileIndexEntry[] ReadUOPEntries() { List <FileIndexEntry> entries = new List <FileIndexEntry>(); _stream = new FileStream(_indexPath, FileMode.Open); using (BinaryReader reader = new BinaryReader(_stream)) { UopHeader header = new UopHeader() { MagicNumber = reader.ReadInt32(), Version = reader.ReadInt32(), Misc = reader.ReadInt32(), StartAddress = reader.ReadInt64(), BlockSize = reader.ReadInt32(), FileCount = reader.ReadInt32(), }; if (header.MagicNumber != UOPMagicNumber) { Tracer.Error("{0} is not a UOP file, magic number not found!", _indexPath); return(new FileIndexEntry[0]); } long nextBlockAddress = header.StartAddress; List <UopIndexEntry> uopEntries = new List <UopIndexEntry>(); while (nextBlockAddress != 0L) { _stream.Seek(nextBlockAddress, SeekOrigin.Begin); UopBlock block = new UopBlock() { FileCount = reader.ReadInt32(), NextBlockAddress = reader.ReadInt64() }; for (int i = 0; i < block.FileCount; i++) { UopIndexEntry uopEntry = new UopIndexEntry() { Lookup = reader.ReadInt64(), Length = reader.ReadInt32(), CompressedSize = reader.ReadInt32(), DecompressedSize = reader.ReadInt32(), EntryHash = reader.ReadInt64(), BlockHash = reader.ReadInt32(), IsCompressed = reader.ReadInt16() == 1, }; uopEntries.Add(uopEntry); } nextBlockAddress = block.NextBlockAddress; } foreach (var uopEntry in uopEntries) { FileIndexEntry entry = new FileIndexEntry() { Lookup = (int)uopEntry.Lookup, Length = uopEntry.DecompressedSize }; entries.Add(entry); } } return(entries.ToArray()); }