// // DatReader.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics.CodeAnalysis; using System.Text; using NosSmooth.Data.NOSFiles.Files; using Remora.Results; namespace NosSmooth.Data.NOSFiles.Parsers.Dat; /// /// Reader of .dat files. /// public class DatReader { private readonly RawFile _file; private IReadOnlyList _lines; private int _currentLine; private string _separator; /// /// Initializes a new instance of the class. /// /// The file to read. public DatReader(RawFile file) { _lines = Encoding.ASCII.GetString(file.Content).Split('\r', '\n').ToArray(); _currentLine = 0; _file = file; _separator = "VNUM"; } /// /// Gets whether the reader has reached the end. /// public bool ReachedEnd => _currentLine >= _lines.Count; /// /// Sets the separator of a new item. /// /// The separator of new item. public void SetSeparatorField(string separator) { _separator = separator; } /// /// Read next item. /// /// The read item. /// Whether an item was read. public bool ReadItem([NotNullWhen(true)] out DatItem? item) { return ReadItem(out item, _currentLine > 0); } private bool ReadItem([NotNullWhen(true)] out DatItem? item, bool readFirstItem) { if (ReachedEnd) { item = null; return false; } int startLine = _currentLine; if (readFirstItem && _lines[_currentLine].Trim().StartsWith(_separator)) { _currentLine++; } while (!ReachedEnd && !_lines[_currentLine].Trim().StartsWith(_separator)) { _currentLine++; } if (!readFirstItem) { return ReadItem(out item, true); } var dictionary = new Dictionary>(); for (int i = startLine; i < _currentLine; i++) { var line = _lines[i]; var splitted = line.Trim().Split('\t'); var key = splitted[0]; var entry = new DatEntry(key, splitted); if (!dictionary.ContainsKey(key)) { dictionary.Add(key, new List()); } ((List)dictionary[key]).Add(entry); } item = new DatItem(dictionary); return true; } }