/// <summary>
        /// Get the next value. The value can be wrapped in quotes. 
        /// The value can be empty.
        /// </summary>

        private string GetValue(TextParser parser) 
        {
            char ch;
            
            do 
            {
                ch = parser.Next();
            } 
            while (ch <= ' ' && ch != TextParser.EOF);

            switch (ch) 
            {
                case TextParser.EOF:
                    return null;
                case '"':
                case '\'':
                    return parser.NextString(ch);
                case ',':
                    parser.Back();
                    return "";
                default:
                    parser.Back();
                    return parser.NextTo(',');
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Get the next char in the string, skipping whitespace
        /// and comments (slashslash and slashstar).
        /// </summary>
        /// <returns>A character, or 0 if there are no more characters.</returns>
        
        private char NextClean(TextParser parser)
        {
            Debug.Assert(parser != null);

            while (true) 
            {
                char ch = parser.Next();

                if (ch == '/') 
                {
                    switch (parser.Next()) 
                    {
                        case '/' :
                        {
                            do 
                            {
                                ch = parser.Next();
                            } 
                            while (ch != '\n' && ch != '\r' && ch != EOF);
                            break;
                        }
                        case '*' :
                        {
                            while (true) 
                            {
                                ch = parser.Next();

                                if (ch == EOF) 
                                    throw new ParseException("Unclosed comment.");

                                if (ch == '*') 
                                {
                                    if (parser.Next() == '/') 
                                        break;
                                    
                                    parser.Back();
                                }
                            }
                            break;
                        }
                        default :
                        {
                            parser.Back();
                            return '/';
                        }
                    }
                } 
                else if (ch == EOF || ch > ' ') 
                {
                    return ch;
                }
            }
        }
Ejemplo n.º 3
0
        private object ParseArray(TextParser parser)
        {
            Debug.Assert(parser != null);

            if (NextClean(parser) != '[') 
                throw new ParseException("An array must start with '['.");

            _output.StartArray();
            
            if (NextClean(parser) != ']') 
            {
                parser.Back();

                bool end = false;

                do
                {
                    _output.ArrayPut(NextObject(parser));

                    switch (NextClean(parser)) 
                    {
                        case ',' :
                        {
                            if (NextClean(parser) == ']') 
                                end = true;
                            else
                                parser.Back();

                            break;
                        }

                        case ']' :
                        {
                            end = true; 
                            break;
                        }
    					
                        default :
                            throw new ParseException("Expected a ',' or ']'.");
                    }
                }
                while (!end);
            }

            return _output.EndArray();
        }
Ejemplo n.º 4
0
        private object ParseObject(TextParser parser)
        {
            Debug.Assert(parser != null);

            if (parser.Next() == '%')
                parser.Restart(Unescape(parser.Source), parser.Index);

            parser.Back();

            if (NextClean(parser) != '{') 
                throw new ParseException("An object must begin with '{'.");

            _output.StartObject();

            char ch = NextClean(parser);

            while (ch != '}')
            {
                string memberName;

                switch (ch) 
                {
                    case JsonParser.EOF :
                        throw new ParseException("An object must end with '}'.");
                    
                    case '}' :
                        continue;
                    
                    default :
                    {
                        parser.Back();
                        memberName = NextObject(parser).ToString();
                        break;
                    }
                }

                if (NextClean(parser) != ':') 
                    throw new ParseException("Expected a ':' after a key.");

                object memberValue = NextObject(parser);

                _output.ObjectPut(memberName, memberValue);

                switch (ch = NextClean(parser))
                {
                    case ',' :
                    {
                        if ((ch = NextClean(parser)) == '}') 
                            continue;

                        parser.Back();
                        break;
                    }
                    
                    case '}' :
                        continue;

                    default :
                        throw new ParseException("Expected a ',' or '}'.");
                }

                ch = NextClean(parser);
            }

            return _output.EndObject();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the next value as object. The value can be a Boolean, a Double,
        /// an Integer, an object array, a JObject, a String, or 
        /// JObject.NULL.
        /// </summary>
        
        private object NextObject(TextParser parser)
        {
            Debug.Assert(parser != null);

            char ch = NextClean(parser);

            //
            // String
            //

            if (ch == '"' || ch == '\'') 
                return _output.ToStringPrimitive(parser.NextString(ch));

            //
            // Object
            //

            if (ch == '{') 
            {
                parser.Back();
                return ParseObject(parser);
            }

            //
            // JSON Array
            //

            if (ch == '[')
            {
                parser.Back();
                return ParseArray(parser);
            }

            StringBuilder sb = new StringBuilder();
            char b = ch;
            
            while (ch >= ' ' && ch != ':' && ch != ',' && ch != ']' && ch != '}' && ch != '/')
            {
                sb.Append(ch);
                ch = parser.Next();
            }

            parser.Back();

            string s = sb.ToString().Trim();
            
            if (s == "true")
                return _output.TruePrimitive;
            
            if (s == "false")
                return _output.FalsePrimitive;

            if (s == "null")
                return _output.NullPrimitive;
            
            if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') 
            {
                object number = _output.ToNumberPrimitive(s);

                if (number == null)
                    throw new ParseException(string.Format("Cannot convert '{0}' to a number.", s));

                return number;
            }

            if (s.Length == 0)
                throw new ParseException("Missing value.");

            return s;
        }