PHP 序列化和反序列化 for ActionScript 3.0

PHP 序列化和反序列化的 for ActionScript 2.0 的代码在 PHPRPC Client for ActionScript 2.0 中已经包含了,下面是 for ActionScript 3.0 的代码,与 for ActionScript 2.0 相比,3.0 版本序列化后的内容是 ByteArray 类型的数据,序列化过程中编码转化直接通过 ByteArray 来完成,速度得到的大幅的提升,另外,增加了对自定义动态类对象类型的序列化和反序列化支持。

Serializable.as

ActionScript代码
 
  1. /**********************************************************\ 
  2. |                                                          | 
  3. | The implementation of PHPRPC Protocol 3.0                | 
  4. |                                                          | 
  5. | Serializable.as                                          | 
  6. |                                                          | 
  7. | Release 3.0.0                                            | 
  8. | Copyright (c) 2005-2007 by Team-PHPRPC                   | 
  9. |                                                          | 
  10. | WebSite:  http://www.phprpc.org/                         | 
  11. |           http://www.phprpc.net/                         | 
  12. |           http://www.phprpc.com/                         | 
  13. |           http://sourceforge.net/projects/php-rpc/       | 
  14. |                                                          | 
  15. | Authors:  Ma Bingyao <andot@ujn.edu.cn>                  | 
  16. |                                                          | 
  17. | This file may be distributed and/or modified under the   | 
  18. | terms of the GNU Lesser General Public License (LGPL)    | 
  19. | version 3.0 as published by the Free Software Foundation | 
  20. | and appearing in the included file LICENSE.              | 
  21. |                                                          | 
  22. \**********************************************************/  
  23.   
  24. /* Serializable interface for custom PHP serialize. 
  25.  * 
  26.  * Copyright (C) 2006-2007 Ma Bingyao <andot@ujn.edu.cn> 
  27.  * Version: 3.0 
  28.  * LastModified: Oct 23, 2007 
  29.  * This library is free.  You can redistribute it and/or modify it. 
  30.  */  
  31.   
  32. package org.phprpc.util{  
  33.     import flash.utils.ByteArray;  
  34.     public interface Serializable {  
  35.         function serialize():ByteArray;  
  36.         function unserialize(ss:ByteArray):void;  
  37.     }  
  38. }  

PHPSerializer.as

