UnityGame/Library/PackageCache/com.unity.inputsystem/InputSystem/Utilities/PredictiveParser.cs
2024-10-27 10:53:47 +03:00

149 lines
3.9 KiB
C#

using System;
namespace UnityEngine.InputSystem.Utilities
{
// this parser uses Span<T> so it's only available from later unity versions
#if UNITY_2021_2_OR_NEWER
internal struct PredictiveParser
{
public void ExpectSingleChar(ReadOnlySpan<char> str, char c)
{
if (str[m_Position] != c)
throw new InvalidOperationException($"Expected a '{c}' character at position {m_Position} in : {str.ToString()}");
++m_Position;
}
public int ExpectInt(ReadOnlySpan<char> str)
{
int pos = m_Position;
int sign = 1;
if (str[pos] == '-')
{
sign = -1;
++pos;
}
int value = 0;
for (;;)
{
var n = str[pos];
if (n >= '0' && n <= '9')
{
value *= 10;
value += n - '0';
++pos;
}
else
break;
}
if (m_Position == pos)
throw new InvalidOperationException($"Expected an int at position {m_Position} in {str.ToString()}");
m_Position = pos;
return value * sign;
}
public ReadOnlySpan<char> ExpectString(ReadOnlySpan<char> str)
{
var startPos = m_Position;
if (str[startPos] != '\"')
throw new InvalidOperationException($"Expected a '\"' character at position {m_Position} in {str.ToString()}");
++m_Position;
for (;;)
{
var c = str[m_Position];
c |= ' ';
if (c >= 'a' && c <= 'z')
{
++m_Position;
continue;
}
break;
}
// if the first non-alpha character is not a quote, throw
if (str[m_Position] != '\"')
throw new InvalidOperationException($"Expected a closing '\"' character at position {m_Position} in string: {str.ToString()}");
if (m_Position - startPos == 1)
return ReadOnlySpan<char>.Empty;
var output = str.Slice(startPos + 1, m_Position - startPos - 1);
++m_Position;
return output;
}
public bool AcceptSingleChar(ReadOnlySpan<char> str, char c)
{
if (str[m_Position] != c)
return false;
m_Position++;
return true;
}
public bool AcceptString(ReadOnlySpan<char> input, out ReadOnlySpan<char> output)
{
output = default;
var startPos = m_Position;
var endPos = startPos;
if (input[endPos] != '\"')
return false;
++endPos;
for (;;)
{
var c = input[endPos];
c |= ' ';
if (c >= 'a' && c <= 'z')
{
++endPos;
continue;
}
break;
}
// if the first non-alpha character is not a quote, throw
if (input[endPos] != '\"')
return false;
// empty string?
if (m_Position - startPos == 1)
output = ReadOnlySpan<char>.Empty;
else
output = input.Slice(startPos + 1, endPos - startPos - 1);
m_Position = endPos + 1;
return true;
}
public void AcceptInt(ReadOnlySpan<char> str)
{
// skip negative sign
if (str[m_Position] == '-')
++m_Position;
for (;;)
{
var n = str[m_Position];
if (n >= '0' && n <= '9')
++m_Position;
else
break;
}
}
private int m_Position;
}
#endif
}