Skip to content

Instantly share code, notes, and snippets.

@cms
Created October 6, 2010 08:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cms/612995 to your computer and use it in GitHub Desktop.
Save cms/612995 to your computer and use it in GitHub Desktop.
Added reviver support to Asen's JSON.js
/**
* Written by Asen Bozhilov
* http://code.google.com/p/js-examples/source/browse/trunk/JSON.js
*/
if (!this.JSON) {
this.JSON = {
parse : (function (undefined) {
var JSON_GRAMMAR = {
STRING : '"([^"\\x00-\\x1F\\\\]|\\\\["\\\\\/bfnrt]|\\\\u[0-9A-Fa-f]{4})*"',
NUMBER : '-?\\d+(?:\\.\\d+)?(?:[Ee][+-]?\\d+)?',
BOOLEAN : 'true|false',
NULL : 'null'
},
REG_EXP = {
property : new RegExp(JSON_GRAMMAR.STRING + '\\s*:', "g"),
value : new RegExp(JSON_GRAMMAR.STRING + '|' + JSON_GRAMMAR.NUMBER + '|' + JSON_GRAMMAR.BOOLEAN + '|' + JSON_GRAMMAR.NULL, "g"),
invalidTokens : /[^{}\[\],\s]/
},
hasOwn = Object.prototype.hasOwnProperty,
toString = Object.prototype.toString;
return function(jsonStr, reviver) {
var output;
if (typeof jsonStr != 'string') {
jsonStr = String(jsonStr);
}
if (!REG_EXP.invalidTokens.test(jsonStr.replace(REG_EXP.property,'').replace(REG_EXP.value, ''))) {
output = eval('Array(null,' + jsonStr + ');');
if (output.length == 2) {
if (typeof reviver == 'function') {
return walk({'':output[1]}, '');
}
return output[1];
}
}
throw new SyntaxError('JSON.parse');
// Walk operation described in 15.12.2
function walk(holder, name) {
var val = holder[name], // 1
i, len, newElement;
if (val && typeof val == 'object') { // 2
if (toString.call(val) == '[object Array]') { // 2.a
i = 0; // 2.a.i
len = val.length; // 2.a.ii
while (i < len) { // 2.a.iii
newElement = walk(val, String(i)); // 2.a.iii.1
if (newElement === undefined) { // 2.a.iii.2
delete val[i]; // 2.a.iii.2.a
} else {
val[i] = newElement; // 2.a.iii.3.a
}
i++; // 2.a.iii.4
}
} else { // 2.b
for (var p in val) { // 2.b.i, ii
if (hasOwn.call(val, p)) {
newElement = walk(val, p); // 2.b.ii.1
if (newElement === undefined) { // 2.b.ii.2
delete val[p]; // 2.b.ii.2.a
} else {
val[p] = newElement; // 2.b.ii.3.a
}
}
}
}
}
return reviver.call(holder, name, val); // 3
}
};
})()
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment