public void TestRead() { SeekableStringReader s = new SeekableStringReader("hello"); Assert.AreEqual('h', s.Read()); Assert.AreEqual('e', s.Read()); Assert.AreEqual("l", s.Read(1)); Assert.AreEqual("lo", s.Read(2)); Assert.Throws <IndexOutOfRangeException>(() => s.Read()); }
public void TestBookmark() { SeekableStringReader s = new SeekableStringReader("hello"); s.Read(2); int bookmark = s.Bookmark(); Assert.AreEqual("ll", s.Read(2)); s.FlipBack(bookmark); Assert.AreEqual("ll", s.Read(2)); Assert.AreEqual("o", s.Read(999)); }
public void TestRanges() { SeekableStringReader s = new SeekableStringReader("hello"); Assert.Throws <ParseException>(() => s.Read(-1)); Assert.AreEqual("hello", s.Read(999)); Assert.Throws <ParseException>(() => s.Read(1)); s.Rewind(int.MaxValue); Assert.IsTrue(s.HasMore()); Assert.AreEqual("hello", s.Peek(999)); Assert.IsTrue(s.HasMore()); }
public void TestNesting() { SeekableStringReader outer = new SeekableStringReader("hello!"); outer.Read(1); SeekableStringReader inner1 = new SeekableStringReader(outer); SeekableStringReader inner2 = new SeekableStringReader(outer); Assert.AreEqual("ell", inner1.Read(3)); Assert.AreEqual("el", inner2.Read(2)); Assert.AreEqual("o", inner1.Read(1)); Assert.AreEqual("l", inner2.Read(1)); Assert.AreEqual("e", outer.Read(1)); Assert.AreEqual("o", inner2.Read(1)); Assert.AreEqual("l", outer.Read(1)); outer.Sync(inner2); Assert.AreEqual("!", outer.Read(1)); }
public void TestContext() { SeekableStringReader s = new SeekableStringReader("abcdefghijklmnopqrstuvwxyz"); s.Read(10); string left, right; s.Context(-1, 5, out left, out right); Assert.AreEqual("fghij", left); Assert.AreEqual("klmno", right); s.Context(-1, 12, out left, out right); Assert.AreEqual("abcdefghij", left); Assert.AreEqual("klmnopqrstuv", right); s.Read(13); s.Context(-1, 6, out left, out right); Assert.AreEqual("rstuvw", left); Assert.AreEqual("xyz", right); s.Context(5, 4, out left, out right); Assert.AreEqual("bcde", left); Assert.AreEqual("fghi", right); }
public void TestStuff() { using (SeekableStringReader s = new SeekableStringReader("hello")) { Assert.AreEqual('h', s.Peek()); Assert.AreEqual("hel", s.Peek(3)); Assert.AreEqual('h', s.Read()); Assert.AreEqual("ell", s.Read(3)); Assert.AreEqual("o", s.Peek(999)); Assert.AreEqual("o", s.Read(999)); } using (SeekableStringReader s2 = new SeekableStringReader(" skip.\t\n\rwhitespace. ")) { s2.SkipWhitespace(); Assert.AreEqual("skip", s2.ReadUntil('.')); s2.SkipWhitespace(); Assert.AreEqual("whitespace", s2.ReadUntil('.')); s2.SkipWhitespace(); Assert.IsFalse(s2.HasMore()); Assert.Throws <IndexOutOfRangeException>(() => s2.Peek()); } }
public void TestReadUntil() { SeekableStringReader s = new SeekableStringReader("hello there"); s.Read(); Assert.AreEqual("ello", s.ReadUntil(' ')); Assert.AreEqual('t', s.Peek()); Assert.Throws <ParseException>(() => s.ReadUntil('x')); Assert.AreEqual("there", s.Rest()); Assert.Throws <ParseException>(() => s.Rest()); s.Rewind(int.MaxValue); Assert.AreEqual("hell", s.ReadUntil('x', 'y', 'z', ' ', 'o')); Assert.Throws <ParseException>(() => s.ReadUntil('x', 'y', '@')); }
/// <summary> /// /// </summary> /// <param name="rest"></param> /// <param name="format"></param> /// <returns></returns> /// <exception cref="">InvalidSystemException</exception> public static string Parse(string rest, OutputFormat format) { SeekableReader reader = new SeekableStringReader(rest); bool success = System.Parse(reader, out System system); if (!success) { throw new InvalidSystemException("Could not parse as a system"); } if (reader.Peek() != -1) { throw new InvalidSystemException($"Saw unexpected character: {(char)reader.Read()}"); } return(system.ToString(format)); }
private VariableNode?ReadVariableNode(SeekableStringReader reader) { int start = reader.NextPosition; int c, len = 0; while ((c = reader.Peek()) > -1 && IsValidVariableChar(c, isFirstChar: len == 0)) { reader.Read(); len++; } if (len == 0) { errorsSink.AddError( "There is a variable with an empty or invalid name. The valid characters are 'a-zA-Z0-9_' and the first character cannot be a number.", start); return(null); } return(new VariableNode(pattern.Substring(start, len))); }
private PatternNode?ReadNode(SeekableStringReader reader, char?stopChar = null) { PatternNode?node = null; int c, len, start; Reset(); void Reset() { len = 0; start = reader.NextPosition; } PatternNode?AppendMatch(string pattern) { if (len > 0) { node += new MatchNode(pattern.Substring(start, len)); } return(node); } while ((c = reader.Read()) > -1) { if (c == stopChar) { return(AppendMatch(pattern)); } PatternNode?next; switch (c) { case Constants.Slash: next = SegmentStartNode.Instance; break; case Constants.Wildcard: next = WildcardNode.Instance; break; case Constants.VariableStart: next = ReadVariableNode(reader); break; case Constants.OptionalStart: next = ReadOptionalNode(reader); break; case Constants.OptionalEnd: errorsSink.AddError($"There is an unexpected '{(char)c}'.", reader.NextPosition - 1); return(null); case Constants.EscapeSequenceStart: if (!ShouldEscape(reader)) { len++; continue; } AppendMatch(pattern); reader.NextPosition += Constants.EscapeSequence.Length; start = reader.NextPosition - 1; len = 1; continue; default: len++; continue; } // failed to parse! if (next is null) { return(null); } if (len > 0) { node += new MatchNode(pattern.Substring(start, len)); } node += next; Reset(); } // expected an end char but didn't find it if (stopChar.HasValue) { errorsSink.AddError($"There is a missing '{stopChar}'."); return(null); } node += len == 0 ? MatchNode.Empty : new MatchNode(pattern.Substring(reader.NextPosition - len, len)); return(node); }