JsonReader.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.IO;
  5. namespace LitJson
  6. {
  7. public class JsonReader
  8. {
  9. static JsonReader()
  10. {
  11. JsonReader.PopulateParseTable();
  12. }
  13. public JsonReader(string json_text) : this(new StringReader(json_text), true)
  14. {
  15. }
  16. public JsonReader(TextReader reader) : this(reader, false)
  17. {
  18. }
  19. private JsonReader(TextReader reader, bool owned)
  20. {
  21. if (reader == null)
  22. {
  23. throw new ArgumentNullException("reader");
  24. }
  25. this.parser_in_string = false;
  26. this.parser_return = false;
  27. this.read_started = false;
  28. this.automaton_stack = new Stack<int>();
  29. this.automaton_stack.Push(65553);
  30. this.automaton_stack.Push(65543);
  31. this.lexer = new Lexer(reader);
  32. this.end_of_input = false;
  33. this.end_of_json = false;
  34. this.skip_non_members = true;
  35. this.reader = reader;
  36. this.reader_is_owned = owned;
  37. }
  38. public bool AllowComments
  39. {
  40. get
  41. {
  42. return this.lexer.AllowComments;
  43. }
  44. set
  45. {
  46. this.lexer.AllowComments = value;
  47. }
  48. }
  49. public bool AllowSingleQuotedStrings
  50. {
  51. get
  52. {
  53. return this.lexer.AllowSingleQuotedStrings;
  54. }
  55. set
  56. {
  57. this.lexer.AllowSingleQuotedStrings = value;
  58. }
  59. }
  60. public bool SkipNonMembers
  61. {
  62. get
  63. {
  64. return this.skip_non_members;
  65. }
  66. set
  67. {
  68. this.skip_non_members = value;
  69. }
  70. }
  71. public bool EndOfInput
  72. {
  73. get
  74. {
  75. return this.end_of_input;
  76. }
  77. }
  78. public bool EndOfJson
  79. {
  80. get
  81. {
  82. return this.end_of_json;
  83. }
  84. }
  85. public JsonToken Token
  86. {
  87. get
  88. {
  89. return this.token;
  90. }
  91. }
  92. public object Value
  93. {
  94. get
  95. {
  96. return this.token_value;
  97. }
  98. }
  99. private static void PopulateParseTable()
  100. {
  101. JsonReader.parse_table = new Dictionary<int, IDictionary<int, int[]>>();
  102. JsonReader.TableAddRow(ParserToken.Array);
  103. JsonReader.TableAddCol(ParserToken.Array, 91, new int[]
  104. {
  105. 91,
  106. 65549
  107. });
  108. JsonReader.TableAddRow(ParserToken.ArrayPrime);
  109. JsonReader.TableAddCol(ParserToken.ArrayPrime, 34, new int[]
  110. {
  111. 65550,
  112. 65551,
  113. 93
  114. });
  115. JsonReader.TableAddCol(ParserToken.ArrayPrime, 91, new int[]
  116. {
  117. 65550,
  118. 65551,
  119. 93
  120. });
  121. JsonReader.TableAddCol(ParserToken.ArrayPrime, 93, new int[]
  122. {
  123. 93
  124. });
  125. JsonReader.TableAddCol(ParserToken.ArrayPrime, 123, new int[]
  126. {
  127. 65550,
  128. 65551,
  129. 93
  130. });
  131. JsonReader.TableAddCol(ParserToken.ArrayPrime, 65537, new int[]
  132. {
  133. 65550,
  134. 65551,
  135. 93
  136. });
  137. JsonReader.TableAddCol(ParserToken.ArrayPrime, 65538, new int[]
  138. {
  139. 65550,
  140. 65551,
  141. 93
  142. });
  143. JsonReader.TableAddCol(ParserToken.ArrayPrime, 65539, new int[]
  144. {
  145. 65550,
  146. 65551,
  147. 93
  148. });
  149. JsonReader.TableAddCol(ParserToken.ArrayPrime, 65540, new int[]
  150. {
  151. 65550,
  152. 65551,
  153. 93
  154. });
  155. JsonReader.TableAddRow(ParserToken.Object);
  156. JsonReader.TableAddCol(ParserToken.Object, 123, new int[]
  157. {
  158. 123,
  159. 65545
  160. });
  161. JsonReader.TableAddRow(ParserToken.ObjectPrime);
  162. JsonReader.TableAddCol(ParserToken.ObjectPrime, 34, new int[]
  163. {
  164. 65546,
  165. 65547,
  166. 125
  167. });
  168. JsonReader.TableAddCol(ParserToken.ObjectPrime, 125, new int[]
  169. {
  170. 125
  171. });
  172. JsonReader.TableAddRow(ParserToken.Pair);
  173. JsonReader.TableAddCol(ParserToken.Pair, 34, new int[]
  174. {
  175. 65552,
  176. 58,
  177. 65550
  178. });
  179. JsonReader.TableAddRow(ParserToken.PairRest);
  180. JsonReader.TableAddCol(ParserToken.PairRest, 44, new int[]
  181. {
  182. 44,
  183. 65546,
  184. 65547
  185. });
  186. JsonReader.TableAddCol(ParserToken.PairRest, 125, new int[]
  187. {
  188. 65554
  189. });
  190. JsonReader.TableAddRow(ParserToken.String);
  191. JsonReader.TableAddCol(ParserToken.String, 34, new int[]
  192. {
  193. 34,
  194. 65541,
  195. 34
  196. });
  197. JsonReader.TableAddRow(ParserToken.Text);
  198. JsonReader.TableAddCol(ParserToken.Text, 91, new int[]
  199. {
  200. 65548
  201. });
  202. JsonReader.TableAddCol(ParserToken.Text, 123, new int[]
  203. {
  204. 65544
  205. });
  206. JsonReader.TableAddRow(ParserToken.Value);
  207. JsonReader.TableAddCol(ParserToken.Value, 34, new int[]
  208. {
  209. 65552
  210. });
  211. JsonReader.TableAddCol(ParserToken.Value, 91, new int[]
  212. {
  213. 65548
  214. });
  215. JsonReader.TableAddCol(ParserToken.Value, 123, new int[]
  216. {
  217. 65544
  218. });
  219. JsonReader.TableAddCol(ParserToken.Value, 65537, new int[]
  220. {
  221. 65537
  222. });
  223. JsonReader.TableAddCol(ParserToken.Value, 65538, new int[]
  224. {
  225. 65538
  226. });
  227. JsonReader.TableAddCol(ParserToken.Value, 65539, new int[]
  228. {
  229. 65539
  230. });
  231. JsonReader.TableAddCol(ParserToken.Value, 65540, new int[]
  232. {
  233. 65540
  234. });
  235. JsonReader.TableAddRow(ParserToken.ValueRest);
  236. JsonReader.TableAddCol(ParserToken.ValueRest, 44, new int[]
  237. {
  238. 44,
  239. 65550,
  240. 65551
  241. });
  242. JsonReader.TableAddCol(ParserToken.ValueRest, 93, new int[]
  243. {
  244. 65554
  245. });
  246. }
  247. private static void TableAddCol(ParserToken row, int col, params int[] symbols)
  248. {
  249. JsonReader.parse_table[(int)row].Add(col, symbols);
  250. }
  251. private static void TableAddRow(ParserToken rule)
  252. {
  253. JsonReader.parse_table.Add((int)rule, new Dictionary<int, int[]>());
  254. }
  255. private void ProcessNumber(string number)
  256. {
  257. double num;
  258. if ((number.IndexOf('.') != -1 || number.IndexOf('e') != -1 || number.IndexOf('E') != -1) && double.TryParse(number, NumberStyles.Any, CultureInfo.InvariantCulture, out num))
  259. {
  260. this.token = JsonToken.Double;
  261. this.token_value = num;
  262. return;
  263. }
  264. int num2;
  265. if (int.TryParse(number, out num2))
  266. {
  267. this.token = JsonToken.Int;
  268. this.token_value = num2;
  269. return;
  270. }
  271. long num3;
  272. if (long.TryParse(number, out num3))
  273. {
  274. this.token = JsonToken.Long;
  275. this.token_value = num3;
  276. return;
  277. }
  278. ulong num4;
  279. if (ulong.TryParse(number, out num4))
  280. {
  281. this.token = JsonToken.Long;
  282. this.token_value = num4;
  283. return;
  284. }
  285. this.token = JsonToken.Int;
  286. this.token_value = 0;
  287. }
  288. private void ProcessSymbol()
  289. {
  290. if (this.current_symbol == 91)
  291. {
  292. this.token = JsonToken.ArrayStart;
  293. this.parser_return = true;
  294. }
  295. else if (this.current_symbol == 93)
  296. {
  297. this.token = JsonToken.ArrayEnd;
  298. this.parser_return = true;
  299. }
  300. else if (this.current_symbol == 123)
  301. {
  302. this.token = JsonToken.ObjectStart;
  303. this.parser_return = true;
  304. }
  305. else if (this.current_symbol == 125)
  306. {
  307. this.token = JsonToken.ObjectEnd;
  308. this.parser_return = true;
  309. }
  310. else if (this.current_symbol == 34)
  311. {
  312. if (this.parser_in_string)
  313. {
  314. this.parser_in_string = false;
  315. this.parser_return = true;
  316. }
  317. else
  318. {
  319. if (this.token == JsonToken.None)
  320. {
  321. this.token = JsonToken.String;
  322. }
  323. this.parser_in_string = true;
  324. }
  325. }
  326. else if (this.current_symbol == 65541)
  327. {
  328. this.token_value = this.lexer.StringValue;
  329. }
  330. else if (this.current_symbol == 65539)
  331. {
  332. this.token = JsonToken.Boolean;
  333. this.token_value = false;
  334. this.parser_return = true;
  335. }
  336. else if (this.current_symbol == 65540)
  337. {
  338. this.token = JsonToken.Null;
  339. this.parser_return = true;
  340. }
  341. else if (this.current_symbol == 65537)
  342. {
  343. this.ProcessNumber(this.lexer.StringValue);
  344. this.parser_return = true;
  345. }
  346. else if (this.current_symbol == 65546)
  347. {
  348. this.token = JsonToken.PropertyName;
  349. }
  350. else if (this.current_symbol == 65538)
  351. {
  352. this.token = JsonToken.Boolean;
  353. this.token_value = true;
  354. this.parser_return = true;
  355. }
  356. }
  357. private bool ReadToken()
  358. {
  359. if (this.end_of_input)
  360. {
  361. return false;
  362. }
  363. this.lexer.NextToken();
  364. if (this.lexer.EndOfInput)
  365. {
  366. this.Close();
  367. return false;
  368. }
  369. this.current_input = this.lexer.Token;
  370. return true;
  371. }
  372. public void Close()
  373. {
  374. if (this.end_of_input)
  375. {
  376. return;
  377. }
  378. this.end_of_input = true;
  379. this.end_of_json = true;
  380. if (this.reader_is_owned)
  381. {
  382. this.reader.Close();
  383. }
  384. this.reader = null;
  385. }
  386. public bool Read()
  387. {
  388. if (this.end_of_input)
  389. {
  390. return false;
  391. }
  392. if (this.end_of_json)
  393. {
  394. this.end_of_json = false;
  395. this.automaton_stack.Clear();
  396. this.automaton_stack.Push(65553);
  397. this.automaton_stack.Push(65543);
  398. }
  399. this.parser_in_string = false;
  400. this.parser_return = false;
  401. this.token = JsonToken.None;
  402. this.token_value = null;
  403. if (!this.read_started)
  404. {
  405. this.read_started = true;
  406. if (!this.ReadToken())
  407. {
  408. return false;
  409. }
  410. }
  411. while (!this.parser_return)
  412. {
  413. this.current_symbol = this.automaton_stack.Pop();
  414. this.ProcessSymbol();
  415. if (this.current_symbol == this.current_input)
  416. {
  417. if (!this.ReadToken())
  418. {
  419. if (this.automaton_stack.Peek() != 65553)
  420. {
  421. throw new JsonException("Input doesn't evaluate to proper JSON text");
  422. }
  423. return this.parser_return;
  424. }
  425. }
  426. else
  427. {
  428. int[] array;
  429. try
  430. {
  431. array = JsonReader.parse_table[this.current_symbol][this.current_input];
  432. }
  433. catch (KeyNotFoundException inner_exception)
  434. {
  435. throw new JsonException((ParserToken)this.current_input, inner_exception);
  436. }
  437. if (array[0] != 65554)
  438. {
  439. for (int i = array.Length - 1; i >= 0; i--)
  440. {
  441. this.automaton_stack.Push(array[i]);
  442. }
  443. }
  444. }
  445. }
  446. if (this.automaton_stack.Peek() == 65553)
  447. {
  448. this.end_of_json = true;
  449. }
  450. return true;
  451. }
  452. private static IDictionary<int, IDictionary<int, int[]>> parse_table;
  453. private Stack<int> automaton_stack;
  454. private int current_input;
  455. private int current_symbol;
  456. private bool end_of_json;
  457. private bool end_of_input;
  458. private Lexer lexer;
  459. private bool parser_in_string;
  460. private bool parser_return;
  461. private bool read_started;
  462. private TextReader reader;
  463. private bool reader_is_owned;
  464. private bool skip_non_members;
  465. private object token_value;
  466. private JsonToken token;
  467. }
  468. }