Exemple #1
0
        public bool IsMatch(string subject)
        {
            int finalPosition = 0;

#if SPAN
            var matched = _rootTokenEvaluator.IsMatch(subject.AsSpan(), 0, out finalPosition);
#else
            var matched = _rootTokenEvaluator.IsMatch(subject, 0, out finalPosition);
#endif

            return(matched);
        }
Exemple #2
0
        public bool IsMatch(string allChars, int currentPosition, out int newPosition)
        {
            newPosition = currentPosition;
            if (!_subEvaluator.ConsumesVariableLength)
            {
                // The remaining tokens match against a fixed length string, so wildcard **must** consume
                // a known amount of characters in order for this to have a chance of successful match.
                // but can't consume past / behind current position!
                //var matchLength = (allChars.Length - _subEvaluator.ConsumesMinLength);
                //if (matchLength < currentPosition)
                //{
                //    return false;
                //}
                //var isMatch = _subEvaluator.IsMatch(allChars, matchLength, out newPosition);
                //return isMatch;
                var isMatch = _subEvaluator.IsMatch(allChars, (allChars.Length - _subEvaluator.ConsumesMinLength), out newPosition);
                return(isMatch);
            }

            // if we are at the end of the string, we match!
            if (currentPosition >= allChars.Length)
            {
                return(true);
            }
            // otherwise we can consume a variable amount of characters but we can't match more characters than the amount that will take
            // us past the min required length required by the sub evaluator tokens, and as we are not a directory wildcard, we
            // can't go past a path seperator.

            var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength);

            for (int i = currentPosition; i <= maxPos; i++)
            {
                var currentChar = allChars[i];
                if (currentChar == '/' || currentChar == '\\')
                {
                    return(false);
                }

                //int newSubPosition;
                var isMatch = _subEvaluator.IsMatch(allChars, i, out newPosition);
                if (isMatch)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #3
0
        public bool IsMatch(string text)
        {
            int finalPosition = 0;
            var matched       = _rootTokenEvaluator.IsMatch(text, 0, out finalPosition);

            return(matched);
        }
Exemple #4
0
        public bool IsMatch(string allChars, int currentPosition, out int newPosition)
        {
            newPosition = currentPosition;


            if (!_requiresSubEvaluation) // We are the last token in the pattern
            {
                // If we have reached the end of the string, then we match.
                if (currentPosition >= allChars.Length)
                {
                    return(true);
                }

                // We dont match if the remaining string has seperators.
                for (int i = currentPosition; i <= allChars.Length - 1; i++)
                {
                    var currentChar = allChars[i];
                    if (currentChar == '/' || currentChar == '\\')
                    {
                        return(false);
                    }
                }

                // we have matched upto the new position.
                newPosition = currentPosition + allChars.Length;
                return(true);
            }

            // We are not the last token in the pattern, and so the _subEvaluator representing the remaining pattern tokens must also match.
            // Does the sub pattern match a fixed length string, or variable length string?
            if (!_subEvaluator.ConsumesVariableLength)
            {
                // The remaining tokens match against a fixed length string, so we can infer that this wildcard **must** match
                // a fixed amount of characters in order for the subevaluator to match its fixed amount of characters from the remaining portion
                // of the string.
                // So we must match upto that position. We can't match seperators.
                var requiredMatchPosition = allChars.Length - _subEvaluator.ConsumesMinLength;
                //if (requiredMatchPosition < currentPosition)
                //{
                //    return false;
                //}
                for (int i = currentPosition; i < requiredMatchPosition; i++)
                {
                    var currentChar = allChars[i];
                    if (currentChar == '/' || currentChar == '\\')
                    {
                        return(false);
                    }
                }
                var isMatch = _subEvaluator.IsMatch(allChars, requiredMatchPosition, out newPosition);
                return(isMatch);
            }

            // Sub pattern matches a variable length string.
            // if we are at the end of the string, we match!
            //if (currentPosition >= allChars.Length)
            //{
            //    return true;
            //}
            // otherwise we can consume a variable amount of characters but we can't match more characters than the amount that will take
            // us past the min required length required by the sub evaluator tokens, and as we are not a directory wildcard, we
            // can't go past a path seperator.

            var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength);

            for (int i = currentPosition; i <= maxPos; i++)
            {
                var currentChar = allChars[i];



                //int newSubPosition;
                var isMatch = _subEvaluator.IsMatch(allChars, i, out newPosition);
                if (isMatch)
                {
                    return(true);
                }

                if (currentChar == '/' || currentChar == '\\')
                {
                    return(false);
                }
            }

            return(false);
        }
