| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 | 
							- #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.IO;
 
- using System.Text;
 
- namespace LitJson
 
- {
 
-     public enum JsonToken
 
-     {
 
-         None,
 
-         ObjectStart,
 
-         PropertyName,
 
-         ObjectEnd,
 
-         ArrayStart,
 
-         ArrayEnd,
 
-         Int,
 
-         Long,
 
-         Double,
 
-         String,
 
-         Boolean,
 
-         Null
 
-     }
 
-     public class JsonReader
 
-     {
 
-         #region Fields
 
-         private static 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 ()
 
-         {
 
-             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 void PopulateParseTable ()
 
-         {
 
-             // See section A.2. of the manual for details
 
-             parse_table = new Dictionary<int, IDictionary<int, int[]>> ();
 
-             TableAddRow (ParserToken.Array);
 
-             TableAddCol (ParserToken.Array, '[',
 
-                          '[',
 
-                          (int) ParserToken.ArrayPrime);
 
-             TableAddRow (ParserToken.ArrayPrime);
 
-             TableAddCol (ParserToken.ArrayPrime, '"',
 
-                          (int) ParserToken.Value,
 
-                          (int) ParserToken.ValueRest,
 
-                          ']');
 
-             TableAddCol (ParserToken.ArrayPrime, '[',
 
-                          (int) ParserToken.Value,
 
-                          (int) ParserToken.ValueRest,
 
-                          ']');
 
-             TableAddCol (ParserToken.ArrayPrime, ']',
 
-                          ']');
 
-             TableAddCol (ParserToken.ArrayPrime, '{',
 
-                          (int) ParserToken.Value,
 
-                          (int) ParserToken.ValueRest,
 
-                          ']');
 
-             TableAddCol (ParserToken.ArrayPrime, (int) ParserToken.Number,
 
-                          (int) ParserToken.Value,
 
-                          (int) ParserToken.ValueRest,
 
-                          ']');
 
-             TableAddCol (ParserToken.ArrayPrime, (int) ParserToken.True,
 
-                          (int) ParserToken.Value,
 
-                          (int) ParserToken.ValueRest,
 
-                          ']');
 
-             TableAddCol (ParserToken.ArrayPrime, (int) ParserToken.False,
 
-                          (int) ParserToken.Value,
 
-                          (int) ParserToken.ValueRest,
 
-                          ']');
 
-             TableAddCol (ParserToken.ArrayPrime, (int) ParserToken.Null,
 
-                          (int) ParserToken.Value,
 
-                          (int) ParserToken.ValueRest,
 
-                          ']');
 
-             TableAddRow (ParserToken.Object);
 
-             TableAddCol (ParserToken.Object, '{',
 
-                          '{',
 
-                          (int) ParserToken.ObjectPrime);
 
-             TableAddRow (ParserToken.ObjectPrime);
 
-             TableAddCol (ParserToken.ObjectPrime, '"',
 
-                          (int) ParserToken.Pair,
 
-                          (int) ParserToken.PairRest,
 
-                          '}');
 
-             TableAddCol (ParserToken.ObjectPrime, '}',
 
-                          '}');
 
-             TableAddRow (ParserToken.Pair);
 
-             TableAddCol (ParserToken.Pair, '"',
 
-                          (int) ParserToken.String,
 
-                          ':',
 
-                          (int) ParserToken.Value);
 
-             TableAddRow (ParserToken.PairRest);
 
-             TableAddCol (ParserToken.PairRest, ',',
 
-                          ',',
 
-                          (int) ParserToken.Pair,
 
-                          (int) ParserToken.PairRest);
 
-             TableAddCol (ParserToken.PairRest, '}',
 
-                          (int) ParserToken.Epsilon);
 
-             TableAddRow (ParserToken.String);
 
-             TableAddCol (ParserToken.String, '"',
 
-                          '"',
 
-                          (int) ParserToken.CharSeq,
 
-                          '"');
 
-             TableAddRow (ParserToken.Text);
 
-             TableAddCol (ParserToken.Text, '[',
 
-                          (int) ParserToken.Array);
 
-             TableAddCol (ParserToken.Text, '{',
 
-                          (int) ParserToken.Object);
 
-             TableAddRow (ParserToken.Value);
 
-             TableAddCol (ParserToken.Value, '"',
 
-                          (int) ParserToken.String);
 
-             TableAddCol (ParserToken.Value, '[',
 
-                          (int) ParserToken.Array);
 
-             TableAddCol (ParserToken.Value, '{',
 
-                          (int) ParserToken.Object);
 
-             TableAddCol (ParserToken.Value, (int) ParserToken.Number,
 
-                          (int) ParserToken.Number);
 
-             TableAddCol (ParserToken.Value, (int) ParserToken.True,
 
-                          (int) ParserToken.True);
 
-             TableAddCol (ParserToken.Value, (int) ParserToken.False,
 
-                          (int) ParserToken.False);
 
-             TableAddCol (ParserToken.Value, (int) ParserToken.Null,
 
-                          (int) ParserToken.Null);
 
-             TableAddRow (ParserToken.ValueRest);
 
-             TableAddCol (ParserToken.ValueRest, ',',
 
-                          ',',
 
-                          (int) ParserToken.Value,
 
-                          (int) ParserToken.ValueRest);
 
-             TableAddCol (ParserToken.ValueRest, ']',
 
-                          (int) ParserToken.Epsilon);
 
-         }
 
-         private static void TableAddCol (ParserToken row, int col,
 
-                                          params int[] symbols)
 
-         {
 
-             parse_table[(int) row].Add (col, symbols);
 
-         }
 
-         private static void TableAddRow (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, out n_double)) {
 
-                     token = JsonToken.Double;
 
-                     token_value = n_double;
 
-                     return;
 
-                 }
 
-             }
 
-             int n_int32;
 
-             if (Int32.TryParse (number, out n_int32)) {
 
-                 token = JsonToken.Int;
 
-                 token_value = n_int32;
 
-                 return;
 
-             }
 
-             long n_int64;
 
-             if (Int64.TryParse (number, out n_int64)) {
 
-                 token = JsonToken.Long;
 
-                 token_value = n_int64;
 
-                 return;
 
-             }
 
-             ulong n_uint64;
 
-             if (UInt64.TryParse(number, 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)
 
-                 reader.Close ();
 
-             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]);
 
-             }
 
-         }
 
-     }
 
- }
 
 
  |