Browse Source

Remove old regex-based parser

pull/1685/head
Jeremy Koritzinsky 8 years ago
parent
commit
dc9fb565fd
  1. 107
      src/Avalonia.Visuals/Media/PathMarkupParser.cs

107
src/Avalonia.Visuals/Media/PathMarkupParser.cs

@ -17,7 +17,6 @@ namespace Avalonia.Media
/// </summary> /// </summary>
public class PathMarkupParser : IDisposable public class PathMarkupParser : IDisposable
{ {
private static readonly string s_separatorPattern;
private static readonly Dictionary<char, Command> s_commands = private static readonly Dictionary<char, Command> s_commands =
new Dictionary<char, Command> new Dictionary<char, Command>
{ {
@ -42,7 +41,6 @@ namespace Avalonia.Media
static PathMarkupParser() static PathMarkupParser()
{ {
s_separatorPattern = CreatesSeparatorPattern();
} }
/// <summary> /// <summary>
@ -82,7 +80,7 @@ namespace Avalonia.Media
/// <param name="pathData">The path data.</param> /// <param name="pathData">The path data.</param>
public void Parse(string pathData) public void Parse(string pathData)
{ {
var tokens = ParseTokens2(pathData); var tokens = ParseTokens(pathData);
CreateGeometry(tokens); CreateGeometry(tokens);
} }
@ -107,21 +105,7 @@ namespace Avalonia.Media
_isDisposed = true; _isDisposed = true;
} }
private static string CreatesSeparatorPattern() private static IEnumerable<CommandToken> ParseTokens(string s)
{
var stringBuilder = new StringBuilder();
foreach (var command in s_commands.Keys)
{
stringBuilder.Append(command);
stringBuilder.Append(char.ToLower(command));
}
return @"(?=[" + stringBuilder + "])";
}
private static IEnumerable<CommandToken> ParseTokens2(string s)
{ {
var commands = new List<CommandToken>(); var commands = new List<CommandToken>();
var span = s.AsSpan(); var span = s.AsSpan();
@ -132,11 +116,6 @@ namespace Avalonia.Media
return commands; return commands;
} }
private static IEnumerable<CommandToken> ParseTokens(string s)
{
return Regex.Split(s, s_separatorPattern).Where(t => !string.IsNullOrEmpty(t)).Select(CommandToken.Parse);
}
private static Point MirrorControlPoint(Point controlPoint, Point center) private static Point MirrorControlPoint(Point controlPoint, Point center)
{ {
var dir = controlPoint - center; var dir = controlPoint - center;
@ -146,7 +125,7 @@ namespace Avalonia.Media
private void CreateGeometry(IEnumerable<CommandToken> commandTokens) private void CreateGeometry(IEnumerable<CommandToken> commandTokens)
{ {
_currentPoint = new Point(); _currentPoint = new Point();
foreach (var commandToken in commandTokens) foreach (var commandToken in commandTokens)
{ {
@ -446,15 +425,13 @@ namespace Avalonia.Media
private class CommandToken private class CommandToken
{ {
private const string ArgumentExpression = @"-?[0-9]*\.?\d+"; private CommandToken(Command command, bool isRelative, List<string> arguments)
private CommandToken(Command command, bool isRelative, IEnumerable<string> arguments)
{ {
Command = command; Command = command;
IsRelative = isRelative; IsRelative = isRelative;
Arguments = new List<string>(arguments); Arguments = arguments;
} }
public Command Command { get; } public Command Command { get; }
@ -477,34 +454,6 @@ namespace Avalonia.Media
private int CurrentPosition { get; set; } private int CurrentPosition { get; set; }
private List<string> Arguments { get; } private List<string> Arguments { get; }
public static CommandToken Parse(string s)
{
using (var reader = new StringReader(s))
{
var command = Command.None;
var isRelative = false;
if (!ReadCommand(reader, ref command, ref isRelative))
{
throw new InvalidDataException("No path command declared.");
}
var commandArguments = reader.ReadToEnd();
var argumentMatches = Regex.Matches(commandArguments, ArgumentExpression);
var arguments = new List<string>();
foreach (Match match in argumentMatches)
{
arguments.Add(match.Value);
}
return new CommandToken(command, isRelative, arguments);
}
}
public static CommandToken Parse(ref ReadOnlySpan<char> span) public static CommandToken Parse(ref ReadOnlySpan<char> span)
{ {
@ -646,33 +595,6 @@ namespace Avalonia.Media
return true; return true;
} }
private static bool ReadCommand(TextReader reader, ref Command command, ref bool relative)
{
ReadWhitespace(reader);
var i = reader.Peek();
if (i == -1)
{
return false;
}
var c = (char)i;
if (!s_commands.TryGetValue(char.ToUpperInvariant(c), out var next))
{
throw new InvalidDataException("Unexpected path command '" + c + "'.");
}
command = next;
relative = char.IsLower(c);
reader.Read();
return true;
}
private static bool ReadArgument(ref ReadOnlySpan<char> remaining, out ReadOnlySpan<char> argument) private static bool ReadArgument(ref ReadOnlySpan<char> remaining, out ReadOnlySpan<char> argument)
{ {
if (remaining.IsEmpty) if (remaining.IsEmpty)
@ -722,25 +644,6 @@ namespace Avalonia.Media
for (; i < span.Length && char.IsWhiteSpace(span[i]); i++) ; for (; i < span.Length && char.IsWhiteSpace(span[i]); i++) ;
return span.Slice(i); return span.Slice(i);
} }
private static void ReadWhitespace(TextReader reader)
{
int i;
while ((i = reader.Peek()) != -1)
{
var c = (char)i;
if (char.IsWhiteSpace(c))
{
reader.Read();
}
else
{
break;
}
}
}
} }
} }
} }
Loading…
Cancel
Save