(file) Return to json2.js CVS log (file) (dir) Up to [Pegasus] / pegasus / www / js

  1 lawrence.luo 1.1.2.1 /*
  2                          json2.js
  3                          2013-05-26
  4                      
  5                          Public Domain.
  6                      
  7                          NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  8                      
  9                          See http://www.JSON.org/js.html
 10                      
 11                      
 12                          This code should be minified before deployment.
 13                          See http://javascript.crockford.com/jsmin.html
 14                      
 15                          USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
 16                          NOT CONTROL.
 17                      
 18                      
 19                          This file creates a global JSON object containing two methods: stringify
 20                          and parse.
 21                      
 22 lawrence.luo 1.1.2.1         JSON.stringify(value, replacer, space)
 23                                  value       any JavaScript value, usually an object or array.
 24                      
 25                                  replacer    an optional parameter that determines how object
 26                                              values are stringified for objects. It can be a
 27                                              function or an array of strings.
 28                      
 29                                  space       an optional parameter that specifies the indentation
 30                                              of nested structures. If it is omitted, the text will
 31                                              be packed without extra whitespace. If it is a number,
 32                                              it will specify the number of spaces to indent at each
 33                                              level. If it is a string (such as '\t' or ' '),
 34                                              it contains the characters used to indent at each level.
 35                      
 36                                  This method produces a JSON text from a JavaScript value.
 37                      
 38                                  When an object value is found, if the object contains a toJSON
 39                                  method, its toJSON method will be called and the result will be
 40                                  stringified. A toJSON method does not serialize: it returns the
 41                                  value represented by the name/value pair that should be serialized,
 42                                  or undefined if nothing should be serialized. The toJSON method
 43 lawrence.luo 1.1.2.1             will be passed the key associated with the value, and this will be
 44                                  bound to the value
 45                      
 46                                  For example, this would serialize Dates as ISO strings.
 47                      
 48                                      Date.prototype.toJSON = function (key) {
 49                                          function f(n) {
 50                                              // Format integers to have at least two digits.
 51                                              return n < 10 ? '0' + n : n;
 52                                          }
 53                      
 54                                          return this.getUTCFullYear()   + '-' +
 55                                               f(this.getUTCMonth() + 1) + '-' +
 56                                               f(this.getUTCDate())      + 'T' +
 57                                               f(this.getUTCHours())     + ':' +
 58                                               f(this.getUTCMinutes())   + ':' +
 59                                               f(this.getUTCSeconds())   + 'Z';
 60                                      };
 61                      
 62                                  You can provide an optional replacer method. It will be passed the
 63                                  key and value of each member, with this bound to the containing
 64 lawrence.luo 1.1.2.1             object. The value that is returned from your method will be
 65                                  serialized. If your method returns undefined, then the member will
 66                                  be excluded from the serialization.
 67                      
 68                                  If the replacer parameter is an array of strings, then it will be
 69                                  used to select the members to be serialized. It filters the results
 70                                  such that only members with keys listed in the replacer array are
 71                                  stringified.
 72                      
 73                                  Values that do not have JSON representations, such as undefined or
 74                                  functions, will not be serialized. Such values in objects will be
 75                                  dropped; in arrays they will be replaced with null. You can use
 76                                  a replacer function to replace those with JSON values.
 77                                  JSON.stringify(undefined) returns undefined.
 78                      
 79                                  The optional space parameter produces a stringification of the
 80                                  value that is filled with line breaks and indentation to make it
 81                                  easier to read.
 82                      
 83                                  If the space parameter is a non-empty string, then that string will
 84                                  be used for indentation. If the space parameter is a number, then
 85 lawrence.luo 1.1.2.1             the indentation will be that many spaces.
 86                      
 87                                  Example:
 88                      
 89                                  text = JSON.stringify(['e', {pluribus: 'unum'}]);
 90                                  // text is '["e",{"pluribus":"unum"}]'
 91                      
 92                      
 93                                  text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
 94                                  // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
 95                      
 96                                  text = JSON.stringify([new Date()], function (key, value) {
 97                                      return this[key] instanceof Date ?
 98                                          'Date(' + this[key] + ')' : value;
 99                                  });
100                                  // text is '["Date(---current time---)"]'
101                      
102                      
103                              JSON.parse(text, reviver)
104                                  This method parses a JSON text to produce an object or array.
105                                  It can throw a SyntaxError exception.
106 lawrence.luo 1.1.2.1 
107                                  The optional reviver parameter is a function that can filter and
108                                  transform the results. It receives each of the keys and values,
109                                  and its return value is used instead of the original value.
110                                  If it returns what it received, then the structure is not modified.
111                                  If it returns undefined then the member is deleted.
112                      
113                                  Example:
114                      
115                                  // Parse the text. Values that look like ISO date strings will
116                                  // be converted to Date objects.
117                      
118                                  myData = JSON.parse(text, function (key, value) {
119                                      var a;
120                                      if (typeof value === 'string') {
121                                          a =
122                      /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
123                                          if (a) {
124                                              return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
125                                                  +a[5], +a[6]));
126                                          }
127 lawrence.luo 1.1.2.1                 }
128                                      return value;
129                                  });
130                      
131                                  myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
132                                      var d;
133                                      if (typeof value === 'string' &&
134                                              value.slice(0, 5) === 'Date(' &&
135                                              value.slice(-1) === ')') {
136                                          d = new Date(value.slice(5, -1));
137                                          if (d) {
138                                              return d;
139                                          }
140                                      }
141                                      return value;
142                                  });
143                      
144                      
145                          This is a reference implementation. You are free to copy, modify, or
146                          redistribute.
147                      */
148 lawrence.luo 1.1.2.1 
149                      /*jslint evil: true, regexp: true */
150                      
151                      /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
152                          call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
153                          getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
154                          lastIndex, length, parse, prototype, push, replace, slice, stringify,
155                          test, toJSON, toString, valueOf
156                      */
157                      
158                      
159                      // Create a JSON object only if one does not already exist. We create the
160                      // methods in a closure to avoid creating global variables.
161                      
162                      if (typeof JSON !== 'object') {
163                          JSON = {};
164                      }
165                      
166                      (function () {
167                          'use strict';
168                      
169 lawrence.luo 1.1.2.1     function f(n) {
170                              // Format integers to have at least two digits.
171                              return n < 10 ? '0' + n : n;
172                          }
173                      
174                          if (typeof Date.prototype.toJSON !== 'function') {
175                      
176                              Date.prototype.toJSON = function () {
177                      
178                                  return isFinite(this.valueOf())
179                                      ? this.getUTCFullYear()     + '-' +
180                                          f(this.getUTCMonth() + 1) + '-' +
181                                          f(this.getUTCDate())      + 'T' +
182                                          f(this.getUTCHours())     + ':' +
183                                          f(this.getUTCMinutes())   + ':' +
184                                          f(this.getUTCSeconds())   + 'Z'
185                                      : null;
186                              };
187                      
188                              String.prototype.toJSON      =
189                                  Number.prototype.toJSON  =
190 lawrence.luo 1.1.2.1             Boolean.prototype.toJSON = function () {
191                                      return this.valueOf();
192                                  };
193                          }
194                      
195                          var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
196                              escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
197                              gap,
198                              indent,
199                              meta = {    // table of character substitutions
200                                  '\b': '\\b',
201                                  '\t': '\\t',
202                                  '\n': '\\n',
203                                  '\f': '\\f',
204                                  '\r': '\\r',
205                                  '"' : '\\"',
206                                  '\\': '\\\\'
207                              },
208                              rep;
209                      
210                      
211 lawrence.luo 1.1.2.1     function quote(string) {
212                      
213                      // If the string contains no control characters, no quote characters, and no
214                      // backslash characters, then we can safely slap some quotes around it.
215                      // Otherwise we must also replace the offending characters with safe escape
216                      // sequences.
217                      
218                              escapable.lastIndex = 0;
219                              return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
220                                  var c = meta[a];
221                                  return typeof c === 'string'
222                                      ? c
223                                      : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
224                              }) + '"' : '"' + string + '"';
225                          }
226                      
227                      
228                          function str(key, holder) {
229                      
230                      // Produce a string from holder[key].
231                      
232 lawrence.luo 1.1.2.1         var i,          // The loop counter.
233                                  k,          // The member key.
234                                  v,          // The member value.
235                                  length,
236                                  mind = gap,
237                                  partial,
238                                  value = holder[key];
239                      
240                      // If the value has a toJSON method, call it to obtain a replacement value.
241                      
242                              if (value && typeof value === 'object' &&
243                                      typeof value.toJSON === 'function') {
244                                  value = value.toJSON(key);
245                              }
246                      
247                      // If we were called with a replacer function, then call the replacer to
248                      // obtain a replacement value.
249                      
250                              if (typeof rep === 'function') {
251                                  value = rep.call(holder, key, value);
252                              }
253 lawrence.luo 1.1.2.1 
254                      // What happens next depends on the value's type.
255                      
256                              switch (typeof value) {
257                              case 'string':
258                                  return quote(value);
259                      
260                              case 'number':
261                      
262                      // JSON numbers must be finite. Encode non-finite numbers as null.
263                      
264                                  return isFinite(value) ? String(value) : 'null';
265                      
266                              case 'boolean':
267                              case 'null':
268                      
269                      // If the value is a boolean or null, convert it to a string. Note:
270                      // typeof null does not produce 'null'. The case is included here in
271                      // the remote chance that this gets fixed someday.
272                      
273                                  return String(value);
274 lawrence.luo 1.1.2.1 
275                      // If the type is 'object', we might be dealing with an object or an array or
276                      // null.
277                      
278                              case 'object':
279                      
280                      // Due to a specification blunder in ECMAScript, typeof null is 'object',
281                      // so watch out for that case.
282                      
283                                  if (!value) {
284                                      return 'null';
285                                  }
286                      
287                      // Make an array to hold the partial results of stringifying this object value.
288                      
289                                  gap += indent;
290                                  partial = [];
291                      
292                      // Is the value an array?
293                      
294                                  if (Object.prototype.toString.apply(value) === '[object Array]') {
295 lawrence.luo 1.1.2.1 
296                      // The value is an array. Stringify every element. Use null as a placeholder
297                      // for non-JSON values.
298                      
299                                      length = value.length;
300                                      for (i = 0; i < length; i += 1) {
301                                          partial[i] = str(i, value) || 'null';
302                                      }
303                      
304                      // Join all of the elements together, separated with commas, and wrap them in
305                      // brackets.
306                      
307                                      v = partial.length === 0
308                                          ? '[]'
309                                          : gap
310                                          ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
311                                          : '[' + partial.join(',') + ']';
312                                      gap = mind;
313                                      return v;
314                                  }
315                      
316 lawrence.luo 1.1.2.1 // If the replacer is an array, use it to select the members to be stringified.
317                      
318                                  if (rep && typeof rep === 'object') {
319                                      length = rep.length;
320                                      for (i = 0; i < length; i += 1) {
321                                          if (typeof rep[i] === 'string') {
322                                              k = rep[i];
323                                              v = str(k, value);
324                                              if (v) {
325                                                  partial.push(quote(k) + (gap ? ': ' : ':') + v);
326                                              }
327                                          }
328                                      }
329                                  } else {
330                      
331                      // Otherwise, iterate through all of the keys in the object.
332                      
333                                      for (k in value) {
334                                          if (Object.prototype.hasOwnProperty.call(value, k)) {
335                                              v = str(k, value);
336                                              if (v) {
337 lawrence.luo 1.1.2.1                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
338                                              }
339                                          }
340                                      }
341                                  }
342                      
343                      // Join all of the member texts together, separated with commas,
344                      // and wrap them in braces.
345                      
346                                  v = partial.length === 0
347                                      ? '{}'
348                                      : gap
349                                      ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
350                                      : '{' + partial.join(',') + '}';
351                                  gap = mind;
352                                  return v;
353                              }
354                          }
355                      
356                      // If the JSON object does not yet have a stringify method, give it one.
357                      
358 lawrence.luo 1.1.2.1     if (typeof JSON.stringify !== 'function') {
359                              JSON.stringify = function (value, replacer, space) {
360                      
361                      // The stringify method takes a value and an optional replacer, and an optional
362                      // space parameter, and returns a JSON text. The replacer can be a function
363                      // that can replace values, or an array of strings that will select the keys.
364                      // A default replacer method can be provided. Use of the space parameter can
365                      // produce text that is more easily readable.
366                      
367                                  var i;
368                                  gap = '';
369                                  indent = '';
370                      
371                      // If the space parameter is a number, make an indent string containing that
372                      // many spaces.
373                      
374                                  if (typeof space === 'number') {
375                                      for (i = 0; i < space; i += 1) {
376                                          indent += ' ';
377                                      }
378                      
379 lawrence.luo 1.1.2.1 // If the space parameter is a string, it will be used as the indent string.
380                      
381                                  } else if (typeof space === 'string') {
382                                      indent = space;
383                                  }
384                      
385                      // If there is a replacer, it must be a function or an array.
386                      // Otherwise, throw an error.
387                      
388                                  rep = replacer;
389                                  if (replacer && typeof replacer !== 'function' &&
390                                          (typeof replacer !== 'object' ||
391                                          typeof replacer.length !== 'number')) {
392                                      throw new Error('JSON.stringify');
393                                  }
394                      
395                      // Make a fake root object containing our value under the key of ''.
396                      // Return the result of stringifying the value.
397                      
398                                  return str('', {'': value});
399                              };
400 lawrence.luo 1.1.2.1     }
401                      
402                      
403                      // If the JSON object does not yet have a parse method, give it one.
404                      
405                          if (typeof JSON.parse !== 'function') {
406                              JSON.parse = function (text, reviver) {
407                      
408                      // The parse method takes a text and an optional reviver function, and returns
409                      // a JavaScript value if the text is a valid JSON text.
410                      
411                                  var j;
412                      
413                                  function walk(holder, key) {
414                      
415                      // The walk method is used to recursively walk the resulting structure so
416                      // that modifications can be made.
417                      
418                                      var k, v, value = holder[key];
419                                      if (value && typeof value === 'object') {
420                                          for (k in value) {
421 lawrence.luo 1.1.2.1                         if (Object.prototype.hasOwnProperty.call(value, k)) {
422                                                  v = walk(value, k);
423                                                  if (v !== undefined) {
424                                                      value[k] = v;
425                                                  } else {
426                                                      delete value[k];
427                                                  }
428                                              }
429                                          }
430                                      }
431                                      return reviver.call(holder, key, value);
432                                  }
433                      
434                      
435                      // Parsing happens in four stages. In the first stage, we replace certain
436                      // Unicode characters with escape sequences. JavaScript handles many characters
437                      // incorrectly, either silently deleting them, or treating them as line endings.
438                      
439                                  text = String(text);
440                                  cx.lastIndex = 0;
441                                  if (cx.test(text)) {
442 lawrence.luo 1.1.2.1                 text = text.replace(cx, function (a) {
443                                          return '\\u' +
444                                              ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
445                                      });
446                                  }
447                      
448                      // In the second stage, we run the text against regular expressions that look
449                      // for non-JSON patterns. We are especially concerned with '()' and 'new'
450                      // because they can cause invocation, and '=' because it can cause mutation.
451                      // But just to be safe, we want to reject all unexpected forms.
452                      
453                      // We split the second stage into 4 regexp operations in order to work around
454                      // crippling inefficiencies in IE's and Safari's regexp engines. First we
455                      // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
456                      // replace all simple value tokens with ']' characters. Third, we delete all
457                      // open brackets that follow a colon or comma or that begin the text. Finally,
458                      // we look to see that the remaining characters are only whitespace or ']' or
459                      // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
460                      
461                                  if (/^[\],:{}\s]*$/
462                                          .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
463 lawrence.luo 1.1.2.1                         .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
464                                              .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
465                      
466                      // In the third stage we use the eval function to compile the text into a
467                      // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
468                      // in JavaScript: it can begin a block or an object literal. We wrap the text
469                      // in parens to eliminate the ambiguity.
470                      
471                                      j = eval('(' + text + ')');
472                      
473                      // In the optional fourth stage, we recursively walk the new structure, passing
474                      // each name/value pair to a reviver function for possible transformation.
475                      
476                                      return typeof reviver === 'function'
477                                          ? walk({'': j}, '')
478                                          : j;
479                                  }
480                      
481                      // If the text is not JSON parseable, then a SyntaxError is thrown.
482                      
483                                  throw new SyntaxError('JSON.parse');
484 lawrence.luo 1.1.2.1         };
485                          }
486                      }());

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2