javascript中模仿php的serialize和unserialize序列化函数

来源:互联网 发布:免费vip软件下载 编辑:程序博客网 时间:2024/05/16 13:52
/* phpserializer.js - JavaScript to PHP serialize / unserialize class. *  * This class is designed to convert php variables to javascript * and javascript variables to php with a php serialize unserialize * compatible way. * * Copyright (C) 2006 Ma Bingyao <andot@ujn.edu.cn> * Version: 3.0c * LastModified: Jun 2, 2006 * This library is free.  You can redistribute it and/or modify it. * http://www.coolcode.cn/?p=171* *2011-01-05 likefei edit without encoding*ser_string()*unser_string()**gbk encoding*不同的编码中文的长度不同,需要调整一下函数*chkLength(strTemp)*/   function serialize(o) {     var p = 0, sb = [], ht = [], hv = 1;     function classname(o) {         if (typeof(o) == "undefined" || typeof(o.constructor) == "undefined") return '';         var c = o.constructor.toString();         c = utf16to8(c.substr(0, c.indexOf('(')).replace(/(^\s*function\s*)|(\s*$)/ig, ''));         return ((c == '') ? 'Object' : c);     }     function is_int(n) {         var s = n.toString(), l = s.length;         if (l > 11) return false;         for (var i = (s.charAt(0) == '-') ? 1 : 0; i < l; i++) {             switch (s.charAt(i)) {                 case '0':                 case '1':                 case '2':                 case '3':                 case '4':                 case '5':                 case '6':                 case '7':                 case '8':                 case '9': break;                 default : return false;             }         }         return !(n < -2147483648 || n > 2147483647);     }     function in_ht(o) {         for (k in ht) if (ht[k] === o) return k;         return false;     }     function ser_null() {         sb[p++] = 'N;';     }     function ser_boolean(b) {         sb[p++] = (b ? 'b:1;' : 'b:0;');     }     function ser_integer(i) {         sb[p++] = 'i:' + i + ';';     }     function ser_double(d) {         if (d == Number.POSITIVE_INFINITY) d = 'INF';         else if (d == Number.NEGATIVE_INFINITY) d = '-INF';         sb[p++] = 'd:' + d + ';';     }    function ser_string(s) {         //var utf8 = utf16to8(s);        var utf8 = s;//当判断是中文时不进行编码转换        sb[p++] = 's:' + chkLength(utf8) + ':"';         sb[p++] = utf8;         sb[p++] = '";';     }     function ser_array(a) {         sb[p++] = 'a:';         var lp = p;         sb[p++] = 0;         sb[p++] = ':{';         for (var k in a) {             if (typeof(a[k]) != 'function') {                 is_int(k) ? ser_integer(k) : ser_string(k);                 __serialize(a[k]);                 sb[lp]++;             }         }         sb[p++] = '}';     }     function ser_object(o) {         var cn = classname(o);         if (cn == '') ser_null();         else if (typeof(o.serialize) != 'function') {             sb[p++] = 'O:' + cn.length + ':"';             sb[p++] = cn;             sb[p++] = '":';             var lp = p;             sb[p++] = 0;             sb[p++] = ':{';             if (typeof(o.__sleep) == 'function') {                 var a = o.__sleep();                 for (var kk in a) {                     ser_string(a[kk]);                     __serialize(o[a[kk]]);                     sb[lp]++;                 }             }             else {                 for (var k in o) {                     if (typeof(o[k]) != 'function') {                         ser_string(k);                         __serialize(o[k]);                         sb[lp]++;                     }                 }             }             sb[p++] = '}';         }         else {             var cs = o.serialize();             sb[p++] = 'C:' + cn.length + ':"';             sb[p++] = cn;             sb[p++] = '":' + cs.length + ':{';             sb[p++] = cs;             sb[p++] = "}";         }     }     function ser_pointref(R) {         sb[p++] = "R:" + R + ";";     }     function ser_ref(r) {         sb[p++] = "r:" + r + ";";     }     function __serialize(o) {         if (o == null || o.constructor == Function) {             hv++;             ser_null();         }         else switch (o.constructor) {             case Boolean: {                 hv++;                 ser_boolean(o);                 break;             }             case Number: {                 hv++;                 is_int(o) ? ser_integer(o) : ser_double(o);                 break;             }             case String: {                 hv++;                 ser_string(o);                 break;             }             case Array: {                 var r = in_ht(o);                 if (r) {                     ser_pointref(r);                 }                 else {                     ht[hv++] = o;                     ser_array(o);                 }                 break;             }             default: {                 var r = in_ht(o);                 if (r) {                     hv++;                     ser_ref(r);                 }                 else {                     ht[hv++] = o;                     ser_object(o);                 }                 break;             }         }     }     __serialize(o);     return sb.join(''); }   function unserialize(ss) {     var p = 0, ht = [], hv = 1; r = null;     function unser_null() {         p++;         return null;     }     function unser_boolean() {         p++;         var b = (ss.charAt(p++) == '1');         p++;         return b;     }     function unser_integer() {         p++;         var i = parseInt(ss.substring(p, p = ss.indexOf(';', p)));         p++;         return i;     }     function unser_double() {         p++;         var d = ss.substring(p, p = ss.indexOf(';', p));         switch (d) {             case 'INF': d = Number.POSITIVE_INFINITY; break;             case '-INF': d = Number.NEGATIVE_INFINITY; break;             default: d = parseFloat(d);         }         p++;         return d;     }     function unser_string() {         p++;        var l = parseInt(ss.substring(p, p = ss.indexOf(':', p)));         p += 2;         //var s = utf8to16(ss.substring(p, p += l));        //var s = ss.substring(p, p += l);        var s = subChnStr(ss,l,p);        p += s.length;        p += 2;         return s;     }     function unser_array() {         p++;         var n = parseInt(ss.substring(p, p = ss.indexOf(':', p)));         p += 2;         var a = [];         ht[hv++] = a;         for (var i = 0; i < n; i++) {             var k;             switch (ss.charAt(p++)) {                 case 'i': k = unser_integer(); break;                 case 's': k = unser_string(); break;                 case 'U': k = unser_unicode_string(); break;                 default: return false;             }             a[k] = __unserialize();         }         p++;         return a;     }     function unser_object() {         p++;         var l = parseInt(ss.substring(p, p = ss.indexOf(':', p)));         p += 2;         var cn = utf8to16(ss.substring(p, p += l));         p += 2;         var n = parseInt(ss.substring(p, p = ss.indexOf(':', p)));         p += 2;         if (eval(['typeof(', cn, ') == "undefined"'].join(''))) {             eval(['function ', cn, '(){}'].join(''));         }         var o = eval(['new ', cn, '()'].join(''));         ht[hv++] = o;         for (var i = 0; i < n; i++) {             var k;             switch (ss.charAt(p++)) {                 case 's': k = unser_string(); break;                 case 'U': k = unser_unicode_string(); break;                 default: return false;             }             if (k.charAt(0) == '\0') {                 k = k.substring(k.indexOf('\0', 1) + 1, k.length);             }             o[k] = __unserialize();         }         p++;         if (typeof(o.__wakeup) == 'function') o.__wakeup();         return o;     }     function unser_custom_object() {         p++;         var l = parseInt(ss.substring(p, p = ss.indexOf(':', p)));         p += 2;         var cn = utf8to16(ss.substring(p, p += l));         p += 2;         var n = parseInt(ss.substring(p, p = ss.indexOf(':', p)));         p += 2;         if (eval(['typeof(', cn, ') == "undefined"'].join(''))) {             eval(['function ', cn, '(){}'].join(''));         }         var o = eval(['new ', cn, '()'].join(''));         ht[hv++] = o;         if (typeof(o.unserialize) != 'function') p += n;         else o.unserialize(ss.substring(p, p += n));         p++;         return o;     }     function unser_unicode_string() {         p++;         var l = parseInt(ss.substring(p, p = ss.indexOf(':', p)));         p += 2;         var sb = [];         for (i = 0; i < l; i++) {             if ((sb[i] = ss.charAt(p++)) == '\\') {                 sb[i] = String.fromCharCode(parseInt(ss.substring(p, p += 4), 16));             }         }         p += 2;         return sb.join('');     }     function unser_ref() {         p++;         var r = parseInt(ss.substring(p, p = ss.indexOf(';', p)));         p++;         return ht­;     }     function __unserialize() {         switch (ss.charAt(p++)) {             case 'N': return ht[hv++] = unser_null();             case 'b': return ht[hv++] = unser_boolean();             case 'i': return ht[hv++] = unser_integer();             case 'd': return ht[hv++] = unser_double();             case 's': return ht[hv++] = unser_string();             case 'U': return ht[hv++] = unser_unicode_string();             case 'r': return ht[hv++] = unser_ref();             case 'a': return unser_array();             case 'O': return unser_object();             case 'C': return unser_custom_object();             case 'R': return unser_ref();             default: return false;         }     }     return __unserialize(); }//gbk encoding下的中文字符长度function chkLength(strTemp)  {      var i,sum;      sum=0;      for(i=0;i<strTemp.length;i++)      {          if ((strTemp.charCodeAt(i)>=0) && (strTemp.charCodeAt(i)<=255))              sum=sum+1;          else              sum=sum+2;      }      return sum;  }//gbk encoding中文字符截取(中文占两个字符)//utf8 encoding中文字符截取(中文占三个字符)//做的改动:增加截取字符串的开始位置function subChnStr(str, len, start, hasDot){    var newLength = 0;    var newStr = "";    var chineseRegex = /[^\x00-\xff]/g;    var singleChar = "";    var strLength = str.replace(chineseRegex,"**").length;        for(var i = start;i < strLength;i++)    {        singleChar = str.charAt(i).toString();        if(singleChar.match(chineseRegex) != null)        {            newLength += 2;        }            else        {            newLength++;        }        if(newLength > len)        {            break;        }        newStr += singleChar;    }        if(hasDot && strLength > len)    {        newStr += "...";    }    return newStr;}