An Efficient Unserialize Function for Javascript
I’ve got this dead useful unserialize function I wrote for Javascript that I’ve been meaning to blog for ages. Good as it may be however there’s not much to say about it so I’m totally going to flesh it out a bit by erratically writing both normally and in the style of a pubescent nineties american teenager. Gnarly.
Ok, so first I should mention that the base of this code derives from one I found which while effective was extremely memory-intensive because it was recursive - in order to move on to the next character in the serialized string the function would call itself, meaning that for every character in the string the function was called with a fresh, one-character shorter string - the longer the input string, the faster the function would propogate ever-shortening versions of itself in a totally non-heinous auroborous fireball of death. Wohhh!
The below function uses only one variable to hold the input string, and shortens it on every pass by the last interpreted character so as the function progresses, whilst the variables it creates grow as does the string shrink and free up memory. Sweeeet.
If there was ever a bodaciously quick-and-easy example of OOP vs procedural method benefits for procedurally scripting dudes, this is it. Excellent.
function unserialize(){ // string that holds the data this.d = arguments[0]; // runs through the string this.r = function(){ // current datatype var t = this.d.charAt(0); // get the value we want var x = this.x(t); var n = Number(x); switch(t){ case 'O': var o = new Object(); // classname, to be removed var c = this.d.substr(x.length + 4, n); // regexes for removing classname and surplus chars var ra = new RegExp('^\x00' + c + '\x00'); var rb = new RegExp('^\x00\\*\x00'); // now move on to object properties this.d = this.d.substr(x.length + 6 + n); x = this.d.substr(0, this.d.indexOf(':')) n = Number(x); // prepare this.d for more recursive interrogation this.d = this.d.substr(x.length + 2); // build the object for(var i=0; i<n ; i++){ o[this.r().replace(ra, '').replace(rb, '')] = this.r(); } // this.d = this.d.substr(1); return o; case 'a': var a = new Array(); this.d = this.d.substr(x.length + 4); for(var i=0; i<n; i++){ a[this.r()] = this.r(); } this.d = this.d.substr(1); return a; case 's': var s = this.d.substr(x.length + 4, n); this.d = this.d.substr(x.length + 6 + n); return s; case 'i': case 'd': this.d = this.d.substr(x.length + 3) return n; case 'b': this.d = this.d.substr(4); return (n == 1); case 'N': this.d = this.d.substr(2); return null; default: // we can't unserialize everything, but then who serializes an object for // javascript anyway? The sort of person who'd cause an error, no doubt... //throw t; this.d = this.d.substr(this.d.indexOf(';')); return this.r(); } } // gets length of array/string/object, or integer/number value, or bool 0/1 this.x = function(t){ switch(t){ case 'O': case 'a': case 's': return this.d.substring(2, this.d.indexOf(':', 2)); case 'i': case 'd': return this.d.substring(2, this.d.indexOf(';')); case 'b': return this.d.substr(2, 1); } return false; } return this.r(); }
Like, you should totally sanitize the string when you pass it to Javascript if you’re expecting single or double quotes. Also Javascript like totally craps out if you don’t replace linebreaks “\n” with their literal equivalent ‘\n’. Like, shuh, we knowww, dude.
Sorry, the comment form is closed at this time.
greatings…
I have already seen it somethere…
Trackback by chineseman — January 2, 2009 @ 12:10 am
yep, it’s based on some code from an OS script I’ve had it in my library for a while - however the orginal was a recursive function, which is just an insane way of doing something like this.
Comment by Felix — May 6, 2009 @ 5:01 pm