Skip to content

Commit

Permalink
Fix Scanner.ReadQuotedString (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastienros authored Jul 23, 2024
1 parent 24c6201 commit 902b805
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
41 changes: 39 additions & 2 deletions src/Parlot/Scanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ public bool ReadText(ReadOnlySpan<char> text, StringComparison comparisonType, o
/// <summary>
/// Reads the specific expected chars.
/// </summary>
[Obsolete("Prefer bool ReadAnyOf(ReadOnlySpan<char>, out ReadOnlySpan<char>)")]
public bool ReadAnyOf(ReadOnlySpan<char> chars, StringComparison comparisonType, out ReadOnlySpan<char> result)
{
var current = Cursor.Buffer.AsSpan(Cursor.Offset, 1);
Expand All @@ -392,6 +393,42 @@ public bool ReadAnyOf(ReadOnlySpan<char> chars, StringComparison comparisonType,
return true;
}

/// <summary>
/// Reads the specific expected chars.
/// </summary>
public bool ReadAnyOf(ReadOnlySpan<char> chars, out ReadOnlySpan<char> result)
{
var start = Cursor.Offset;

while (true)
{
var current = Cursor.Current;
var index = chars.IndexOf(current);

if (index == -1)
{
if (Cursor.Offset == start)
{
result = [];
return false;
}

var length = Cursor.Offset - start;

result = Cursor.Buffer.AsSpan(start, length);
return true;
}

if (Cursor.Eof)
{
result = [];
return false;
}

Cursor.Advance(1);
}
}

#if NET8_0_OR_GREATER
/// <summary>
/// Reads the specific expected chars.
Expand Down Expand Up @@ -631,7 +668,7 @@ private bool ReadQuotedString(char quoteChar, out ReadOnlySpan<char> result)
}
}

nextEscape = Cursor.Buffer.AsSpan(Cursor.Offset).IndexOfAny('\\', startChar);
nextEscape = Cursor.Span.IndexOfAny('\\', startChar);

if (Cursor.Match(startChar))
{
Expand All @@ -647,7 +684,7 @@ private bool ReadQuotedString(char quoteChar, out ReadOnlySpan<char> result)
}
}

result = Buffer.AsSpan(start.Offset, Cursor.Offset);
result = Buffer.AsSpan(start.Offset, Cursor.Offset - start.Offset);

return true;
}
Expand Down
42 changes: 42 additions & 0 deletions test/Parlot.Tests/ScannerTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Buffers;
using Xunit;

namespace Parlot.Tests
Expand Down Expand Up @@ -55,6 +56,47 @@ public void ShouldNotReadStringWithInvalidEscapes(string text)
Assert.False(s.ReadQuotedString());
}

[Fact]
public void ShouldReadQuotedStringPartial()
{
var s = new Scanner("[h a='\\\"']");
Assert.True(s.ReadText("[h a="));
Assert.True(s.ReadSingleQuotedString(out var result));
Assert.Equal("'\\\"'", result);
}

[Theory]
[InlineData("hello world", "helo", "hello")]
[InlineData("hello world", "helo wrd", "hello world")]
[InlineData("hello world", "h", "h")]
public void ShouldReadAnyOf(string source, string pattern, string expected)
{
var s = new Scanner(source);
Assert.True(s.ReadAnyOf(pattern, out var result));
Assert.Equal(expected, result);

#if NET8_0_OR_GREATER
s = new Scanner(source);
Assert.True(s.ReadAnyOf(SearchValues.Create(pattern), out result));
Assert.Equal(expected, result);
#endif
}

[Theory]
[InlineData("hello world", "wrd")]
[InlineData("", "helo wrd")]
[InlineData("hello world", "")]
public void ShouldNotReadAnyOf(string source, string pattern)
{
var s = new Scanner(source);
Assert.False(s.ReadAnyOf(pattern, out var result));

#if NET8_0_OR_GREATER
s = new Scanner(source);
Assert.False(s.ReadAnyOf(SearchValues.Create(pattern), out result));
#endif
}

[Fact]
public void SkipWhitespaceShouldSkipWhitespace()
{
Expand Down

0 comments on commit 902b805

Please sign in to comment.