PageRenderTime 54ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/Assets/Plugins/JSONObject.cs

https://bitbucket.org/Werring/unity-indusim
C# | 343 lines | 322 code | 5 blank | 16 comment | 10 complexity | df1f8c87df01dfe57791a5235978232d MD5 | raw file
  1. #define READABLE
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. /*
  6. * http://www.opensource.org/licenses/lgpl-2.1.php
  7. * JSONObject class
  8. * for use with Unity
  9. * Copyright Matt Schoen 2010
  10. */
  11. public class JSONObject:Nullable {
  12. const int MAX_DEPTH = 1000;
  13. public enum Type { NULL, STRING, NUMBER, OBJECT, ARRAY, BOOL }
  14. public JSONObject parent;
  15. public Type type = Type.NULL;
  16. public ArrayList list = new ArrayList();
  17. public ArrayList keys = new ArrayList();
  18. public string str;
  19. public double n;
  20. public bool b;
  21. public static JSONObject nullJO { get { return new JSONObject(JSONObject.Type.NULL); } }
  22. public static JSONObject obj { get { return new JSONObject(JSONObject.Type.OBJECT); } }
  23. public static JSONObject arr { get { return new JSONObject(JSONObject.Type.ARRAY); } }
  24. public JSONObject(JSONObject.Type t) {
  25. type = t;
  26. switch(t) {
  27. case Type.ARRAY:
  28. list = new ArrayList();
  29. break;
  30. case Type.OBJECT:
  31. list = new ArrayList();
  32. keys = new ArrayList();
  33. break;
  34. }
  35. }
  36. public JSONObject(bool b) {
  37. type = Type.BOOL;
  38. this.b = b;
  39. }
  40. public JSONObject(float f) {
  41. type = Type.NUMBER;
  42. this.n = f;
  43. }
  44. public JSONObject(Dictionary<string, string> dic) {
  45. type = Type.OBJECT;
  46. foreach(KeyValuePair<string, string> kvp in dic){
  47. keys.Add(kvp.Key);
  48. list.Add(kvp.Value);
  49. }
  50. }
  51. public JSONObject() { }
  52. public JSONObject(string str) { //create a new JSONObject from a string (this will also create any children, and parse the whole string)
  53. //Debug.Log(str);
  54. if(str != null) {
  55. #if(READABLE)
  56. str = str.Replace("\\n", "");
  57. str = str.Replace("\\t", "");
  58. str = str.Replace("\\r", "");
  59. str = str.Replace("\t", "");
  60. str = str.Replace("\n", "");
  61. str = str.Replace("\\", "");
  62. #endif
  63. if(str.Length > 0) {
  64. if(string.Compare(str, "true", true) == 0) {
  65. type = Type.BOOL;
  66. b = true;
  67. } else if(string.Compare(str, "false", true) == 0) {
  68. type = Type.BOOL;
  69. b = false;
  70. } else if(str == "null") {
  71. type = Type.NULL;
  72. } else if(str[0] == '"') {
  73. type = Type.STRING;
  74. this.str = str.Substring(1, str.Length - 2);
  75. } else {
  76. try {
  77. n = System.Convert.ToDouble(str);
  78. type = Type.NUMBER;
  79. } catch(System.FormatException) {
  80. int token_tmp = 0;
  81. /*
  82. * Checking for the following formatting (www.json.org)
  83. * object - {"field1":value,"field2":value}
  84. * array - [value,value,value]
  85. * value - string - "string"
  86. * - number - 0.0
  87. * - bool - true -or- false
  88. * - null - null
  89. */
  90. switch(str[0]) {
  91. case '{':
  92. type = Type.OBJECT;
  93. keys = new ArrayList();
  94. list = new ArrayList();
  95. break;
  96. case '[':
  97. type = JSONObject.Type.ARRAY;
  98. list = new ArrayList();
  99. break;
  100. default:
  101. type = Type.NULL;
  102. Debug.LogWarning("improper JSON formatting:" + str);
  103. return;
  104. }
  105. int depth = 0;
  106. bool openquote = false;
  107. bool inProp = false;
  108. for(int i = 1; i < str.Length; i++) {
  109. if(str[i] == '\\') {
  110. i++;
  111. continue;
  112. }
  113. if(str[i] == '"')
  114. openquote = !openquote;
  115. if(str[i] == '[' || str[i] == '{')
  116. depth++;
  117. if(depth == 0 && !openquote) {
  118. if(str[i] == ':' && !inProp) {
  119. inProp = true;
  120. try {
  121. keys.Add(str.Substring(token_tmp + 2, i - token_tmp - 3));
  122. } catch { Debug.Log(i + " - " + str.Length + " - " + str); }
  123. token_tmp = i;
  124. }
  125. if(str[i] == ',') {
  126. inProp = false;
  127. list.Add(new JSONObject(str.Substring(token_tmp + 1, i - token_tmp - 1)));
  128. token_tmp = i;
  129. }
  130. if(str[i] == ']' || str[i] == '}')
  131. list.Add(new JSONObject(str.Substring(token_tmp + 1, i - token_tmp - 1)));
  132. }
  133. if(str[i] == ']' || str[i] == '}')
  134. depth--;
  135. }
  136. }
  137. }
  138. }
  139. } else {
  140. type = Type.NULL; //If the string is missing, this is a null
  141. }
  142. }
  143. public void AddField(bool val) { Add(new JSONObject(val)); }
  144. public void AddField(float val) { Add(new JSONObject(val)); }
  145. public void AddField(int val) { Add(new JSONObject(val)); }
  146. public void Add(JSONObject obj) {
  147. if(obj) { //Don't do anything if the object is null
  148. if(type != JSONObject.Type.ARRAY) {
  149. type = JSONObject.Type.ARRAY; //Congratulations, son, you're an ARRAY now
  150. Debug.LogWarning("tried to add an object to a non-array JSONObject. We'll do it for you, but you might be doing something wrong.");
  151. }
  152. list.Add(obj);
  153. }
  154. }
  155. public void AddField(string name, bool val) { AddField(name, new JSONObject(val)); }
  156. public void AddField(string name, float val) { AddField(name, new JSONObject(val)); }
  157. public void AddField(string name, int val) { AddField(name, new JSONObject(val)); }
  158. public void AddField(string name, string val) {
  159. AddField(name, new JSONObject { type = JSONObject.Type.STRING, str = val });
  160. }
  161. public void AddField(string name, JSONObject obj) {
  162. if(obj){ //Don't do anything if the object is null
  163. if(type != JSONObject.Type.OBJECT){
  164. type = JSONObject.Type.OBJECT; //Congratulations, son, you're an OBJECT now
  165. Debug.LogWarning("tried to add a field to a non-object JSONObject. We'll do it for you, but you might be doing something wrong.");
  166. }
  167. keys.Add(name);
  168. list.Add(obj);
  169. }
  170. }
  171. public void SetField(string name, JSONObject obj) {
  172. if(HasField(name)) {
  173. list.Remove(this[name]);
  174. keys.Remove(name);
  175. }
  176. AddField(name, obj);
  177. }
  178. public JSONObject GetField(string name) {
  179. if(type == JSONObject.Type.OBJECT)
  180. for(int i = 0; i < keys.Count; i++)
  181. if((string)keys[i] == name)
  182. return (JSONObject)list[i];
  183. return null;
  184. }
  185. public bool HasField(string name) {
  186. if(type == JSONObject.Type.OBJECT)
  187. for(int i = 0; i < keys.Count; i++)
  188. if((string)keys[i] == name)
  189. return true;
  190. return false;
  191. }
  192. public void Clear() {
  193. type = JSONObject.Type.NULL;
  194. list.Clear();
  195. keys.Clear();
  196. str = "";
  197. n = 0;
  198. b = false;
  199. }
  200. public JSONObject Copy() {
  201. return new JSONObject(print());
  202. }
  203. /*
  204. * The Merge function is experimental. Use at your own risk.
  205. */
  206. public void Merge(JSONObject obj) {
  207. MergeRecur(this, obj);
  208. }
  209. static void MergeRecur(JSONObject left, JSONObject right) {
  210. if(right.type == JSONObject.Type.OBJECT) {
  211. for(int i = 0; i < right.list.Count; i++) {
  212. if(right.keys[i] != null) {
  213. string key = (string)right.keys[i];
  214. JSONObject val = (JSONObject)right.list[i];
  215. if(val.type == JSONObject.Type.ARRAY || val.type == JSONObject.Type.OBJECT) {
  216. if(left.HasField(key))
  217. MergeRecur(left[key], val);
  218. else
  219. left.AddField(key, val);
  220. } else {
  221. if(left.HasField(key))
  222. left.SetField(key, val);
  223. else
  224. left.AddField(key, val);
  225. }
  226. }
  227. }
  228. }// else left.list.Add(right.list);
  229. }
  230. public string print() {
  231. return print(0);
  232. }
  233. public string print(int depth) { //Convert the JSONObject into a stiring
  234. if(depth++ > MAX_DEPTH) {
  235. Debug.Log("reached max depth!");
  236. return "";
  237. }
  238. string str = "";
  239. switch(type) {
  240. case Type.STRING:
  241. str = "\"" + this.str + "\"";
  242. break;
  243. case Type.NUMBER:
  244. str += n;
  245. break;
  246. case JSONObject.Type.OBJECT:
  247. if(list.Count > 0) {
  248. str = "{";
  249. #if(READABLE) //for a bit more readability, comment the define above to save space
  250. str += "\n";
  251. depth++;
  252. #endif
  253. for(int i = 0; i < list.Count; i++) {
  254. string key = (string)keys[i];
  255. JSONObject obj = (JSONObject)list[i];
  256. if(obj) {
  257. #if(READABLE)
  258. for(int j = 0; j < depth; j++)
  259. str += "\t"; //for a bit more readability
  260. #endif
  261. str += "\"" + key + "\":";
  262. str += obj.print(depth) + ",";
  263. #if(READABLE)
  264. str += "\n";
  265. #endif
  266. }
  267. }
  268. #if(READABLE)
  269. str = str.Substring(0, str.Length - 1);
  270. #endif
  271. str = str.Substring(0, str.Length - 1);
  272. str += "}";
  273. } else str += "null";
  274. break;
  275. case JSONObject.Type.ARRAY:
  276. if(list.Count > 0) {
  277. str = "[";
  278. #if(READABLE)
  279. str += "\n"; //for a bit more readability
  280. depth++;
  281. #endif
  282. foreach(JSONObject obj in list) {
  283. if(obj) {
  284. #if(READABLE)
  285. for(int j = 0; j < depth; j++)
  286. str += "\t"; //for a bit more readability
  287. #endif
  288. str += obj.print(depth) + ",";
  289. #if(READABLE)
  290. str += "\n"; //for a bit more readability
  291. #endif
  292. }
  293. }
  294. #if(READABLE)
  295. str = str.Substring(0, str.Length - 1);
  296. #endif
  297. str = str.Substring(0, str.Length - 1);
  298. str += "]";
  299. }
  300. break;
  301. case Type.BOOL:
  302. if(b)
  303. str += "true";
  304. else
  305. str += "false";
  306. break;
  307. case Type.NULL:
  308. str = "null";
  309. break;
  310. }
  311. return str;
  312. }
  313. public JSONObject this[int index] {
  314. get { return (JSONObject)list[index]; }
  315. }
  316. public JSONObject this[string index] {
  317. get { return GetField(index); }
  318. }
  319. public override string ToString() {
  320. return print();
  321. }
  322. public Dictionary<string, string> ToDictionary() {
  323. if(type == Type.OBJECT) {
  324. Dictionary<string, string> result = new Dictionary<string, string>();
  325. for(int i = 0; i < list.Count; i++) {
  326. JSONObject val = (JSONObject)list[i];
  327. switch(val.type){
  328. case Type.STRING: result.Add((string)keys[i], val.str); break;
  329. case Type.NUMBER: result.Add((string)keys[i], val.n + ""); break;
  330. case Type.BOOL: result.Add((string)keys[i], val.b + ""); break;
  331. default: Debug.LogWarning("Omitting object: " + (string)keys[i] + " in dictionary conversion"); break;
  332. }
  333. }
  334. return result;
  335. } else Debug.LogWarning("Tried to turn non-Object JSONObject into a dictionary");
  336. return null;
  337. }
  338. }