Beispiel #1
0
        // return JObject, JArray, jendarray indicating end array if inarray is set, string, long, ulong, bigint, true, false, JNull
        // null if unhappy

        static private JToken DecodeValue(IStringParserQuick parser, char[] textbuffer, bool inarray)
        {
            //System.Diagnostics.Debug.WriteLine("Decode at " + p.LineLeft);
            char next = parser.GetChar();

            switch (next)
            {
            case '{':
                parser.SkipSpace();
                return(new JObject());

            case '[':
                parser.SkipSpace();
                return(new JArray());

            case '"':
                int textlen = parser.NextQuotedString(next, textbuffer, true);
                return(textlen >= 0 ? new JToken(TType.String, new string(textbuffer, 0, textlen)) : null);

            case ']':
                if (inarray)
                {
                    parser.SkipSpace();
                    return(jendarray);
                }
                else
                {
                    return(null);
                }

            case '0':           // all positive. JSON does not allow a + at the start (integer fraction exponent)
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                parser.BackUp();
                return(parser.JNextNumber(false));

            case '-':
                return(parser.JNextNumber(true));

            case 't':
                return(parser.IsStringMoveOn("rue") ? new JToken(TType.Boolean, true) : null);

            case 'f':
                return(parser.IsStringMoveOn("alse") ? new JToken(TType.Boolean, false) : null);

            case 'n':
                return(parser.IsStringMoveOn("ull") ? new JToken(TType.Null) : null);

            default:
                return(null);
            }
        }
        private static IEnumerable <JToken> ParseTokenInt(IStringParserQuick parser, JToken.ParseOptions flags = JToken.ParseOptions.None, int maxstringlen = 16384)
        {
            char[]   textbuffer = new char[maxstringlen];
            JToken[] stack      = new JToken[256];
            int      sptr       = 0;
            bool     comma      = false;
            JArray   curarray   = null;
            JObject  curobject  = null;

            {
                parser.SkipSpace();

                JToken o = DecodeValue(parser, textbuffer, false);       // grab new value, not array end

                if (o == null)
                {
                    throw new TokenException(GenErrorString(parser, "No Obj/Array"));
                }
                else if (o.TokenType == JToken.TType.Array)
                {
                    stack[++sptr] = o;                      // push this one onto stack
                    curarray      = o as JArray;            // this is now the current array
                    yield return(o);
                }
                else if (o.TokenType == JToken.TType.Object)
                {
                    stack[++sptr] = o;                      // push this one onto stack
                    curobject     = o as JObject;           // this is now the current object
                    yield return(o);
                }
                else
                {
                    yield return(o);                               // value only

                    yield break;
                }
            }

            while (true)
            {
                if (curobject != null)      // if object..
                {
                    while (true)
                    {
                        char next = parser.GetChar();

                        if (next == '}')    // end object
                        {
                            parser.SkipSpace();

                            if (comma == true && (flags & JToken.ParseOptions.AllowTrailingCommas) == 0)
                            {
                                throw new TokenException(GenErrorString(parser, "Comma"));
                            }
                            else
                            {
                                yield return(new JToken(JToken.TType.EndObject));

                                JToken prevtoken = stack[--sptr];
                                if (prevtoken == null)      // if popped stack is null, we are back to beginning, return this
                                {
                                    yield break;
                                }
                                else
                                {
                                    comma     = parser.IsCharMoveOn(',');
                                    curobject = prevtoken as JObject;
                                    if (curobject == null)
                                    {
                                        curarray = prevtoken as JArray;
                                        break;
                                    }
                                }
                            }
                        }
                        else if (next == '"')   // property name
                        {
                            int textlen = parser.NextQuotedString(next, textbuffer, true);

                            if (textlen < 1 || (comma == false && curobject.Count > 0) || !parser.IsCharMoveOn(':'))
                            {
                                throw new TokenException(GenErrorString(parser, "Object missing property name"));
                            }
                            else
                            {
                                string name = new string(textbuffer, 0, textlen);

                                JToken o = DecodeValue(parser, textbuffer, false);      // get value

                                if (o == null)
                                {
                                    throw new TokenException(GenErrorString(parser, "Object bad value"));
                                }

                                o.Name = name;

                                yield return(o);

                                if (o.TokenType == JToken.TType.Array) // if array, we need to change to this as controlling object on top of stack
                                {
                                    if (sptr == stack.Length - 1)
                                    {
                                        throw new TokenException(GenErrorString(parser, "Stack overflow"));
                                    }

                                    stack[++sptr] = o;           // push this one onto stack
                                    curarray      = o as JArray; // this is now the current object
                                    curobject     = null;
                                    comma         = false;
                                    break;
                                }
                                else if (o.TokenType == JToken.TType.Object)   // if object, this is the controlling object
                                {
                                    if (sptr == stack.Length - 1)
                                    {
                                        throw new TokenException(GenErrorString(parser, "Stack overflow"));
                                    }

                                    stack[++sptr] = o;            // push this one onto stack
                                    curobject     = o as JObject; // this is now the current object
                                    comma         = false;
                                }
                                else
                                {
                                    comma = parser.IsCharMoveOn(',');
                                }
                            }
                        }
                        else
                        {
                            throw new TokenException(GenErrorString(parser, "Bad format in object"));
                        }
                    }
                }
                else
                {
                    while (true)
                    {
                        JToken o = DecodeValue(parser, textbuffer, true);       // grab new value

                        if (o == null)
                        {
                            throw new TokenException(GenErrorString(parser, "Bad array value"));
                        }
                        else if (o.TokenType == JToken.TType.EndArray)          // if end marker, jump back
                        {
                            if (comma == true && (flags & JToken.ParseOptions.AllowTrailingCommas) == 0)
                            {
                                throw new TokenException(GenErrorString(parser, "Comma"));
                            }
                            else
                            {
                                yield return(new JToken(JToken.TType.EndArray));

                                JToken prevtoken = stack[--sptr];
                                if (prevtoken == null)      // if popped stack is null, we are back to beginning, return this
                                {
                                    yield break;
                                }
                                else
                                {
                                    comma     = parser.IsCharMoveOn(',');
                                    curobject = prevtoken as JObject;
                                    if (curobject == null)
                                    {
                                        curarray = prevtoken as JArray;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        else if ((comma == false && curarray.Count > 0))   // missing comma
                        {
                            throw new TokenException(GenErrorString(parser, "Comma"));
                        }
                        else
                        {
                            yield return(o);

                            if (o.TokenType == JToken.TType.Array) // if array, we need to change to this as controlling object on top of stack
                            {
                                if (sptr == stack.Length - 1)
                                {
                                    throw new TokenException(GenErrorString(parser, "Stack overflow"));
                                }

                                stack[++sptr] = o;              // push this one onto stack
                                curarray      = o as JArray;    // this is now the current array
                                comma         = false;
                            }
                            else if (o.TokenType == JToken.TType.Object) // if object, this is the controlling object
                            {
                                if (sptr == stack.Length - 1)
                                {
                                    throw new TokenException(GenErrorString(parser, "Stack overflow"));
                                }

                                stack[++sptr] = o;              // push this one onto stack
                                curobject     = o as JObject;   // this is now the current object
                                curarray      = null;
                                comma         = false;
                                break;
                            }
                            else
                            {
                                comma = parser.IsCharMoveOn(',');
                            }
                        }
                    }
                }
            }
        }
Beispiel #3
0
        // internal parse, does not check EOL
        private static JToken IntParse(IStringParserQuick parser, out string error, ParseOptions flags, char[] textbuffer)
        {
            error = null;

            JToken[] stack     = new JToken[256];
            int      sptr      = 0;
            bool     comma     = false;
            JArray   curarray  = null;
            JObject  curobject = null;

            // first decode the first value/object/array
            {
                JToken o = DecodeValue(parser, textbuffer, false);       // grab new value, not array end

                if (o == null)
                {
                    return(ParseError(parser, "No Obj/Array", flags, out error));
                }
                else if (o.TokenType == TType.Array)
                {
                    stack[++sptr] = o;                      // push this one onto stack
                    curarray      = o as JArray;            // this is now the current array
                }
                else if (o.TokenType == TType.Object)
                {
                    stack[++sptr] = o;                      // push this one onto stack
                    curobject     = o as JObject;           // this is now the current object
                }
                else
                {
                    return(o);                               // value only
                }
            }

            while (true)
            {
                if (curobject != null)      // if object..
                {
                    while (true)
                    {
                        char next = parser.GetChar();

                        if (next == '}')    // end object
                        {
                            parser.SkipSpace();

                            if (comma == true && (flags & ParseOptions.AllowTrailingCommas) == 0)
                            {
                                return(ParseError(parser, "Comma", flags, out error));
                            }
                            else
                            {
                                JToken prevtoken = stack[--sptr];
                                if (prevtoken == null)      // if popped stack is null, we are back to beginning, return this
                                {
                                    return(stack[sptr + 1]);
                                }
                                else
                                {
                                    comma     = parser.IsCharMoveOn(',');
                                    curobject = prevtoken as JObject;
                                    if (curobject == null)
                                    {
                                        curarray = prevtoken as JArray;
                                        break;
                                    }
                                }
                            }
                        }
                        else if (next == '"')   // property name
                        {
                            int textlen = parser.NextQuotedString(next, textbuffer, true);

                            if (textlen < 1 || (comma == false && curobject.Count > 0))
                            {
                                return(ParseError(parser, "Object missing property name", flags, out error));
                            }
                            else if (!parser.IsCharMoveOn(':'))
                            {
                                return(ParseError(parser, "Object missing : after property name", flags, out error));
                            }
                            else
                            {
                                string name = new string(textbuffer, 0, textlen);

                                JToken o = DecodeValue(parser, textbuffer, false);      // get value

                                if (o == null)
                                {
                                    return(ParseError(parser, "Object bad value", flags, out error));
                                }

                                o.Name          = name;                 // object gets the name, indicating its a property
                                curobject[name] = o;                    // assign to dictionary

                                if (o.TokenType == TType.Array)         // if array, we need to change to this as controlling object on top of stack
                                {
                                    if (sptr == stack.Length - 1)
                                    {
                                        return(ParseError(parser, "Stack overflow", flags, out error));
                                    }

                                    stack[++sptr] = o;                  // push this one onto stack
                                    curarray      = o as JArray;        // this is now the current object
                                    curobject     = null;
                                    comma         = false;
                                    break;
                                }
                                else if (o.TokenType == TType.Object)   // if object, this is the controlling object
                                {
                                    if (sptr == stack.Length - 1)
                                    {
                                        return(ParseError(parser, "Stack overflow", flags, out error));
                                    }

                                    stack[++sptr] = o;                  // push this one onto stack
                                    curobject     = o as JObject;       // this is now the current object
                                    comma         = false;
                                }
                                else
                                {
                                    comma = parser.IsCharMoveOn(',');
                                }
                            }
                        }
                        else
                        {
                            return(ParseError(parser, "Bad format in object", flags, out error));
                        }
                    }
                }
                else
                {
                    while (true)
                    {
                        JToken o = DecodeValue(parser, textbuffer, true);       // grab new value

                        if (o == null)
                        {
                            return(ParseError(parser, "Bad array value", flags, out error));
                        }
                        else if (o.TokenType == TType.EndArray)          // if end marker, jump back
                        {
                            if (comma == true && (flags & ParseOptions.AllowTrailingCommas) == 0)
                            {
                                return(ParseError(parser, "Comma", flags, out error));
                            }
                            else
                            {
                                JToken prevtoken = stack[--sptr];
                                if (prevtoken == null)      // if popped stack is null, we are back to beginning, return this
                                {
                                    return(stack[sptr + 1]);
                                }
                                else
                                {
                                    comma     = parser.IsCharMoveOn(',');
                                    curobject = prevtoken as JObject;
                                    if (curobject == null)
                                    {
                                        curarray = prevtoken as JArray;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        else if ((comma == false && curarray.Count > 0))   // missing comma
                        {
                            return(ParseError(parser, "Comma", flags, out error));
                        }
                        else
                        {
                            curarray.Add(o);

                            if (o.TokenType == TType.Array) // if array, we need to change to this as controlling object on top of stack
                            {
                                if (sptr == stack.Length - 1)
                                {
                                    return(ParseError(parser, "Stack overflow", flags, out error));
                                }

                                stack[++sptr] = o;              // push this one onto stack
                                curarray      = o as JArray;    // this is now the current array
                                comma         = false;
                            }
                            else if (o.TokenType == TType.Object) // if object, this is the controlling object
                            {
                                if (sptr == stack.Length - 1)
                                {
                                    return(ParseError(parser, "Stack overflow", flags, out error));
                                }

                                stack[++sptr] = o;              // push this one onto stack
                                curobject     = o as JObject;   // this is now the current object
                                curarray      = null;
                                comma         = false;
                                break;
                            }
                            else
                            {
                                comma = parser.IsCharMoveOn(',');
                            }
                        }
                    }
                }
            }
        }