Exemple #5
0
        public bool IsMatch(string allChars, int currentPosition, out int newPosition)
        {
            // We shortcut to success for a ** in some special cases:-
            //  1. We are already at the end of the test string.
            //  2. The ** token is the last token - in which case it will math all remaining text

            // We shortcut to failure for a ** in some special cases:-
            // A) The token was parsed with a leading seperator (i.e '/**' and the current charater we are matching from doesn't match that seperator.

            newPosition = currentPosition;

            // 1. Are we already at the end of the test string?
            if (currentPosition >= allChars.Length)
            {
                return(true);
            }

            // A) If leading seperator then current character needs to be that seperator.
            var currentChar = allChars[currentPosition];

            if (this._token.LeadingPathSeperator != null)
            {
                if (currentChar != this._token.LeadingPathSeperator.Value)
                {
                    // expected seperator.
                    return(false);
                }
                // advance current position to match the leading seperator.
                currentPosition = currentPosition + 1;
            }

            // 2. if no more tokens require matching (i.e ** is the last token) - we match.
            if (this._subEvaluator.EvaluatorCount == 0)
            {
                newPosition = allChars.Length;
                return(true);
            }

            // Because we know we have more tokens in the pattern (subevaluators) - those will require a minimum amount of characters to match (could be 0 too).
            // We can therefore calculate a "max" character position that we can match to, as if we exceed that position the remaining tokens cant possibly match.
            var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength);

            // If all of the remaining tokens have a precise length, we can calculate the exact character that we need to macth to in the string.
            // Otherwise we have to test at multiple character positions until we find a match (less efficient)
            if (!_subEvaluator.ConsumesVariableLength)
            {
                // Fixed length.
                // As we can only match full segments, make sure character before chacracter at max pos is a seperator,

                var mustMatchUntilChar = allChars[maxPos - 1];
                if (mustMatchUntilChar != '/' && mustMatchUntilChar != '\\')
                {
                    // can only match full segments.
                    return(false);
                }

                // Advance position to max pos.
                currentPosition = maxPos;
                return(_subEvaluator.IsMatch(allChars, currentPosition, out newPosition));
            }
            else
            {
                // Remaining tokens match a variable length of the test string.
                // We iterate each position (within acceptable range) and test at each position.
                bool isMatch;

                currentChar = allChars[currentPosition];

                // If the ** token was parsed with a trailing slash - i.e "**/" then we need to match past it before we test remainijng tokens.
                if (_token.TrailingPathSeperator != null)
                {
                    if (currentChar == '/' || currentChar == '\\')
                    {
                        // match the seperator.
                        currentPosition = currentPosition + 1;
                    }
                }

                // Match until maxpos, is reached.
                while (currentPosition <= maxPos)
                {
                    // Test at current position.
                    isMatch = _subEvaluator.IsMatch(allChars, currentPosition, out newPosition);
                    if (isMatch)
                    {
                        return(isMatch);
                    }

                    if (currentPosition == maxPos)
                    {
                        return(false);
                    }

                    // Iterate until we hit a seperator or maxPos.
                    while (currentPosition < maxPos)
                    {
                        currentPosition = currentPosition + 1;
                        currentChar     = allChars[currentPosition];
                        if (currentChar == '/' || currentChar == '\\')
                        {
                            // advance past the seperator.
                            currentPosition = currentPosition + 1;
                            break;
                        }
                    }
                }
            }

            return(false);
        }
        public bool IsMatch(string allChars, int currentPosition, out int newPosition)
#endif
        {
            // We shortcut to success for a ** in some special cases:-
            //  1. The remaining tokens don't need to consume a minimum number of chracters in order to match.

            // We shortcut to failure for a ** in some special cases:-
            // A) The token was parsed with a leading path separator (i.e '/**' and the current charater we are matching from isn't a path separator.

            newPosition = currentPosition;

            // A) If leading seperator then current character needs to be that seperator.
            char currentChar = allChars[currentPosition];

            if (_token.LeadingPathSeparator != null)
            {
                if (!GlobStringReader.IsPathSeparator(currentChar))
                {
                    // expected separator.
                    return(false);
                }
                //else
                //{
                // advance current position to match the leading separator.
                currentPosition = currentPosition + 1;
                //}
            }
            else
            {
                // no leading seperator, means ** used at start of pattern not /** used within pattern.
                // If **/ is used for start of pattern then input string doesn't need to start with a / or \ and it will be matched.
                // i.e **/foo/bar will match foo/bar or /foo/bar.
                //     where as /**/foo/bar will not match foo/bar it will only match /foo/bar.
                currentChar = allChars[currentPosition];
                if (GlobStringReader.IsPathSeparator(currentChar))
                {
                    // advance current position to match the leading separator.
                    currentPosition = currentPosition + 1;
                }
            }

            // 1. if no more tokens require matching we match.
            if (_subEvaluator.ConsumesMinLength == 0)
            {
                newPosition = allChars.Length;
                return(true);
            }

            // Because we know we have more tokens in the pattern (subevaluators) - those will require a minimum amount of characters to match (could be 0 too).
            // We can therefore calculate a "max" character position that we can match to, as if we exceed that position the remaining tokens cant possibly match.
            int maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength);

            // If all of the remaining tokens have a precise length, we can calculate the exact character that we need to macth to in the string.
            // Otherwise we have to test at multiple character positions until we find a match (less efficient)
            if (!_subEvaluator.ConsumesVariableLength)
            {
                // Fixed length.
                // As we can only match full segments, make sure character before chacracter at max pos is a separator,
                if (maxPos > 0)
                {
                    char mustMatchUntilChar = allChars[maxPos - 1];
                    if (!GlobStringReader.IsPathSeparator(mustMatchUntilChar))
                    {
                        // can only match full segments.
                        return(false);
                    }
                }

                // Advance position to max pos.
                currentPosition = maxPos;
                return(_subEvaluator.IsMatch(allChars, currentPosition, out newPosition));
            }
            else
            {
                // Remaining tokens match a variable length of the test string.
                // We iterate each position (within acceptable range) and test at each position.
                bool isMatch;

                currentChar = allChars[currentPosition];

                // If the ** token was parsed with a trailing slash - i.e "**/" then we need to match past it before we test remainijng tokens.
                // special exception if **/ is at start of pattern, as then the input string need not have any path separators.
                if (_token.TrailingPathSeparator != null)
                {
                    if (GlobStringReader.IsPathSeparator(currentChar))
                    {
                        // match the separator.
                        currentPosition = currentPosition + 1;
                    }
                }

                // Match until maxpos, is reached.
                while (currentPosition <= maxPos)
                {
                    // Test at current position.
                    isMatch = _subEvaluator.IsMatch(allChars, currentPosition, out newPosition);
                    if (isMatch)
                    {
                        return(isMatch);
                    }

                    if (currentPosition == maxPos)
                    {
                        return(false);
                    }

                    // Iterate until we hit a separator or maxPos.
                    while (currentPosition < maxPos)
                    {
                        currentPosition = currentPosition + 1;
                        currentChar     = allChars[currentPosition];

                        if (GlobStringReader.IsPathSeparator(currentChar))
                        {
                            // match the separator.
                            currentPosition = currentPosition + 1;
                            break;
                        }
                    }
                }
            }

            return(false);
        }
Exemple #7
0
        public bool IsMatch(string allChars, int currentPosition, out int newPosition)
        {
            newPosition = currentPosition;
            //if (!_subEvaluator.ConsumesVariableLength)


            // if we are at the end of the string, we match!
            if (currentPosition >= allChars.Length)
            {
                return(true);
            }


            // The max pos we can match upto in the string, because of subtoken match requirements.
            var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength);

            // we can only match full segments at a time, where as match pos could point to a char in the middle of a segment.

            if (!_subEvaluator.ConsumesVariableLength)
            {
                // must match a fixed length of the string (must match all to max pos), but we can only match entire segments,
                // so for a successful match, the char before maxpos must either be current pos (we match nothing), or a seperator.
                if (maxPos - 1 != currentPosition)
                {
                    var precedingchar = allChars[maxPos - 1];
                    if (precedingchar != '/' && precedingchar != '\\')
                    {
                        return(false);
                    }
                }

                return(_subEvaluator.IsMatch(allChars, maxPos, out newPosition));
            }
            else
            {
                // can match a variable length, but in compelte segments at a time, not past max pos.

                int pos = currentPosition;

                bool isMatch;

                var currentChar = allChars[pos];

                var isSeprator = currentChar == '/' || currentChar == '\\';

                if (this._token.LeadingPathSeperator != null && !isSeprator)
                {
                    // must begin with seperator.
                    return(false);
                }

                if (currentChar == '/' || currentChar == '\\')
                {
                    if (pos == maxPos)
                    {
                        return(false);
                    }
                    pos = pos + 1;
                }


                while (pos <= maxPos)
                {
                    isMatch = _subEvaluator.IsMatch(allChars, pos, out newPosition);
                    if (isMatch)
                    {
                        return(isMatch);
                    }

                    currentChar = allChars[pos];
                    while (currentChar != '/' && currentChar != '\\' && pos + 1 < maxPos)
                    {
                        pos         = pos + 1;
                        currentChar = allChars[pos];
                    }

                    pos = pos + 1;
                }
            }

            return(false);
        }