ru-se.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

serialize.js (8114B)


      1 function serialize(mixed_value) {
      2   //  discuss at: http://phpjs.org/functions/serialize/
      3   // original by: Arpad Ray (mailto:arpad@php.net)
      4   // improved by: Dino
      5   // improved by: Le Torbi (http://www.letorbi.de/)
      6   // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
      7   // bugfixed by: Andrej Pavlovic
      8   // bugfixed by: Garagoth
      9   // bugfixed by: Russell Walker (http://www.nbill.co.uk/)
     10   // bugfixed by: Jamie Beck (http://www.terabit.ca/)
     11   // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
     12   // bugfixed by: Ben (http://benblume.co.uk/)
     13   //	input by: DtTvB (http://dt.in.th/2008-09-16.string-length-in-bytes.html)
     14   //	input by: Martin (http://www.erlenwiese.de/)
     15   //		note: We feel the main purpose of this function should be to ease the transport of data between php & js
     16   //		note: Aiming for PHP-compatibility, we have to translate objects to arrays
     17   //   example 1: serialize(['Kevin', 'van', 'Zonneveld']);
     18   //   returns 1: 'a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}'
     19   //   example 2: serialize({firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'});
     20   //   returns 2: 'a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}'
     21 
     22   var val, key, okey,
     23 	ktype = '',
     24 	vals = '',
     25 	count = 0,
     26 	_utf8Size = function(str) {
     27 	  var size = 0,
     28 		i = 0,
     29 		l = str.length,
     30 		code = '';
     31 	  for (i = 0; i < l; i++) {
     32 		code = str.charCodeAt(i);
     33 		if (code < 0x0080) {
     34 		  size += 1;
     35 		} else if (code < 0x0800) {
     36 		  size += 2;
     37 		} else {
     38 		  size += 3;
     39 		}
     40 	  }
     41 	  return size;
     42 	};
     43   _getType = function(inp) {
     44 	var match, key, cons, types, type = typeof inp;
     45 
     46 	if (type === 'object' && !inp) {
     47 	  return 'null';
     48 	}
     49 	if (type === 'object') {
     50 	  if (!inp.constructor) {
     51 		return 'object';
     52 	  }
     53 	  cons = inp.constructor.toString();
     54 	  match = cons.match(/(\w+)\(/);
     55 	  if (match) {
     56 		cons = match[1].toLowerCase();
     57 	  }
     58 	  types = ['boolean', 'number', 'string', 'array'];
     59 	  for (key in types) {
     60 		if (cons == types[key]) {
     61 		  type = types[key];
     62 		  break;
     63 		}
     64 	  }
     65 	}
     66 	return type;
     67   };
     68   type = _getType(mixed_value);
     69 
     70   switch (type) {
     71 	case 'function':
     72 	  val = '';
     73 	  break;
     74 	case 'boolean':
     75 	  val = 'b:' + (mixed_value ? '1' : '0');
     76 	  break;
     77 	case 'number':
     78 	  val = (Math.round(mixed_value) == mixed_value ? 'i' : 'd') + ':' + mixed_value;
     79 	  break;
     80 	case 'string':
     81 	  val = 's:' + _utf8Size(mixed_value) + ':"' + mixed_value + '"';
     82 	  break;
     83 	case 'array':
     84 	case 'object':
     85 	  val = 'a';
     86 	  /*
     87 		if (type === 'object') {
     88 		  var objname = mixed_value.constructor.toString().match(/(\w+)\(\)/);
     89 		  if (objname == undefined) {
     90 			return;
     91 		  }
     92 		  objname[1] = this.serialize(objname[1]);
     93 		  val = 'O' + objname[1].substring(1, objname[1].length - 1);
     94 		}
     95 		*/
     96 
     97 	  for (key in mixed_value) {
     98 		if (mixed_value.hasOwnProperty(key)) {
     99 		  ktype = _getType(mixed_value[key]);
    100 		  if (ktype === 'function') {
    101 			continue;
    102 		  }
    103 
    104 
    105 		  okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key);
    106 		  vals += this.serialize(okey) + this.serialize(mixed_value[key]);
    107 		  count++;
    108 		}
    109 	  }
    110 	  val += ':' + count + ':{' + vals + '}';
    111 	  break;
    112 	case 'undefined':
    113 	  // Fall-through
    114 	default:
    115 	  // if the JS object has a property which contains a null value, the string cannot be unserialized by PHP
    116 	  val = 'N';
    117 	  break;
    118   }
    119   if (type !== 'object' && type !== 'array') {
    120 	  if ( type == 'string' && val.indexOf('}') != -1 ) {
    121 	  } else {
    122 			val += ';';
    123 		}
    124   }
    125   return val;
    126 }
    127 
    128 
    129 function unserialize(data) {
    130   //  discuss at: http://phpjs.org/functions/unserialize/
    131   // original by: Arpad Ray (mailto:arpad@php.net)
    132   // improved by: Pedro Tainha (http://www.pedrotainha.com)
    133   // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    134   // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    135   // improved by: Chris
    136   // improved by: James
    137   // improved by: Le Torbi
    138   // improved by: Eli Skeggs
    139   // bugfixed by: dptr1988
    140   // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    141   // bugfixed by: Brett Zamir (http://brett-zamir.me)
    142   //  revised by: d3x
    143   //	input by: Brett Zamir (http://brett-zamir.me)
    144   //	input by: Martin (http://www.erlenwiese.de/)
    145   //	input by: kilops
    146   //	input by: Jaroslaw Czarniak
    147   //		note: We feel the main purpose of this function should be to ease the transport of data between php & js
    148   //		note: Aiming for PHP-compatibility, we have to translate objects to arrays
    149   //   example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
    150   //   returns 1: ['Kevin', 'van', 'Zonneveld']
    151   //   example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}');
    152   //   returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}
    153 
    154   var that = this,
    155 	utf8Overhead = function(chr) {
    156 	  // http://phpjs.org/functions/unserialize:571#comment_95906
    157 	  var code = chr.charCodeAt(0);
    158 	  if (code < 0x0080) {
    159 		return 0;
    160 	  }
    161 	  if (code < 0x0800) {
    162 		return 1;
    163 	  }
    164 	  return 2;
    165 	};
    166   error = function(type, msg, filename, line) {
    167 	throw new that.window[type](msg, filename, line);
    168   };
    169   read_until = function(data, offset, stopchr) {
    170 	var i = 2,
    171 	  buf = [],
    172 	  chr = data.slice(offset, offset + 1);
    173 
    174 	while (chr != stopchr) {
    175 	  if ((i + offset) > data.length) {
    176 		error('Error', 'Invalid');
    177 	  }
    178 	  buf.push(chr);
    179 	  chr = data.slice(offset + (i - 1), offset + i);
    180 	  i += 1;
    181 	}
    182 	return [buf.length, buf.join('')];
    183   };
    184   read_chrs = function(data, offset, length) {
    185 	var i, chr, buf;
    186 
    187 	buf = [];
    188 	for (i = 0; i < length; i++) {
    189 	  chr = data.slice(offset + (i - 1), offset + i);
    190 	  buf.push(chr);
    191 	  length -= utf8Overhead(chr);
    192 	}
    193 	return [buf.length, buf.join('')];
    194   };
    195   _unserialize = function(data, offset) {
    196 	var dtype, dataoffset, keyandchrs, keys, contig,
    197 	  length, array, readdata, readData, ccount,
    198 	  stringlength, i, key, kprops, kchrs, vprops,
    199 	  vchrs, value, chrs = 0,
    200 	  typeconvert = function(x) {
    201 		return x;
    202 	  };
    203 
    204 	if (!offset) {
    205 	  offset = 0;
    206 	}
    207 	dtype = (data.slice(offset, offset + 1))
    208 	  .toLowerCase();
    209 
    210 	dataoffset = offset + 2;
    211 
    212 	switch (dtype) {
    213 	  case 'i':
    214 		typeconvert = function(x) {
    215 		  return parseInt(x, 10);
    216 		};
    217 		readData = read_until(data, dataoffset, ';');
    218 		chrs = readData[0];
    219 		readdata = readData[1];
    220 		dataoffset += chrs + 1;
    221 		break;
    222 	  case 'b':
    223 		typeconvert = function(x) {
    224 		  return parseInt(x, 10) !== 0;
    225 		};
    226 		readData = read_until(data, dataoffset, ';');
    227 		chrs = readData[0];
    228 		readdata = readData[1];
    229 		dataoffset += chrs + 1;
    230 		break;
    231 	  case 'd':
    232 		typeconvert = function(x) {
    233 		  return parseFloat(x);
    234 		};
    235 		readData = read_until(data, dataoffset, ';');
    236 		chrs = readData[0];
    237 		readdata = readData[1];
    238 		dataoffset += chrs + 1;
    239 		break;
    240 	  case 'n':
    241 		readdata = null;
    242 		break;
    243 	  case 's':
    244 		ccount = read_until(data, dataoffset, ':');
    245 		chrs = ccount[0];
    246 		stringlength = ccount[1];
    247 		dataoffset += chrs + 2;
    248 
    249 		readData = read_chrs(data, dataoffset + 1, parseInt(stringlength, 10));
    250 		chrs = readData[0];
    251 		readdata = readData[1];
    252 		dataoffset += chrs + 2;
    253 		if (chrs != parseInt(stringlength, 10) && chrs != readdata.length) {
    254 		  error('SyntaxError', 'String length mismatch');
    255 		}
    256 		break;
    257 	  case 'a':
    258 		readdata = {};
    259 
    260 		keyandchrs = read_until(data, dataoffset, ':');
    261 		chrs = keyandchrs[0];
    262 		keys = keyandchrs[1];
    263 		dataoffset += chrs + 2;
    264 
    265 		length = parseInt(keys, 10);
    266 		contig = true;
    267 
    268 		for (i = 0; i < length; i++) {
    269 		  kprops = _unserialize(data, dataoffset);
    270 		  kchrs = kprops[1];
    271 		  key = kprops[2];
    272 		  dataoffset += kchrs;
    273 
    274 		  vprops = _unserialize(data, dataoffset);
    275 		  vchrs = vprops[1];
    276 		  value = vprops[2];
    277 		  dataoffset += vchrs;
    278 
    279 		  if (key !== i)
    280 			contig = false;
    281 
    282 		  readdata[key] = value;
    283 		}
    284 
    285 		if (contig) {
    286 		  array = new Array(length);
    287 		  for (i = 0; i < length; i++)
    288 			array[i] = readdata[i];
    289 		  readdata = array;
    290 		}
    291 
    292 		dataoffset += 1;
    293 		break;
    294 	  default:
    295 		error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype);
    296 		break;
    297 	}
    298 	return [dtype, dataoffset - offset, typeconvert(readdata)];
    299   };
    300 
    301   return _unserialize((data + ''), 0)[2];
    302 }