479 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
		
		
			
		
	
	
			479 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
| 
								 | 
							
								#region Header
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * JsonReader.cs
							 | 
						||
| 
								 | 
							
								 *   Stream-like access to JSON text.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The authors disclaim copyright to this source code. For more details, see
							 | 
						||
| 
								 | 
							
								 * the COPYING file included with this distribution.
							 | 
						||
| 
								 | 
							
								 **/
							 | 
						||
| 
								 | 
							
								#endregion
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using System;
							 | 
						||
| 
								 | 
							
								using System.Collections.Generic;
							 | 
						||
| 
								 | 
							
								using System.Globalization;
							 | 
						||
| 
								 | 
							
								using System.IO;
							 | 
						||
| 
								 | 
							
								using System.Text;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace Guru.LitJson
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    public enum JsonToken
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        None,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ObjectStart,
							 | 
						||
| 
								 | 
							
								        PropertyName,
							 | 
						||
| 
								 | 
							
								        ObjectEnd,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ArrayStart,
							 | 
						||
| 
								 | 
							
								        ArrayEnd,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Int,
							 | 
						||
| 
								 | 
							
								        Long,
							 | 
						||
| 
								 | 
							
								        Double,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        String,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Boolean,
							 | 
						||
| 
								 | 
							
								        Null
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public class JsonReader
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        #region Fields
							 | 
						||
| 
								 | 
							
								        private static readonly IDictionary<int, IDictionary<int, int[]>> parse_table;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private Stack<int>    automaton_stack;
							 | 
						||
| 
								 | 
							
								        private int           current_input;
							 | 
						||
| 
								 | 
							
								        private int           current_symbol;
							 | 
						||
| 
								 | 
							
								        private bool          end_of_json;
							 | 
						||
| 
								 | 
							
								        private bool          end_of_input;
							 | 
						||
| 
								 | 
							
								        private Lexer         lexer;
							 | 
						||
| 
								 | 
							
								        private bool          parser_in_string;
							 | 
						||
| 
								 | 
							
								        private bool          parser_return;
							 | 
						||
| 
								 | 
							
								        private bool          read_started;
							 | 
						||
| 
								 | 
							
								        private TextReader    reader;
							 | 
						||
| 
								 | 
							
								        private bool          reader_is_owned;
							 | 
						||
| 
								 | 
							
								        private bool          skip_non_members;
							 | 
						||
| 
								 | 
							
								        private object        token_value;
							 | 
						||
| 
								 | 
							
								        private JsonToken     token;
							 | 
						||
| 
								 | 
							
								        #endregion
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        #region Public Properties
							 | 
						||
| 
								 | 
							
								        public bool AllowComments {
							 | 
						||
| 
								 | 
							
								            get { return lexer.AllowComments; }
							 | 
						||
| 
								 | 
							
								            set { lexer.AllowComments = value; }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public bool AllowSingleQuotedStrings {
							 | 
						||
| 
								 | 
							
								            get { return lexer.AllowSingleQuotedStrings; }
							 | 
						||
| 
								 | 
							
								            set { lexer.AllowSingleQuotedStrings = value; }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public bool SkipNonMembers {
							 | 
						||
| 
								 | 
							
								            get { return skip_non_members; }
							 | 
						||
| 
								 | 
							
								            set { skip_non_members = value; }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public bool EndOfInput {
							 | 
						||
| 
								 | 
							
								            get { return end_of_input; }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public bool EndOfJson {
							 | 
						||
| 
								 | 
							
								            get { return end_of_json; }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public JsonToken Token {
							 | 
						||
| 
								 | 
							
								            get { return token; }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public object Value {
							 | 
						||
| 
								 | 
							
								            get { return token_value; }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        #endregion
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        #region Constructors
							 | 
						||
| 
								 | 
							
								        static JsonReader ()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            parse_table = PopulateParseTable ();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public JsonReader (string json_text) :
							 | 
						||
| 
								 | 
							
								            this (new StringReader (json_text), true)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public JsonReader (TextReader reader) :
							 | 
						||
| 
								 | 
							
								            this (reader, false)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private JsonReader (TextReader reader, bool owned)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (reader == null)
							 | 
						||
| 
								 | 
							
								                throw new ArgumentNullException ("reader");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            parser_in_string = false;
							 | 
						||
| 
								 | 
							
								            parser_return    = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            read_started = false;
							 | 
						||
| 
								 | 
							
								            automaton_stack = new Stack<int> ();
							 | 
						||
| 
								 | 
							
								            automaton_stack.Push ((int) ParserToken.End);
							 | 
						||
| 
								 | 
							
								            automaton_stack.Push ((int) ParserToken.Text);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            lexer = new Lexer (reader);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            end_of_input = false;
							 | 
						||
| 
								 | 
							
								            end_of_json  = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            skip_non_members = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            this.reader = reader;
							 | 
						||
| 
								 | 
							
								            reader_is_owned = owned;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        #endregion
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        #region Static Methods
							 | 
						||
| 
								 | 
							
								        private static IDictionary<int, IDictionary<int, int[]>> PopulateParseTable ()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            // See section A.2. of the manual for details
							 | 
						||
| 
								 | 
							
								            IDictionary<int, IDictionary<int, int[]>> parse_table = new Dictionary<int, IDictionary<int, int[]>> ();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.Array);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Array, '[',
							 | 
						||
| 
								 | 
							
								                            '[',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ArrayPrime);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.ArrayPrime);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ArrayPrime, '"',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Value,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ValueRest,
							 | 
						||
| 
								 | 
							
								                            ']');
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ArrayPrime, '[',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Value,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ValueRest,
							 | 
						||
| 
								 | 
							
								                            ']');
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ArrayPrime, ']',
							 | 
						||
| 
								 | 
							
								                            ']');
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ArrayPrime, '{',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Value,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ValueRest,
							 | 
						||
| 
								 | 
							
								                            ']');
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Number,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Value,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ValueRest,
							 | 
						||
