JSON.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // JSON.js
  2. // For JSON functions.
  3. // FZ, Copyright (c) 2010 Zlongames
  4. (function()
  5. {
  6. FZ.JSON = {
  7. parse: function (text, reviver) {
  8. var j;
  9. function walk(holder, key) {
  10. var k, v, value = holder[key];
  11. if (value && typeof value === 'object') {
  12. for (k in value) {
  13. if (Object.hasOwnProperty.call(value, k)) {
  14. v = walk(value, k);
  15. if (v !== undefined) {
  16. value[k] = v;
  17. } else {
  18. delete value[k];
  19. }
  20. }
  21. }
  22. }
  23. return reviver.call(holder, key, value);
  24. }
  25. text = String(text);
  26. cx.lastIndex = 0;
  27. if (cx.test(text)) {
  28. text = text.replace(cx, function (a) {
  29. return '\\u' +
  30. ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  31. });
  32. }
  33. if (/^[\],:{}\s]*$/.
  34. test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
  35. replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
  36. replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
  37. j = eval('(' + text + ')');
  38. return typeof reviver === 'function' ?
  39. walk({'': j}, '') : j;
  40. }
  41. throw new SyntaxError('JSON.parse');
  42. },
  43. stringify: function(value, replacer, space){
  44. var i;
  45. gap = '';
  46. indent = '';
  47. if (typeof space === 'number') {
  48. for (i = 0; i < space; i += 1) {
  49. indent += ' ';
  50. }
  51. } else if (typeof space === 'string') {
  52. indent = space;
  53. }
  54. rep = replacer;
  55. if (replacer && typeof replacer !== 'function' &&
  56. (typeof replacer !== 'object' ||
  57. typeof replacer.length !== 'number')) {
  58. throw new Error('JSON.stringify');
  59. }
  60. return str('', {'': value});
  61. }
  62. };
  63. function quote(string) {
  64. escapable.lastIndex = 0;
  65. return escapable.test(string) ?
  66. '"' + string.replace(escapable, function (a) {
  67. var c = meta[a];
  68. return typeof c === 'string' ? c :
  69. '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  70. }) + '"' :
  71. '"' + string + '"';
  72. }
  73. function str(key, holder) {
  74. var i,
  75. k,
  76. v,
  77. length,
  78. mind = gap,
  79. partial,
  80. value = holder[key];
  81. if (value && typeof value === 'object' &&
  82. typeof value.toJSON === 'function') {
  83. value = value.toJSON(key);
  84. }
  85. if (typeof rep === 'function') {
  86. value = rep.call(holder, key, value);
  87. }
  88. switch (typeof value) {
  89. case 'string':
  90. return quote(value);
  91. case 'number':
  92. return isFinite(value) ? String(value) : 'null';
  93. case 'boolean':
  94. case 'null':
  95. return String(value);
  96. case 'object':
  97. if (!value) {
  98. return 'null';
  99. }
  100. gap += indent;
  101. partial = [];
  102. if (Object.prototype.toString.apply(value) === '[object Array]') {
  103. length = value.length;
  104. for (i = 0; i < length; i += 1) {
  105. partial[i] = str(i, value) || 'null';
  106. }
  107. v = partial.length === 0 ? '[]' :
  108. gap ? '[\n' + gap +
  109. partial.join(',\n' + gap) + '\n' +
  110. mind + ']' :
  111. '[' + partial.join(',') + ']';
  112. gap = mind;
  113. return v;
  114. }
  115. if (rep && typeof rep === 'object') {
  116. length = rep.length;
  117. for (i = 0; i < length; i += 1) {
  118. k = rep[i];
  119. if (typeof k === 'string') {
  120. v = str(k, value);
  121. if (v) {
  122. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  123. }
  124. }
  125. }
  126. } else {
  127. for (k in value) {
  128. if (Object.hasOwnProperty.call(value, k)) {
  129. v = str(k, value);
  130. if (v) {
  131. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  132. }
  133. }
  134. }
  135. }
  136. v = partial.length === 0 ? '{}' :
  137. gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
  138. mind + '}' : '{' + partial.join(',') + '}';
  139. gap = mind;
  140. return v;
  141. }
  142. }
  143. var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  144. escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  145. gap,
  146. indent,
  147. meta = { // table of character substitutions
  148. '\b': '\\b',
  149. '\t': '\\t',
  150. '\n': '\\n',
  151. '\f': '\\f',
  152. '\r': '\\r',
  153. '"' : '\\"',
  154. '\\': '\\\\'
  155. },
  156. rep;
  157. function f(n) {
  158. return n < 10 ? '0' + n : n;
  159. }
  160. if (typeof Date.prototype.toJSON !== 'function') {
  161. Date.prototype.toJSON = function (key) {
  162. return isFinite(this.valueOf()) ?
  163. this.getUTCFullYear() + '-' +
  164. f(this.getUTCMonth() + 1) + '-' +
  165. f(this.getUTCDate()) + 'T' +
  166. f(this.getUTCHours()) + ':' +
  167. f(this.getUTCMinutes()) + ':' +
  168. f(this.getUTCSeconds()) + 'Z' : null;
  169. };
  170. String.prototype.toJSON =
  171. Number.prototype.toJSON =
  172. Boolean.prototype.toJSON = function (key) {
  173. return this.valueOf();
  174. };
  175. }
  176. })();