0
我有一個動作序列化和序列化與PHP序列化功能兼容的數據序列化類。我擴展它來支持二進制數據,但現在非序列化似乎不起作用。Actionscript序列化類
例如,這種數據不能正確去系列化:
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;
}
}
}
你有解釋你是如何解決這個問題的?未來可能會幫助別人。 – Niklas