| 
								 | 
							
								                            ']');
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.True,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Value,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ValueRest,
							 | 
						||
| 
								 | 
							
								                            ']');
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.False,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Value,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ValueRest,
							 | 
						||
| 
								 | 
							
								                            ']');
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Null,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Value,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ValueRest,
							 | 
						||
| 
								 | 
							
								                            ']');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.Object);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Object, '{',
							 | 
						||
| 
								 | 
							
								                            '{',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ObjectPrime);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.ObjectPrime);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ObjectPrime, '"',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Pair,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.PairRest,
							 | 
						||
| 
								 | 
							
								                            '}');
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ObjectPrime, '}',
							 | 
						||
| 
								 | 
							
								                            '}');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.Pair);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Pair, '"',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.String,
							 | 
						||
| 
								 | 
							
								                            ':',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.PairRest);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.PairRest, ',',
							 | 
						||
| 
								 | 
							
								                            ',',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Pair,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.PairRest);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.PairRest, '}',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Epsilon);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.String);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.String, '"',
							 | 
						||
| 
								 | 
							
								                            '"',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.CharSeq,
							 | 
						||
| 
								 | 
							
								                            '"');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.Text);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Text, '[',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Array);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Text, '{',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Object);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.Value);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Value, '"',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.String);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Value, '[',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Array);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Value, '{',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Object);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Number,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Number);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.True,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.True);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.False,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.False);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Null,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TableAddRow (parse_table, ParserToken.ValueRest);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ValueRest, ',',
							 | 
						||
| 
								 | 
							
								                            ',',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Value,
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.ValueRest);
							 | 
						||
| 
								 | 
							
								            TableAddCol (parse_table, ParserToken.ValueRest, ']',
							 | 
						||
| 
								 | 
							
								                            (int) ParserToken.Epsilon);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return parse_table;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private static void TableAddCol (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken row, int col,
							 | 
						||
| 
								 | 
							
								                                         params int[] symbols)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            parse_table[(int) row].Add (col, symbols);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private static void TableAddRow (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken rule)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            parse_table.Add ((int) rule, new Dictionary<int, int[]> ());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        #endregion
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        #region Private Methods
							 | 
						||
| 
								 | 
							
								        private void ProcessNumber (string number)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (number.IndexOf ('.') != -1 ||
							 | 
						||
| 
								 | 
							
								                number.IndexOf ('e') != -1 ||
							 | 
						||
| 
								 | 
							
								                number.IndexOf ('E') != -1) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                double n_double;
							 | 
						||
| 
								 | 
							
								                if (double.TryParse (number, NumberStyles.Any, CultureInfo.InvariantCulture, out n_double)) {
							 | 
						||
| 
								 | 
							
								                    token = JsonToken.Double;
							 | 
						||
| 
								 | 
							
								                    token_value = n_double;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    return;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            int n_int32;
							 | 
						||
| 
								 | 
							
								            if (int.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int32)) {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.Int;
							 | 
						||
| 
								 | 
							
								                token_value = n_int32;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            long n_int64;
							 | 
						||
| 
								 | 
							
								            if (long.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int64)) {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.Long;
							 | 
						||
| 
								 | 
							
								                token_value = n_int64;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            ulong n_uint64;
							 | 
						||
| 
								 | 
							
								            if (ulong.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_uint64))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.Long;
							 | 
						||
