Exemplo n.º 1
0
        private static StringSlice ParseString(ref StringSlice text)
        {
            ConsumeWhitespace(ref text);
            if (text.Length == 0)
            {
                throw new QueryParseException("string", text);
            }

            char start = text[0];

            if (start == '\'' || start == '"')
            {
                char terminator = start;

                // Keep a StringBuilder for unescaping (only if needed) and track what we've copied to it already
                StringBuilder unescapedForm = null;
                int           nextCopyFrom  = 1;

                int terminatorIndex = 1;
                for (; terminatorIndex < text.Length - 1; ++terminatorIndex)
                {
                    if (text[terminatorIndex] == terminator)
                    {
                        // If this wasn't a doubled quote, the string is done
                        if (text[terminatorIndex + 1] != terminator)
                        {
                            break;
                        }

                        // Copy to the StringBuilder without either quote
                        if (unescapedForm == null)
                        {
                            unescapedForm = new StringBuilder();
                        }
                        text.Substring(nextCopyFrom, terminatorIndex - nextCopyFrom).AppendTo(unescapedForm);

                        // Include the second quote next time
                        nextCopyFrom = terminatorIndex + 1;

                        // Skip to look after the second quote next iteration
                        terminatorIndex += 1;
                    }
                }

                // Ensure the string is terminated
                if (terminatorIndex == text.Length || text[terminatorIndex] != terminator)
                {
                    throw new QueryParseException("string terminator", text);
                }

                if (unescapedForm != null)
                {
                    if (nextCopyFrom < terminatorIndex)
                    {
                        text.Substring(nextCopyFrom, terminatorIndex - nextCopyFrom).AppendTo(unescapedForm);
                    }
                    text = text.Substring(terminatorIndex + 1);
                    return(unescapedForm.ToString());
                }
                else
                {
                    StringSlice resultSlice = text.Substring(1, terminatorIndex - 1);
                    text = text.Substring(terminatorIndex + 1);
                    return(resultSlice);
                }
            }
            else
            {
                // Read until whitespace or ')' (so closing a subexpression doesn't require a space)
                int terminatorIndex = 0;
                for (; terminatorIndex < text.Length; ++terminatorIndex)
                {
                    char c = text[terminatorIndex];
                    if (c == ')' || IsWhitespace(c))
                    {
                        break;
                    }
                }

                // Consume and return the string
                StringSlice result = text.Substring(0, terminatorIndex);
                text = text.Substring(terminatorIndex);
                return(result);
            }
        }
Exemplo n.º 2
0
 public Literal(StringSlice text, T value)
 {
     Text  = text;
     Value = value;
 }
Exemplo n.º 3
0
 internal QueryParseException(string categoryExpected, StringSlice text)
     : this($"Expected {categoryExpected} but found {(text.Length == 0 ? "<End>" : text)}")
 {
 }