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

/* 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 <[email protected]> 
* 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;
} 

 

你可能感兴趣的:(JavaScript,反序列化unserialize,js序列化serialize)