最近、SWFファイルを解析してそのSWF内に含まれるクラスの一覧を取得する方法を考えていました。ちょっとGoogle先生で調べていたところ、まさしく「SWF内のクラスを抽出するライブラリ」そのものを公開しているblogを見つけました!
Swf Class Explorer for AS3
公開されている方法は、SWFのバイナリを解析して、クラス情報を抽出するという方法をとっています。SWCファイルとライブラリの使い方のサンプルだけでなく、ソースコードそのものも公開されています!こういうものをサクッと公開できるセンスには脱帽です・・・。
私なりにサンプルを書いてみました。
上記のSWFLoadHelperクラスのloadClassesメソッドの使い方の例です。
ちなみにSWFファイルのフォーマットについては、SWFファイルフォーマットやSWFの構造要約が参考になります。
Swf Class Explorer for AS3
公開されている方法は、SWFのバイナリを解析して、クラス情報を抽出するという方法をとっています。SWCファイルとライブラリの使い方のサンプルだけでなく、ソースコードそのものも公開されています!こういうものをサクッと公開できるセンスには脱帽です・・・。
私なりにサンプルを書いてみました。
package utils.tool
{
import com.flassari.swfclassexplorer.SwfClassExplorer;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.system.LoaderContext;
import flash.utils.ByteArray;
/**
* ...
* @author Duke
*/
public class SWFLoadHelper
{
public static function loadClasses(swf:ByteArray, start:Function, inLoop:Function, finish:Function):void
{
var complete:Function = function complete(e:Event):void {
start();
var loaderInfo:LoaderInfo = (e.currentTarget) as LoaderInfo;
var classNames:Array = SwfClassExplorer.getClasses(swf);
loaderInfo.removeEventListener(Event.COMPLETE, complete);
for each(var className:String in classNames) {
className = className.replace(":", ".");
inLoop((loaderInfo.applicationDomain.getDefinition(className) as Class));
}
finish();
inLoop = null;
classNames.length = 0;
classNames = null;
loaderInfo.loader.unload();
};
var loader:Loader = new Loader();
var context:LoaderContext = new LoaderContext();
context.allowLoadBytesCodeExecution = true;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, complete);
loader.loadBytes(swf, context);
}
}
}
上記のSWFLoadHelperクラスのloadClassesメソッドの使い方の例です。
package test
{
import flash.display.Sprite;
import flash.utils.Dictionary;
import utils.IOUtils;
import utils.tool.SWFLoadHelper;
/**
* ...
* @author Duke
*/
public class SWFLoaderHelperTest extends Sprite
{
public function SWFLoaderHelperTest()
{
var dict:Dictionary = new Dictionary();
SWFLoadHelper.loadClasses(
IOUtils.readByteData("c:/temp/Example.swf"), // anyway you should give bytearray of swf :)
function():void {},
function(clazz:Class):void {
dict[clazz.toString()] = clazz;
},
function():void {
for each(var clazz:Class in dict) {
trace(clazz);
}
}
);
}
}
}
ちなみにSWFファイルのフォーマットについては、SWFファイルフォーマットやSWFの構造要約が参考になります。
コメント