| 
								 | 
							
								                token_value = n_uint64;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Shouldn't happen, but just in case, return something
							 | 
						||
| 
								 | 
							
								            token = JsonToken.Int;
							 | 
						||
| 
								 | 
							
								            token_value = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private void ProcessSymbol ()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (current_symbol == '[')  {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.ArrayStart;
							 | 
						||
| 
								 | 
							
								                parser_return = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == ']')  {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.ArrayEnd;
							 | 
						||
| 
								 | 
							
								                parser_return = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == '{')  {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.ObjectStart;
							 | 
						||
| 
								 | 
							
								                parser_return = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == '}')  {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.ObjectEnd;
							 | 
						||
| 
								 | 
							
								                parser_return = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == '"')  {
							 | 
						||
| 
								 | 
							
								                if (parser_in_string) {
							 | 
						||
| 
								 | 
							
								                    parser_in_string = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    parser_return = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    if (token == JsonToken.None)
							 | 
						||
| 
								 | 
							
								                        token = JsonToken.String;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    parser_in_string = true;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == (int) ParserToken.CharSeq) {
							 | 
						||
| 
								 | 
							
								                token_value = lexer.StringValue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == (int) ParserToken.False)  {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.Boolean;
							 | 
						||
| 
								 | 
							
								                token_value = false;
							 | 
						||
| 
								 | 
							
								                parser_return = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == (int) ParserToken.Null)  {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.Null;
							 | 
						||
| 
								 | 
							
								                parser_return = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == (int) ParserToken.Number)  {
							 | 
						||
| 
								 | 
							
								                ProcessNumber (lexer.StringValue);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                parser_return = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == (int) ParserToken.Pair)  {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.PropertyName;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (current_symbol == (int) ParserToken.True)  {
							 | 
						||
| 
								 | 
							
								                token = JsonToken.Boolean;
							 | 
						||
| 
								 | 
							
								                token_value = true;
							 | 
						||
| 
								 | 
							
								                parser_return = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private bool ReadToken ()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (end_of_input)
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            lexer.NextToken ();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (lexer.EndOfInput) {
							 | 
						||
| 
								 | 
							
								                Close ();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            current_input = lexer.Token;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        #endregion
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void Close ()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (end_of_input)
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            end_of_input = true;
							 | 
						||
| 
								 | 
							
								            end_of_json  = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (reader_is_owned)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                using(reader){}
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            reader = null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public bool Read ()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (end_of_input)
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (end_of_json) {
							 | 
						||
| 
								 | 
							
								                end_of_json = false;
							 | 
						||
| 
								 | 
							
								                automaton_stack.Clear ();
							 | 
						||
| 
								 | 
							
								                automaton_stack.Push ((int) ParserToken.End);
							 | 
						||
| 
								 | 
							
								                automaton_stack.Push ((int) ParserToken.Text);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            parser_in_string = false;
							 | 
						||
| 
								 | 
							
								            parser_return    = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            token       = JsonToken.None;
							 | 
						||
| 
								 | 
							
								            token_value = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (! read_started) {
							 | 
						||
| 
								 | 
							
								                read_started = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (! ReadToken ())
							 | 
						||
| 
								 | 
							
								                    return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            int[] entry_symbols;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            while (true) {
							 | 
						||
| 
								 | 
							
								                if (parser_return) {
							 | 
						||
| 
								 | 
							
								                    if (automaton_stack.Peek () == (int) ParserToken.End)
							 | 
						||
| 
								 | 
							
								                        end_of_json = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    return true;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                current_symbol = automaton_stack.Pop ();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                ProcessSymbol ();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (current_symbol == current_input) {
							 | 
						||
| 
								 | 
							
								                    if (! ReadToken ()) {
							 | 
						||
| 
								 | 
							
								                        if (automaton_stack.Peek () != (int) ParserToken.End)
							 | 
						||
| 
								 | 
							
								                            throw new JsonException (
							 | 
						||
| 
								 | 
							
								                                "Input doesn't evaluate to proper JSON text");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                        if (parser_return)
							 | 
						||
| 
								 | 
							
								                            return true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                        return false;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    continue;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                try {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    entry_symbols =
							 | 
						||
| 
								 | 
							
								                        parse_table[current_symbol][current_input];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                } catch (KeyNotFoundException e) {
							 | 
						||
| 
								 | 
							
								                    throw new JsonException ((ParserToken) current_input, e);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (entry_symbols[0] == (int) ParserToken.Epsilon)
							 | 
						||
| 
								 | 
							
								                    continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                for (int i = entry_symbols.Length - 1; i >= 0; i--)
							 | 
						||
| 
								 | 
							
								                    automaton_stack.Push (entry_symbols[i]);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |