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

/library/JSONParser.py

http://pyjamas.googlecode.com/
Python | 207 lines | 207 code | 0 blank | 0 comment | 0 complexity | 869c26e35539251cc7e6807f7dd48839 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. JS("""
  2. /*
  3. JSONEncode:
  4. +---------------+-------------------+---------------+
  5. | PYGWT | Python | JSON |
  6. +===============+===================+===============+
  7. | pyjslib_Dict | dict | object |
  8. +---------------+-------------------+---------------+
  9. | pyjslib_List | list, tuple | array |
  10. +---------------+-------------------+---------------+
  11. | string | str, unicode | string |
  12. +---------------+-------------------+---------------+
  13. | number | int, long, float | number |
  14. +---------------+-------------------+---------------+
  15. | true | True | true |
  16. +---------------+-------------------+---------------+
  17. | false | False | false |
  18. +---------------+-------------------+---------------+
  19. | null | None | null |
  20. +---------------+-------------------+---------------+
  21. JSONDecode:
  22. +---------------+-------------------+--------------+
  23. | JSON | Python | PYGWT |
  24. +===============+===================+==============+
  25. | object | dict | pyjslib_Dict |
  26. +---------------+-------------------+--------------+
  27. | array | list | pyjslib_List |
  28. +---------------+-------------------+--------------+
  29. | string | unicode | string |
  30. +---------------+-------------------+--------------+
  31. | number (int) | int, long | number |
  32. +---------------+-------------------+--------------+
  33. | number (real) | float | number |
  34. +---------------+-------------------+--------------+
  35. | true | True | true |
  36. +---------------+-------------------+--------------+
  37. | false | False | false |
  38. +---------------+-------------------+--------------+
  39. | null | None | null |
  40. +---------------+-------------------+--------------+
  41. */
  42. """)
  43. # toJSONString & parseJSON from http://www.json.org/json.js
  44. class JSONParser:
  45. def decode(self, str):
  46. return self.jsObjectToPy(self.parseJSON(str))
  47. def decodeAsObject(self, str):
  48. return self.jsObjectToPyObject(self.parseJSON(str))
  49. def encode(self, obj):
  50. return self.toJSONString(obj)
  51. def jsObjectToPy(self, obj):
  52. JS("""
  53. if (pyjslib_isArray(obj)) {
  54. for (var i in obj) obj[i] = this.jsObjectToPy(obj[i]);
  55. obj=new pyjslib_List(obj);
  56. }
  57. else if (pyjslib_isObject(obj)) {
  58. for (var i in obj) obj[i]=this.jsObjectToPy(obj[i]);
  59. obj=new pyjslib_Dict(obj);
  60. }
  61. return obj;
  62. """)
  63. # TODO: __init__ parameters
  64. def jsObjectToPyObject(self, obj):
  65. JS("""
  66. if (pyjslib_isArray(obj)) {
  67. for (var i in obj) obj[i] = this.jsObjectToPyObject(obj[i]);
  68. obj=new pyjslib_List(obj);
  69. }
  70. else if (pyjslib_isObject(obj)) {
  71. if (obj["__jsonclass__"]) {
  72. var class_name = obj["__jsonclass__"][0];
  73. class_name = class_name.replace(".", "_");
  74. var new_obj = eval("new " + class_name + "()");
  75. delete obj["__jsonclass__"];
  76. for (var i in obj) new_obj[i] = this.jsObjectToPyObject(obj[i]);
  77. obj = new_obj;
  78. }
  79. else {
  80. for (var i in obj) obj[i]=this.jsObjectToPyObject(obj[i]);
  81. obj=new pyjslib_Dict(obj);
  82. }
  83. }
  84. return obj;
  85. """)
  86. # modified to detect __pyjslib_List & __pyjslib_Dict
  87. def toJSONString(self, obj):
  88. JS(r"""
  89. var m = {
  90. '\b': '\\b',
  91. '\t': '\\t',
  92. '\n': '\\n',
  93. '\f': '\\f',
  94. '\r': '\\r',
  95. '"' : '\\"',
  96. '\\': '\\\\'
  97. },
  98. s = {
  99. array: function (x) {
  100. var a = ['['], b, f, i, l = x.length, v;
  101. for (i = 0; i < l; i += 1) {
  102. v = x[i];
  103. f = s[typeof v];
  104. if (f) {
  105. v = f(v);
  106. if (typeof v == 'string') {
  107. if (b) {
  108. a[a.length] = ',';
  109. }
  110. a[a.length] = v;
  111. b = true;
  112. }
  113. }
  114. }
  115. a[a.length] = ']';
  116. return a.join('');
  117. },
  118. 'boolean': function (x) {
  119. return String(x);
  120. },
  121. 'undefined':function (x) {
  122. return "null";
  123. },
  124. 'null': function (x) {
  125. return "null";
  126. },
  127. number: function (x) {
  128. return isFinite(x) ? String(x) : 'null';
  129. },
  130. object: function (x) {
  131. if (x) {
  132. if (x instanceof Array) {
  133. return s.array(x);
  134. }
  135. if (x instanceof __pyjslib_List) {
  136. return s.array(x.l);
  137. }
  138. if (x instanceof __pyjslib_Dict) {
  139. return s.object(x.d);
  140. }
  141. var a = ['{'], b, f, i, v;
  142. for (i in x) {
  143. v = x[i];
  144. f = s[typeof v];
  145. if (f) {
  146. v = f(v);
  147. if (typeof v == 'string') {
  148. if (b) {
  149. a[a.length] = ',';
  150. }
  151. a.push(s.string(i), ':', v);
  152. b = true;
  153. }
  154. }
  155. }
  156. a[a.length] = '}';
  157. return a.join('');
  158. }
  159. return 'null';
  160. },
  161. string: function (x) {
  162. if (/["\\\x00-\x1f]/.test(x)) {
  163. x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
  164. var c = m[b];
  165. if (c) {
  166. return c;
  167. }
  168. c = b.charCodeAt();
  169. return '\\u00' +
  170. Math.floor(c / 16).toString(16) +
  171. (c % 16).toString(16);
  172. });
  173. }
  174. return '"' + x + '"';
  175. }
  176. };
  177. f=s[typeof obj];
  178. return f(obj);
  179. """)
  180. def parseJSON(self, str):
  181. JS(r"""
  182. try {
  183. return (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(str)) &&
  184. eval('(' + str + ')');
  185. } catch (e) {
  186. return false;
  187. }
  188. """)