ActionScript代码
 
  1. /**********************************************************\ 
  2. |                                                          | 
  3. | The implementation of PHPRPC Protocol 3.0                | 
  4. |                                                          | 
  5. | PHPSerializer.as                                         | 
  6. |                                                          | 
  7. | Release 3.0.0                                            | 
  8. | Copyright (c) 2005-2007 by Team-PHPRPC                   | 
  9. |                                                          | 
  10. | WebSite:  http://www.phprpc.org/                         | 
  11. |           http://www.phprpc.net/                         | 
  12. |           http://www.phprpc.com/                         | 
  13. |           http://sourceforge.net/projects/php-rpc/       | 
  14. |                                                          | 
  15. | Authors:  Ma Bingyao <andot@ujn.edu.cn>                  | 
  16. |                                                          | 
  17. | This file may be distributed and/or modified under the   | 
  18. | terms of the GNU Lesser General Public License (LGPL)    | 
  19. | version 3.0 as published by the Free Software Foundation | 
  20. | and appearing in the included file LICENSE.              | 
  21. |                                                          | 
  22. \**********************************************************/  
  23. /* PHP serialize/unserialize library for ActionScript 3.0. 
  24.  * 
  25.  * Copyright (C) 2006-2007 Ma Bingyao <andot@ujn.edu.cn> 
  26.  * Version: 3.0 
  27.  * LastModified: Nov 6, 2007 
  28.  * This library is free.  You can redistribute it and/or modify it. 
  29.  */  
  30. package org.phprpc.util {  
  31.     import org.phprpc.util.Serializable;  
  32.     import flash.utils.ByteArray;  
  33.     import flash.utils.Dictionary;  
  34.     import flash.utils.getQualifiedClassName;  
  35.     import flash.utils.getDefinitionByName;  
  36.     public class PHPSerializer {  
  37.         private static function isInteger(s:String):Boolean {  
  38.             var i:int;  
  39.             var l:int = s.length;  
  40.             if (l > 11) {  
  41.                 return false;  
  42.             }  
  43.             for (i = (s.charAt(0) == '-') ? 1 : 0; i < l; i++) {  
  44.                 switch (s.charAt(i)) {  
  45.                 case '0' :  
  46.                 case '1' :  
  47.                 case '2' :  
  48.                 case '3' :  
  49.                 case '4' :  
  50.                 case '5' :  
  51.                 case '6' :  
  52.                 case '7' :  
  53.                 case '8' :  
  54.                 case '9' :  
  55.                     break;  
  56.                 default :  
  57.                     return false;  
  58.                 }  
  59.             }  
  60.             var n:Number = Number(s);  
  61.             return !(n < -2147483648 || n > 2147483647);  
  62.         }  
  63.         public static function getClassName(o:*):String {  
  64.             var className:String = getQualifiedClassName(o);  
  65.             return className.replace(/\./g, '_').replace(/\:\:/g, '_');  
  66.         }  
  67.         private static function getObjectOfClass(cn:Array, poslist:Array, i:uint, c:String):Object {  
  68.             if (i < poslist.length) {  
  69.                 var pos:uint = poslist[i];  
  70.                 cn[pos] = c;  
  71.                 var obj:Object = getObjectOfClass(cn, poslist, i + 1, '.');  
  72.                 if (i + 1 < poslist.length) {  
  73.                     if (obj == null) {  
  74.                         obj = getObjectOfClass(cn, poslist, i + 1, '_');  
  75.                     }  
  76.                 }  
  77.                 return obj;  
  78.             }  
  79.             var classname:String = cn.join('');  
  80.             try {  
  81.                 return new (flash.utils.getDefinitionByName(classname) as Class);  
  82.             }  
  83.             catch (e:Error) { };  
  84.             return null;  
  85.         }  
  86.         public static function createObjectOfClass(classname:String):Object {  
  87.             try {  
  88.                 return new (flash.utils.getDefinitionByName(classname) as Class);  
  89.             }  
  90.             catch (e:Error) {}  
  91.             var poslist:Array = [];  
  92.             var pos:int = classname.indexOf("_");  
  93.             while (pos > -1) {  
  94.                 poslist[poslist.length] = pos;  
  95.                 pos = classname.indexOf("_", pos + 1);  
  96.             }  
  97.             if (poslist.length > 0) {  
  98.                 var cn:Array = classname.split('');  
  99.                 var obj:Object = getObjectOfClass(cn, poslist, 0, '.');  
  100.                 if (obj == null) {  
  101.                     obj = getObjectOfClass(cn, poslist, 0, '_');  
  102.                 }  
  103.                 if (obj != null) {  
  104.                     return obj;  
  105.                 }  
  106.             }  
  107.             return {name:classname};  
  108.         }  
  109.         public static function serialize(o:Object):ByteArray {  
  110.             var sb:ByteArray = new ByteArray();  
  111.             var ht:Dictionary = new Dictionary();  
  112.             var hv:uint = 1;  
  113.             function _serializeNull():void {  
  114.                 sb.writeUTFBytes('N;');  
  115.             }  
  116.             function _serializeBoolean(b:Boolean):void {  
  117.                 sb.writeUTFBytes(b ? 'b:1;' : 'b:0;');  
  118.             }  
  119.             function _serializeInteger(i:int):void {  
  120.                 sb.writeUTFBytes('i:' + i + ';');  
  121.             }  
  122.             function _serializeDouble(d:Number):void {  
  123.                 var s:String;  
  124.                 if (isNaN(d)) {  
  125.                     s = 'NAN';  
  126.                 }  
  127.                 else if (d == Number.POSITIVE_INFINITY) {  
  128.                     s = 'INF';  
  129.                 }  
  130.                 else if (d == Number.NEGATIVE_INFINITY) {  
  131.                     s = '-INF';  
  132.                 }  
  133.                 else {  
  134.                     s = d.toString(10);  
  135.                 }  
  136.                 sb.writeUTFBytes('d:' + s + ';');  
  137.             }  
  138.             function _serializeByteArray(ba:ByteArray):void {  
  139.                 ba.position = 0;  
  140.                 sb.writeUTFBytes('s:' + ba.length + ':"');  
  141.                 sb.writeBytes(ba);  
  142.                 sb.writeUTFBytes('";');               
  143.             }  
  144.             function _serializeString(s:String):void {  
  145.                 var utf8:ByteArray = new ByteArray();  
  146.                 utf8.writeUTFBytes(s);  
  147.                 sb.writeUTFBytes('s:' + utf8.length + ':"');  
  148.                 sb.writeBytes(utf8);  
  149.                 sb.writeUTFBytes('";');  
  150.             }  
  151.             function _serializeDate(dt:Date):void {  
  152.                 sb.writeUTFBytes('O:11:"PHPRPC_Date":7:{');  
  153.                 sb.writeUTFBytes('s:4:"year";');  
  154.                 _serializeInteger(dt.getFullYear());  
  155.                 sb.writeUTFBytes('s:5:"month";');  
  156.                 _serializeInteger(dt.getMonth() + 1);  
  157.                 sb.writeUTFBytes('s:3:"day";');  
  158.                 _serializeInteger(dt.getDate());  
  159.                 sb.writeUTFBytes('s:4:"hour";');  
  160.                 _serializeInteger(dt.getHours());  
  161.                 sb.writeUTFBytes('s:6:"minute";');  
  162.                 _serializeInteger(dt.getMinutes());  
  163.                 sb.writeUTFBytes('s:6:"second";');  
  164.                 _serializeInteger(dt.getSeconds());  
  165.                 sb.writeUTFBytes('s:11:"millisecond";');  
  166.                 _serializeInteger(dt.getMilliseconds());  
  167.                 sb.writeUTFBytes('}');  
  168.             }  
  169.             function _serializeArray(a:Object):void {  
  170.                 var k:String;  
  171.                 var l:uint = 0;  
  172.                 for (k in a) l++;  
  173.                 sb.writeUTFBytes('a:' + l + ':{');  
  174.                 for (k in a) {  
  175.                     if (typeof (a[k]) != 'function') {  
  176.                         isInteger(k) ? _serializeInteger(k) : _serializeString(k);  
  177.                         _serialize(a[k]);  
  178.                     }  
  179.                 }  
  180.                 sb.writeUTFBytes('}');  
  181.             }  
  182.             function _serializeObject(o:Object, cn:String):void {  
  183.                 var c:Serializable = o as Serializable;  
  184.                 var cnb:ByteArray = new ByteArray();  
  185.                 cnb.writeUTFBytes(cn);  
  186.                 if (c == null) {  
  187.                     sb.writeUTFBytes('O:' + cnb.length + ':"');  
  188.                     sb.writeBytes(cnb);  
  189.                     var k:String;  
  190.                     var l:uint = 0;  
  191.                     for (k in o) l++;  
  192.                     sb.writeUTFBytes('":' + l + ':{');                    
  193.                     for (k in o) {  
  194.                         if (typeof(o[k]) != 'function') {  
  195.                             _serializeString(k);  
  196.                             _serialize(o[k]);  
  197.                         }  
  198.                     }  
  199.                     sb.writeUTFBytes('}');  
  200.                 }  
  201.                 else {  
  202.                     var data:ByteArray = c.serialize();  
  203.                     sb.writeUTFBytes('C:' + cnb.length + ':"');  
  204.                     sb.writeBytes(cnb);  
  205.                     sb.writeUTFBytes('":' + data.length + ':{');  
  206.                     sb.writeBytes(data);  
  207.                     sb.writeUTFBytes('}');  
  208.                 }  
  209.             }  
  210.             function _serializePointRef(R:uint):void {  
  211.                 sb.writeUTFBytes('R:' + R + ';');  
  212.             }  
  213.             function _serializeRef(r:uint):void {  
  214.                 sb.writeUTFBytes('r:' + r + ';');  
  215.             }  
  216.             function _serialize(o:*):void {  
  217.                 if (typeof (o) == "undefined" || o == null || o.constructor == Function) {  
  218.                     hv++;  
  219.                     _serializeNull();  
  220.                     return;  
  221.                 }  
  222.                 var className:String = getClassName(o);  
  223.                 switch (o.constructor) {  
  224.                 case Boolean :  
  225.                     hv++;  
  226.                     _serializeBoolean(o);  
  227.                     break;  
  228.                 case Number :  
  229.                     hv++;  
  230.                     isInteger(o) ? _serializeInteger(o) : _serializeDouble(o);  
  231.                     break;  
  232.                 case String :  
  233.                     hv++;  
  234.                     _serializeString(o);  
  235.                     break;  
  236.                 case ByteArray :  
  237.                     hv++;  
  238.                     _serializeByteArray(o);  
  239.                     break;  
  240.                 case Date :  
  241.                     hv++;  
  242.                     _serializeDate(o);  
  243.                     break;  
  244.                 default :  
  245.                     var r:int = ht[o];  
  246.                     if (className == "Object" || o.constructor == Array) {  
  247.                         if (r) {  
  248.                             _serializePointRef(r);  
  249.                         }  
  250.                         else {  
  251.                             ht[o] = hv++;  
  252.                             _serializeArray(o);  
  253.                         }  
  254.                     }  
  255.                     else {  
  256.                         if (r) {  
  257.                             hv++;  
  258.                             _serializeRef(r);  
  259.                         }  
  260.                         else {  
  261.                             ht[o] = hv++;  
  262.                             _serializeObject(o, className);  
  263.                         }                     
  264.                     }  
  265.                     break;  
  266.                 }  
  267.             }  
  268.             _serialize(o);  
  269.             return sb;  
  270.         }  
  271.         public static function unserialize(sb:ByteArray):* {  
  272.             var ht:Dictionary = new Dictionary();  
  273.             var hv:int = 1;  
  274.             function _readNumber():String {  
  275.                 var s:String = '';  
  276.                 var c:String = sb.readUTFBytes(1);  
  277.                 while ((c != ';') && (c != ':')) {  
  278.                     s += c;  
  279.                     c = sb.readUTFBytes(1);  
  280.                 }  
  281.                 return s;  
  282.             }  
  283.             function _unserializeNull():Object {  
  284.                 sb.position++;  
  285.                 return null;  
  286.             }  
  287.             function _unserializeBoolean():Boolean {  
  288.                 sb.position++;  
  289.                 var b:Boolean = (sb.readUTFBytes(1) == '1');  
  290.                 sb.position++;  
  291.                 return b;  
  292.             }  
  293.             function _unserializeInteger():int {  
  294.                 sb.readByte();  
  295.                 var i:int = parseInt(_readNumber());  
  296.                 return i;  
  297.             }  
  298.             function _unserializeDouble():Number {  
  299.                 sb.position++;  
  300.                 var d:Number;  
  301.                 var s:String = _readNumber();  
  302.                 switch (s) {  
  303.                 case 'NAN' :  
  304.                     d = Number.NaN;  
  305.                     break;  
  306.                 case 'INF' :  
  307.                     d = Number.POSITIVE_INFINITY;  
  308.                     break;  
  309.                 case '-INF' :  
  310.                     d = Number.NEGATIVE_INFINITY;  
  311.                     break;  
  312.                 default :  
  313.                     d = parseFloat(s);  
  314.                 }  
  315.                 return d;  
  316.             }  
  317.             function _unserializeByteArray():ByteArray {  
  318.                 sb.position++;  
  319.                 var l:uint = parseInt(_readNumber());  
  320.                 sb.position++;  
  321.                 var ba:ByteArray = new ByteArray();  
  322.                 if (l > 0) {  
  323.                     sb.readBytes(ba, 0, l);  
  324.                 }  
  325.                 sb.position += 2;  
  326.                 return ba;  
  327.             }  
  328.             function _unserializeString():String {  
  329.                 sb.position++;  
  330.                 var l:uint = parseInt(_readNumber());  
  331.                 sb.position++;  
  332.                 var s:String = sb.readUTFBytes(l);  
  333.                 sb.position += 2;  
  334.                 return s;  
  335.             }  
  336.             function _unserializeEscapedString(len:int):String {  
  337.                 sb.position++;  
  338.                 var l:uint = parseInt(_readNumber());  
  339.                 sb.position++;  
  340.                 var i:int;  
  341.                 var s:Array = new Array(l);  
  342.                 for (i = 0; i < l; i++) {  
  343.                     if ((s[i] = sb.readUTFBytes(1)) == '\\') {  
  344.                         s[i] = String.fromCharCode(parseInt(sb.readUTFBytes(len), 16));  
  345.                     }  
  346.                 }  
  347.                 sb.position += 2;  
  348.                 return s.join('');  
  349.             }  
  350.             function _unserializeArray():Array {  
  351.                 sb.position++;  
  352.                 var n:int = parseInt(_readNumber());  
  353.                 sb.position++;  
  354.                 var i:int;  
  355.                 var k:*;  
  356.                 var a:Array = [];  
  357.                 ht[hv++] = a;  
  358.                 for (i = 0; i < n; i++) {  
  359.                     switch (sb.readUTFBytes(1)) {  
  360.                     case 'i' :  
  361.                         k = _unserializeInteger();  
  362.                         break;  
  363.                     case 's' :  
  364.                         k = _unserializeString();  
  365.                         break;  
  366.                     case 'S' :  
  367.                         k = _unserializeEscapedString(2);  
  368.                         break;  
  369.                     case 'U' :  
  370.                         k = _unserializeEscapedString(4);  
  371.                         break;  
  372.                     default :  
  373.                         return null;  
  374.                     }  
  375.                     a[k] = _unserialize();  
  376.                 }  
  377.                 sb.position++;  
  378.                 return a;  
  379.             }  
  380.             function _unserializeDate(n:int):Date {  
  381.                 var i:int;  
  382.                 var k:String;  
  383.                 var a:Object = {};  
  384.                 for (i = 0; i < n; i++) {  
  385.                     switch (sb.readUTFBytes(1)) {  
  386.                     case 's' :  
  387.                         k = _unserializeString();  
  388.                         break;  
  389.                     case 'S' :  
  390.                         k = _unserializeEscapedString(2);  
  391.                         break;  
  392.                     case 'U' :  
  393.                         k = _unserializeEscapedString(4);  
  394.                         break;  
  395.                     default :  
  396.                         return null;  
  397.                     }  
  398.                     if (sb.readUTFBytes(1) == 'i') {  
  399.                         a[k] = _unserializeInteger();  
  400.                     }  
  401.                     else {  
  402.                         return null;  
  403.                     }  
  404.                 }  
  405.                 sb.position++;  
  406.                 var dt:Date = new Date(a.year, a.month - 1, a.day, a.hour, a.minute, a.second, a.millisecond);  
  407.                 ht[hv++] = dt;  
  408.                 return dt;  
  409.             }  
  410.             function _unserializeObject():* {  
  411.                 sb.position++;  
  412.                 var l:uint = parseInt(_readNumber());  
  413.                 sb.position++;  
  414.                 var cn:String = sb.readUTFBytes(l);  
  415.                 sb.position += 2;  
  416.                 var n:uint = parseInt(_readNumber());  
  417.                 sb.position++;  
  418.                 if (cn == "PHPRPC_Date") {  
  419.                     return _unserializeDate(n);  
  420.                 }  
  421.                 var i:int;  
  422.                 var k:String;  
  423.                 var o:Object = createObjectOfClass(cn);  
  424.                 ht[hv++] = o;  
  425.                 for (i = 0; i < n; i++) {  
  426.                     switch (sb.readUTFBytes(1)) {  
  427.                     case 's' :  
  428.                         k = _unserializeString();  
  429.                         break;  
  430.                     case 'S' :  
  431.                         k = _unserializeEscapedString(2);  
  432.                         break;  
  433.                     case 'U' :  
  434.                         k = _unserializeEscapedString(4);  
  435.                         break;  
  436.                     default :  
  437.                         return false;  
  438.                     }  
  439.                     if (k.charAt(0) == '\0') {  
  440.                         k = k.substring(k.indexOf('\0', 1) + 1, k.length);  
  441.                     }  
  442.                     o[k] = _unserialize();  
  443.                 }  
  444.                 sb.position++;  
  445.                 return o;  
  446.             }  
  447.             function _unserializeCustomObject():* {  
  448.                 sb.position++;  
  449.                 sb.position++;  
  450.                 var l:uint = parseInt(_readNumber());  
  451.                 sb.position++;  
  452.                 var cn:String = sb.readUTFBytes(l);  
  453.                 sb.position += 2;  
  454.                 var n:uint = parseInt(_readNumber());  
  455.                 sb.position++;  
  456.                 var data:ByteArray = new ByteArray();  
  457.                 sb.readBytes(data, 0, n);  
  458.                 sb.position++;  
  459.                 var o:Object = createObjectOfClass(cn);  
  460.                 var c:Serializable = o as Serializable;  
  461.                 if (c == null) {  
  462.                     o.data = data;  
  463.                     return o;  
  464.                 }  
  465.                 c.unserialize(data);  
  466.                 return c;  
  467.             }  
  468.             function _unserializeRef():* {  
  469.                 sb.position++;  
  470.                 var r:uint = parseInt(_readNumber());  
  471.                 return ht[r];  
  472.             }  
  473.             function _unserialize():* {  
  474.                 var result:*;  
  475.                 switch (sb.readUTFBytes(1)) {  
  476.                 case 'N' :  
  477.                     result = _unserializeNull();  
  478.                     ht[hv] = result;  
  479.                     hv++;  
  480.                     return result;  
  481.                 case 'b' :  
  482.                     result = _unserializeBoolean();  
  483.                     ht[hv] = result;  
  484.                     hv++;  
  485.                     return result;  
  486.                 case 'i' :  
  487.                     result = _unserializeInteger();  
  488.                     ht[hv] = result;  
  489.                     hv++;  
  490.                     return result;  
  491.                 case 'd' :  
  492.                     result = _unserializeDouble();  
  493.                     ht[hv] = result;  
  494.                     hv++;  
  495.                     return result;  
  496.                 case 's' :  
  497.                     result = _unserializeByteArray();  
  498.                     ht[hv] = result;  
  499.                     hv++;  
  500.                     return result;  
  501.                 case 'S' :  
  502.                     result = _unserializeEscapedString(2);  
  503.                     ht[hv] = result;  
  504.                     hv++;  
  505.                     return result;  
  506.                 case 'U' :  
  507.                     result = _unserializeEscapedString(4);  
  508.                     ht[hv] = result;  
  509.                     hv++;  
  510.                     return result;  
  511.                 case 'r' :  
  512.                     result = _unserializeRef();  
  513.                     ht[hv] = result;  
  514.                     hv++;  
  515.                     return result;  
  516.                 case 'a' :  
  517.                     return _unserializeArray();  
  518.                 case 'O' :  
  519.                     return _unserializeObject();  
  520.                 case 'C' :  
  521.                     return _unserializeCustomObject();  
  522.                 case 'R' :  
  523.                     return _unserializeRef();  
  524.                 }  
  525.                 return false;  
  526.             }  
  527.             sb.position = 0;  
  528.             return _unserialize();  
  529.         }  
  530.     }  
  531. }  

标签: ActionScript/Flash

« 上一篇 | 下一篇 »

只显示10条记录相关文章

发表评论

评论 (必须):