function serialize (mixed_value) { |
// http://kevin.vanzonneveld.net |
// + original by: Arpad Ray (mailto:arpad@php.net) |
// + improved by: Dino |
// + bugfixed by: Andrej Pavlovic |
// + bugfixed by: Garagoth |
// + input by: DtTvB (http://dt.in.th/2008-09-16.string-length-in-bytes.html) |
// + bugfixed by: Russell Walker (http://www.nbill.co.uk/) |
// + bugfixed by: Jamie Beck (http://www.terabit.ca/) |
// + input by: Martin (http://www.erlenwiese.de/) |
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/) |
// + improved by: Le Torbi (http://www.letorbi.de/) |
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/) |
// + bugfixed by: Ben (http://benblume.co.uk/) |
// - depends on: utf8_encode |
// % note: We feel the main purpose of this function should be to ease the transport of data between php & js |
// % note: Aiming for PHP-compatibility, we have to translate objects to arrays |
// * example 1: serialize(['Kevin', 'van', 'Zonneveld']); |
// * returns 1: 'a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}' |
// * example 2: serialize({firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}); |
// * returns 2: 'a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}' |
var _utf8Size = function (str) { |
var size = 0, |
i = 0, |
l = str.length, |
code = ''; |
for (i = 0; i < l; i++) { |
code = str.charCodeAt(i); |
if (code < 0x0080) { |
size += 1; |
} else if (code < 0x0800) { |
size += 2; |
} else { |
size += 3; |
} |
} |
return size; |
}; |
var _getType = function (inp) { |
var type = typeof inp, |
match; |
var key; |
|
if (type === 'object' && !inp) { |
return 'null'; |
} |
if (type === "object") { |
if (!inp.constructor) { |
return 'object'; |
} |
var cons = inp.constructor.toString(); |
match = cons.match(/(\w+)\(/); |
if (match) { |
cons = match[1].toLowerCase(); |
} |
var types = ["boolean", "number", "string", "array"]; |
for (key in types) { |
if (cons == types[key]) { |
type = types[key]; |
break; |
} |
} |
} |
return type; |
}; |
var type = _getType(mixed_value); |
var val, ktype = ''; |
|
switch (type) { |
case "function": |
val = ""; |
break; |
case "boolean": |
val = "b:" + (mixed_value ? "1" : "0"); |
break; |
case "number": |
val = (Math.round(mixed_value) == mixed_value ? "i" : "d") + ":" + mixed_value; |
break; |
case "string": |
val = "s:" + _utf8Size(mixed_value) + ":\"" + mixed_value + "\""; |
break; |
case "array": |
case "object": |
val = "a"; |
/* |
if (type == "object") { |
var objname = mixed_value.constructor.toString().match(/(\w+)\(\)/); |
if (objname == undefined) { |
return; |
} |
objname[1] = this.serialize(objname[1]); |
val = "O" + objname[1].substring(1, objname[1].length - 1); |
} |
*/ |
var count = 0; |
var vals = ""; |
var okey; |
var key; |
for (key in mixed_value) { |
if (mixed_value.hasOwnProperty(key)) { |
ktype = _getType(mixed_value[key]); |
if (ktype === "function") { |
continue; |
} |
|
okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key); |
vals += this.serialize(okey) + this.serialize(mixed_value[key]); |
count++; |
} |
} |
val += ":" + count + ":{" + vals + "}"; |
break; |
case "undefined": |
// Fall-through |
default: |
// if the JS object has a property which contains a null value, the string cannot be unserialized by PHP |
val = "N"; |
break; |
} |
if (type !== "object" && type !== "array") { |
val += ";"; |
} |
return val; |
} |
function unserialize (data) { |
// http://kevin.vanzonneveld.net |
// + original by: Arpad Ray (mailto:arpad@php.net) |
// + improved by: Pedro Tainha (http://www.pedrotainha.com) |
// + bugfixed by: dptr1988 |
// + revised by: d3x |
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) |
// + input by: Brett Zamir (http://brett-zamir.me) |
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) |
// + improved by: Chris |
// + improved by: James |
// + input by: Martin (http://www.erlenwiese.de/) |
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) |
// + improved by: Le Torbi |
// + input by: kilops |
// + bugfixed by: Brett Zamir (http://brett-zamir.me) |
// - depends on: utf8_decode |
// % note: We feel the main purpose of this function should be to ease the transport of data between php & js |
// % note: Aiming for PHP-compatibility, we have to translate objects to arrays |
// * example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}'); |
// * returns 1: ['Kevin', 'van', 'Zonneveld'] |
// * example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}'); |
// * returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'} |
var that = this; |
var utf8Overhead = function (chr) { |
// http://phpjs.org/functions/unserialize:571#comment_95906 |
var code = chr.charCodeAt(0); |
if (code < 0x0080) { |
return 0; |
} |
if (code < 0x0800) { |
return 1; |
} |
return 2; |
}; |
|
|
var error = function (type, msg, filename, line) { |
throw new that.window[type](msg, filename, line); |
}; |
var read_until = function (data, offset, stopchr) { |
var buf = []; |
var chr = data.slice(offset, offset + 1); |
var i = 2; |
while (chr != stopchr) { |
if ((i + offset) > data.length) { |
error('Error', 'Invalid'); |
} |
buf.push(chr); |
chr = data.slice(offset + (i - 1), offset + i); |
i += 1; |
} |
return [buf.length, buf.join('')]; |
}; |
var read_chrs = function (data, offset, length) { |
var buf; |
|
buf = []; |
for (var i = 0; i < length; i++) { |
var chr = data.slice(offset + (i - 1), offset + i); |
buf.push(chr); |
length -= utf8Overhead(chr); |
} |
return [buf.length, buf.join('')]; |
}; |
var _unserialize = function (data, offset) { |
var readdata; |
var readData; |
var chrs = 0; |
var ccount; |
var stringlength; |
var keyandchrs; |
var keys; |
|
if (!offset) { |
offset = 0; |
} |
var dtype = (data.slice(offset, offset + 1)).toLowerCase(); |
|
var dataoffset = offset + 2; |
var typeconvert = function (x) { |
return x; |
}; |
|
switch (dtype) { |
case 'i': |
typeconvert = function (x) { |
return parseInt(x, 10); |
}; |
readData = read_until(data, dataoffset, ';'); |
chrs = readData[0]; |
readdata = readData[1]; |
dataoffset += chrs + 1; |
break; |
case 'b': |
typeconvert = function (x) { |
return parseInt(x, 10) !== 0; |
}; |
readData = read_until(data, dataoffset, ';'); |
chrs = readData[0]; |
readdata = readData[1]; |
dataoffset += chrs + 1; |
break; |
case 'd': |
typeconvert = function (x) { |
return parseFloat(x); |
}; |
readData = read_until(data, dataoffset, ';'); |
chrs = readData[0]; |
readdata = readData[1]; |
dataoffset += chrs + 1; |
break; |
case 'n': |
readdata = null; |
break; |
case 's': |
ccount = read_until(data, dataoffset, ':'); |
chrs = ccount[0]; |
stringlength = ccount[1]; |
dataoffset += chrs + 2; |
|
readData = read_chrs(data, dataoffset + 1, parseInt(stringlength, 10)); |
chrs = readData[0]; |
readdata = readData[1]; |
dataoffset += chrs + 2; |
if (chrs != parseInt(stringlength, 10) && chrs != readdata.length) { |
error('SyntaxError', 'String length mismatch'); |
} |
|
// Length was calculated on an utf-8 encoded string |
// so wait with decoding |
readdata = that.utf8_decode(readdata); |
break; |
case 'a': |
readdata = {}; |
|
keyandchrs = read_until(data, dataoffset, ':'); |
chrs = keyandchrs[0]; |
keys = keyandchrs[1]; |
dataoffset += chrs + 2; |
|
for (var i = 0; i < parseInt(keys, 10); i++) { |
var kprops = _unserialize(data, dataoffset); |
var kchrs = kprops[1]; |
var key = kprops[2]; |
dataoffset += kchrs; |
|
var vprops = _unserialize(data, dataoffset); |
var vchrs = vprops[1]; |
var value = vprops[2]; |
dataoffset += vchrs; |
|
readdata[key] = value; |
} |
|
dataoffset += 1; |
break; |
default: |
error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype); |
break; |
} |
return [dtype, dataoffset - offset, typeconvert(readdata)]; |
}; |
|
return _unserialize((data + ''), 0)[2]; |
} |
function utf8_encode (argString) { |
// http://kevin.vanzonneveld.net |
// + original by: Webtoolkit.info (http://www.webtoolkit.info/) |
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) |
// + improved by: sowberry |
// + tweaked by: Jack |
// + bugfixed by: Onno Marsman |
// + improved by: Yves Sucaet |
// + bugfixed by: Onno Marsman |
// + bugfixed by: Ulrich |
// + bugfixed by: Rafal Kukawski |
// * example 1: utf8_encode('Kevin van Zonneveld'); |
// * returns 1: 'Kevin van Zonneveld' |
|
if (argString === null || typeof argString === "undefined") { |
return ""; |
} |
|
var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n"); |
var utftext = "", |
start, end, stringl = 0; |
|
start = end = 0; |
stringl = string.length; |
for (var n = 0; n < stringl; n++) { |
var c1 = string.charCodeAt(n); |
var enc = null; |
|
if (c1 < 128) { |
end++; |
} else if (c1 > 127 && c1 < 2048) { |
enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128); |
} else { |
enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128); |
} |
if (enc !== null) { |
if (end > start) { |
utftext += string.slice(start, end); |
} |
utftext += enc; |
start = end = n + 1; |
} |
} |
|
if (end > start) { |
utftext += string.slice(start, stringl); |
} |
|
return utftext; |
} |
function utf8_decode (str_data) { |
// http://kevin.vanzonneveld.net |
// + original by: Webtoolkit.info (http://www.webtoolkit.info/) |
// + input by: Aman Gupta |
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) |
// + improved by: Norman "zEh" Fuchs |
// + bugfixed by: hitwork |
// + bugfixed by: Onno Marsman |
// + input by: Brett Zamir (http://brett-zamir.me) |
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) |
// * example 1: utf8_decode('Kevin van Zonneveld'); |
// * returns 1: 'Kevin van Zonneveld' |
var tmp_arr = [], |
i = 0, |
ac = 0, |
c1 = 0, |
c2 = 0, |
c3 = 0; |
|
str_data += ''; |
|
while (i < str_data.length) { |
c1 = str_data.charCodeAt(i); |
if (c1 < 128) { |
tmp_arr[ac++] = String.fromCharCode(c1); |
i++; |
} else if (c1 > 191 && c1 < 224) { |
c2 = str_data.charCodeAt(i + 1); |
tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)); |
i += 2; |
} else { |
c2 = str_data.charCodeAt(i + 1); |
c3 = str_data.charCodeAt(i + 2); |
tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); |
i += 3; |
} |
} |
|
return tmp_arr.join(''); |
} |