public int LastIndexOf(IStringView other, StringComparison sc = StringComparison.Ordinal)
        {
            if (length < other.length)
            {
                return(-1);
            }

            int otherIndex = other.length - 1;

            for (var i = length - 1; i >= 0 && otherIndex >= 0; --i)
            {
                if (!StringView.Compare(this[i], other[otherIndex], sc))
                {
                    otherIndex = other.length - 1;
                }
                else
                {
                    if (otherIndex == 0)
                    {
                        return(i);
                    }
                    otherIndex--;
                }
            }

            return(-1);
        }
        public int IndexOf(StringView other, StringComparison sc = StringComparison.Ordinal)
        {
            if (Length < other.Length)
            {
                return(-1);
            }

            int foundStartIndex = -1;
            int otherIndex      = 0;

            for (var i = 0; i < Length && otherIndex < other.Length; ++i)
            {
                if (!Compare(this[i], other[otherIndex], sc))
                {
                    if (foundStartIndex > -1)
                    {
                        foundStartIndex = -1;
                        otherIndex      = 0;
                    }
                }
                else
                {
                    if (foundStartIndex == -1)
                    {
                        foundStartIndex = i;
                    }
                    otherIndex++;
                }
            }

            return(foundStartIndex);
        }
Esempio n. 3
0
        static int LastIndexOf(StringView source, StringView other, StringComparison sc)
        {
            if (source.Length < other.Length)
            {
                return(-1);
            }

            int otherIndex = other.Length - 1;

            for (var i = source.Length - 1; i >= 0 && otherIndex >= 0; --i)
            {
                if (!Compare(source[i], other[otherIndex], sc))
                {
                    otherIndex = other.Length - 1;
                }
                else
                {
                    if (otherIndex == 0)
                    {
                        return(i);
                    }
                    otherIndex--;
                }
            }

            return(-1);
        }
 public bool EndsWith(char c, StringComparison sc = StringComparison.Ordinal)
 {
     if (length == 0)
     {
         return(false);
     }
     return(StringView.Compare(this[length - 1], c, sc));
 }
 public static bool IsNullOrEmpty(this StringView sv)
 {
     if (sv == null || !sv.valid)
     {
         return(true);
     }
     return(sv.Length == 0);
 }
 public bool StartsWith(char c, StringComparison stringComparison = StringComparison.Ordinal)
 {
     if (length == 0)
     {
         return(false);
     }
     return(StringView.Compare(this[0], c, stringComparison));
 }
        public bool Equals(StringView other, StringComparison comparisonOptions = StringComparison.OrdinalIgnoreCase)
        {
            if (other.Length != Length)
            {
                return(false);
            }

            return(string.Compare(m_BaseString, m_StartIndex, other.m_BaseString, other.m_StartIndex, Length, comparisonOptions) == 0);
        }
        internal static SearchExpression SelectorParser(StringView outerText)
        {
            var text = ParserUtils.SimplifyExpression(outerText);

            if (!s_SelectorPattern.IsMatch(text.ToString()))
            {
                return(null);
            }
            return(new SearchExpression(SearchExpressionType.Selector, outerText, text.Substring(1), s_SelectorEvaluator));
        }
        internal static SearchExpression BooleanParser(StringView text)
        {
            var trimmedText = ParserUtils.SimplifyExpression(text);

            if (!bool.TryParse(trimmedText.ToString(), out _))
            {
                return(null);
            }
            return(new SearchExpression(SearchExpressionType.Boolean, text, trimmedText, ConstantEvaluator));
        }
Esempio n. 10
0
 internal SearchExpression(SearchExpressionType types,
                           StringView outerText, StringView innerText, StringView alias,
                           SearchExpressionEvaluator evaluator, SearchExpression[] parameters)
 {
     this.types      = types;
     this.outerText  = outerText;
     this.innerText  = innerText.valid ? innerText : outerText;
     this.alias      = alias;
     this.parameters = parameters ?? new SearchExpression[0];
     this.evaluator  = evaluator;
 }
 public bool Contains(char c, StringComparison ordinal = StringComparison.Ordinal)
 {
     for (var i = 0; i < length; ++i)
     {
         if (StringView.Compare(this[i], c, ordinal))
         {
             return(true);
         }
     }
     return(false);
 }
Esempio n. 12
0
 public void ThrowError(string message, StringView errorPosition)
 {
     if (!errorPosition.IsNullOrEmpty())
     {
         throw new SearchExpressionEvaluatorException(message, errorPosition, this);
     }
     else
     {
         throw new SearchExpressionEvaluatorException(message, expression.outerText, this);
     }
 }
        public static bool HasQuotes(StringView sv)
        {
            if (sv.length < 2)
            {
                return(false);
            }
            var c = sv[0];

            if (!IsQuote(c))
            {
                return(false);
            }
            return(c == sv.Last());
        }
 public static bool IsNullOrWhiteSpace(this StringView sv)
 {
     if (sv.IsNullOrEmpty())
     {
         return(true);
     }
     for (var i = 0; i < sv.Length; ++i)
     {
         if (!char.IsWhiteSpace(sv[i]))
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 15
0
        static int LastIndexOf(StringView source, char other, StringComparison sc)
        {
            if (!source.valid)
            {
                return(-1);
            }

            for (var i = source.Length - 1; i >= 0; --i)
            {
                if (Compare(source[i], other, sc))
                {
                    return(i);
                }
            }

            return(-1);
        }
        public bool StartsWith(string v, StringComparison sc = StringComparison.Ordinal)
        {
            if (v.Length > length)
            {
                return(false);
            }

            for (var i = 0; i < v.Length; ++i)
            {
                if (!StringView.Compare(this[i], v[i], sc))
                {
                    return(false);
                }
            }

            return(true);
        }
        public bool EndsWith(IStringView v, StringComparison sc = StringComparison.Ordinal)
        {
            if (v.length > length)
            {
                return(false);
            }

            for (var i = 0; i < v.length; ++i)
            {
                if (!StringView.Compare(this[length - v.length + i], v[i], sc))
                {
                    return(false);
                }
            }

            return(true);
        }
        private static SearchExpressionEvaluator GetEvaluatorByName(string name, StringView errorView, bool duringParsing, SearchExpressionContext context = default)
        {
            var evaluator = FindEvaluatorByName(name);

            if (!evaluator.valid)
            {
                if (duringParsing)
                {
                    throw new SearchExpressionParseException(GetEvaluatorNameExceptionMessage(name), errorView.startIndex, errorView.Length);
                }
                else
                {
                    context.ThrowError(GetEvaluatorNameExceptionMessage(name), errorView);
                }
            }
            return(evaluator);
        }
        static int IndexOf(SubsetStringView source, char other, StringComparison sc)
        {
            if (!source.valid)
            {
                return(-1);
            }

            for (var i = 0; i < source.length; ++i)
            {
                if (StringView.Compare(source[i], other, sc))
                {
                    return(i);
                }
            }

            return(-1);
        }
        internal static SearchExpression NumberParser(StringView outerText)
        {
            var trimmedText = ParserUtils.SimplifyExpression(outerText);

            if (!Utils.TryParse(trimmedText.ToString(), out double _))
            {
                return(null);
            }

            SearchExpressionType types = SearchExpressionType.Number;

            if (trimmedText == "0" || trimmedText == "1")
            {
                types |= SearchExpressionType.Boolean;
            }
            return(new SearchExpression(types, outerText, trimmedText, ConstantEvaluator));
        }
Esempio n. 21
0
        static bool EndsWith(StringView source, StringView other, StringComparison sc)
        {
            if (other.Length > source.Length)
            {
                return(false);
            }

            for (var i = 0; i < other.Length; ++i)
            {
                if (!Compare(source[source.Length - other.Length + i], other[i], sc))
                {
                    return(false);
                }
            }

            return(true);
        }
        public bool Equals(SubsetStringView other, StringComparison comparisonOptions = StringComparison.OrdinalIgnoreCase)
        {
            if (other.length != length)
            {
                return(false);
            }

            for (var i = 0; i < length; ++i)
            {
                if (!StringView.Compare(this[i], other[i], comparisonOptions))
                {
                    return(false);
                }
            }

            return(true);
        }
        public static void ValidateExpressionArguments(SearchExpressionEvaluator evaluator, SearchExpression[] args, IEnumerable <Signature> signatures, StringView expressionInnerText)
        {
            // First pass to get all valid argument number signatures (must do a ToList to separate the 2 passes)
            // Second pass to validate the argument types. The last error is kept (lowest number of arguments if no signature matches the number of argument, wrong type if there is at least one)
            var lastError     = "";
            var errorPosition = StringView.Null;

            if (signatures.Where(s => ValidateExpressionArgumentsCount(evaluator.name, args, s, (msg, errorPos) => { lastError = msg; errorPosition = errorPos; })).ToList()
                .Any(s => ValidateExpressionArguments(evaluator.name, args, s, (msg, errorPos) => { lastError = msg; errorPosition = errorPos; })))
            {
                return;
            }

            if (!errorPosition.valid)
            {
                errorPosition = expressionInnerText;
            }
            throw new SearchExpressionParseException($"Syntax error: {lastError}", errorPosition.startIndex, errorPosition.Length);
        }
Esempio n. 24
0
        static int IndexOf(StringView source, StringView other, StringComparison sc)
        {
            if (!source.valid || !other.valid)
            {
                return(-1);
            }
            if (source.Length < other.Length)
            {
                return(-1);
            }

            int foundStartIndex = -1;
            int otherIndex      = 0;

            for (var i = 0; i < source.Length && otherIndex < other.Length; ++i)
            {
                if (!Compare(source[i], other[otherIndex], sc))
                {
                    if (foundStartIndex > -1)
                    {
                        foundStartIndex = -1;
                        otherIndex      = 0;
                    }
                }
                else
                {
                    if (foundStartIndex == -1)
                    {
                        foundStartIndex = i;
                    }
                    otherIndex++;
                }
            }

            if (otherIndex != other.Length)
            {
                return(-1);
            }
            return(foundStartIndex);
        }
        public int IndexOf(IStringView other, StringComparison sc = StringComparison.Ordinal)
        {
            if (!valid || !other.valid)
            {
                return(-1);
            }
            if (length < other.length)
            {
                return(-1);
            }

            int foundStartIndex = -1;
            int otherIndex      = 0;

            for (var i = 0; i < length && otherIndex < other.length; ++i)
            {
                if (!StringView.Compare(this[i], other[otherIndex], sc))
                {
                    if (foundStartIndex > -1)
                    {
                        foundStartIndex = -1;
                        otherIndex      = 0;
                    }
                }
                else
                {
                    if (foundStartIndex == -1)
                    {
                        foundStartIndex = i;
                    }
                    otherIndex++;
                }
            }

            if (otherIndex != other.length)
            {
                return(-1);
            }
            return(foundStartIndex);
        }
Esempio n. 26
0
        public static string ReplaceMarkersWithRawValues(StringView text, out QueryMarker[] markers)
        {
            markers = ParseAllMarkers(text);
            if (markers == null || markers.Length == 0)
            {
                return(text.ToString());
            }

            var modifiedSv = text.GetSubsetStringView();

            foreach (var queryMarker in markers)
            {
                if (!queryMarker.valid || queryMarker.args == null || queryMarker.args.Length == 0)
                {
                    continue;
                }
                var valueArg = queryMarker.args[0];
                modifiedSv.ReplaceWithSubset(queryMarker.text.startIndex, queryMarker.text.endIndex, valueArg.rawText.startIndex, valueArg.rawText.endIndex);
            }

            return(modifiedSv.ToString());
        }
 internal SearchExpressionParserArgs With(StringView newText, SearchExpressionParserFlags optionsToAdd = SearchExpressionParserFlags.None)
 {
     return(new SearchExpressionParserArgs(newText, context, options | optionsToAdd));
 }
 public SearchExpressionParserArgs(StringView text, SearchContext context = null, SearchExpressionParserFlags options = SearchExpressionParserFlags.Default)
 {
     this.text    = text.Trim();
     this.context = context;
     this.options = options;
 }
        public static StringView SimplifyExpression(StringView outerText, bool trimLastWhiteSpaces = true)
        {
            // First we look for the closers that could be trimmed
            Stack <int> nestedLevelsEnd   = new Stack <int>();
            Stack <int> nestedLevelsStart = new Stack <int>();

            for (int i = outerText.length - 1; i >= 0; --i)
            {
                if (char.IsWhiteSpace(outerText[i]))
                {
                    continue;
                }
                if (outerText[i] == '}')
                {
                    nestedLevelsEnd.Push(i);
                    continue;
                }
                break;
            }
            // Then we parse the string to check how many we can trim
            bool hasTrimmedText = false;

            if (nestedLevelsEnd.Any())
            {
                bool inNonTrimmableText  = false;
                int  nonTrimmableOpeners = 0;
                bool isInString          = false;
                for (int i = 0; i < outerText.length; ++i)
                {
                    if (char.IsWhiteSpace(outerText[i]))
                    {
                        continue;
                    }
                    if (k_Quotes.Contains(outerText[i]))
                    {
                        isInString = !isInString;
                    }
                    if (isInString)
                    {
                        continue;
                    }
                    if (outerText[i] == '{')
                    {
                        nestedLevelsStart.Push(i);
                        // if part can't be trimmed we must not keep the { so we keep track of how many
                        if (inNonTrimmableText)
                        {
                            ++nonTrimmableOpeners;
                        }
                        continue;
                    }
                    if (!nestedLevelsStart.Any() || !nestedLevelsEnd.Any())
                    {
                        break;
                    }
                    if (outerText[i] == '}')
                    {
                        if (nonTrimmableOpeners == 0 && i == nestedLevelsEnd.Peek() && nestedLevelsStart.Count == nestedLevelsEnd.Count)
                        {
                            hasTrimmedText = true;
                            break;
                        }
                        nestedLevelsStart.Pop();
                        if (i == nestedLevelsEnd.Peek())
                        {
                            nestedLevelsEnd.Pop();
                        }
                        // In that case that means there was one expression that was closed and no more remaining so we should exit
                        if (!nestedLevelsStart.Any())
                        {
                            break;
                        }
                        if (inNonTrimmableText && nonTrimmableOpeners > 0)
                        {
                            --nonTrimmableOpeners;
                        }
                    }
                    // if we find other characters that means that part can't be trimmed, in that case we must not keep the next { we might find
                    inNonTrimmableText = true;
                }
            }
            var result = outerText;

            if (hasTrimmedText)
            {
                int start  = nestedLevelsStart.Peek() + 1;
                int length = nestedLevelsEnd.Peek() - start;
                result = outerText.Substring(start, length);
            }
            return(trimLastWhiteSpaces ? result.Trim() : result);
        }
        public static StringView[] GetExpressionsStartAndLength(StringView text, out bool rootHasParameters)
        {
            rootHasParameters = false;
            var openersStack            = new Stack <char>();
            var expressions             = new List <StringView>();
            int firstOpenerIndex        = -1;
            int currentStringTokenIndex = -1;

            for (int i = 0; i < text.length; ++i)
            {
                if (text[i] == ' ')
                {
                    continue;
                }

                // In case of a string, we must find the end of the string before checking any nested levels or ,
                if (k_Quotes.Any(c => c == text[i]))
                {
                    if (currentStringTokenIndex == -1)
                    {
                        currentStringTokenIndex = i;
                    }
                    else if (text[currentStringTokenIndex] != text[i])
                    {
                        throw new SearchExpressionParseException($"Nested strings are not allowed, \"{text[i]}\" found instead of \"{text[currentStringTokenIndex]}\" in \"{text.Substring(currentStringTokenIndex, i + 1 - currentStringTokenIndex)}\"", text.startIndex + currentStringTokenIndex, i - currentStringTokenIndex + 1);
                    }
                    else
                    {
                        currentStringTokenIndex = -1;
                    }
                }
                if (currentStringTokenIndex != -1) // is in string
                {
                    continue;
                }

                if (k_Openers.Any(c => c == text[i]))
                {
                    if (openersStack.Count == 0)
                    {
                        firstOpenerIndex = i;
                    }
                    openersStack.Push(text[i]);
                    continue;
                }

                if (k_Closers.Any(c => c == text[i]))
                {
                    if (openersStack.Count == 0)
                    {
                        throw new SearchExpressionParseException($"Extra \"{text[i]}\" found", text.startIndex + i, 1);
                    }
                    if (CharMatchOpener(openersStack.Peek(), text[i]))
                    {
                        openersStack.Pop();
                        // We found the final closer, that means we found the end of the expression
                        if (openersStack.Count == 0)
                        {
                            expressions.Add(text.Substring(firstOpenerIndex, i - firstOpenerIndex + 1));
                        }
                        continue;
                    }
                    else
                    {
                        throw new SearchExpressionParseException($"Missing \"{GetCorrespondingCloser(openersStack.Peek())}\" in \"{text.Substring(0, i + 1)}\"", text.startIndex + firstOpenerIndex, i - firstOpenerIndex + 1);
                    }
                }

                if (openersStack.Count == 0 && text[i] == ',')
                {
                    rootHasParameters = true;
                }
            }
            if (currentStringTokenIndex != -1)
            {
                throw new SearchExpressionParseException($"The string \"{text.Substring(currentStringTokenIndex)}\" is not closed correctly", text.startIndex + currentStringTokenIndex, text.length - currentStringTokenIndex);
            }
            if (openersStack.Any())
            {
                throw new SearchExpressionParseException($"Missing \"{GetCorrespondingCloser(openersStack.Peek())}\" in \"{text}\"", text.startIndex + firstOpenerIndex, text.length - firstOpenerIndex);
            }
            return(expressions.ToArray());
        }