示例#1
0
        public void StringSplitterEmpty()
        {
            string pattern         = "";
            var    splitEnumerator = new SpanSplitEnumerator <char>(pattern.ToCharArray(), ' ');

            Assert.True(splitEnumerator.MoveNext());
            Assert.Equal("", splitEnumerator.Current.ToString());
            Assert.False(splitEnumerator.MoveNext());
        }
    public void SplitsSingleWordIntoSingleSegment()
    {
        var value      = "bunt";
        var enumerator = new SpanSplitEnumerator(value);

        Assert.True(enumerator.MoveNext());
        Assert.Equal(value, enumerator.Current.ToString());
        Assert.False(enumerator.MoveNext());
    }
    public void SplitsSingleQuotedTermIntoSingleSegment()
    {
        var value      = "\"one term\"";
        var enumerator = new SpanSplitEnumerator(value);

        Assert.True(enumerator.MoveNext());
        Assert.Equal(value, enumerator.Current.ToString());
        Assert.False(enumerator.MoveNext());
    }
示例#4
0
 private static void AssertEqual <T>(T[][] items, ReadOnlySpan <T> orig, SpanSplitEnumerator <T> source) where T : IEquatable <T>
 {
     foreach (var item in items)
     {
         Assert.True(source.MoveNext());
         var slice = orig[source.Current];
         Assert.Equal(item, slice.ToArray());
     }
     Assert.False(source.MoveNext());
 }
    public void SplitsMultipleWordsIntoMultipleSegments()
    {
        var value      = "a b c d e f g";
        var enumerator = new SpanSplitEnumerator(value);

        for (var i = 0; i < 7; i++)
        {
            Assert.True(enumerator.MoveNext());
            Assert.Equal(value[i * 2].ToString(), enumerator.Current.ToString());
        }

        Assert.False(enumerator.MoveNext());
    }
    public void SplitsEmptyStringsIntoNothing()
    {
        var value      = string.Empty;
        var enumerator = new SpanSplitEnumerator(value);

        Assert.False(enumerator.MoveNext());
    }
示例#7
0
        /// <summary>
        /// Creates a new pattern scan target given a string representation of a pattern.
        /// </summary>
        /// <param name="stringPattern">
        ///     The pattern to look for inside the given region.
        ///     Example: "11 22 33 ?? 55".
        ///     Key: ?? represents a byte that should be ignored, anything else if a hex byte. i.e. 11 represents 0x11, 1F represents 0x1F.
        /// </param>
        public SimplePatternScanData(string stringPattern)
        {
#if SPAN_API
            var enumerator = new SpanSplitEnumerator <char>(stringPattern, ' ');
#else
            var enumerator = new SpanSplitEnumerator <char>(new ReadOnlySpan <char>(stringPattern.ToCharArray()), ' ');
#endif
            var questionMarkFlag = new ReadOnlySpan <char>(_maskIgnore);

            lock (_buildLock)
            {
                _maskBuilder.Clear();
                _bytes.Clear();

                while (enumerator.MoveNext())
                {
                    if (enumerator.Current.Equals(questionMarkFlag, StringComparison.Ordinal))
                    {
                        _maskBuilder.Add(0x0);
                    }
                    else
                    {
#if SPAN_API
                        _bytes.Add(byte.Parse(enumerator.Current, NumberStyles.AllowHexSpecifier));
#else
                        _bytes.Add(byte.Parse(enumerator.Current.ToString(), NumberStyles.AllowHexSpecifier));
#endif
                        _maskBuilder.Add(0x1);
                    }
                }

                Mask  = _maskBuilder.ToArray();
                Bytes = _bytes.ToArray();
            }
        }
示例#8
0
        public void StringSplitterNormal()
        {
            string pattern = "11 22 33 ?? 55";

            string[] splitSegments = { "11", "22", "33", "??", "55" };

            // Note: ToCharArray can be omitted in .NET Standard 2.1 and Core 3.0
            var splitEnumerator = new SpanSplitEnumerator <char>(pattern.ToCharArray(), ' ');

            for (int x = 0; x < splitSegments.Length; x++)
            {
                Assert.True(splitEnumerator.MoveNext());
                Assert.Equal(splitSegments[x], splitEnumerator.Current.ToString());
            }

            Assert.False(splitEnumerator.MoveNext());
        }
示例#9
0
        public SpanSplitEnumerator <char> SpanSplit()
        {
            var enumerator = new SpanSplitEnumerator <char>(_pattern, ' ');

            while (enumerator.MoveNext())
            {
            }

            return(enumerator);
        }
示例#10
0
    /// <summary>
    /// Performs a depth-first search of the given node.
    /// </summary>
    /// <param name="parentNode">The node.</param>
    /// <param name="enumerator">The splitting enumerator.</param>
    /// <param name="searchOptions">A set of search options.</param>
    /// <returns>The matching nodes.</returns>
    private IEnumerable <CommandNode> Search
    (
        IParentNode parentNode,
        SpanSplitEnumerator enumerator,
        TreeSearchOptions searchOptions
    )
    {
        var commandNodes = new List <CommandNode>();

        foreach (var child in parentNode.Children)
        {
            if (!IsNodeMatch(child, enumerator, searchOptions))
            {
                continue;
            }

            switch (child)
            {
            case CommandNode commandNode:
            {
                commandNodes.Add(commandNode);
                break;
            }

            case IParentNode groupNode:
            {
                // Consume the token
                if (!enumerator.MoveNext())
                {
                    // No more tokens, so we can't continue searching
                    return(commandNodes);
                }

                var nestedResults = Search(groupNode, enumerator, searchOptions);
                commandNodes.AddRange(nestedResults);

                continue;
            }

            default:
            {
                throw new InvalidOperationException
                      (
                          "Unknown node type encountered; tree is invalid and the search cannot continue."
                      );
            }
            }
        }

        return(commandNodes);
    }
        public static int Last <T>(this SpanSplitEnumerator <T> enumerator, out ReadOnlySpan <T> last)
            where T : IEquatable <T>
        {
            int cnt = 0;

            last = null;

            while (enumerator.MoveNext())
            {
                last = enumerator.Current;
                cnt++;
            }

            return(cnt);
        }
