JSONParser.cs
上传用户:szgaoree
上传日期:2009-01-05
资源大小:74k
文件大小:9k
源码类别:

Ajax

开发平台:

C#

  1. using System;
  2. using System.Reflection;
  3. using System.Data;
  4. using System.IO;
  5. using System.Collections;
  6. using System.Globalization;
  7. using System.Text;
  8. namespace AjaxPro
  9. {
  10. /// <summary>
  11. /// Represents a parser for JSON strings.
  12. /// </summary>
  13. public sealed class JSONParser
  14. {
  15. /// <summary>
  16. /// Initialize a new instance of JSONParser.
  17. /// </summary>
  18. [Obsolete("The recommended alternative is AjaxPro.JavaScriptSerializer and AjaxPro.JavaScriptDeserializer.", false)]
  19. public JSONParser()
  20. {
  21. }
  22. #region Constant Variables
  23. public const char JSON_OBJECT_BEGIN = '{';
  24. public const char JSON_OBJECT_END = '}';
  25. public const char JSON_ARRAY_BEGIN = '[';
  26. public const char JSON_ARRAY_END = ']';
  27. public const char JSON_PROPERTY_SEPARATOR = ':';
  28. public const char JSON_STRING_SINGLE_QUOTE = ''';
  29. public const char JSON_STRING_DOUBLE_QUOTE = '"';
  30. public const char JSON_ITEMS_SEPARATOR = ',';
  31. public const char JSON_DECIMAL_SEPARATOR = '.';
  32. public const char END_OF_STRING = '';
  33. public const char NEW_LINE = 'n';
  34. public const char RETURN = 'r';
  35. #endregion
  36. #region Private Variables
  37. private int _idx = 0;
  38. private string _json = null;
  39. private char _ch = ' ';
  40. #endregion
  41. #region Read Methods
  42. /// <summary>
  43. /// Read on the JSON string until first non-whitespace character.
  44. /// </summary>
  45. internal void ReadWhiteSpaces()
  46. {
  47. while(_ch != END_OF_STRING && _ch <= ' ')
  48. ReadNext();
  49. }
  50. /// <summary>
  51. /// Read the next character from the JSON string and store it in the private variable ch.
  52. /// </summary>
  53. /// <returns>Returns false if at end of JSON string.</returns>
  54. internal bool ReadNext()
  55. {
  56. if(_idx >= _json.Length)
  57. {
  58. _ch = END_OF_STRING;
  59. return false;
  60. }
  61. _ch = _json[_idx];
  62. _idx++;
  63. return true;
  64. }
  65. internal bool CompareNext(string s)
  66. {
  67. if(_idx + s.Length > _json.Length)
  68. return false;
  69. if(_json.Substring(_idx, s.Length) == s)
  70. return true;
  71. return false;
  72. }
  73. /// <summary>
  74. /// Read the previous character from the JSON string and store it in the private variable ch.
  75. /// </summary>
  76. /// <returns>Returns false if at the beginning of the JSON string.</returns>
  77. internal bool ReadPrev()
  78. {
  79. if(_idx <= 0)
  80. return false;
  81. _idx--;
  82. _ch = _json[_idx];
  83. return true;
  84. }
  85. #endregion
  86. #region Read JSON Methods
  87. /// <summary>
  88. /// Read a string object from the JSON string.
  89. /// </summary>
  90. /// <returns>Returns the string.</returns>
  91. internal JavaScriptString ReadString()
  92. {
  93. JavaScriptString s = new JavaScriptString();
  94. if(_ch == JSON_STRING_DOUBLE_QUOTE)
  95. {
  96. while(ReadNext())
  97. {
  98. if(_ch == JSON_STRING_DOUBLE_QUOTE)
  99. {
  100. ReadNext();
  101. return s;
  102. }
  103. else if(_ch == '\')
  104. {
  105. ReadNext();
  106. switch(_ch)
  107. {
  108. case 'n': s += 'n'; break;
  109. case 'r': s += 'r'; break;
  110. case 'b': s += 'b'; break;
  111. case 'f': s += 'f'; break;
  112. case 't': s += 't'; break;
  113. case '\': s += '\'; break;
  114. // case 'u':
  115. // u = 0;
  116. // for (i = 0; i < 4; i += 1) 
  117. // {
  118. // t = parseInt(next(), 16);
  119. // if (!isFinite(t)) 
  120. // {
  121. // break outer;
  122. // }
  123. // u = u * 16 + t;
  124. // }
  125. // s += String.fromCharCode(u);
  126. // break;
  127. default:
  128. s += _ch;
  129. break;
  130. }
  131. }
  132. else
  133. {
  134. s += _ch;
  135. }
  136. }
  137. }
  138. else
  139. {
  140. throw new NotSupportedException("The string could not be read.");
  141. }
  142. return s;
  143. }
  144. /// <summary>
  145. /// 
  146. /// </summary>
  147. /// <returns></returns>
  148. internal JavaScriptString ReadJavaScriptObject()
  149. {
  150. JavaScriptString n = new JavaScriptString();
  151. int b = 0;
  152. bool bf = false;
  153. while(_ch != END_OF_STRING)
  154. {
  155. if(_ch == '(')
  156. {
  157. b++;
  158. bf = true;
  159. }
  160. else
  161. if(_ch == ')') b--;
  162. if(bf)
  163. {
  164. }
  165. n += _ch;
  166. ReadNext();
  167. if(bf && b == 0)
  168. break;
  169. }
  170. return n;
  171. }
  172. /// <summary>
  173. /// Read a number object from the JSON string.
  174. /// </summary>
  175. /// <returns>Returns the number.</returns>
  176. internal JavaScriptNumber ReadNumber()
  177. {
  178. JavaScriptNumber n = new JavaScriptNumber();
  179. if(_ch == '-') // negative numbers
  180. {
  181. n += "-";
  182. ReadNext();
  183. }
  184. // Searching for all numbers until the first character that is not 
  185. // a number.
  186. while(_ch >= '0' && _ch <= '9' && _ch != END_OF_STRING) // all numbers between 0..9
  187. {
  188. n += _ch;
  189. ReadNext();
  190. }
  191. // In JavaScript (JSON) the decimal separator is always a point. If we
  192. // have a decimal number we read all the numbers after the separator.
  193. if(_ch == '.')
  194. {
  195. n += '.';
  196. ReadNext();
  197. while(_ch >= '0' && _ch <= '9' && _ch != END_OF_STRING)
  198. {
  199. n += _ch;
  200. ReadNext();
  201. }
  202. }
  203. if (_ch == 'e' || _ch == 'E') 
  204. {
  205. n += 'e';
  206. ReadNext();
  207. if (_ch == '-' || _ch == '+') 
  208. {
  209. n += _ch;
  210. ReadNext();
  211. }
  212. while (_ch >= '0' && _ch <= '9' && _ch != END_OF_STRING) 
  213. {
  214. n += _ch;
  215. ReadNext();
  216. }
  217. }
  218. return n;
  219. }
  220. /// <summary>
  221. /// Read a word object from the JSON string.
  222. /// </summary>
  223. /// <returns>Returns the word.</returns>
  224. internal IJavaScriptObject ReadWord()
  225. {
  226. switch(_ch)
  227. {
  228. case 't':
  229. if(CompareNext("rue") == true)
  230. {
  231. ReadNext();ReadNext();ReadNext();ReadNext();
  232. return new JavaScriptBoolean(true);
  233. }
  234. break;
  235. case 'f':
  236. if(CompareNext("alse") == true)
  237. {
  238. ReadNext();ReadNext();ReadNext();ReadNext();ReadNext();
  239. return new JavaScriptBoolean(false);
  240. }
  241. break;
  242. case 'n':
  243. if(CompareNext("ull") == true)
  244. {
  245. ReadNext();ReadNext();ReadNext();ReadNext();
  246. return null;
  247. }
  248. else if(CompareNext("ew ") == true)
  249. {
  250. return ReadJavaScriptObject();
  251. }
  252. break;
  253. }
  254. throw new NotSupportedException("word " + _ch);
  255. }
  256. /// <summary>
  257. /// Read an array object from the JSON string.
  258. /// </summary>
  259. /// <returns>Returns an ArrayList with all objects.</returns>
  260. internal JavaScriptArray ReadArray()
  261. {
  262. JavaScriptArray a = new JavaScriptArray();
  263. if(_ch == JSON_ARRAY_BEGIN)
  264. {
  265. ReadNext();
  266. ReadWhiteSpaces();
  267. if(_ch == JSON_ARRAY_END)
  268. {
  269. ReadNext();
  270. return a;
  271. }
  272. while(_ch != END_OF_STRING)
  273. {
  274. a.Add(GetObject());
  275. ReadWhiteSpaces();
  276. if(_ch == JSON_ARRAY_END)
  277. {
  278. ReadNext();
  279. return a;
  280. }
  281. else if(_ch != JSON_ITEMS_SEPARATOR)
  282. {
  283. break;
  284. }
  285. ReadNext();
  286. ReadWhiteSpaces();
  287. }
  288. }
  289. else
  290. {
  291. throw new NotSupportedException("Array could not be read.");
  292. }
  293. return a;
  294. }
  295. /// <summary>
  296. /// Reads the next object from the JSON string.
  297. /// </summary>
  298. /// <returns>Returns an Hashtable with all properties.</returns>
  299. internal JavaScriptObject ReadObject()
  300. {
  301. JavaScriptObject h = new JavaScriptObject();
  302. string k;
  303. if(_ch == JSON_OBJECT_BEGIN)
  304. {
  305. ReadNext();
  306. ReadWhiteSpaces();
  307. if(_ch == JSON_OBJECT_END)
  308. {
  309. ReadNext();
  310. return h;
  311. }
  312. while(_ch != END_OF_STRING)
  313. {
  314. k = ReadString();
  315. ReadWhiteSpaces();
  316. if(_ch != JSON_PROPERTY_SEPARATOR)
  317. {
  318. break;
  319. }
  320. ReadNext();
  321. h.Add(k, GetObject());
  322. ReadWhiteSpaces();
  323. if(_ch == JSON_OBJECT_END)
  324. {
  325. ReadNext();
  326. return h;
  327. }
  328. else if(_ch != JSON_ITEMS_SEPARATOR)
  329. {
  330. break;
  331. }
  332. ReadNext();
  333. ReadWhiteSpaces();
  334. }
  335. }
  336. throw new NotSupportedException("obj");
  337. }
  338. #endregion
  339. #region JSON string and JSON object
  340. /// <summary>
  341. /// Returns a JSON object using Hashtable, ArrayList or string.
  342. /// </summary>
  343. /// <returns></returns>
  344. internal IJavaScriptObject GetObject()
  345. {
  346. if(_json == null)
  347. throw new Exception("Missing json string.");
  348. ReadWhiteSpaces();
  349. switch(_ch)
  350. {
  351. case JSON_OBJECT_BEGIN: return ReadObject();
  352. case JSON_ARRAY_BEGIN: return ReadArray();
  353. case JSON_STRING_DOUBLE_QUOTE: return ReadString();
  354. case '-': return ReadNumber();
  355. default:
  356. return _ch >= '0' && _ch <= '9' ? ReadNumber() : ReadWord();
  357. }
  358. }
  359. #endregion
  360. /// <summary>
  361. /// Reads the object that represents the JSON string.
  362. /// </summary>
  363. /// <returns>Returns an object.</returns>
  364. public IJavaScriptObject GetJSONObject(string json)
  365. {
  366. _json = json;
  367. _idx = 0;
  368. _ch = ' ';
  369. return GetObject();
  370. }
  371. }
  372. }