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