示例#12
0
        public static void DefaultSpanSplitEnumeratorBehavior()
        {
            var charSpanEnumerator = new SpanSplitEnumerator <string>();

            Assert.Equal(new Range(0, 0), charSpanEnumerator.Current);
            Assert.False(charSpanEnumerator.MoveNext());

            // Implicit DoesNotThrow assertion
            charSpanEnumerator.GetEnumerator();

            var stringSpanEnumerator = new SpanSplitEnumerator <string>();

            Assert.Equal(new Range(0, 0), stringSpanEnumerator.Current);
            Assert.False(stringSpanEnumerator.MoveNext());
            stringSpanEnumerator.GetEnumerator();
        }
示例#13
0
    /// <summary>
    /// Determines whether a node matches the current state of the enumerator.
    /// </summary>
    /// <param name="node">The node.</param>
    /// <param name="enumerator">The tokenizer.</param>
    /// <param name="searchOptions">A set of search options.</param>
    /// <returns>true if the node matches; otherwise, false.</returns>
    private bool IsNodeMatch(IChildNode node, SpanSplitEnumerator enumerator, TreeSearchOptions searchOptions)
    {
        if (!enumerator.MoveNext())
        {
            return(false);
        }

        if (enumerator.Current.Equals(node.Key, searchOptions.KeyComparison))
        {
            return(true);
        }

        foreach (var alias in node.Aliases)
        {
            if (enumerator.Current.Equals(alias, searchOptions.KeyComparison))
            {
                return(true);
            }
        }

        return(false);
    }
示例#14
0
    /// <summary>
    /// Attempts to advance the enumerator.
    /// </summary>
    /// <returns>true if the enumerator advanced and a new value is available; otherwise, false.</returns>
    public bool MoveNext()
    {
        if (_segment.Length == 0)
        {
            if (!_splitEnumerator.MoveNext())
            {
                return(false);
            }

            _isInCombinedShortNameSegment = false;
            _segment = _splitEnumerator.Current;
        }

        var span      = _segment;
        var remainder = ReadOnlySpan <char> .Empty;

        var type = TokenType.Value;

        if (span.StartsWith("--"))
        {
            type = TokenType.LongName;
            span = span[2..];
示例#15
0
        public static void ValidateArguments_OverloadWithoutSeparator()
        {
            ReadOnlySpan <char> buffer = default;

            SpanSplitEnumerator <char> enumerator = buffer.Split();

            Assert.True(enumerator.MoveNext());
            Assert.Equal(new Range(0, 0), enumerator.Current);
            Assert.False(enumerator.MoveNext());

            buffer     = "";
            enumerator = buffer.Split();
            Assert.True(enumerator.MoveNext());
            Assert.Equal(new Range(0, 0), enumerator.Current);
            Assert.False(enumerator.MoveNext());

            buffer     = " ";
            enumerator = buffer.Split();
            Assert.True(enumerator.MoveNext());
            Assert.Equal(new Range(0, 0), enumerator.Current);
            Assert.True(enumerator.MoveNext());
            Assert.Equal(new Range(1, 1), enumerator.Current);
            Assert.False(enumerator.MoveNext());
        }
示例#16
0
        public static void ValidateArguments_OverloadWithStringSeparator()
        {
            // Default buffer
            ReadOnlySpan <char> buffer = default;

            SpanSplitEnumerator <char> enumerator = buffer.Split(null); // null is treated as empty string

            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            enumerator = buffer.Split("");
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            enumerator = buffer.Split(" ");
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            // Empty buffer
            buffer = "";

            enumerator = buffer.Split(null);
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            enumerator = buffer.Split("");
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            enumerator = buffer.Split(" ");
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            // Single whitespace buffer
            buffer = " ";

            enumerator = buffer.Split(null); // null is treated as empty string
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(1, 1));
            Assert.False(enumerator.MoveNext());

            enumerator = buffer.Split("");
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(1, 1));
            Assert.False(enumerator.MoveNext());

            enumerator = buffer.Split(" ");
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(1, 1));
            Assert.False(enumerator.MoveNext());
        }
示例#17
0
        public static void ValidateArguments_OverloadWithROSSeparator()
        {
            // Default buffer
            ReadOnlySpan <char> buffer = default;

            SpanSplitEnumerator <char> enumerator = buffer.Split(default(char));

            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            enumerator = buffer.Split(' ');
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            // Empty buffer
            buffer = "";

            enumerator = buffer.Split(default(char));
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            enumerator = buffer.Split(' ');
            Assert.True(enumerator.MoveNext());
            Assert.Equal(enumerator.Current, new Range(0, 0));
            Assert.False(enumerator.MoveNext());

            // Single whitespace buffer
            buffer = " ";

            enumerator = buffer.Split(default(char));
            Assert.True(enumerator.MoveNext());
            Assert.False(enumerator.MoveNext());

            enumerator = buffer.Split(' ');
            Assert.Equal(new Range(0, 0), enumerator.Current);
            Assert.True(enumerator.MoveNext());
            Assert.Equal(new Range(0, 0), enumerator.Current);
            Assert.True(enumerator.MoveNext());
            Assert.Equal(new Range(1, 1), enumerator.Current);
            Assert.False(enumerator.MoveNext());
        }