63 lines
1.5 KiB
C#
63 lines
1.5 KiB
C#
|
using CanonSharp.Combinator.Abstractions;
|
||
|
|
||
|
namespace CanonSharp.Common.Scanner;
|
||
|
|
||
|
/// <summary>
|
||
|
/// 字符串输入流状态
|
||
|
/// </summary>
|
||
|
public sealed class StringReadState : IReadState<char, StringReadState>
|
||
|
{
|
||
|
private readonly string _source;
|
||
|
|
||
|
private readonly int _index;
|
||
|
|
||
|
public char Current => _source[_index];
|
||
|
|
||
|
public bool HasValue => _index < _source.Length;
|
||
|
|
||
|
public StringReadState Next => new(_source, _index + 1);
|
||
|
|
||
|
private StringReadState(string source, int index)
|
||
|
{
|
||
|
_source = source;
|
||
|
_index = index;
|
||
|
}
|
||
|
|
||
|
public StringReadState(string source) : this(source, 0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public bool Equals(StringReadState? other)
|
||
|
{
|
||
|
if (other is null)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return _source == other._source && _index == other._index;
|
||
|
}
|
||
|
|
||
|
public override bool Equals(object? obj) => obj is StringReadState other && Equals(other);
|
||
|
|
||
|
public override int GetHashCode() => _source.GetHashCode() ^ _index;
|
||
|
|
||
|
public override string ToString()
|
||
|
{
|
||
|
return HasValue ? $"{ToReadableString(Current)}<0x{(int)Current:X2}>" : "End of string.";
|
||
|
}
|
||
|
|
||
|
private static string ToReadableString(char token)
|
||
|
=> token switch
|
||
|
{
|
||
|
'\0' => "\\0",
|
||
|
'\a' => "\\a",
|
||
|
'\b' => "\\b",
|
||
|
'\f' => "\\f",
|
||
|
'\n' => "\\n",
|
||
|
'\r' => "\\r",
|
||
|
'\t' => "\\t",
|
||
|
'\v' => "\\v",
|
||
|
_ => token.ToString(),
|
||
|
};
|
||
|
}
|