demonixis

SimpleJSON

Sep 11th, 2014
471
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 33.62 KB | None | 0 0
  1. //#define USE_SharpZipLib
  2. #if !UNITY_WEBPLAYER
  3. #define USE_FileIO
  4. #endif
  5.  
  6. /* * * * *
  7.  * A simple JSON Parser / builder
  8.  * ------------------------------
  9.  *
  10.  * It mainly has been written as a simple JSON parser. It can build a JSON string
  11.  * from the node-tree, or generate a node tree from any valid JSON string.
  12.  *
  13.  * If you want to use compression when saving to file / stream / B64 you have to include
  14.  * SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ ) in your project and
  15.  * define "USE_SharpZipLib" at the top of the file
  16.  *
  17.  * Written by Bunny83
  18.  * 2012-06-09
  19.  *
  20.  * Features / attributes:
  21.  * - provides strongly typed node classes and lists / dictionaries
  22.  * - provides easy access to class members / array items / data values
  23.  * - the parser ignores data types. Each value is a string.
  24.  * - only double quotes (") are used for quoting strings.
  25.  * - values and names are not restricted to quoted strings. They simply add up and are trimmed.
  26.  * - There are only 3 types: arrays(JSONArray), objects(JSONClass) and values(JSONData)
  27.  * - provides "casting" properties to easily convert to / from those types:
  28.  *   int / float / double / bool
  29.  * - provides a common interface for each node so no explicit casting is required.
  30.  * - the parser try to avoid errors, but if malformed JSON is parsed the result is undefined
  31.  *
  32.  *
  33.  * 2012-12-17 Update:
  34.  * - Added internal JSONLazyCreator class which simplifies the construction of a JSON tree
  35.  *   Now you can simple reference any item that doesn't exist yet and it will return a JSONLazyCreator
  36.  *   The class determines the required type by it's further use, creates the type and removes itself.
  37.  * - Added binary serialization / deserialization.
  38.  * - Added support for BZip2 zipped binary format. Requires the SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ )
  39.  *   The usage of the SharpZipLib library can be disabled by removing or commenting out the USE_SharpZipLib define at the top
  40.  * - The serializer uses different types when it comes to store the values. Since my data values
  41.  *   are all of type string, the serializer will "try" which format fits best. The order is: int, float, double, bool, string.
  42.  *   It's not the most efficient way but for a moderate amount of data it should work on all platforms.
  43.  *
  44.  * * * * */
  45. using System;
  46. using System.Collections;
  47. using System.Collections.Generic;
  48. using System.Linq;
  49.  
  50.  
  51. namespace SimpleJSON
  52. {
  53.     public enum JSONBinaryTag
  54.     {
  55.         Array            = 1,
  56.         Class            = 2,
  57.         Value            = 3,
  58.         IntValue        = 4,
  59.         DoubleValue        = 5,
  60.         BoolValue        = 6,
  61.         FloatValue        = 7,
  62.     }
  63.  
  64.     public class JSONNode
  65.     {
  66.         #region common interface
  67.         public virtual void Add(string aKey, JSONNode aItem){ }
  68.         public virtual JSONNode this[int aIndex]   { get { return null; } set { } }
  69.         public virtual JSONNode this[string aKey]  { get { return null; } set { } }
  70.         public virtual string Value                { get { return "";   } set { } }
  71.         public virtual int Count                   { get { return 0;    } }
  72.  
  73.         public virtual void Add(JSONNode aItem)
  74.         {
  75.             Add("", aItem);
  76.         }
  77.  
  78.         public virtual JSONNode Remove(string aKey) { return null; }
  79.         public virtual JSONNode Remove(int aIndex) { return null; }
  80.         public virtual JSONNode Remove(JSONNode aNode) { return aNode; }
  81.  
  82.         public virtual IEnumerable<JSONNode> Childs { get { yield break;} }
  83.         public IEnumerable<JSONNode> DeepChilds
  84.         {
  85.             get
  86.             {
  87.                 foreach (var C in Childs)
  88.                     foreach (var D in C.DeepChilds)
  89.                         yield return D;
  90.             }
  91.         }
  92.  
  93.         public override string ToString()
  94.         {
  95.             return "JSONNode";
  96.         }
  97.         public virtual string ToString(string aPrefix)
  98.         {
  99.             return "JSONNode";
  100.         }
  101.  
  102.         #endregion common interface
  103.  
  104.         #region typecasting properties
  105.         public virtual int AsInt
  106.         {
  107.             get
  108.             {
  109.                 int v = 0;
  110.                 if (int.TryParse(Value,out v))
  111.                     return v;
  112.                 return 0;
  113.             }
  114.             set
  115.             {
  116.                 Value = value.ToString();
  117.             }
  118.         }
  119.         public virtual float AsFloat
  120.         {
  121.             get
  122.             {
  123.                 float v = 0.0f;
  124.                 if (float.TryParse(Value,out v))
  125.                     return v;
  126.                 return 0.0f;
  127.             }
  128.             set
  129.             {
  130.                 Value = value.ToString();
  131.             }
  132.         }
  133.         public virtual double AsDouble
  134.         {
  135.             get
  136.             {
  137.                 double v = 0.0;
  138.                 if (double.TryParse(Value,out v))
  139.                     return v;
  140.                 return 0.0;
  141.             }
  142.             set
  143.             {
  144.                 Value = value.ToString();
  145.             }
  146.         }
  147.         public virtual bool AsBool
  148.         {
  149.             get
  150.             {
  151.                 bool v = false;
  152.                 if (bool.TryParse(Value,out v))
  153.                     return v;
  154.                 return !string.IsNullOrEmpty(Value);
  155.             }
  156.             set
  157.             {
  158.                 Value = (value)?"true":"false";
  159.             }
  160.         }
  161.         public virtual JSONArray AsArray
  162.         {
  163.             get
  164.             {
  165.                 return this as JSONArray;
  166.             }
  167.         }
  168.         public virtual JSONClass AsObject
  169.         {
  170.             get
  171.             {
  172.                 return this as JSONClass;
  173.             }
  174.         }
  175.  
  176.  
  177.         #endregion typecasting properties
  178.  
  179.         #region operators
  180.         public static implicit operator JSONNode(string s)
  181.         {
  182.             return new JSONData(s);
  183.         }
  184.         public static implicit operator string(JSONNode d)
  185.         {
  186.             return (d == null)?null:d.Value;
  187.         }
  188.         public static bool operator ==(JSONNode a, object b)
  189.         {
  190.             if (b == null && a is JSONLazyCreator)
  191.                 return true;
  192.             return System.Object.ReferenceEquals(a,b);
  193.         }
  194.  
  195.         public static bool operator !=(JSONNode a, object b)
  196.         {
  197.             return !(a == b);
  198.         }
  199.         public override bool Equals (object obj)
  200.         {
  201.             return System.Object.ReferenceEquals(this, obj);
  202.         }
  203.         public override int GetHashCode ()
  204.         {
  205.             return base.GetHashCode();
  206.         }
  207.  
  208.  
  209.         #endregion operators
  210.  
  211.         internal static string Escape(string aText)
  212.         {
  213.             string result = "";
  214.             foreach(char c in aText)
  215.             {
  216.                 switch(c)
  217.                 {
  218.                     case '\\' : result += "\\\\"; break;
  219.                     case '\"' : result += "\\\""; break;
  220.                     case '\n' : result += "\\n" ; break;
  221.                     case '\r' : result += "\\r" ; break;
  222.                     case '\t' : result += "\\t" ; break;
  223.                     case '\b' : result += "\\b" ; break;
  224.                     case '\f' : result += "\\f" ; break;
  225.                     default   : result += c     ; break;
  226.                 }
  227.             }
  228.             return result;
  229.         }
  230.  
  231.         public static JSONNode Parse(string aJSON)
  232.         {
  233.             Stack<JSONNode> stack = new Stack<JSONNode>();
  234.             JSONNode ctx = null;
  235.             int i = 0;
  236.             string Token = "";
  237.             string TokenName = "";
  238.             bool QuoteMode = false;
  239.             while (i < aJSON.Length)
  240.             {
  241.                 switch (aJSON[i])
  242.                 {
  243.                     case '{':
  244.                         if (QuoteMode)
  245.                         {
  246.                             Token += aJSON[i];
  247.                             break;
  248.                         }
  249.                         stack.Push(new JSONClass());
  250.                         if (ctx != null)
  251.                         {
  252.                             TokenName = TokenName.Trim();
  253.                             if (ctx is JSONArray)
  254.                                 ctx.Add(stack.Peek());
  255.                             else if (TokenName != "")
  256.                                 ctx.Add(TokenName,stack.Peek());
  257.                         }
  258.                         TokenName = "";
  259.                         Token = "";
  260.                         ctx = stack.Peek();
  261.                     break;
  262.  
  263.                     case '[':
  264.                         if (QuoteMode)
  265.                         {
  266.                             Token += aJSON[i];
  267.                             break;
  268.                         }
  269.  
  270.                         stack.Push(new JSONArray());
  271.                         if (ctx != null)
  272.                         {
  273.                             TokenName = TokenName.Trim();
  274.                             if (ctx is JSONArray)
  275.                                 ctx.Add(stack.Peek());
  276.                             else if (TokenName != "")
  277.                                 ctx.Add(TokenName,stack.Peek());
  278.                         }
  279.                         TokenName = "";
  280.                         Token = "";
  281.                         ctx = stack.Peek();
  282.                     break;
  283.  
  284.                     case '}':
  285.                     case ']':
  286.                         if (QuoteMode)
  287.                         {
  288.                             Token += aJSON[i];
  289.                             break;
  290.                         }
  291.                         if (stack.Count == 0)
  292.                             throw new Exception("JSON Parse: Too many closing brackets");
  293.  
  294.                         stack.Pop();
  295.                         if (Token != "")
  296.                         {
  297.                             TokenName = TokenName.Trim();
  298.                             if (ctx is JSONArray)
  299.                                 ctx.Add(Token);
  300.                             else if (TokenName != "")
  301.                                 ctx.Add(TokenName,Token);
  302.                         }
  303.                         TokenName = "";
  304.                         Token = "";
  305.                         if (stack.Count>0)
  306.                             ctx = stack.Peek();
  307.                     break;
  308.  
  309.                     case ':':
  310.                         if (QuoteMode)
  311.                         {
  312.                             Token += aJSON[i];
  313.                             break;
  314.                         }
  315.                         TokenName = Token;
  316.                         Token = "";
  317.                     break;
  318.  
  319.                     case '"':
  320.                         QuoteMode ^= true;
  321.                     break;
  322.  
  323.                     case ',':
  324.                         if (QuoteMode)
  325.                         {
  326.                             Token += aJSON[i];
  327.                             break;
  328.                         }
  329.                         if (Token != "")
  330.                         {
  331.                             if (ctx is JSONArray)
  332.                                 ctx.Add(Token);
  333.                             else if (TokenName != "")
  334.                                 ctx.Add(TokenName, Token);
  335.                         }
  336.                         TokenName = "";
  337.                         Token = "";
  338.                     break;
  339.  
  340.                     case '\r':
  341.                     case '\n':
  342.                     break;
  343.  
  344.                     case ' ':
  345.                     case '\t':
  346.                         if (QuoteMode)
  347.                             Token += aJSON[i];
  348.                     break;
  349.  
  350.                     case '\\':
  351.                         ++i;
  352.                         if (QuoteMode)
  353.                         {
  354.                             char C = aJSON[i];
  355.                             switch (C)
  356.                             {
  357.                                 case 't' : Token += '\t'; break;
  358.                                 case 'r' : Token += '\r'; break;
  359.                                 case 'n' : Token += '\n'; break;
  360.                                 case 'b' : Token += '\b'; break;
  361.                                 case 'f' : Token += '\f'; break;
  362.                                 case 'u':
  363.                                 {
  364.                                     string s = aJSON.Substring(i+1,4);
  365.                                     Token += (char)int.Parse(s, System.Globalization.NumberStyles.AllowHexSpecifier);
  366.                                     i += 4;
  367.                                     break;
  368.                                 }
  369.                                 default  : Token += C; break;
  370.                             }
  371.                         }
  372.                     break;
  373.  
  374.                     default:
  375.                         Token += aJSON[i];
  376.                     break;
  377.                 }
  378.                 ++i;
  379.             }
  380.             if (QuoteMode)
  381.             {
  382.                 throw new Exception("JSON Parse: Quotation marks seems to be messed up.");
  383.             }
  384.             return ctx;
  385.         }
  386.  
  387.         public virtual void Serialize(System.IO.BinaryWriter aWriter) {}
  388.  
  389.         public void SaveToStream(System.IO.Stream aData)
  390.         {
  391.             var W = new System.IO.BinaryWriter(aData);
  392.             Serialize(W);
  393.         }
  394.  
  395.         #if USE_SharpZipLib
  396.         public void SaveToCompressedStream(System.IO.Stream aData)
  397.         {
  398.             using (var gzipOut = new ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(aData))
  399.             {
  400.                 gzipOut.IsStreamOwner = false;
  401.                 SaveToStream(gzipOut);
  402.                 gzipOut.Close();
  403.             }
  404.         }
  405.  
  406.         public void SaveToCompressedFile(string aFileName)
  407.         {
  408.             #if USE_FileIO
  409.             System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName);
  410.             using(var F = System.IO.File.OpenWrite(aFileName))
  411.             {
  412.                 SaveToCompressedStream(F);
  413.             }
  414.             #else
  415.             throw new Exception("Can't use File IO stuff in webplayer");
  416.             #endif
  417.         }
  418.         public string SaveToCompressedBase64()
  419.         {
  420.             using (var stream = new System.IO.MemoryStream())
  421.             {
  422.                 SaveToCompressedStream(stream);
  423.                 stream.Position = 0;
  424.                 return System.Convert.ToBase64String(stream.ToArray());
  425.             }
  426.         }
  427.  
  428.         #else
  429.         public void SaveToCompressedStream(System.IO.Stream aData)
  430.         {
  431.             throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
  432.         }
  433.         public void SaveToCompressedFile(string aFileName)
  434.         {
  435.             throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
  436.         }
  437.         public string SaveToCompressedBase64()
  438.         {
  439.             throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
  440.         }
  441.         #endif
  442.  
  443.         public void SaveToFile(string aFileName)
  444.         {
  445.             #if USE_FileIO
  446.             System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName);
  447.             using(var F = System.IO.File.OpenWrite(aFileName))
  448.             {
  449.                 SaveToStream(F);
  450.             }
  451.             #else
  452.             throw new Exception("Can't use File IO stuff in webplayer");
  453.             #endif
  454.         }
  455.         public string SaveToBase64()
  456.         {
  457.             using (var stream = new System.IO.MemoryStream())
  458.             {
  459.                 SaveToStream(stream);
  460.                 stream.Position = 0;
  461.                 return System.Convert.ToBase64String(stream.ToArray());
  462.             }
  463.         }
  464.         public static JSONNode Deserialize(System.IO.BinaryReader aReader)
  465.         {
  466.             JSONBinaryTag type = (JSONBinaryTag)aReader.ReadByte();
  467.             switch(type)
  468.             {
  469.             case JSONBinaryTag.Array:
  470.             {
  471.                 int count = aReader.ReadInt32();
  472.                 JSONArray tmp = new JSONArray();
  473.                 for(int i = 0; i < count; i++)
  474.                     tmp.Add(Deserialize(aReader));
  475.                 return tmp;
  476.             }
  477.             case JSONBinaryTag.Class:
  478.             {
  479.                 int count = aReader.ReadInt32();                
  480.                 JSONClass tmp = new JSONClass();
  481.                 for(int i = 0; i < count; i++)
  482.                 {
  483.                     string key = aReader.ReadString();
  484.                     var val = Deserialize(aReader);
  485.                     tmp.Add(key, val);
  486.                 }
  487.                 return tmp;
  488.             }
  489.             case JSONBinaryTag.Value:
  490.             {
  491.                 return new JSONData(aReader.ReadString());
  492.             }
  493.             case JSONBinaryTag.IntValue:
  494.             {
  495.                 return new JSONData(aReader.ReadInt32());
  496.             }
  497.             case JSONBinaryTag.DoubleValue:
  498.             {
  499.                 return new JSONData(aReader.ReadDouble());
  500.             }
  501.             case JSONBinaryTag.BoolValue:
  502.             {
  503.                 return new JSONData(aReader.ReadBoolean());
  504.             }
  505.             case JSONBinaryTag.FloatValue:
  506.             {
  507.                 return new JSONData(aReader.ReadSingle());
  508.             }
  509.  
  510.             default:
  511.             {
  512.                 throw new Exception("Error deserializing JSON. Unknown tag: " + type);
  513.             }
  514.             }
  515.         }
  516.  
  517.         #if USE_SharpZipLib
  518.         public static JSONNode LoadFromCompressedStream(System.IO.Stream aData)
  519.         {
  520.             var zin = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(aData);
  521.             return LoadFromStream(zin);
  522.         }
  523.         public static JSONNode LoadFromCompressedFile(string aFileName)
  524.         {
  525.             #if USE_FileIO
  526.             using(var F = System.IO.File.OpenRead(aFileName))
  527.             {
  528.                 return LoadFromCompressedStream(F);
  529.             }
  530.             #else
  531.             throw new Exception("Can't use File IO stuff in webplayer");
  532.             #endif
  533.         }
  534.         public static JSONNode LoadFromCompressedBase64(string aBase64)
  535.         {
  536.             var tmp = System.Convert.FromBase64String(aBase64);
  537.             var stream = new System.IO.MemoryStream(tmp);
  538.             stream.Position = 0;
  539.             return LoadFromCompressedStream(stream);
  540.         }
  541.         #else
  542.         public static JSONNode LoadFromCompressedFile(string aFileName)
  543.         {
  544.             throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
  545.         }
  546.         public static JSONNode LoadFromCompressedStream(System.IO.Stream aData)
  547.         {
  548.             throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
  549.         }
  550.         public static JSONNode LoadFromCompressedBase64(string aBase64)
  551.         {
  552.             throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
  553.         }
  554.         #endif
  555.  
  556.         public static JSONNode LoadFromStream(System.IO.Stream aData)
  557.         {
  558.             using(var R = new System.IO.BinaryReader(aData))
  559.             {
  560.                 return Deserialize(R);
  561.             }
  562.         }
  563.         public static JSONNode LoadFromFile(string aFileName)
  564.         {
  565.             #if USE_FileIO
  566.             using(var F = System.IO.File.OpenRead(aFileName))
  567.             {
  568.                 return LoadFromStream(F);
  569.             }
  570.             #else
  571.             throw new Exception("Can't use File IO stuff in webplayer");
  572.             #endif
  573.         }
  574.         public static JSONNode LoadFromBase64(string aBase64)
  575.         {
  576.             var tmp = System.Convert.FromBase64String(aBase64);
  577.             var stream = new System.IO.MemoryStream(tmp);
  578.             stream.Position = 0;
  579.             return LoadFromStream(stream);
  580.         }
  581.     } // End of JSONNode
  582.  
  583.     public class JSONArray : JSONNode, IEnumerable
  584.     {
  585.         private List<JSONNode> m_List = new List<JSONNode>();
  586.         public override JSONNode this[int aIndex]
  587.         {
  588.             get
  589.             {
  590.                 if (aIndex<0 || aIndex >= m_List.Count)
  591.                     return new JSONLazyCreator(this);
  592.                 return m_List[aIndex];
  593.             }
  594.             set
  595.             {
  596.                 if (aIndex<0 || aIndex >= m_List.Count)
  597.                     m_List.Add(value);
  598.                 else
  599.                     m_List[aIndex] = value;
  600.             }
  601.         }
  602.         public override JSONNode this[string aKey]
  603.         {
  604.             get{ return new JSONLazyCreator(this);}
  605.             set{ m_List.Add(value); }
  606.         }
  607.         public override int Count
  608.         {
  609.             get { return m_List.Count; }
  610.         }
  611.         public override void Add(string aKey, JSONNode aItem)
  612.         {
  613.             m_List.Add(aItem);
  614.         }
  615.         public override JSONNode Remove(int aIndex)
  616.         {
  617.             if (aIndex < 0 || aIndex >= m_List.Count)
  618.                 return null;
  619.             JSONNode tmp = m_List[aIndex];
  620.             m_List.RemoveAt(aIndex);
  621.             return tmp;
  622.         }
  623.         public override JSONNode Remove(JSONNode aNode)
  624.         {
  625.             m_List.Remove(aNode);
  626.             return aNode;
  627.         }
  628.         public override IEnumerable<JSONNode> Childs
  629.         {
  630.             get
  631.             {
  632.                 foreach(JSONNode N in m_List)
  633.                     yield return N;
  634.             }
  635.         }
  636.         public IEnumerator GetEnumerator()
  637.         {
  638.             foreach(JSONNode N in m_List)
  639.                 yield return N;
  640.         }
  641.         public override string ToString()
  642.         {
  643.             string result = "[ ";
  644.             foreach (JSONNode N in m_List)
  645.             {
  646.                 if (result.Length > 2)
  647.                     result += ", ";
  648.                 result += N.ToString();
  649.             }
  650.             result += " ]";
  651.             return result;
  652.         }
  653.         public override string ToString(string aPrefix)
  654.         {
  655.             string result = "[ ";
  656.             foreach (JSONNode N in m_List)
  657.             {
  658.                 if (result.Length > 3)
  659.                     result += ", ";
  660.                 result += "\n" + aPrefix + "   ";                
  661.                 result += N.ToString(aPrefix+"   ");
  662.             }
  663.             result += "\n" + aPrefix + "]";
  664.             return result;
  665.         }
  666.         public override void Serialize (System.IO.BinaryWriter aWriter)
  667.         {
  668.             aWriter.Write((byte)JSONBinaryTag.Array);
  669.             aWriter.Write(m_List.Count);
  670.             for(int i = 0; i < m_List.Count; i++)
  671.             {
  672.                 m_List[i].Serialize(aWriter);
  673.             }
  674.         }
  675.     } // End of JSONArray
  676.  
  677.     public class JSONClass : JSONNode, IEnumerable
  678.     {
  679.         private Dictionary<string,JSONNode> m_Dict = new Dictionary<string,JSONNode>();
  680.         public override JSONNode this[string aKey]
  681.         {
  682.             get
  683.             {
  684.                 if (m_Dict.ContainsKey(aKey))
  685.                     return m_Dict[aKey];
  686.                 else
  687.                     return new JSONLazyCreator(this, aKey);
  688.             }
  689.             set
  690.             {
  691.                 if (m_Dict.ContainsKey(aKey))
  692.                     m_Dict[aKey] = value;
  693.                 else
  694.                     m_Dict.Add(aKey,value);
  695.             }
  696.         }
  697.         public override JSONNode this[int aIndex]
  698.         {
  699.             get
  700.             {
  701.                 if (aIndex < 0 || aIndex >= m_Dict.Count)
  702.                     return null;
  703.                 return m_Dict.ElementAt(aIndex).Value;
  704.             }
  705.             set
  706.             {
  707.                 if (aIndex < 0 || aIndex >= m_Dict.Count)
  708.                     return;
  709.                 string key = m_Dict.ElementAt(aIndex).Key;
  710.                 m_Dict[key] = value;
  711.             }
  712.         }
  713.         public override int Count
  714.         {
  715.             get { return m_Dict.Count; }
  716.         }
  717.  
  718.  
  719.         public override void Add(string aKey, JSONNode aItem)
  720.         {
  721.             if (!string.IsNullOrEmpty(aKey))
  722.             {
  723.                 if (m_Dict.ContainsKey(aKey))
  724.                     m_Dict[aKey] = aItem;
  725.                 else
  726.                     m_Dict.Add(aKey, aItem);
  727.             }
  728.             else
  729.                 m_Dict.Add(Guid.NewGuid().ToString(), aItem);
  730.         }
  731.  
  732.         public override JSONNode Remove(string aKey)
  733.         {
  734.             if (!m_Dict.ContainsKey(aKey))
  735.                 return null;
  736.             JSONNode tmp = m_Dict[aKey];
  737.             m_Dict.Remove(aKey);
  738.             return tmp;        
  739.         }
  740.         public override JSONNode Remove(int aIndex)
  741.         {
  742.             if (aIndex < 0 || aIndex >= m_Dict.Count)
  743.                 return null;
  744.             var item = m_Dict.ElementAt(aIndex);
  745.             m_Dict.Remove(item.Key);
  746.             return item.Value;
  747.         }
  748.         public override JSONNode Remove(JSONNode aNode)
  749.         {
  750.             try
  751.             {
  752.                 var item = m_Dict.Where(k => k.Value == aNode).First();
  753.                 m_Dict.Remove(item.Key);
  754.                 return aNode;
  755.             }
  756.             catch
  757.             {
  758.                 return null;
  759.             }
  760.         }
  761.  
  762.         public override IEnumerable<JSONNode> Childs
  763.         {
  764.             get
  765.             {
  766.                 foreach(KeyValuePair<string,JSONNode> N in m_Dict)
  767.                     yield return N.Value;
  768.             }
  769.         }
  770.  
  771.         public IEnumerator GetEnumerator()
  772.         {
  773.             foreach(KeyValuePair<string, JSONNode> N in m_Dict)
  774.                 yield return N;
  775.         }
  776.         public override string ToString()
  777.         {
  778.             string result = "{";
  779.             foreach (KeyValuePair<string, JSONNode> N in m_Dict)
  780.             {
  781.                 if (result.Length > 2)
  782.                     result += ", ";
  783.                 result += "\"" + Escape(N.Key) + "\":" + N.Value.ToString();
  784.             }
  785.             result += "}";
  786.             return result;
  787.         }
  788.         public override string ToString(string aPrefix)
  789.         {
  790.             string result = "{ ";
  791.             foreach (KeyValuePair<string, JSONNode> N in m_Dict)
  792.             {
  793.                 if (result.Length > 3)
  794.                     result += ", ";
  795.                 result += "\n" + aPrefix + "   ";
  796.                 result += "\"" + Escape(N.Key) + "\" : " + N.Value.ToString(aPrefix+"   ");
  797.             }
  798.             result += "\n" + aPrefix + "}";
  799.             return result;
  800.         }
  801.         public override void Serialize (System.IO.BinaryWriter aWriter)
  802.         {
  803.             aWriter.Write((byte)JSONBinaryTag.Class);
  804.             aWriter.Write(m_Dict.Count);
  805.             foreach(string K in m_Dict.Keys)
  806.             {
  807.                 aWriter.Write(K);
  808.                 m_Dict[K].Serialize(aWriter);
  809.             }
  810.         }
  811.     } // End of JSONClass
  812.  
  813.     public class JSONData : JSONNode
  814.     {
  815.         private string m_Data;
  816.         public override string Value
  817.         {
  818.             get { return m_Data; }
  819.             set { m_Data = value; }
  820.         }
  821.         public JSONData(string aData)
  822.         {
  823.             m_Data = aData;
  824.         }
  825.         public JSONData(float aData)
  826.         {
  827.             AsFloat = aData;
  828.         }
  829.         public JSONData(double aData)
  830.         {
  831.             AsDouble = aData;
  832.         }
  833.         public JSONData(bool aData)
  834.         {
  835.             AsBool = aData;
  836.         }
  837.         public JSONData(int aData)
  838.         {
  839.             AsInt = aData;
  840.         }
  841.  
  842.         public override string ToString()
  843.         {
  844.             return "\"" + Escape(m_Data) + "\"";
  845.         }
  846.         public override string ToString(string aPrefix)
  847.         {
  848.             return "\"" + Escape(m_Data) + "\"";
  849.         }
  850.         public override void Serialize (System.IO.BinaryWriter aWriter)
  851.         {
  852.             var tmp = new JSONData("");
  853.  
  854.             tmp.AsInt = AsInt;
  855.             if (tmp.m_Data == this.m_Data)
  856.             {
  857.                 aWriter.Write((byte)JSONBinaryTag.IntValue);
  858.                 aWriter.Write(AsInt);
  859.                 return;
  860.             }
  861.             tmp.AsFloat = AsFloat;
  862.             if (tmp.m_Data == this.m_Data)
  863.             {
  864.                 aWriter.Write((byte)JSONBinaryTag.FloatValue);
  865.                 aWriter.Write(AsFloat);
  866.                 return;
  867.             }
  868.             tmp.AsDouble = AsDouble;
  869.             if (tmp.m_Data == this.m_Data)
  870.             {
  871.                 aWriter.Write((byte)JSONBinaryTag.DoubleValue);
  872.                 aWriter.Write(AsDouble);
  873.                 return;
  874.             }
  875.  
  876.             tmp.AsBool = AsBool;
  877.             if (tmp.m_Data == this.m_Data)
  878.             {
  879.                 aWriter.Write((byte)JSONBinaryTag.BoolValue);
  880.                 aWriter.Write(AsBool);
  881.                 return;
  882.             }
  883.             aWriter.Write((byte)JSONBinaryTag.Value);
  884.             aWriter.Write(m_Data);
  885.         }
  886.     } // End of JSONData
  887.  
  888.     internal class JSONLazyCreator : JSONNode
  889.     {
  890.         private JSONNode m_Node = null;
  891.         private string m_Key = null;
  892.  
  893.         public JSONLazyCreator(JSONNode aNode)
  894.         {
  895.             m_Node = aNode;
  896.             m_Key  = null;
  897.         }
  898.         public JSONLazyCreator(JSONNode aNode, string aKey)
  899.         {
  900.             m_Node = aNode;
  901.             m_Key = aKey;
  902.         }
  903.  
  904.         private void Set(JSONNode aVal)
  905.         {
  906.             if (m_Key == null)
  907.             {
  908.                 m_Node.Add(aVal);
  909.             }
  910.             else
  911.             {
  912.                 m_Node.Add(m_Key, aVal);
  913.             }
  914.             m_Node = null; // Be GC friendly.
  915.         }
  916.  
  917.         public override JSONNode this[int aIndex]
  918.         {
  919.             get
  920.             {
  921.                 return new JSONLazyCreator(this);
  922.             }
  923.             set
  924.             {
  925.                 var tmp = new JSONArray();
  926.                 tmp.Add(value);
  927.                 Set(tmp);
  928.             }
  929.         }
  930.  
  931.         public override JSONNode this[string aKey]
  932.         {
  933.             get
  934.             {
  935.                 return new JSONLazyCreator(this, aKey);
  936.             }
  937.             set
  938.             {
  939.                 var tmp = new JSONClass();
  940.                 tmp.Add(aKey, value);
  941.                 Set(tmp);
  942.             }
  943.         }
  944.         public override void Add (JSONNode aItem)
  945.         {
  946.             var tmp = new JSONArray();
  947.             tmp.Add(aItem);
  948.             Set(tmp);
  949.         }
  950.         public override void Add (string aKey, JSONNode aItem)
  951.         {
  952.             var tmp = new JSONClass();
  953.             tmp.Add(aKey, aItem);
  954.             Set(tmp);
  955.         }
  956.         public static bool operator ==(JSONLazyCreator a, object b)
  957.         {
  958.             if (b == null)
  959.                 return true;
  960.             return System.Object.ReferenceEquals(a,b);
  961.         }
  962.  
  963.         public static bool operator !=(JSONLazyCreator a, object b)
  964.         {
  965.             return !(a == b);
  966.         }
  967.         public override bool Equals (object obj)
  968.         {
  969.             if (obj == null)
  970.                 return true;
  971.             return System.Object.ReferenceEquals(this, obj);
  972.         }
  973.         public override int GetHashCode ()
  974.         {
  975.             return base.GetHashCode();
  976.         }
  977.  
  978.         public override string ToString()
  979.         {
  980.             return "";
  981.         }
  982.         public override string ToString(string aPrefix)
  983.         {
  984.             return "";
  985.         }
  986.  
  987.         public override int AsInt
  988.         {
  989.             get
  990.             {
  991.                 JSONData tmp = new JSONData(0);
  992.                 Set(tmp);
  993.                 return 0;
  994.             }
  995.             set
  996.             {
  997.                 JSONData tmp = new JSONData(value);
  998.                 Set(tmp);
  999.             }
  1000.         }
  1001.         public override float AsFloat
  1002.         {
  1003.             get
  1004.             {
  1005.                 JSONData tmp = new JSONData(0.0f);
  1006.                 Set(tmp);
  1007.                 return 0.0f;
  1008.             }
  1009.             set
  1010.             {
  1011.                 JSONData tmp = new JSONData(value);
  1012.                 Set(tmp);
  1013.             }
  1014.         }
  1015.         public override double AsDouble
  1016.         {
  1017.             get
  1018.             {
  1019.                 JSONData tmp = new JSONData(0.0);
  1020.                 Set(tmp);
  1021.                 return 0.0;
  1022.             }
  1023.             set
  1024.             {
  1025.                 JSONData tmp = new JSONData(value);
  1026.                 Set(tmp);
  1027.             }
  1028.         }
  1029.         public override bool AsBool
  1030.         {
  1031.             get
  1032.             {
  1033.                 JSONData tmp = new JSONData(false);
  1034.                 Set(tmp);
  1035.                 return false;
  1036.             }
  1037.             set
  1038.             {
  1039.                 JSONData tmp = new JSONData(value);
  1040.                 Set(tmp);
  1041.             }
  1042.         }
  1043.         public override JSONArray AsArray
  1044.         {
  1045.             get
  1046.             {
  1047.                 JSONArray tmp = new JSONArray();
  1048.                 Set(tmp);
  1049.                 return tmp;
  1050.             }
  1051.         }
  1052.         public override JSONClass AsObject
  1053.         {
  1054.             get
  1055.             {
  1056.                 JSONClass tmp = new JSONClass();
  1057.                 Set(tmp);
  1058.                 return tmp;
  1059.             }
  1060.         }
  1061.     } // End of JSONLazyCreator
  1062.  
  1063.     public static class JSON
  1064.     {
  1065.         public static JSONNode Parse(string aJSON)
  1066.         {
  1067.             return JSONNode.Parse(aJSON);
  1068.         }
  1069.     }
  1070. }
Add Comment
Please, Sign In to add comment