You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

513 lines
11 KiB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.Text;
  6. namespace SUISS.Core
  7. {
  8. public class Json
  9. {
  10. public static object Decode(string json)
  11. {
  12. bool flag = true;
  13. return Json.Decode(json, ref flag);
  14. }
  15. public static object Decode(string json, ref bool success)
  16. {
  17. success = true;
  18. if (json != null)
  19. {
  20. char[] json2 = json.ToCharArray();
  21. int num = 0;
  22. return Json.ParseValue(json2, ref num, ref success);
  23. }
  24. return null;
  25. }
  26. public static string Encode(object json)
  27. {
  28. StringBuilder stringBuilder = new StringBuilder(2000);
  29. bool flag = Json.SerializeValue(json, stringBuilder);
  30. return (!flag) ? null : stringBuilder.ToString();
  31. }
  32. protected static Dictionary<string, object> ParseObject(char[] json, ref int index, ref bool success)
  33. {
  34. Dictionary<string, object> dictionary = new Dictionary<string, object>();
  35. Json.NextToken(json, ref index);
  36. bool flag = false;
  37. while (!flag)
  38. {
  39. int num = Json.LookAhead(json, index);
  40. if (num == 0)
  41. {
  42. success = false;
  43. return null;
  44. }
  45. if (num == 6)
  46. {
  47. Json.NextToken(json, ref index);
  48. }
  49. else
  50. {
  51. if (num == 2)
  52. {
  53. Json.NextToken(json, ref index);
  54. return dictionary;
  55. }
  56. string key = Json.ParseString(json, ref index, ref success);
  57. if (!success)
  58. {
  59. success = false;
  60. return null;
  61. }
  62. num = Json.NextToken(json, ref index);
  63. if (num != 5)
  64. {
  65. success = false;
  66. return null;
  67. }
  68. object value = Json.ParseValue(json, ref index, ref success);
  69. if (!success)
  70. {
  71. success = false;
  72. return null;
  73. }
  74. dictionary[key] = value;
  75. }
  76. }
  77. return dictionary;
  78. }
  79. protected static List<object> ParseArray(char[] json, ref int index, ref bool success)
  80. {
  81. List<object> list = new List<object>();
  82. Json.NextToken(json, ref index);
  83. bool flag = false;
  84. while (!flag)
  85. {
  86. int num = Json.LookAhead(json, index);
  87. if (num == 0)
  88. {
  89. success = false;
  90. return null;
  91. }
  92. if (num == 6)
  93. {
  94. Json.NextToken(json, ref index);
  95. }
  96. else
  97. {
  98. if (num == 4)
  99. {
  100. Json.NextToken(json, ref index);
  101. break;
  102. }
  103. object item = Json.ParseValue(json, ref index, ref success);
  104. if (!success)
  105. {
  106. return null;
  107. }
  108. list.Add(item);
  109. }
  110. }
  111. return list;
  112. }
  113. protected static object ParseValue(char[] json, ref int index, ref bool success)
  114. {
  115. switch (Json.LookAhead(json, index))
  116. {
  117. case 1:
  118. return Json.ParseObject(json, ref index, ref success);
  119. case 3:
  120. return Json.ParseArray(json, ref index, ref success);
  121. case 7:
  122. return Json.ParseString(json, ref index, ref success);
  123. case 8:
  124. return Json.ParseNumber(json, ref index, ref success);
  125. case 9:
  126. Json.NextToken(json, ref index);
  127. return true;
  128. case 10:
  129. Json.NextToken(json, ref index);
  130. return false;
  131. case 11:
  132. Json.NextToken(json, ref index);
  133. return null;
  134. }
  135. success = false;
  136. return null;
  137. }
  138. protected static string ParseString(char[] json, ref int index, ref bool success)
  139. {
  140. StringBuilder stringBuilder = new StringBuilder(2000);
  141. Json.EatWhitespace(json, ref index);
  142. char c = json[index++];
  143. bool flag = false;
  144. while (!flag)
  145. {
  146. if (index == json.Length)
  147. {
  148. break;
  149. }
  150. c = json[index++];
  151. if (c == '"')
  152. {
  153. flag = true;
  154. break;
  155. }
  156. if (c == '\\')
  157. {
  158. if (index == json.Length)
  159. {
  160. break;
  161. }
  162. c = json[index++];
  163. if (c == '"')
  164. {
  165. stringBuilder.Append('"');
  166. }
  167. else if (c == '\\')
  168. {
  169. stringBuilder.Append('\\');
  170. }
  171. else if (c == '/')
  172. {
  173. stringBuilder.Append('/');
  174. }
  175. else if (c == 'b')
  176. {
  177. stringBuilder.Append('\b');
  178. }
  179. else if (c == 'f')
  180. {
  181. stringBuilder.Append('\f');
  182. }
  183. else if (c == 'n')
  184. {
  185. stringBuilder.Append('\n');
  186. }
  187. else if (c == 'r')
  188. {
  189. stringBuilder.Append('\r');
  190. }
  191. else if (c == 't')
  192. {
  193. stringBuilder.Append('\t');
  194. }
  195. else if (c == 'u')
  196. {
  197. int num = json.Length - index;
  198. if (num < 4)
  199. {
  200. break;
  201. }
  202. uint utf;
  203. if (!(success = uint.TryParse(new string(json, index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out utf)))
  204. {
  205. return string.Empty;
  206. }
  207. stringBuilder.Append(char.ConvertFromUtf32((int)utf));
  208. index += 4;
  209. }
  210. }
  211. else
  212. {
  213. stringBuilder.Append(c);
  214. }
  215. }
  216. if (!flag)
  217. {
  218. success = false;
  219. return null;
  220. }
  221. return stringBuilder.ToString();
  222. }
  223. protected static double ParseNumber(char[] json, ref int index, ref bool success)
  224. {
  225. Json.EatWhitespace(json, ref index);
  226. int lastIndexOfNumber = Json.GetLastIndexOfNumber(json, index);
  227. int length = lastIndexOfNumber - index + 1;
  228. double result;
  229. success = double.TryParse(new string(json, index, length), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
  230. index = lastIndexOfNumber + 1;
  231. return result;
  232. }
  233. protected static int GetLastIndexOfNumber(char[] json, int index)
  234. {
  235. int i;
  236. for (i = index; i < json.Length; i++)
  237. {
  238. if ("0123456789+-.eE".IndexOf(json[i]) == -1)
  239. {
  240. break;
  241. }
  242. }
  243. return i - 1;
  244. }
  245. protected static void EatWhitespace(char[] json, ref int index)
  246. {
  247. while (index < json.Length)
  248. {
  249. if (" \t\n\r".IndexOf(json[index]) == -1)
  250. {
  251. break;
  252. }
  253. index++;
  254. }
  255. }
  256. protected static int LookAhead(char[] json, int index)
  257. {
  258. int num = index;
  259. return Json.NextToken(json, ref num);
  260. }
  261. protected static int NextToken(char[] json, ref int index)
  262. {
  263. Json.EatWhitespace(json, ref index);
  264. if (index == json.Length)
  265. {
  266. return 0;
  267. }
  268. char c = json[index];
  269. index++;
  270. switch (c)
  271. {
  272. case ',':
  273. return 6;
  274. case '-':
  275. case '0':
  276. case '1':
  277. case '2':
  278. case '3':
  279. case '4':
  280. case '5':
  281. case '6':
  282. case '7':
  283. case '8':
  284. case '9':
  285. return 8;
  286. default:
  287. switch (c)
  288. {
  289. case '[':
  290. return 3;
  291. default:
  292. switch (c)
  293. {
  294. case '{':
  295. return 1;
  296. default:
  297. {
  298. if (c == '"')
  299. {
  300. return 7;
  301. }
  302. index--;
  303. int num = json.Length - index;
  304. if (num >= 5 && json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e')
  305. {
  306. index += 5;
  307. return 10;
  308. }
  309. if (num >= 4 && json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e')
  310. {
  311. index += 4;
  312. return 9;
  313. }
  314. if (num >= 4 && json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l')
  315. {
  316. index += 4;
  317. return 11;
  318. }
  319. return 0;
  320. }
  321. case '}':
  322. return 2;
  323. }
  324. break;
  325. case ']':
  326. return 4;
  327. }
  328. break;
  329. case ':':
  330. return 5;
  331. }
  332. }
  333. protected static bool SerializeValue(object value, StringBuilder builder)
  334. {
  335. bool result = true;
  336. if (value is string)
  337. {
  338. result = Json.SerializeString((string)value, builder);
  339. }
  340. else if (value is IDictionary)
  341. {
  342. result = Json.SerializeObject((IDictionary)value, builder);
  343. }
  344. else if (value is IList)
  345. {
  346. result = Json.SerializeArray(value as IList, builder);
  347. }
  348. else if (value is bool && (bool)value)
  349. {
  350. builder.Append("true");
  351. }
  352. else if (value is bool && !(bool)value)
  353. {
  354. builder.Append("false");
  355. }
  356. else if (value is ValueType)
  357. {
  358. result = Json.SerializeNumber(Convert.ToDouble(value), builder);
  359. }
  360. else if (value == null)
  361. {
  362. builder.Append("null");
  363. }
  364. else
  365. {
  366. result = false;
  367. }
  368. return result;
  369. }
  370. protected static bool SerializeObject(IDictionary anObject, StringBuilder builder)
  371. {
  372. builder.Append("{");
  373. IDictionaryEnumerator enumerator = anObject.GetEnumerator();
  374. bool flag = true;
  375. while (enumerator.MoveNext())
  376. {
  377. string aString = enumerator.Key.ToString();
  378. object value = enumerator.Value;
  379. if (!flag)
  380. {
  381. builder.Append(", ");
  382. }
  383. Json.SerializeString(aString, builder);
  384. builder.Append(":");
  385. if (!Json.SerializeValue(value, builder))
  386. {
  387. return false;
  388. }
  389. flag = false;
  390. }
  391. builder.Append("}");
  392. return true;
  393. }
  394. protected static bool SerializeArray(IList anArray, StringBuilder builder)
  395. {
  396. builder.Append("[");
  397. bool flag = true;
  398. for (int i = 0; i < anArray.Count; i++)
  399. {
  400. object value = anArray[i];
  401. if (!flag)
  402. {
  403. builder.Append(", ");
  404. }
  405. if (!Json.SerializeValue(value, builder))
  406. {
  407. return false;
  408. }
  409. flag = false;
  410. }
  411. builder.Append("]");
  412. return true;
  413. }
  414. protected static bool SerializeString(string aString, StringBuilder builder)
  415. {
  416. builder.Append("\"");
  417. foreach (char c in aString.ToCharArray())
  418. {
  419. if (c == '"')
  420. {
  421. builder.Append("\\\"");
  422. }
  423. else if (c == '\\')
  424. {
  425. builder.Append("\\\\");
  426. }
  427. else if (c == '\b')
  428. {
  429. builder.Append("\\b");
  430. }
  431. else if (c == '\f')
  432. {
  433. builder.Append("\\f");
  434. }
  435. else if (c == '\n')
  436. {
  437. builder.Append("\\n");
  438. }
  439. else if (c == '\r')
  440. {
  441. builder.Append("\\r");
  442. }
  443. else if (c == '\t')
  444. {
  445. builder.Append("\\t");
  446. }
  447. else
  448. {
  449. int num = Convert.ToInt32(c);
  450. if (num >= 32 && num <= 126)
  451. {
  452. builder.Append(c);
  453. }
  454. else
  455. {
  456. builder.Append("\\u" + Convert.ToString(num, 16).PadLeft(4, '0'));
  457. }
  458. }
  459. }
  460. builder.Append("\"");
  461. return true;
  462. }
  463. protected static bool SerializeNumber(double number, StringBuilder builder)
  464. {
  465. builder.Append(Convert.ToString(number, CultureInfo.InvariantCulture));
  466. return true;
  467. }
  468. private const int TOKEN_NONE = 0;
  469. private const int TOKEN_CURLY_OPEN = 1;
  470. private const int TOKEN_CURLY_CLOSE = 2;
  471. private const int TOKEN_SQUARED_OPEN = 3;
  472. private const int TOKEN_SQUARED_CLOSE = 4;
  473. private const int TOKEN_COLON = 5;
  474. private const int TOKEN_COMMA = 6;
  475. private const int TOKEN_STRING = 7;
  476. private const int TOKEN_NUMBER = 8;
  477. private const int TOKEN_TRUE = 9;
  478. private const int TOKEN_FALSE = 10;
  479. private const int TOKEN_NULL = 11;
  480. private const int BUILDER_CAPACITY = 2000;
  481. }
  482. }