Класс сериализации Actionscript - PullRequest
0 голосов
/ 30 июля 2011

У меня есть класс actionscript, который сериализует и десериализует данные, совместимые с функциями сериализации php. Я расширил его для поддержки двоичных данных, но теперь десериализация, похоже, не работает.

Например, эти данные не правильно сериализуются:

a:2:{i:0;s:1:"õ";i:1;a:2:{i:0;s:32:"mÎiyl·T=doÁ°ýNd_¤ÁÝ`:AåÁˆ@";i:1;s:32:"ÿ^ò`d^|“T¶&JÐÞG[±iÏ*Ÿ!–Ü’IÍ";}}

Вот класс:

package pack
{
    import flash.utils.ByteArray;
    import flash.utils.Dictionary;

    import mx.collections.ArrayCollection;
    import mx.controls.Alert;
    import mx.core.*;

    use namespace mx_internal;

    public class Serializer extends Object
    {
        public static const version:String = "3.0.0";

        mx_internal static var c:uint;
        mx_internal static var pattern:RegExp = /[A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4} \d{2}:\d{2}:\d{2} \+|\-\d{4}/g

        public static function serialize(data:*):ByteArray
        {
            var bas:ByteArray = new ByteArray();
            var tmp:ByteArray = new ByteArray();
            var i:int = 0;
            var key:String;

            if(data is Boolean){
                bas.writeUTFBytes('b:');
                bas.writeUnsignedInt(data);
                bas.writeUTFBytes(';');
            } else if(data is int){
                bas.writeUTFBytes('i:');
                bas.writeUTFBytes(data);
                bas.writeUTFBytes(';');
            } else if(data is Number){
                bas.writeUTFBytes('d:');
                bas.writeUTFBytes(data);
                bas.writeUTFBytes(';');
            } else if(data is ByteArray){
                bas.writeUTFBytes('s:');
                bas.writeUTFBytes(data.length.toString());
                bas.writeUTFBytes(':"');
                bas.writeBytes(data);
                bas.writeUTFBytes('";');
            } else if(data is String){
                bas.writeUTFBytes('s:');
                bas.writeUTFBytes(data.length.toString());
                bas.writeUTFBytes(':"');
                bas.writeUTFBytes(data);
                bas.writeUTFBytes('";');
            } else if(data is Date){
                bas.writeUTFBytes('s:');
                bas.writeUTFBytes(data.toString().length.toString());
                bas.writeUTFBytes(':"');
                bas.writeUTFBytes(data);
                bas.writeUTFBytes('";');
            } else if(data is ArrayCollection){
                for(key in data){
                    tmp.writeBytes(Serializer.serialize(i));
                    tmp.writeBytes(Serializer.serialize(data[key]));
                    i += 1;
                }
                bas.writeUTFBytes('a:');
                bas.writeUTFBytes(i.toString());
                bas.writeUTFBytes(':{');
                bas.writeBytes(tmp);
                bas.writeUTFBytes('}');
            } else if(data is Array){
                for(key in data){
                    tmp.writeBytes(Serializer.serialize(i));
                    tmp.writeBytes(Serializer.serialize(data[key]));
                    i += 1;
                }
                bas.writeUTFBytes('a:');
                bas.writeUTFBytes(i.toString());
                bas.writeUTFBytes(':{');
                bas.writeBytes(tmp);
                bas.writeUTFBytes('}');
            } else if(data is Object){
                for(key in data){
                    tmp.writeBytes(Serializer.serialize(key));
                    tmp.writeBytes(Serializer.serialize(data[key]));
                    i += 1;
                }
                bas.writeUTFBytes('O:8:"stdClass":');
                bas.writeUTFBytes(i.toString());
                bas.writeUTFBytes(':{');
                bas.writeBytes(tmp);
                bas.writeUTFBytes('}');
            } else if(data == null || data == undefined){
                bas.writeUTFBytes('N;');
            } else {
                bas.writeUTFBytes('i:0;');
            }
            return bas;
        }

        public static function unserialize(data:ByteArray):*
        {
            Serializer.c = 0;
            return Serializer.unserialize_internal(data);
        }


        mx_internal static function unserialize_internal(data:ByteArray):*
        {
            var result:*;
            var tmpvar:*;
            var tmp:Array = new Array();
            var type:String = Serializer.charAt(data, Serializer.c);
            var pos:uint = 0;
            var islist:Boolean = true;
            var i:uint;

            switch(type){
                case "N":
                    Serializer.c += 2;
                    break;
                case "b":
                    result = Serializer.substr(data, Serializer.c+2, 1).toString() == '1'
                    //result = data.substr(Serializer.c+2, 1) == "1"
                    Serializer.c += 4
                    break;
                case "i":
                    tmp.push(Serializer.indexOf(data, ';', Serializer.c));
                    //tmp.push(data.indexOf(";", Serializer.c))
                    pos = Serializer.c+2
                    Serializer.c = tmp[0]+1
                    result = int(Serializer.substring(data, pos, tmp[0]));
                    //result = int(data.substring(pos,tmp[0]))
                    break;
                case "d":
                    tmp.push(Serializer.indexOf(data, ';', Serializer.c));
                    //tmp.push(data.indexOf(";", Serializer.c))
                    pos = Serializer.c + 2
                    Serializer.c = tmp[0]+1
                    result = Number(Serializer.substring(data, pos, tmp[0]));
                    //result = Number(data.substring(pos,tmp[0]))
                    break;
                case "s":
                    tmp.push(int(Serializer.indexOf(data, ':', Serializer.c+2)));
                    //tmp.push(int(data.indexOf(":", Serializer.c+2)))
                    tmp.push(tmp[0]+2)
                    pos = Serializer.c+2
                    tmp.push(0)
                    tmp.push(int(Serializer.substring(data, pos, tmp[0])));
                    //tmp.push(int(data.substring(pos, tmp[0])));
                    if(tmp[3] == 0)
                    {
                        result = "";
                        Serializer.c = pos+5
                    } else {
                        var lenc:uint = Serializer.stringBCLenght(data, Serializer.c, tmp[3]);
                        if(lenc != tmp[3])
                        {
                            result = Serializer.substr(data, tmp[0]+2, lenc);
                            //result = data.substr(tmp[0]+2, lenc);
                            Serializer.c = tmp[0]+4+lenc;
                        } else {
                            result = Serializer.substr(data, tmp[0]+2, tmp[3]);
                            //result = data.substr(tmp[0]+2, tmp[3]);
                            Serializer.c = tmp[0]+4+tmp[3];
                        }
                    }
                    if(Serializer.pattern.test(result))
                    {
                        result = new Date(result)
                    }
                    break;
                case "a":
                    //result:ByteArray;
                    pos = Serializer.c+2
                    tmp.push(int(Serializer.indexOf(data, ":", pos)))
                    tmp.push(int(Serializer.substring(data, pos, tmp[0])))          
                    //tmp.push(int(data.indexOf(":", pos)))
                    //tmp.push(int(data.substring(pos, tmp[0])))
                    Serializer.c = tmp[0]+2
                    result = []
                    for(i = 0; i < tmp[1]; i++){
                        tmpvar = Serializer.unserialize_internal(data)
                        result[tmpvar] = Serializer.unserialize_internal(data)
                        if(!(tmpvar is int) || tmpvar < 0){
                            islist = false
                        }
                    }
                    if(islist){
                        tmp.push([])
                        for(var key:uint = 0; key < result.length; key++){
                            pos = tmp[2].length
                            while(key > pos){
                                tmp[2].push(null)
                                pos +=1
                            }
                            tmp[2].push(result[key])
                        }
                        result = tmp[2]
                    }
                    Serializer.c += 1
                    break;
                case "O":
                    pos = Serializer.indexOf(data, "\"", Serializer.c)+1;
                    Serializer.c =  Serializer.indexOf(data, "\"", pos);
                    tmp.push(Serializer.substring(data, pos, Serializer.c))
                    //pos = data.indexOf("\"", Serializer.c)+1;
                    //Serializer.c =  data.indexOf("\"", pos);
                    //tmp.push(data.substring(pos, Serializer.c))
                    Serializer.c += 2
                    i = Serializer.c
                    Serializer.c = Serializer.indexOf(data, ":", i)
                    i = int(Serializer.substring(data, i, Serializer.c))
                    //Serializer.c = data.indexOf(":", i)
                    //i = int(data.substring(i, Serializer.c))
                    Serializer.c +=2;
                    result = {};
                    var tmps:*;
                    while(i > 0){
                        tmps = Serializer.unserialize_internal(data)
                        result[tmps] = Serializer.unserialize_internal(data)
                        i -= 1
                    }
                    break;
            }
            return result;
        }


        mx_internal static function stringCLenght(data:String, from:uint = 0, len:uint = 0):int
        {
            var i:uint;
            var j:uint = len;
            var startIndex:uint = from + 4 + len.toString().length;
            for (i = 0; i < j; i++){
                if (data.charCodeAt(i+startIndex) > 128)
                {
                    j = j - 1
                }
            }
            return j;
        }

        mx_internal static function stringBCLenght(data:ByteArray, from:uint = 0, len:uint = 0):int
        {
            var i:uint;
            var j:uint = len;
            var startIndex:uint = from + 4 + len.toString().length;
            for (i = 0; i < j; i++){
                if (Serializer.charCodeAt(data, i+startIndex) > 128)
                {
                    j = j - 1
                }
            }
            return j;
        }

        mx_internal static function stringLength(data:String):uint
        {
            var code:int   = 0
            var result:int = 0
            var slen:int   = data.length;
            while(slen){
                slen = slen - 1
                try
                {
                    code = data.charCodeAt(slen)
                } catch(e:Error){
                    code = 65536
                }
                if(code < 128){
                    result = result + 1
                } else if(code < 2048){
                    result = result + 2
                } else if(code < 65536){
                    result = result + 3
                } else {
                    result = result + 4
                }
            }
            return result
        }

        public static function charAt(bytes:ByteArray, index:int):String {
            if (bytes.length <= index) return null;
            return String.fromCharCode(bytes[index]);
        }

        public static function charCodeAt(bytes:ByteArray, index:int):int {
            if (bytes.length <= index) return -1;
            return bytes[index];
        }

        public static function substr(bytes:ByteArray, start:int, length:int=0):ByteArray {
            var res:ByteArray = new ByteArray();
            bytes.position = start;
            bytes.readBytes(res, 0, length);
            return res;
        }

        public static function substring(bytes:ByteArray, start:int, end:int=0):ByteArray {
            return substr(bytes, start, end-start);
        }

        public static function indexOf(bytes:ByteArray, str:String, startIndex:int):int {
            var num:int = 0;
            for (var i:int=0; i<bytes.length; i++) {
                var strPos:int = 0;
                while (bytes[i+strPos] == str.charCodeAt(strPos)) {
                    strPos++;
                    if (strPos == str.length) {
                        num++;
                        if(num == startIndex) {
                            return i;
                        }
                    }
                }
            }
            return -1;
        }

    }
}

1 Ответ

0 голосов
/ 09 августа 2011

Я решил проблему, ответы не нужны.

...