public IEnumerable <TES4Record> Load(TES4FileLoadScheme scheme) { Console.Write("Processing " + nameof(TES4File) + " Data..."); Stopwatch stopwatch = Stopwatch.StartNew(); using (FileStream contents = GetFile()) { this.FetchTES4(contents); while (true) { byte[] headerBytes = new byte[TES4Grup.GRUP_HEADER_SIZE]; int read = contents.Read(headerBytes); if (read == 0) { break; } string headerString = ISO_8859_1.Value.GetString(headerBytes); if (headerString.Substring(0, 4) != "GRUP") { throw new InvalidESFileException("Invalid GRUP magic, found " + headerString.Substring(0, 4)); } contents.Seek(-TES4Grup.GRUP_HEADER_SIZE, SeekOrigin.Current); int grupSize = PHPFunction.UnpackV(headerBytes.Skip(4).Take(4).ToArray()); TES4RecordType grupType = TES4RecordType.First(headerString.Substring(8, 4)); if (scheme.ShouldLoad(grupType)) { TES4GrupLoadScheme?rules = scheme.GetRulesFor(grupType); if (rules == null) { throw new InvalidOperationException(nameof(rules) + " was null for " + nameof(grupType) + " " + grupType.Name + "."); } TES4Grup grup = new TES4Grup(); foreach (var loadedRecord in grup.Load(contents, this, rules, true)) { yield return(loadedRecord); } if (grup.Type == null) { throw new InvalidOperationException(nameof(grup.Type) + " was null."); } this.grups.Add(grup.Type, grup); } else { contents.Seek(grupSize, SeekOrigin.Current); } } } stopwatch.Stop(); Console.WriteLine("\rProcessing " + nameof(TES4File) + " Complete (" + stopwatch.ElapsedMilliseconds + " ms)"); }
public List <TES4Grup> GetGrup(TES4RecordType type) { List <TES4Grup> grups = new List <TES4Grup>(); foreach (var file in this.files) { TES4Grup grup = file.GetGrup(type); if (grup != null) { grups.Add(grup); } } return(grups); }
/* * @throws InvalidESFileException */ public IEnumerable <ITES4Record> Load(FileStream fileContents, TES4File file, TES4GrupLoadScheme scheme, bool isTopLevelGrup) { long startPosition = fileContents.Position; byte[] headerBytes = fileContents.Read(GRUP_HEADER_SIZE); string headerString = TES4File.ISO_8859_1.Value.GetString(headerBytes); if (headerString.Substring(0, 4) != "GRUP") { throw new InvalidESFileException("Invalid GRUP magic, found " + headerString.Substring(0, 4)); } this.Size = PHPFunction.UnpackV(headerBytes.Skip(4).Take(4).ToArray()); if (isTopLevelGrup) { this.Type = TES4RecordType.First(headerString.Substring(8, 4)); } long end = startPosition + this.Size; while (fileContents.Position < end) { //Ineffective lookahead, but oh well byte[] nextEntryTypeBytes = new byte[4]; int bytesRead = fileContents.Read(nextEntryTypeBytes); if (bytesRead == 0) { break; } fileContents.Seek(-4, SeekOrigin.Current); string nextEntryType = TES4File.ISO_8859_1.Value.GetString(nextEntryTypeBytes); switch (nextEntryType) { case "GRUP": { TES4Grup nestedGrup = new TES4Grup(); foreach (var subrecord in nestedGrup.Load(fileContents, file, scheme, false)) { yield return(subrecord); } break; } default: { byte[] recordHeaderBytes = fileContents.Read(TES4LoadedRecord.RECORD_HEADER_SIZE); string recordTypeString = TES4File.ISO_8859_1.Value.GetString(recordHeaderBytes.Take(4).ToArray()); TES4RecordType recordType = TES4RecordType.First(recordTypeString); int recordSize = PHPFunction.UnpackV(recordHeaderBytes.Skip(4).Take(4).ToArray()); int recordFlags = PHPFunction.UnpackV(recordHeaderBytes.Skip(8).Take(4).ToArray()); int recordFormid = PHPFunction.UnpackV(recordHeaderBytes.Skip(12).Take(4).ToArray()); if (scheme.ShouldLoad(recordType)) { TES4LoadedRecord record = new TES4LoadedRecord(file, recordType, recordFormid, recordSize, recordFlags); record.Load(fileContents, scheme.GetRulesFor(recordType)); this.records.Add(record); yield return(record); } else { fileContents.Seek(recordSize, SeekOrigin.Current); } break; } } } }