Serializable.as
ActionScript代码
/**********************************************************\
| |
| The implementation of PHPRPC Protocol 3.0 |
| |
| Serializable.as |
| |
| Release 3.0.0 |
| Copyright (c) 2005-2007 by Team-PHPRPC |
| |
| WebSite: http://www.phprpc.org/ |
| http://www.phprpc.net/ |
| http://www.phprpc.com/ |
| http://sourceforge.net/projects/php-rpc/ |
| |
| Authors: Ma Bingyao <andot@ujn.edu.cn> |
| |
| This file may be distributed and/or modified under the |
| terms of the GNU Lesser General Public License (LGPL) |
| version 3.0 as published by the Free Software Foundation |
| and appearing in the included file LICENSE. |
| |
\**********************************************************/
/* Serializable interface for custom PHP serialize.
*
* Copyright (C) 2006-2007 Ma Bingyao <andot@ujn.edu.cn>
* Version: 3.0
* LastModified: Oct 23, 2007
* This library is free. You can redistribute it and/or modify it.
*/
package org.phprpc.util{
import flash.utils.ByteArray;
public interface Serializable {
function serialize():ByteArray;
function unserialize(ss:ByteArray):void;
}
}
PHPSerializer.as
ActionScript代码
/**********************************************************\
| |
| The implementation of PHPRPC Protocol 3.0 |
| |
| PHPSerializer.as |
| |
| Release 3.0.0 |
| Copyright (c) 2005-2007 by Team-PHPRPC |
| |
| WebSite: http://www.phprpc.org/ |
| http://www.phprpc.net/ |
| http://www.phprpc.com/ |
| http://sourceforge.net/projects/php-rpc/ |
| |
| Authors: Ma Bingyao <andot@ujn.edu.cn> |
| |
| This file may be distributed and/or modified under the |
| terms of the GNU Lesser General Public License (LGPL) |
| version 3.0 as published by the Free Software Foundation |
| and appearing in the included file LICENSE. |
| |
\**********************************************************/
/* PHP serialize/unserialize library for ActionScript 3.0.
*
* Copyright (C) 2006-2007 Ma Bingyao <andot@ujn.edu.cn>
* Version: 3.0
* LastModified: Nov 6, 2007
* This library is free. You can redistribute it and/or modify it.
*/
package org.phprpc.util {
import org.phprpc.util.Serializable;
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import flash.utils.getQualifiedClassName;
import flash.utils.getDefinitionByName;
public class PHPSerializer {
private static function isInteger(s:String):Boolean {
var i:int;
var l:int = s.length;
if (l > 11) {
return false;
}
for (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;
}
}
var n:Number = Number(s);
return !(n < -2147483648 || n > 2147483647);
}
public static function getClassName(o:*):String {
var className:String = getQualifiedClassName(o);
return className.replace(/\./g, '_').replace(/\:\:/g, '_');
}
private static function getObjectOfClass(cn:Array, poslist:Array, i:uint, c:String):Object {
if (i < poslist.length) {
var pos:uint = poslist[i];
cn[pos] = c;
var obj:Object = getObjectOfClass(cn, poslist, i + 1, '.');
if (i + 1 < poslist.length) {
if (obj == null) {
obj = getObjectOfClass(cn, poslist, i + 1, '_');
}
}
return obj;
}
var classname:String = cn.join('');
try {
return new (flash.utils.getDefinitionByName(classname) as Class);
}
catch (e:Error) { };
return null;
}
public static function createObjectOfClass(classname:String):Object {
try {
return new (flash.utils.getDefinitionByName(classname) as Class);
}
catch (e:Error) {}
var poslist:Array = [];
var pos:int = classname.indexOf("_");
while (pos > -1) {
poslist[poslist.length] = pos;
pos = classname.indexOf("_", pos + 1);
}
if (poslist.length > 0) {
var cn:Array = classname.split('');
var obj:Object = getObjectOfClass(cn, poslist, 0, '.');
if (obj == null) {
obj = getObjectOfClass(cn, poslist, 0, '_');
}
if (obj != null) {
return obj;
}
}
return {name:classname};
}
public static function serialize(o:Object):ByteArray {
var sb:ByteArray = new ByteArray();
var ht:Dictionary = new Dictionary();
var hv:uint = 1;
function _serializeNull():void {
sb.writeUTFBytes('N;');
}
function _serializeBoolean(b:Boolean):void {
sb.writeUTFBytes(b ? 'b:1;' : 'b:0;');
}
function _serializeInteger(i:int):void {
sb.writeUTFBytes('i:' + i + ';');
}
function _serializeDouble(d:Number):void {
var s:String;
if (isNaN(d)) {
s = 'NAN';
}
else if (d == Number.POSITIVE_INFINITY) {
s = 'INF';
}
else if (d == Number.NEGATIVE_INFINITY) {
s = '-INF';
}
else {
s = d.toString(10);
}
sb.writeUTFBytes('d:' + s + ';');
}
function _serializeByteArray(ba:ByteArray):void {
ba.position = 0;
sb.writeUTFBytes('s:' + ba.length + ':"');
sb.writeBytes(ba);
sb.writeUTFBytes('";');
}
function _serializeString(s:String):void {
var utf8:ByteArray = new ByteArray();
utf8.writeUTFBytes(s);
sb.writeUTFBytes('s:' + utf8.length + ':"');
sb.writeBytes(utf8);
sb.writeUTFBytes('";');
}
function _serializeDate(dt:Date):void {
sb.writeUTFBytes('O:11:"PHPRPC_Date":7:{');
sb.writeUTFBytes('s:4:"year";');
_serializeInteger(dt.getFullYear());
sb.writeUTFBytes('s:5:"month";');
_serializeInteger(dt.getMonth() + 1);
sb.writeUTFBytes('s:3:"day";');
_serializeInteger(dt.getDate());
sb.writeUTFBytes('s:4:"hour";');
_serializeInteger(dt.getHours());
sb.writeUTFBytes('s:6:"minute";');
_serializeInteger(dt.getMinutes());
sb.writeUTFBytes('s:6:"second";');
_serializeInteger(dt.getSeconds());
sb.writeUTFBytes('s:11:"millisecond";');
_serializeInteger(dt.getMilliseconds());
sb.writeUTFBytes('}');
}
function _serializeArray(a:Object):void {
var k:String;
var l:uint = 0;
for (k in a) l++;
sb.writeUTFBytes('a:' + l + ':{');
for (k in a) {
if (typeof (a[k]) != 'function') {
isInteger(k) ? _serializeInteger(k) : _serializeString(k);
_serialize(a[k]);
}
}
sb.writeUTFBytes('}');
}
function _serializeObject(o:Object, cn:String):void {
var c:Serializable = o as Serializable;
var cnb:ByteArray = new ByteArray();
cnb.writeUTFBytes(cn);
if (c == null) {
sb.writeUTFBytes('O:' + cnb.length + ':"');
sb.writeBytes(cnb);
var k:String;
var l:uint = 0;
for (k in o) l++;
sb.writeUTFBytes('":' + l + ':{');
for (k in o) {
if (typeof(o[k]) != 'function') {
_serializeString(k);
_serialize(o[k]);
}
}
sb.writeUTFBytes('}');
}
else {
var data:ByteArray = c.serialize();
sb.writeUTFBytes('C:' + cnb.length + ':"');
sb.writeBytes(cnb);
sb.writeUTFBytes('":' + data.length + ':{');
sb.writeBytes(data);
sb.writeUTFBytes('}');
}
}
function _serializePointRef(R:uint):void {
sb.writeUTFBytes('R:' + R + ';');
}
function _serializeRef(r:uint):void {
sb.writeUTFBytes('r:' + r + ';');
}
function _serialize(o:*):void {
if (typeof (o) == "undefined" || o == null || o.constructor == Function) {
hv++;
_serializeNull();
return;
}
var className:String = getClassName(o);
switch (o.constructor) {
case Boolean :
hv++;
_serializeBoolean(o);
break;
case Number :
hv++;
isInteger(o) ? _serializeInteger(o) : _serializeDouble(o);
break;
case String :
hv++;
_serializeString(o);
break;
case ByteArray :
hv++;
_serializeByteArray(o);
break;
case Date :
hv++;
_serializeDate(o);
break;
default :
var r:int = ht[o];
if (className == "Object" || o.constructor == Array) {
if (r) {
_serializePointRef(r);
}
else {
ht[o] = hv++;
_serializeArray(o);
}
}
else {
if (r) {
hv++;
_serializeRef(r);
}
else {
ht[o] = hv++;
_serializeObject(o, className);
}
}
break;
}
}
_serialize(o);
return sb;
}
public static function unserialize(sb:ByteArray):* {
var ht:Dictionary = new Dictionary();
var hv:int = 1;
function _readNumber():String {
var s:String = '';
var c:String = sb.readUTFBytes(1);
while ((c != ';') && (c != ':')) {
s += c;
c = sb.readUTFBytes(1);
}
return s;
}
function _unserializeNull():Object {
sb.position++;
return null;
}
function _unserializeBoolean():Boolean {
sb.position++;
var b:Boolean = (sb.readUTFBytes(1) == '1');
sb.position++;
return b;
}
function _unserializeInteger():int {
sb.readByte();
var i:int = parseInt(_readNumber());
return i;
}
function _unserializeDouble():Number {
sb.position++;
var d:Number;
var s:String = _readNumber();
switch (s) {
case 'NAN' :
d = Number.NaN;
break;
case 'INF' :
d = Number.POSITIVE_INFINITY;
break;
case '-INF' :
d = Number.NEGATIVE_INFINITY;
break;
default :
d = parseFloat(s);
}
return d;
}
function _unserializeByteArray():ByteArray {
sb.position++;
var l:uint = parseInt(_readNumber());
sb.position++;
var ba:ByteArray = new ByteArray();
if (l > 0) {
sb.readBytes(ba, 0, l);
}
sb.position += 2;
return ba;
}
function _unserializeString():String {
sb.position++;
var l:uint = parseInt(_readNumber());
sb.position++;
var s:String = sb.readUTFBytes(l);
sb.position += 2;
return s;
}
function _unserializeEscapedString(len:int):String {
sb.position++;
var l:uint = parseInt(_readNumber());
sb.position++;
var i:int;
var s:Array = new Array(l);
for (i = 0; i < l; i++) {
if ((s[i] = sb.readUTFBytes(1)) == '\\') {
s[i] = String.fromCharCode(parseInt(sb.readUTFBytes(len), 16));
}
}
sb.position += 2;
return s.join('');
}
function _unserializeArray():Array {
sb.position++;
var n:int = parseInt(_readNumber());
sb.position++;
var i:int;
var k:*;
var a:Array = [];
ht[hv++] = a;
for (i = 0; i < n; i++) {
switch (sb.readUTFBytes(1)) {
case 'i' :
k = _unserializeInteger();
break;
case 's' :
k = _unserializeString();
break;
case 'S' :
k = _unserializeEscapedString(2);
break;
case 'U' :
k = _unserializeEscapedString(4);
break;
default :
return null;
}
a[k] = _unserialize();
}
sb.position++;
return a;
}
function _unserializeDate(n:int):Date {
var i:int;
var k:String;
var a:Object = {};
for (i = 0; i < n; i++) {
switch (sb.readUTFBytes(1)) {
case 's' :
k = _unserializeString();
break;
case 'S' :
k = _unserializeEscapedString(2);
break;
case 'U' :
k = _unserializeEscapedString(4);
break;
default :
return null;
}
if (sb.readUTFBytes(1) == 'i') {
a[k] = _unserializeInteger();
}
else {
return null;
}
}
sb.position++;
var dt:Date = new Date(a.year, a.month - 1, a.day, a.hour, a.minute, a.second, a.millisecond);
ht[hv++] = dt;
return dt;
}
function _unserializeObject():* {
sb.position++;
var l:uint = parseInt(_readNumber());
sb.position++;
var cn:String = sb.readUTFBytes(l);
sb.position += 2;
var n:uint = parseInt(_readNumber());
sb.position++;
if (cn == "PHPRPC_Date") {
return _unserializeDate(n);
}
var i:int;
var k:String;
var o:Object = createObjectOfClass(cn);
ht[hv++] = o;
for (i = 0; i < n; i++) {
switch (sb.readUTFBytes(1)) {
case 's' :
k = _unserializeString();
break;
case 'S' :
k = _unserializeEscapedString(2);
break;
case 'U' :
k = _unserializeEscapedString(4);
break;
default :
return false;
}
if (k.charAt(0) == '\0') {
k = k.substring(k.indexOf('\0', 1) + 1, k.length);
}
o[k] = _unserialize();
}
sb.position++;
return o;
}
function _unserializeCustomObject():* {
sb.position++;
sb.position++;
var l:uint = parseInt(_readNumber());
sb.position++;
var cn:String = sb.readUTFBytes(l);
sb.position += 2;
var n:uint = parseInt(_readNumber());
sb.position++;
var data:ByteArray = new ByteArray();
sb.readBytes(data, 0, n);
sb.position++;
var o:Object = createObjectOfClass(cn);
var c:Serializable = o as Serializable;
if (c == null) {
o.data = data;
return o;
}
c.unserialize(data);
return c;
}
function _unserializeRef():* {
sb.position++;
var r:uint = parseInt(_readNumber());
return ht[r];
}
function _unserialize():* {
var result:*;
switch (sb.readUTFBytes(1)) {
case 'N' :
result = _unserializeNull();
ht[hv] = result;
hv++;
return result;
case 'b' :
result = _unserializeBoolean();
ht[hv] = result;
hv++;
return result;
case 'i' :
result = _unserializeInteger();
ht[hv] = result;
hv++;
return result;
case 'd' :
result = _unserializeDouble();
ht[hv] = result;
hv++;
return result;
case 's' :
result = _unserializeByteArray();
ht[hv] = result;
hv++;
return result;
case 'S' :
result = _unserializeEscapedString(2);
ht[hv] = result;
hv++;
return result;
case 'U' :
result = _unserializeEscapedString(4);
ht[hv] = result;
hv++;
return result;
case 'r' :
result = _unserializeRef();
ht[hv] = result;
hv++;
return result;
case 'a' :
return _unserializeArray();
case 'O' :
return _unserializeObject();
case 'C' :
return _unserializeCustomObject();
case 'R' :
return _unserializeRef();
}
return false;
}
sb.position = 0;
return _unserialize();
}
}
}