OpenVRSimpleJSON.cs 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352
  1. /* * * * *
  2. * A simple JSON Parser / builder
  3. * ------------------------------
  4. *
  5. * It mainly has been written as a simple JSON parser. It can build a JSON string
  6. * from the node-tree, or generate a node tree from any valid JSON string.
  7. *
  8. * Written by Bunny83
  9. * 2012-06-09
  10. *
  11. * Changelog now external. See Changelog.txt
  12. *
  13. * The MIT License (MIT)
  14. *
  15. * Copyright (c) 2012-2019 Markus Göbel (Bunny83)
  16. *
  17. * Permission is hereby granted, free of charge, to any person obtaining a copy
  18. * of this software and associated documentation files (the "Software"), to deal
  19. * in the Software without restriction, including without limitation the rights
  20. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  21. * copies of the Software, and to permit persons to whom the Software is
  22. * furnished to do so, subject to the following conditions:
  23. *
  24. * The above copyright notice and this permission notice shall be included in all
  25. * copies or substantial portions of the Software.
  26. *
  27. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  28. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  29. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  30. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  31. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  32. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  33. * SOFTWARE.
  34. *
  35. * * * * */
  36. using System;
  37. using System.Collections;
  38. using System.Collections.Generic;
  39. using System.Globalization;
  40. using System.Linq;
  41. using System.Text;
  42. namespace Unity.XR.OpenVR.SimpleJSON
  43. {
  44. public enum JSONNodeType
  45. {
  46. Array = 1,
  47. Object = 2,
  48. String = 3,
  49. Number = 4,
  50. NullValue = 5,
  51. Boolean = 6,
  52. None = 7,
  53. Custom = 0xFF,
  54. }
  55. public enum JSONTextMode
  56. {
  57. Compact,
  58. Indent
  59. }
  60. public abstract partial class JSONNode
  61. {
  62. #region Enumerators
  63. public struct Enumerator
  64. {
  65. private enum Type { None, Array, Object }
  66. private Type type;
  67. private Dictionary<string, JSONNode>.Enumerator m_Object;
  68. private List<JSONNode>.Enumerator m_Array;
  69. public bool IsValid { get { return type != Type.None; } }
  70. public Enumerator(List<JSONNode>.Enumerator aArrayEnum)
  71. {
  72. type = Type.Array;
  73. m_Object = default(Dictionary<string, JSONNode>.Enumerator);
  74. m_Array = aArrayEnum;
  75. }
  76. public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
  77. {
  78. type = Type.Object;
  79. m_Object = aDictEnum;
  80. m_Array = default(List<JSONNode>.Enumerator);
  81. }
  82. public KeyValuePair<string, JSONNode> Current
  83. {
  84. get
  85. {
  86. if (type == Type.Array)
  87. return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current);
  88. else if (type == Type.Object)
  89. return m_Object.Current;
  90. return new KeyValuePair<string, JSONNode>(string.Empty, null);
  91. }
  92. }
  93. public bool MoveNext()
  94. {
  95. if (type == Type.Array)
  96. return m_Array.MoveNext();
  97. else if (type == Type.Object)
  98. return m_Object.MoveNext();
  99. return false;
  100. }
  101. }
  102. public struct ValueEnumerator
  103. {
  104. private Enumerator m_Enumerator;
  105. public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { }
  106. public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { }
  107. public ValueEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; }
  108. public JSONNode Current { get { return m_Enumerator.Current.Value; } }
  109. public bool MoveNext() { return m_Enumerator.MoveNext(); }
  110. public ValueEnumerator GetEnumerator() { return this; }
  111. }
  112. public struct KeyEnumerator
  113. {
  114. private Enumerator m_Enumerator;
  115. public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { }
  116. public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { }
  117. public KeyEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; }
  118. public string Current { get { return m_Enumerator.Current.Key; } }
  119. public bool MoveNext() { return m_Enumerator.MoveNext(); }
  120. public KeyEnumerator GetEnumerator() { return this; }
  121. }
  122. public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IEnumerable<KeyValuePair<string, JSONNode>>
  123. {
  124. private JSONNode m_Node;
  125. private Enumerator m_Enumerator;
  126. internal LinqEnumerator(JSONNode aNode)
  127. {
  128. m_Node = aNode;
  129. if (m_Node != null)
  130. m_Enumerator = m_Node.GetEnumerator();
  131. }
  132. public KeyValuePair<string, JSONNode> Current { get { return m_Enumerator.Current; } }
  133. object IEnumerator.Current { get { return m_Enumerator.Current; } }
  134. public bool MoveNext() { return m_Enumerator.MoveNext(); }
  135. public void Dispose()
  136. {
  137. m_Node = null;
  138. m_Enumerator = new Enumerator();
  139. }
  140. public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator()
  141. {
  142. return new LinqEnumerator(m_Node);
  143. }
  144. public void Reset()
  145. {
  146. if (m_Node != null)
  147. m_Enumerator = m_Node.GetEnumerator();
  148. }
  149. IEnumerator IEnumerable.GetEnumerator()
  150. {
  151. return new LinqEnumerator(m_Node);
  152. }
  153. }
  154. #endregion Enumerators
  155. #region common interface
  156. public static bool forceASCII = false; // Use Unicode by default
  157. public static bool longAsString = false; // lazy creator creates a JSONString instead of JSONNumber
  158. public static bool allowLineComments = true; // allow "//"-style comments at the end of a line
  159. public abstract JSONNodeType Tag { get; }
  160. public virtual JSONNode this[int aIndex] { get { return null; } set { } }
  161. public virtual JSONNode this[string aKey] { get { return null; } set { } }
  162. public virtual string Value { get { return ""; } set { } }
  163. public virtual int Count { get { return 0; } }
  164. public virtual bool IsNumber { get { return false; } }
  165. public virtual bool IsString { get { return false; } }
  166. public virtual bool IsBoolean { get { return false; } }
  167. public virtual bool IsNull { get { return false; } }
  168. public virtual bool IsArray { get { return false; } }
  169. public virtual bool IsObject { get { return false; } }
  170. public virtual bool Inline { get { return false; } set { } }
  171. public virtual void Add(string aKey, JSONNode aItem)
  172. {
  173. }
  174. public virtual void Add(JSONNode aItem)
  175. {
  176. Add("", aItem);
  177. }
  178. public virtual JSONNode Remove(string aKey)
  179. {
  180. return null;
  181. }
  182. public virtual JSONNode Remove(int aIndex)
  183. {
  184. return null;
  185. }
  186. public virtual JSONNode Remove(JSONNode aNode)
  187. {
  188. return aNode;
  189. }
  190. public virtual JSONNode Clone()
  191. {
  192. return null;
  193. }
  194. public virtual IEnumerable<JSONNode> Children
  195. {
  196. get
  197. {
  198. yield break;
  199. }
  200. }
  201. public IEnumerable<JSONNode> DeepChildren
  202. {
  203. get
  204. {
  205. foreach (var C in Children)
  206. foreach (var D in C.DeepChildren)
  207. yield return D;
  208. }
  209. }
  210. public virtual bool HasKey(string aKey)
  211. {
  212. return false;
  213. }
  214. public virtual JSONNode GetValueOrDefault(string aKey, JSONNode aDefault)
  215. {
  216. return aDefault;
  217. }
  218. public override string ToString()
  219. {
  220. StringBuilder sb = new StringBuilder();
  221. WriteToStringBuilder(sb, 0, 0, JSONTextMode.Compact);
  222. return sb.ToString();
  223. }
  224. public virtual string ToString(int aIndent)
  225. {
  226. StringBuilder sb = new StringBuilder();
  227. WriteToStringBuilder(sb, 0, aIndent, JSONTextMode.Indent);
  228. return sb.ToString();
  229. }
  230. internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode);
  231. public abstract Enumerator GetEnumerator();
  232. public IEnumerable<KeyValuePair<string, JSONNode>> Linq { get { return new LinqEnumerator(this); } }
  233. public KeyEnumerator Keys { get { return new KeyEnumerator(GetEnumerator()); } }
  234. public ValueEnumerator Values { get { return new ValueEnumerator(GetEnumerator()); } }
  235. #endregion common interface
  236. #region typecasting properties
  237. public virtual double AsDouble
  238. {
  239. get
  240. {
  241. double v = 0.0;
  242. if (double.TryParse(Value, NumberStyles.Float, CultureInfo.InvariantCulture, out v))
  243. return v;
  244. return 0.0;
  245. }
  246. set
  247. {
  248. Value = value.ToString(CultureInfo.InvariantCulture);
  249. }
  250. }
  251. public virtual int AsInt
  252. {
  253. get { return (int)AsDouble; }
  254. set { AsDouble = value; }
  255. }
  256. public virtual float AsFloat
  257. {
  258. get { return (float)AsDouble; }
  259. set { AsDouble = value; }
  260. }
  261. public virtual bool AsBool
  262. {
  263. get
  264. {
  265. bool v = false;
  266. if (bool.TryParse(Value, out v))
  267. return v;
  268. return !string.IsNullOrEmpty(Value);
  269. }
  270. set
  271. {
  272. Value = (value) ? "true" : "false";
  273. }
  274. }
  275. public virtual long AsLong
  276. {
  277. get
  278. {
  279. long val = 0;
  280. if (long.TryParse(Value, out val))
  281. return val;
  282. return 0L;
  283. }
  284. set
  285. {
  286. Value = value.ToString();
  287. }
  288. }
  289. public virtual JSONArray AsArray
  290. {
  291. get
  292. {
  293. return this as JSONArray;
  294. }
  295. }
  296. public virtual JSONObject AsObject
  297. {
  298. get
  299. {
  300. return this as JSONObject;
  301. }
  302. }
  303. #endregion typecasting properties
  304. #region operators
  305. public static implicit operator JSONNode(string s)
  306. {
  307. return new JSONString(s);
  308. }
  309. public static implicit operator string(JSONNode d)
  310. {
  311. return (d == null) ? null : d.Value;
  312. }
  313. public static implicit operator JSONNode(double n)
  314. {
  315. return new JSONNumber(n);
  316. }
  317. public static implicit operator double(JSONNode d)
  318. {
  319. return (d == null) ? 0 : d.AsDouble;
  320. }
  321. public static implicit operator JSONNode(float n)
  322. {
  323. return new JSONNumber(n);
  324. }
  325. public static implicit operator float(JSONNode d)
  326. {
  327. return (d == null) ? 0 : d.AsFloat;
  328. }
  329. public static implicit operator JSONNode(int n)
  330. {
  331. return new JSONNumber(n);
  332. }
  333. public static implicit operator int(JSONNode d)
  334. {
  335. return (d == null) ? 0 : d.AsInt;
  336. }
  337. public static implicit operator JSONNode(long n)
  338. {
  339. if (longAsString)
  340. return new JSONString(n.ToString());
  341. return new JSONNumber(n);
  342. }
  343. public static implicit operator long(JSONNode d)
  344. {
  345. return (d == null) ? 0L : d.AsLong;
  346. }
  347. public static implicit operator JSONNode(bool b)
  348. {
  349. return new JSONBool(b);
  350. }
  351. public static implicit operator bool(JSONNode d)
  352. {
  353. return (d == null) ? false : d.AsBool;
  354. }
  355. public static implicit operator JSONNode(KeyValuePair<string, JSONNode> aKeyValue)
  356. {
  357. return aKeyValue.Value;
  358. }
  359. public static bool operator ==(JSONNode a, object b)
  360. {
  361. if (ReferenceEquals(a, b))
  362. return true;
  363. bool aIsNull = a is JSONNull || ReferenceEquals(a, null) || a is JSONLazyCreator;
  364. bool bIsNull = b is JSONNull || ReferenceEquals(b, null) || b is JSONLazyCreator;
  365. if (aIsNull && bIsNull)
  366. return true;
  367. return !aIsNull && a.Equals(b);
  368. }
  369. public static bool operator !=(JSONNode a, object b)
  370. {
  371. return !(a == b);
  372. }
  373. public override bool Equals(object obj)
  374. {
  375. return ReferenceEquals(this, obj);
  376. }
  377. public override int GetHashCode()
  378. {
  379. return base.GetHashCode();
  380. }
  381. #endregion operators
  382. [ThreadStatic]
  383. private static StringBuilder m_EscapeBuilder;
  384. internal static StringBuilder EscapeBuilder
  385. {
  386. get
  387. {
  388. if (m_EscapeBuilder == null)
  389. m_EscapeBuilder = new StringBuilder();
  390. return m_EscapeBuilder;
  391. }
  392. }
  393. internal static string Escape(string aText)
  394. {
  395. var sb = EscapeBuilder;
  396. sb.Length = 0;
  397. if (sb.Capacity < aText.Length + aText.Length / 10)
  398. sb.Capacity = aText.Length + aText.Length / 10;
  399. foreach (char c in aText)
  400. {
  401. switch (c)
  402. {
  403. case '\\':
  404. sb.Append("\\\\");
  405. break;
  406. case '\"':
  407. sb.Append("\\\"");
  408. break;
  409. case '\n':
  410. sb.Append("\\n");
  411. break;
  412. case '\r':
  413. sb.Append("\\r");
  414. break;
  415. case '\t':
  416. sb.Append("\\t");
  417. break;
  418. case '\b':
  419. sb.Append("\\b");
  420. break;
  421. case '\f':
  422. sb.Append("\\f");
  423. break;
  424. default:
  425. if (c < ' ' || (forceASCII && c > 127))
  426. {
  427. ushort val = c;
  428. sb.Append("\\u").Append(val.ToString("X4"));
  429. }
  430. else
  431. sb.Append(c);
  432. break;
  433. }
  434. }
  435. string result = sb.ToString();
  436. sb.Length = 0;
  437. return result;
  438. }
  439. private static JSONNode ParseElement(string token, bool quoted)
  440. {
  441. if (quoted)
  442. return token;
  443. string tmp = token.ToLower();
  444. if (tmp == "false" || tmp == "true")
  445. return tmp == "true";
  446. if (tmp == "null")
  447. return JSONNull.CreateOrGet();
  448. double val;
  449. if (double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out val))
  450. return val;
  451. else
  452. return token;
  453. }
  454. public static JSONNode Parse(string aJSON)
  455. {
  456. Stack<JSONNode> stack = new Stack<JSONNode>();
  457. JSONNode ctx = null;
  458. int i = 0;
  459. StringBuilder Token = new StringBuilder();
  460. string TokenName = "";
  461. bool QuoteMode = false;
  462. bool TokenIsQuoted = false;
  463. while (i < aJSON.Length)
  464. {
  465. switch (aJSON[i])
  466. {
  467. case '{':
  468. if (QuoteMode)
  469. {
  470. Token.Append(aJSON[i]);
  471. break;
  472. }
  473. stack.Push(new JSONObject());
  474. if (ctx != null)
  475. {
  476. ctx.Add(TokenName, stack.Peek());
  477. }
  478. TokenName = "";
  479. Token.Length = 0;
  480. ctx = stack.Peek();
  481. break;
  482. case '[':
  483. if (QuoteMode)
  484. {
  485. Token.Append(aJSON[i]);
  486. break;
  487. }
  488. stack.Push(new JSONArray());
  489. if (ctx != null)
  490. {
  491. ctx.Add(TokenName, stack.Peek());
  492. }
  493. TokenName = "";
  494. Token.Length = 0;
  495. ctx = stack.Peek();
  496. break;
  497. case '}':
  498. case ']':
  499. if (QuoteMode)
  500. {
  501. Token.Append(aJSON[i]);
  502. break;
  503. }
  504. if (stack.Count == 0)
  505. throw new Exception("JSON Parse: Too many closing brackets");
  506. stack.Pop();
  507. if (Token.Length > 0 || TokenIsQuoted)
  508. ctx.Add(TokenName, ParseElement(Token.ToString(), TokenIsQuoted));
  509. TokenIsQuoted = false;
  510. TokenName = "";
  511. Token.Length = 0;
  512. if (stack.Count > 0)
  513. ctx = stack.Peek();
  514. break;
  515. case ':':
  516. if (QuoteMode)
  517. {
  518. Token.Append(aJSON[i]);
  519. break;
  520. }
  521. TokenName = Token.ToString();
  522. Token.Length = 0;
  523. TokenIsQuoted = false;
  524. break;
  525. case '"':
  526. QuoteMode ^= true;
  527. TokenIsQuoted |= QuoteMode;
  528. break;
  529. case ',':
  530. if (QuoteMode)
  531. {
  532. Token.Append(aJSON[i]);
  533. break;
  534. }
  535. if (Token.Length > 0 || TokenIsQuoted)
  536. ctx.Add(TokenName, ParseElement(Token.ToString(), TokenIsQuoted));
  537. TokenIsQuoted = false;
  538. TokenName = "";
  539. Token.Length = 0;
  540. TokenIsQuoted = false;
  541. break;
  542. case '\r':
  543. case '\n':
  544. break;
  545. case ' ':
  546. case '\t':
  547. if (QuoteMode)
  548. Token.Append(aJSON[i]);
  549. break;
  550. case '\\':
  551. ++i;
  552. if (QuoteMode)
  553. {
  554. char C = aJSON[i];
  555. switch (C)
  556. {
  557. case 't':
  558. Token.Append('\t');
  559. break;
  560. case 'r':
  561. Token.Append('\r');
  562. break;
  563. case 'n':
  564. Token.Append('\n');
  565. break;
  566. case 'b':
  567. Token.Append('\b');
  568. break;
  569. case 'f':
  570. Token.Append('\f');
  571. break;
  572. case 'u':
  573. {
  574. string s = aJSON.Substring(i + 1, 4);
  575. Token.Append((char)int.Parse(
  576. s,
  577. System.Globalization.NumberStyles.AllowHexSpecifier));
  578. i += 4;
  579. break;
  580. }
  581. default:
  582. Token.Append(C);
  583. break;
  584. }
  585. }
  586. break;
  587. case '/':
  588. if (allowLineComments && !QuoteMode && i + 1 < aJSON.Length && aJSON[i + 1] == '/')
  589. {
  590. while (++i < aJSON.Length && aJSON[i] != '\n' && aJSON[i] != '\r') ;
  591. break;
  592. }
  593. Token.Append(aJSON[i]);
  594. break;
  595. case '\uFEFF': // remove / ignore BOM (Byte Order Mark)
  596. break;
  597. default:
  598. Token.Append(aJSON[i]);
  599. break;
  600. }
  601. ++i;
  602. }
  603. if (QuoteMode)
  604. {
  605. throw new Exception("JSON Parse: Quotation marks seems to be messed up.");
  606. }
  607. if (ctx == null)
  608. return ParseElement(Token.ToString(), TokenIsQuoted);
  609. return ctx;
  610. }
  611. }
  612. // End of JSONNode
  613. public partial class JSONArray : JSONNode
  614. {
  615. private List<JSONNode> m_List = new List<JSONNode>();
  616. private bool inline = false;
  617. public override bool Inline
  618. {
  619. get { return inline; }
  620. set { inline = value; }
  621. }
  622. public override JSONNodeType Tag { get { return JSONNodeType.Array; } }
  623. public override bool IsArray { get { return true; } }
  624. public override Enumerator GetEnumerator() { return new Enumerator(m_List.GetEnumerator()); }
  625. public override JSONNode this[int aIndex]
  626. {
  627. get
  628. {
  629. if (aIndex < 0 || aIndex >= m_List.Count)
  630. return new JSONLazyCreator(this);
  631. return m_List[aIndex];
  632. }
  633. set
  634. {
  635. if (value == null)
  636. value = JSONNull.CreateOrGet();
  637. if (aIndex < 0 || aIndex >= m_List.Count)
  638. m_List.Add(value);
  639. else
  640. m_List[aIndex] = value;
  641. }
  642. }
  643. public override JSONNode this[string aKey]
  644. {
  645. get { return new JSONLazyCreator(this); }
  646. set
  647. {
  648. if (value == null)
  649. value = JSONNull.CreateOrGet();
  650. m_List.Add(value);
  651. }
  652. }
  653. public override int Count
  654. {
  655. get { return m_List.Count; }
  656. }
  657. public override void Add(string aKey, JSONNode aItem)
  658. {
  659. if (aItem == null)
  660. aItem = JSONNull.CreateOrGet();
  661. m_List.Add(aItem);
  662. }
  663. public override JSONNode Remove(int aIndex)
  664. {
  665. if (aIndex < 0 || aIndex >= m_List.Count)
  666. return null;
  667. JSONNode tmp = m_List[aIndex];
  668. m_List.RemoveAt(aIndex);
  669. return tmp;
  670. }
  671. public override JSONNode Remove(JSONNode aNode)
  672. {
  673. m_List.Remove(aNode);
  674. return aNode;
  675. }
  676. public override JSONNode Clone()
  677. {
  678. var node = new JSONArray();
  679. node.m_List.Capacity = m_List.Capacity;
  680. foreach (var n in m_List)
  681. {
  682. if (n != null)
  683. node.Add(n.Clone());
  684. else
  685. node.Add(null);
  686. }
  687. return node;
  688. }
  689. public override IEnumerable<JSONNode> Children
  690. {
  691. get
  692. {
  693. foreach (JSONNode N in m_List)
  694. yield return N;
  695. }
  696. }
  697. internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
  698. {
  699. aSB.Append('[');
  700. int count = m_List.Count;
  701. if (inline)
  702. aMode = JSONTextMode.Compact;
  703. for (int i = 0; i < count; i++)
  704. {
  705. if (i > 0)
  706. aSB.Append(',');
  707. if (aMode == JSONTextMode.Indent)
  708. aSB.AppendLine();
  709. if (aMode == JSONTextMode.Indent)
  710. aSB.Append(' ', aIndent + aIndentInc);
  711. m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
  712. }
  713. if (aMode == JSONTextMode.Indent)
  714. aSB.AppendLine().Append(' ', aIndent);
  715. aSB.Append(']');
  716. }
  717. }
  718. // End of JSONArray
  719. public partial class JSONObject : JSONNode
  720. {
  721. private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>();
  722. private bool inline = false;
  723. public override bool Inline
  724. {
  725. get { return inline; }
  726. set { inline = value; }
  727. }
  728. public override JSONNodeType Tag { get { return JSONNodeType.Object; } }
  729. public override bool IsObject { get { return true; } }
  730. public override Enumerator GetEnumerator() { return new Enumerator(m_Dict.GetEnumerator()); }
  731. public override JSONNode this[string aKey]
  732. {
  733. get
  734. {
  735. if (m_Dict.ContainsKey(aKey))
  736. return m_Dict[aKey];
  737. else
  738. return new JSONLazyCreator(this, aKey);
  739. }
  740. set
  741. {
  742. if (value == null)
  743. value = JSONNull.CreateOrGet();
  744. if (m_Dict.ContainsKey(aKey))
  745. m_Dict[aKey] = value;
  746. else
  747. m_Dict.Add(aKey, value);
  748. }
  749. }
  750. public override JSONNode this[int aIndex]
  751. {
  752. get
  753. {
  754. if (aIndex < 0 || aIndex >= m_Dict.Count)
  755. return null;
  756. return m_Dict.ElementAt(aIndex).Value;
  757. }
  758. set
  759. {
  760. if (value == null)
  761. value = JSONNull.CreateOrGet();
  762. if (aIndex < 0 || aIndex >= m_Dict.Count)
  763. return;
  764. string key = m_Dict.ElementAt(aIndex).Key;
  765. m_Dict[key] = value;
  766. }
  767. }
  768. public override int Count
  769. {
  770. get { return m_Dict.Count; }
  771. }
  772. public override void Add(string aKey, JSONNode aItem)
  773. {
  774. if (aItem == null)
  775. aItem = JSONNull.CreateOrGet();
  776. if (aKey != null)
  777. {
  778. if (m_Dict.ContainsKey(aKey))
  779. m_Dict[aKey] = aItem;
  780. else
  781. m_Dict.Add(aKey, aItem);
  782. }
  783. else
  784. m_Dict.Add(Guid.NewGuid().ToString(), aItem);
  785. }
  786. public override JSONNode Remove(string aKey)
  787. {
  788. if (!m_Dict.ContainsKey(aKey))
  789. return null;
  790. JSONNode tmp = m_Dict[aKey];
  791. m_Dict.Remove(aKey);
  792. return tmp;
  793. }
  794. public override JSONNode Remove(int aIndex)
  795. {
  796. if (aIndex < 0 || aIndex >= m_Dict.Count)
  797. return null;
  798. var item = m_Dict.ElementAt(aIndex);
  799. m_Dict.Remove(item.Key);
  800. return item.Value;
  801. }
  802. public override JSONNode Remove(JSONNode aNode)
  803. {
  804. try
  805. {
  806. var item = m_Dict.Where(k => k.Value == aNode).First();
  807. m_Dict.Remove(item.Key);
  808. return aNode;
  809. }
  810. catch
  811. {
  812. return null;
  813. }
  814. }
  815. public override JSONNode Clone()
  816. {
  817. var node = new JSONObject();
  818. foreach (var n in m_Dict)
  819. {
  820. node.Add(n.Key, n.Value.Clone());
  821. }
  822. return node;
  823. }
  824. public override bool HasKey(string aKey)
  825. {
  826. return m_Dict.ContainsKey(aKey);
  827. }
  828. public override JSONNode GetValueOrDefault(string aKey, JSONNode aDefault)
  829. {
  830. JSONNode res;
  831. if (m_Dict.TryGetValue(aKey, out res))
  832. return res;
  833. return aDefault;
  834. }
  835. public override IEnumerable<JSONNode> Children
  836. {
  837. get
  838. {
  839. foreach (KeyValuePair<string, JSONNode> N in m_Dict)
  840. yield return N.Value;
  841. }
  842. }
  843. internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
  844. {
  845. aSB.Append('{');
  846. bool first = true;
  847. if (inline)
  848. aMode = JSONTextMode.Compact;
  849. foreach (var k in m_Dict)
  850. {
  851. if (!first)
  852. aSB.Append(',');
  853. first = false;
  854. if (aMode == JSONTextMode.Indent)
  855. aSB.AppendLine();
  856. if (aMode == JSONTextMode.Indent)
  857. aSB.Append(' ', aIndent + aIndentInc);
  858. aSB.Append('\"').Append(Escape(k.Key)).Append('\"');
  859. if (aMode == JSONTextMode.Compact)
  860. aSB.Append(':');
  861. else
  862. aSB.Append(" : ");
  863. k.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
  864. }
  865. if (aMode == JSONTextMode.Indent)
  866. aSB.AppendLine().Append(' ', aIndent);
  867. aSB.Append('}');
  868. }
  869. }
  870. // End of JSONObject
  871. public partial class JSONString : JSONNode
  872. {
  873. private string m_Data;
  874. public override JSONNodeType Tag { get { return JSONNodeType.String; } }
  875. public override bool IsString { get { return true; } }
  876. public override Enumerator GetEnumerator() { return new Enumerator(); }
  877. public override string Value
  878. {
  879. get { return m_Data; }
  880. set
  881. {
  882. m_Data = value;
  883. }
  884. }
  885. public JSONString(string aData)
  886. {
  887. m_Data = aData;
  888. }
  889. public override JSONNode Clone()
  890. {
  891. return new JSONString(m_Data);
  892. }
  893. internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
  894. {
  895. aSB.Append('\"').Append(Escape(m_Data)).Append('\"');
  896. }
  897. public override bool Equals(object obj)
  898. {
  899. if (base.Equals(obj))
  900. return true;
  901. string s = obj as string;
  902. if (s != null)
  903. return m_Data == s;
  904. JSONString s2 = obj as JSONString;
  905. if (s2 != null)
  906. return m_Data == s2.m_Data;
  907. return false;
  908. }
  909. public override int GetHashCode()
  910. {
  911. return m_Data.GetHashCode();
  912. }
  913. }
  914. // End of JSONString
  915. public partial class JSONNumber : JSONNode
  916. {
  917. private double m_Data;
  918. public override JSONNodeType Tag { get { return JSONNodeType.Number; } }
  919. public override bool IsNumber { get { return true; } }
  920. public override Enumerator GetEnumerator() { return new Enumerator(); }
  921. public override string Value
  922. {
  923. get { return m_Data.ToString(CultureInfo.InvariantCulture); }
  924. set
  925. {
  926. double v;
  927. if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out v))
  928. m_Data = v;
  929. }
  930. }
  931. public override double AsDouble
  932. {
  933. get { return m_Data; }
  934. set { m_Data = value; }
  935. }
  936. public override long AsLong
  937. {
  938. get { return (long)m_Data; }
  939. set { m_Data = value; }
  940. }
  941. public JSONNumber(double aData)
  942. {
  943. m_Data = aData;
  944. }
  945. public JSONNumber(string aData)
  946. {
  947. Value = aData;
  948. }
  949. public override JSONNode Clone()
  950. {
  951. return new JSONNumber(m_Data);
  952. }
  953. internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
  954. {
  955. aSB.Append(Value);
  956. }
  957. private static bool IsNumeric(object value)
  958. {
  959. return value is int || value is uint
  960. || value is float || value is double
  961. || value is decimal
  962. || value is long || value is ulong
  963. || value is short || value is ushort
  964. || value is sbyte || value is byte;
  965. }
  966. public override bool Equals(object obj)
  967. {
  968. if (obj == null)
  969. return false;
  970. if (base.Equals(obj))
  971. return true;
  972. JSONNumber s2 = obj as JSONNumber;
  973. if (s2 != null)
  974. return m_Data == s2.m_Data;
  975. if (IsNumeric(obj))
  976. return Convert.ToDouble(obj) == m_Data;
  977. return false;
  978. }
  979. public override int GetHashCode()
  980. {
  981. return m_Data.GetHashCode();
  982. }
  983. }
  984. // End of JSONNumber
  985. public partial class JSONBool : JSONNode
  986. {
  987. private bool m_Data;
  988. public override JSONNodeType Tag { get { return JSONNodeType.Boolean; } }
  989. public override bool IsBoolean { get { return true; } }
  990. public override Enumerator GetEnumerator() { return new Enumerator(); }
  991. public override string Value
  992. {
  993. get { return m_Data.ToString(); }
  994. set
  995. {
  996. bool v;
  997. if (bool.TryParse(value, out v))
  998. m_Data = v;
  999. }
  1000. }
  1001. public override bool AsBool
  1002. {
  1003. get { return m_Data; }
  1004. set { m_Data = value; }
  1005. }
  1006. public JSONBool(bool aData)
  1007. {
  1008. m_Data = aData;
  1009. }
  1010. public JSONBool(string aData)
  1011. {
  1012. Value = aData;
  1013. }
  1014. public override JSONNode Clone()
  1015. {
  1016. return new JSONBool(m_Data);
  1017. }
  1018. internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
  1019. {
  1020. aSB.Append((m_Data) ? "true" : "false");
  1021. }
  1022. public override bool Equals(object obj)
  1023. {
  1024. if (obj == null)
  1025. return false;
  1026. if (obj is bool)
  1027. return m_Data == (bool)obj;
  1028. return false;
  1029. }
  1030. public override int GetHashCode()
  1031. {
  1032. return m_Data.GetHashCode();
  1033. }
  1034. }
  1035. // End of JSONBool
  1036. public partial class JSONNull : JSONNode
  1037. {
  1038. static JSONNull m_StaticInstance = new JSONNull();
  1039. public static bool reuseSameInstance = true;
  1040. public static JSONNull CreateOrGet()
  1041. {
  1042. if (reuseSameInstance)
  1043. return m_StaticInstance;
  1044. return new JSONNull();
  1045. }
  1046. private JSONNull() { }
  1047. public override JSONNodeType Tag { get { return JSONNodeType.NullValue; } }
  1048. public override bool IsNull { get { return true; } }
  1049. public override Enumerator GetEnumerator() { return new Enumerator(); }
  1050. public override string Value
  1051. {
  1052. get { return "null"; }
  1053. set { }
  1054. }
  1055. public override bool AsBool
  1056. {
  1057. get { return false; }
  1058. set { }
  1059. }
  1060. public override JSONNode Clone()
  1061. {
  1062. return CreateOrGet();
  1063. }
  1064. public override bool Equals(object obj)
  1065. {
  1066. if (object.ReferenceEquals(this, obj))
  1067. return true;
  1068. return (obj is JSONNull);
  1069. }
  1070. public override int GetHashCode()
  1071. {
  1072. return 0;
  1073. }
  1074. internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
  1075. {
  1076. aSB.Append("null");
  1077. }
  1078. }
  1079. // End of JSONNull
  1080. internal partial class JSONLazyCreator : JSONNode
  1081. {
  1082. private JSONNode m_Node = null;
  1083. private string m_Key = null;
  1084. public override JSONNodeType Tag { get { return JSONNodeType.None; } }
  1085. public override Enumerator GetEnumerator() { return new Enumerator(); }
  1086. public JSONLazyCreator(JSONNode aNode)
  1087. {
  1088. m_Node = aNode;
  1089. m_Key = null;
  1090. }
  1091. public JSONLazyCreator(JSONNode aNode, string aKey)
  1092. {
  1093. m_Node = aNode;
  1094. m_Key = aKey;
  1095. }
  1096. private T Set<T>(T aVal) where T : JSONNode
  1097. {
  1098. if (m_Key == null)
  1099. m_Node.Add(aVal);
  1100. else
  1101. m_Node.Add(m_Key, aVal);
  1102. m_Node = null; // Be GC friendly.
  1103. return aVal;
  1104. }
  1105. public override JSONNode this[int aIndex]
  1106. {
  1107. get { return new JSONLazyCreator(this); }
  1108. set { Set(new JSONArray()).Add(value); }
  1109. }
  1110. public override JSONNode this[string aKey]
  1111. {
  1112. get { return new JSONLazyCreator(this, aKey); }
  1113. set { Set(new JSONObject()).Add(aKey, value); }
  1114. }
  1115. public override void Add(JSONNode aItem)
  1116. {
  1117. Set(new JSONArray()).Add(aItem);
  1118. }
  1119. public override void Add(string aKey, JSONNode aItem)
  1120. {
  1121. Set(new JSONObject()).Add(aKey, aItem);
  1122. }
  1123. public static bool operator ==(JSONLazyCreator a, object b)
  1124. {
  1125. if (b == null)
  1126. return true;
  1127. return System.Object.ReferenceEquals(a, b);
  1128. }
  1129. public static bool operator !=(JSONLazyCreator a, object b)
  1130. {
  1131. return !(a == b);
  1132. }
  1133. public override bool Equals(object obj)
  1134. {
  1135. if (obj == null)
  1136. return true;
  1137. return System.Object.ReferenceEquals(this, obj);
  1138. }
  1139. public override int GetHashCode()
  1140. {
  1141. return 0;
  1142. }
  1143. public override int AsInt
  1144. {
  1145. get { Set(new JSONNumber(0)); return 0; }
  1146. set { Set(new JSONNumber(value)); }
  1147. }
  1148. public override float AsFloat
  1149. {
  1150. get { Set(new JSONNumber(0.0f)); return 0.0f; }
  1151. set { Set(new JSONNumber(value)); }
  1152. }
  1153. public override double AsDouble
  1154. {
  1155. get { Set(new JSONNumber(0.0)); return 0.0; }
  1156. set { Set(new JSONNumber(value)); }
  1157. }
  1158. public override long AsLong
  1159. {
  1160. get
  1161. {
  1162. if (longAsString)
  1163. Set(new JSONString("0"));
  1164. else
  1165. Set(new JSONNumber(0.0));
  1166. return 0L;
  1167. }
  1168. set
  1169. {
  1170. if (longAsString)
  1171. Set(new JSONString(value.ToString()));
  1172. else
  1173. Set(new JSONNumber(value));
  1174. }
  1175. }
  1176. public override bool AsBool
  1177. {
  1178. get { Set(new JSONBool(false)); return false; }
  1179. set { Set(new JSONBool(value)); }
  1180. }
  1181. public override JSONArray AsArray
  1182. {
  1183. get { return Set(new JSONArray()); }
  1184. }
  1185. public override JSONObject AsObject
  1186. {
  1187. get { return Set(new JSONObject()); }
  1188. }
  1189. internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
  1190. {
  1191. aSB.Append("null");
  1192. }
  1193. }
  1194. // End of JSONLazyCreator
  1195. public static class JSON
  1196. {
  1197. public static JSONNode Parse(string aJSON)
  1198. {
  1199. return JSONNode.Parse(aJSON);
  1200. }
  1201. }
  1202. }