Last active
November 19, 2020 12:39
-
-
Save cyppan/e4b3963c5642a0176a330ee640d379b7 to your computer and use it in GitHub Desktop.
Javascript (very incomplete) port of the "unserialize" PHP function
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
function unserialize(serialized) { | |
serialized = serialized.split("") | |
const res = [] | |
const parseNumber = () => { | |
next = serialized.shift() | |
let digits = "" | |
while (!isNaN(parseInt(next))) { | |
digits += next | |
next = serialized.shift() | |
} | |
return { value: parseInt(digits), next } | |
} | |
const parseString = (len) => { | |
serialized.shift() // remove quote | |
const str = serialized.splice(0, len) | |
serialized.shift() // remove quote | |
return { value: str.join(""), next: serialized.shift() } | |
} | |
const parseBool = () => { | |
const value = serialized.shift() | |
const next = serialized.shift() | |
return { value, next } | |
} | |
const parse = (obj = [], parents = []) => { | |
if (serialized.length === 0) return obj | |
const type = serialized.shift() | |
let parsed = { value: null, next: null } | |
if (type === 'i') { // number (we only support ints) | |
serialized.shift() | |
parsed = parseNumber() | |
obj.push(parsed.value) | |
} else if (type === 's') { // string | |
serialized.shift() | |
const { value: len, next } = parseNumber() | |
parsed = parseString(len) | |
obj.push(parsed.value) | |
} else if (type === 'a') { // assocative array (map) | |
serialized.shift() | |
const { value: len, next } = parseNumber() | |
serialized.shift() | |
const childObj = [] | |
obj.push(childObj) | |
parse(childObj, [...parents, obj]) | |
} else if (type === '}') { | |
parse(parents[parents.length - 1], parents.slice(0, parents.length - 1)) | |
} else if (type === 'b') { // boolean | |
serialized.shift() | |
parsed = parseBool() | |
} else if (type === 'N') { // null | |
parsed = { value: null, next: serialized.shift() } | |
} else { | |
console.error(obj) | |
throw new Error("unsupported serialized type " + type + obj.join(" ")) | |
} | |
if (parsed.next === ';') { | |
parse(obj, parents) | |
} | |
return obj | |
} | |
const associativeArrayToMap = (arr) => { | |
const map = {} | |
const len = arr.length | |
for (let i = 0; i < len / 2; i++) { | |
let [key, val] = arr.splice(0, 2) | |
if (Array.isArray(val)) { | |
val = associativeArrayToMap(val) | |
} | |
map[key] = val | |
} | |
return map | |
} | |
return associativeArrayToMap(parse(res)[0]) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment