namespace EonaCat.FirstLight.SaveTransfer.VdfGenerator.KeyValue; /// /// Provides functionality for tokenizing a key-value formatted string input, allowing sequential reading and validation of symbols and quoted strings. /// /// The input string to tokenize. Must not be null. public class KeyValueTokenizer(string text) { private int _pos; /// /// Determines whether the next non-whitespace character in the input matches the specified character without advancing the current position. /// /// The character to compare with the next non-whitespace character in the input. /// if the next non-whitespace character matches the specified character; otherwise, . public bool PeekSymbol(char c) { SkipWhitespace(); return _pos < text.Length && text[_pos] == c; } /// /// Reads the next non-whitespace character from the input and verifies that it matches the specified symbol. /// /// The character to match at the current position in the input. /// Thrown if the next non-whitespace character does not match the specified symbol. public void ReadSymbol(char c) { SkipWhitespace(); if (_pos >= text.Length || text[_pos] != c) throw new Exception($"Expected '{c}' at position {_pos}"); _pos++; } /// /// Reads a string enclosed in quotation marks from the current position in the input text. /// /// The string located between the opening and closing quotation marks or an empty string if there are no characters between the quotes. /// Thrown when the current position does not contain an opening quotation mark or when a closing quotation mark cannot be found. public string ReadString() { SkipWhitespace(); if (_pos >= text.Length || text[_pos] != '"') throw new Exception($"Expected '\"' at position {_pos}, but found '{text[_pos]}'!"); _pos++; // skip opening quote var start = _pos; while (_pos < text.Length && text[_pos] != '"') _pos++; if (_pos >= text.Length) throw new Exception("Unterminated string literal!"); var result = text.Substring(start, _pos - start); _pos++; // skip closing quote return result; } /// /// Advances the current position past any consecutive whitespace characters in the input text. /// private void SkipWhitespace() { while (_pos < text.Length) { var c = text[_pos]; if (c is ' ' or '\t' or '\n' or '\r') { _pos++; continue; } break; } } }