zip対応版、MQOViewerを作ってみた。

  • このエントリーをはてなブックマークに追加
  • 0

ZipLoaderのソースは以下。
そろそろSpark Projectのコミッターになって、MQOViewer本体共々そっちに上げたいと思っている(MQOViewerはmxmlファイルなので上げられるか不安だが)。なので、まずはSHA1ハッシュを出力してくれるプログラムを、AS3で書く予定。

ActionScript

  1. package {
  2.     import flash.events.Event;
  3.     import flash.events.EventDispatcher;
  4.     import flash.net.URLLoader;
  5.     import flash.net.URLLoaderDataFormat;
  6.     import flash.net.URLRequest;
  7.     import flash.utils.ByteArray;
  8.     import flash.utils.Dictionary;
  9.     import flash.utils.IDataInput;
  10.     import nochump.util.zip.ZipEntry;
  11.     import nochump.util.zip.ZipFile;
  12.    
  13.     /**
  14.     * URLRequest#urlが、http://??/*.zip://??/.fileだった場合:
  15.     * 1.Zipファイルがキャッシュにあればキャッシュから、なければダウンロードして、保持状態にする
  16.     * 2.Zipファイルの中からByteCode形式でデータを取り出す。
  17.     * URLRequest#urlがhttp://??/*.zipだった場合:
  18.     * ZipファイルをByteCode形式で返しつつ、キャッシュにURLとの組で保存
  19.     * 他の場合:
  20.     * 通常のURLLoaderと同じ
  21.     * @author 太郎
  22.     */
  23.     public class ZipLoader extends URLLoader {
  24.        
  25.         private static const ZIP_CACHE:Dictionary = new Dictionary();
  26.        
  27.         /**
  28.          * zipファイルのURLを指す正規表現
  29.          */
  30.         private static const ZIP_FILE_REG:RegExp = /.*?\.zip$/;
  31.         /**
  32.          * zipファイル内のエントリを指す正規表現
  33.          */
  34.         private static const ZIP_ENTRY_REG:RegExp = /(.*?\.zip):\/\/(.*$)/;
  35.         /**
  36.          * ロード対象のZipファイルのURL
  37.          */
  38.         private var _zipUrl:String;
  39.         /**
  40.          * ロードしたZipファイルの中に入っているエントリ部分のURL。
  41.          * Zipファイルの頂点が「/」となる。
  42.          */
  43.         private var _entryUrl:String;
  44.        
  45.         public function ZipLoader() {
  46.             super();
  47.             this.dataFormat = URLLoaderDataFormat.BINARY;
  48.             this.addEventListener(Event.COMPLETE , zipFileLoadCompleted , false , int.MAX_VALUE);
  49.             this._zipUrl = null;
  50.             this._entryUrl = null;
  51.         }
  52.  
  53.         public override function load(req:URLRequest):void {
  54.             var url:String = req.url;
  55.             switch (true) {
  56.                 case ZIP_ENTRY_REG.test(url)://zip内のファイルを探している
  57.                     var result:Object = ZIP_ENTRY_REG.exec(url);
  58.                     this._zipUrl = result[1];//TODO Zipファイル部分のURL
  59.                     this._entryUrl = result[2];//TODO Zip内部のパス
  60.                     var zip:ZipFile = ZIP_CACHE[this._zipUrl] as ZipFile;
  61.                     if ( zip ) {
  62.                         //キャッシュにZipファイル有
  63.                         this.dataFromZip(zip);
  64.                         this.removeEventListener(Event.COMPLETE, zipFileLoadCompleted);
  65.                         dispatchEvent(new Event(Event.COMPLETE));
  66.                     } else {
  67.                         //キャッシュに無。新規にロードする
  68.                         this.load(new URLRequest(zipUrl));
  69.                     }
  70.                     break;
  71.                 case ZIP_FILE_REG.test(url)://zipファイル自体をロードしようとしている
  72.                     this._zipUrl = url;
  73.                     super.load(req);
  74.                     break;
  75.                 default://他(そのままロードする)
  76.                     this.removeEventListener(Event.COMPLETE, zipFileLoadCompleted);
  77.                     super.load(req);
  78.                     break;
  79.             }
  80.         }
  81.        
  82.         /**
  83.          * zipファイルをネットワーク上から取得完了時のイベント処理。
  84.          * データをZipFileに変換し、エントリ取り出し処理を呼び出す
  85.          * @param    e
  86.          */
  87.         private function zipFileLoadCompleted(e:Event):void {
  88.             //Zipファイルの読み込みが完了したら、ZipEntry形式にしてキャッシュに入れておく
  89.             var zipfile:ZipFile = new ZipFile(e.target.data);
  90.             //zipファイルをキャッシュに格納
  91.             ZIP_CACHE[this._zipUrl] = zipfile;
  92.             this.dataFromZip(zipfile);
  93.         }
  94.        
  95.         /**
  96.          * zipファイルのロード及びエントリの取り出し処理完了時に呼ばれる
  97.          * @param    zip            zipファイル
  98.          */
  99.         private function dataFromZip(zip:ZipFile):void
  100.         {
  101.             if ( zip && this.entryUrl) {
  102.                 var entryData:ByteArray = this.getZipEntry(zip, this.entryUrl);
  103.                 if (entryData) {
  104.                     this.data = entryData;
  105.                 }
  106.             }
  107.         }
  108.        
  109.         private function getZipEntry(zip:ZipFile, entryUrl:String):ByteArray
  110.         {
  111.             if (ZIP_ENTRY_REG.test(entryUrl)) {
  112.                 //zipファイル内のzipファイルを参照している(foo.zip://bar.txtなど)
  113.                 var result:Object = ZIP_ENTRY_REG.exec(entryUrl);
  114.                 var outerEntry:String = result[1];
  115.                 var innerEntry:String = result[2];
  116.                 var innerZip:ZipFile = new ZipFile(zip.getInput(zip.getEntry(outerEntry)));
  117.                 return this.getZipEntry(innerZip, innerEntry);
  118.             } else {
  119.                 //zipファイルからエントリを探し出し、byteArrayにして返す
  120.                 return zip.getInput(zip.getEntry(entryUrl));
  121.             }
  122.            
  123.         }
  124.         public function get zipUrl():String { return _zipUrl; }
  125.        
  126.         public function get entryUrl():String { return _entryUrl; }
  127.     }
  128.    
  129. }
スポンサーリンク
スポンサーリンク
  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク