using System; namespace ClassicalSharp.Commands { /// Reads and parses arguments for a client command. /// Spaces are designated as the argument separators. public class CommandReader { string rawInput; int firstArgOffset; int curOffset; /// Returns the next argument, or null if there are no more arguments left. public string Next() { if( curOffset >= rawInput.Length ) return null; int next = rawInput.IndexOf( ' ', curOffset ); if( next == -1 ) { next = rawInput.Length; } string arg = rawInput.Substring( curOffset, next - curOffset ); curOffset = next + 1; // skip following space return arg; } /// Returns all remaining arguments (including the space separators), /// or null if there are no more arguments left. public string NextAll() { if( curOffset >= rawInput.Length ) return null; string arg = rawInput.Substring( curOffset, rawInput.Length - curOffset ); curOffset = rawInput.Length; return arg; } /// Attempts to parse the next argument as a 32-bit integer. public bool NextInt( out int value ) { return Int32.TryParse( Next(), out value ); } /// Attempts to parse the next argument as a 32-bit floating point number. public bool NextFloat( out float value ) { return Single.TryParse( Next(), out value ); } /// Attempts to parse the next argument as a 6 digit hex number. /// #xxxxxx or xxxxxx are accepted. public bool NextHexColour( out FastColour value ) { return FastColour.TryParse( Next(), out value ); } /// Attempts to parse the next argument using the specified parsing function. public bool NextOf( out T value, TryParseFunc parser ) { bool success = parser( Next(), out value ); if( !success ) value = default( T ); return success; } bool MoveNext() { if( curOffset >= rawInput.Length ) return false; int next = rawInput.IndexOf( ' ', curOffset ); if( next == -1 ) { next = rawInput.Length; } curOffset = next + 1; return true; } /// Total number of arguments yet to be processed. public int RemainingArgs { get { return CountArgsFrom( curOffset ); } } /// Total number of arguments provided by the user. public int TotalArgs { get { return CountArgsFrom( firstArgOffset ); } } int CountArgsFrom( int startOffset ) { int count = 0; int pos = curOffset; curOffset = startOffset; while( MoveNext() ) { count++; } curOffset = pos; return count; } /// Rewinds the internal state back to the first argument. public void Reset() { curOffset = firstArgOffset; } public CommandReader( string input ) { rawInput = input.TrimEnd( ' ' ); // Check that the string has at least one argument - the command name int firstSpaceIndex = rawInput.IndexOf( ' ' ); if( firstSpaceIndex < 0 ) { firstSpaceIndex = rawInput.Length - 1; } firstArgOffset = firstSpaceIndex + 1; curOffset = firstArgOffset; } } }