Created
November 7, 2012 12:23
-
-
Save lexich/4031246 to your computer and use it in GitHub Desktop.
Own realization SAX parser of JSON
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by CoffeeScript 1.4.0 | |
(function() { | |
var DATA, JSON2, res; | |
JSON2 = { | |
OBJECT: "Object", | |
ARRAY: "Array", | |
nextToken: function(buf, i) { | |
var ch, isFloat, isNum, isWord, str, token; | |
token = void 0; | |
isWord = false; | |
isNum = false; | |
isFloat = false; | |
str = ""; | |
while (i < buf.length) { | |
ch = buf.charCodeAt(i); | |
++i; | |
switch (ch) { | |
case 123: | |
case 125: | |
case 58: | |
case 91: | |
case 93: | |
case 44: | |
return [String.fromCharCode(ch), str, i]; | |
case 34: | |
isWord = !isWord; | |
if (!isWord) { | |
return ["w", str, i]; | |
} | |
break; | |
default: | |
if (ch === 46 && isNum) { | |
if (!isFloat) { | |
isFloat = true; | |
} else { | |
throw new Error("more then one char '.' in number token"); | |
} | |
} | |
if (!isWord && ch >= 48 && ch <= 57) { | |
isNum = true; | |
} | |
if (isWord || isNum) { | |
str += String.fromCharCode(ch); | |
} | |
if (isNum && i + 1 < buf.length) { | |
ch = buf.charCodeAt(i + 1); | |
if ((ch < 48 || ch > 57) && ch !== 46) { | |
if (!isFloat) { | |
return ['i', parseInt(str), i]; | |
} else { | |
return ["f", parseFloat(str), i]; | |
} | |
} | |
} | |
} | |
} | |
return ["", "", i]; | |
}, | |
processValue: function(obj, key, value, type) { | |
if (type === this.OBJECT) { | |
if ((key != null) && (value != null) && (obj != null)) { | |
obj[key] = value; | |
} else { | |
throw new Error("Invalid params for [" + type + "]: key:'" + key + "' value:'" + value + "' obj:'" + obj + "'"); | |
} | |
} else if (type === this.ARRAY) { | |
if ((value != null) && (obj != null)) { | |
obj.push(value); | |
} else { | |
throw new Error("Invalid params for [" + type + "]: value:'" + value + "' obj:'" + obj + "'"); | |
} | |
} else { | |
throw new Error("Unknown type"); | |
} | |
key = null; | |
value = null; | |
return [obj, key, value, type]; | |
}, | |
_parse: function(buf, obj, i, type) { | |
var key, token, v, value, _ref, _ref1, _ref2, _ref3, _ref4; | |
key = null; | |
value = null; | |
try { | |
while (i < buf.length) { | |
_ref = this.nextToken(buf, i), token = _ref[0], v = _ref[1], i = _ref[2]; | |
switch (token) { | |
case "{": | |
_ref1 = this._parse(buf, {}, i, this.OBJECT), i = _ref1[0], value = _ref1[1]; | |
break; | |
case "[": | |
_ref2 = this._parse(buf, [], i, this.ARRAY), i = _ref2[0], value = _ref2[1]; | |
break; | |
case "}": | |
case "]": | |
_ref3 = this.processValue(obj, key, value, type), obj = _ref3[0], key = _ref3[1], value = _ref3[2], type = _ref3[3]; | |
return [i, obj]; | |
case ",": | |
_ref4 = this.processValue(obj, key, value, type), obj = _ref4[0], key = _ref4[1], value = _ref4[2], type = _ref4[3]; | |
break; | |
case ":": | |
key = value; | |
value = null; | |
break; | |
case "w": | |
case "i": | |
case "f": | |
value = v; | |
} | |
} | |
} catch (e) { | |
e.buf = buf; | |
e.i = i; | |
throw e; | |
} | |
return [i, value]; | |
}, | |
parse: function(buf) { | |
try { | |
return this._parse(buf, {}, 0, this.OBJECT)[1]; | |
} catch (e) { | |
throw new Error("msg:" + e.message + " text:" + (e.buf.slice(0, e.i).to)); | |
} | |
} | |
}; | |
DATA = "{\n \"one\":[0,\"1\",0,\"3\",\"4\",\"9\"],\n \"two\":\"three\",\n \"four\":{\n 1:\"one\",\n \"five\":1.0,\n \"six\":3\n }\n}"; | |
res = JSON2.parse(DATA.toString()); | |
if (res.one.length === 6) { | |
console.log("PASS"); | |
} else { | |
console.error("FAIL"); | |
} | |
if (res.one[0] === 0) { | |
console.log("PASS"); | |
} else { | |
console.error("FAIL"); | |
} | |
if (res.one[1] === "1") { | |
console.log("PASS"); | |
} else { | |
console.error("FAIL"); | |
} | |
if (res.two === "three") { | |
console.log("PASS"); | |
} else { | |
console.error("FAIL"); | |
} | |
if (res.four["1"] === "one") { | |
console.log("PASS"); | |
} else { | |
console.error("FAIL"); | |
} | |
}).call(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment