93 lines
2.7 KiB
C#
93 lines
2.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Linq;
|
|
namespace ln.types.text
|
|
{
|
|
public class TokenReader
|
|
{
|
|
public TextReader Reader { get; }
|
|
|
|
public TokenReader(Stream stream)
|
|
: this(new UnbufferedStreamReader(stream)) { }
|
|
public TokenReader(TextReader textReader)
|
|
{
|
|
Reader = textReader;
|
|
}
|
|
|
|
public String Read(Func<char, bool> criteria)
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
int ch;
|
|
while (((ch = Reader.Peek()) != -1) && criteria((char)ch))
|
|
stringBuilder.Append((char)Reader.Read());
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
public bool EndOfStream => Reader.Peek() == -1;
|
|
|
|
public String Read(char validChar) => Read((ch) => ch == validChar);
|
|
public String Read(char[] validChars) => Read((ch) => validChars.Contains(ch));
|
|
|
|
public String ReadWhiteSpace() => Read((ch) => char.IsWhiteSpace(ch));
|
|
public String ReadToken() => Read((ch) => char.IsLetterOrDigit(ch) || (ch == '_'));
|
|
|
|
public String ReadValue() => Reader.Peek() == '"' ? ReadQuotedString() : ReadToken();
|
|
|
|
public String ReadQuotedString()
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
int nextCh = Reader.Peek();
|
|
if (nextCh != -1)
|
|
{
|
|
if (nextCh != '"')
|
|
throw new FormatException("expected double quotes");
|
|
Reader.Read();
|
|
|
|
while (((nextCh = Reader.Read()) != -1) && (nextCh != '"'))
|
|
{
|
|
if (nextCh == '\\')
|
|
nextCh = Reader.Read();
|
|
stringBuilder.Append((char)nextCh);
|
|
}
|
|
}
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
public String ReadPath()
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
string token;
|
|
|
|
if (Reader.Peek() == '/')
|
|
stringBuilder.Append((char)Reader.Read());
|
|
|
|
while ((token = ReadToken()).Length > 0)
|
|
{
|
|
stringBuilder.Append(token);
|
|
|
|
if (Reader.Peek() == '/')
|
|
stringBuilder.Append((char)Reader.Read());
|
|
else
|
|
break;
|
|
}
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
class UnbufferedStreamReader : TextReader
|
|
{
|
|
public Stream BaseStream { get; }
|
|
|
|
public UnbufferedStreamReader(Stream stream)
|
|
{
|
|
BaseStream = stream;
|
|
}
|
|
public override int Read() => BaseStream.ReadByte();
|
|
}
|
|
}
|
|
}
|