using System; namespace UnityEngine.InputSystem.Utilities { // this parser uses Span so it's only available from later unity versions #if UNITY_2021_2_OR_NEWER internal struct PredictiveParser { public void ExpectSingleChar(ReadOnlySpan 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 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 ExpectString(ReadOnlySpan 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.Empty; var output = str.Slice(startPos + 1, m_Position - startPos - 1); ++m_Position; return output; } public bool AcceptSingleChar(ReadOnlySpan str, char c) { if (str[m_Position] != c) return false; m_Position++; return true; } public bool AcceptString(ReadOnlySpan input, out ReadOnlySpan 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.Empty; else output = input.Slice(startPos + 1, endPos - startPos - 1); m_Position = endPos + 1; return true; } public void AcceptInt(ReadOnlySpan 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 }