root/as3/ForcibleLoader/src/org/libspark/utils/ForcibleLoader.as

リビジョン 132, 4.0 kB (コミッタ: yossy, コミット時期: 1 年 前)

Moved.

Line 
1 package org.libspark.utils
2 {
3         import flash.display.Loader;
4         import flash.net.URLRequest;
5         import flash.net.URLStream;
6         import flash.events.IOErrorEvent;
7         import flash.events.SecurityErrorEvent;
8         import flash.events.Event;
9         import flash.utils.ByteArray;
10         import flash.utils.Endian;
11         import flash.errors.EOFError;
12        
13         /**
14          * Usage:
15          * <pre>
16          * var loader:Loader = Loader(addChild(new Loader()));
17          * var fLoader:ForcibleLoader = new ForcibleLoader(loader);
18          * fLoader.load(new URLRequest('swf7.swf'));
19          * </pre>
20          */
21         public class ForcibleLoader
22         {
23                 public function ForcibleLoader(loader:Loader)
24                 {
25                         this.loader = loader;
26                        
27                         _stream = new URLStream();
28                         _stream.addEventListener(Event.COMPLETE, completeHandler);
29                         _stream.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
30                         _stream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
31                 }
32                
33                 private var _loader:Loader;
34                 private var _stream:URLStream;
35                
36                 public function get loader():Loader
37                 {
38                         return _loader;
39                 }
40                
41                 public function set loader(value:Loader):void
42                 {
43                         _loader = value;
44                 }
45                
46                 public function load(request:URLRequest):void
47                 {
48                         _stream.load(request);
49                 }
50                
51                 private function completeHandler(event:Event):void
52                 {
53                         var inputBytes:ByteArray = new ByteArray();
54                         _stream.readBytes(inputBytes);
55                         _stream.close();
56                         inputBytes.endian = Endian.LITTLE_ENDIAN;
57                        
58                         if (isCompressed(inputBytes)) {
59                                 uncompress(inputBytes);
60                         }
61                        
62                         var version:uint = uint(inputBytes[3]);
63                        
64                         if (version < 9) {
65                                 if (version == 8) {
66                                         flagSWF9Bit(inputBytes);
67                                 }
68                                 else if (version <= 7) {
69                                         insertFileAttributesTag(inputBytes);
70                                 }
71                                 updateVersion(inputBytes, 9);
72                         }
73                        
74                         loader.loadBytes(inputBytes);
75                 }
76                
77                 private function isCompressed(bytes:ByteArray):Boolean
78                 {
79                         return bytes[0] == 0x43;
80                 }
81                
82                 private function uncompress(bytes:ByteArray):void
83                 {
84                         var cBytes:ByteArray = new ByteArray();
85                         cBytes.writeBytes(bytes, 8);
86                         bytes.length = 8;
87                         bytes.position = 8;
88                         cBytes.uncompress();
89                         bytes.writeBytes(cBytes);
90                         bytes[0] = 0x46;
91                         cBytes.length = 0;
92                 }
93                
94                 private function getBodyPosition(bytes:ByteArray):uint
95                 {
96                         var result:uint = 0;
97                        
98                         result += 3; // FWS/CWS
99                         result += 1; // version(byte)
100                         result += 4; // length(32bit-uint)
101                        
102                         var rectNBits:uint = bytes[result] >>> 3;
103                         result += (5 + rectNBits * 4) / 8; // stage(rect)
104                        
105                         result += 2;
106                        
107                         result += 1; // frameRate(byte)
108                         result += 2; // totalFrames(16bit-uint)
109                        
110                         return result;
111                 }
112                
113                 private function findFileAttributesPosition(offset:uint, bytes:ByteArray):uint
114                 {
115                         bytes.position = offset;
116                        
117                         try {
118                                 for (;;) {
119                                         var byte:uint = bytes.readShort();
120                                         var tag:uint = byte >>> 6;
121                                         if (tag == 69) {
122                                                 return bytes.position - 2;
123                                         }
124                                         var length:uint = byte & 0x3f;
125                                         if (length == 0x3f) {
126                                                 length = bytes.readInt();
127                                         }
128                                         bytes.position += length;
129                                 }
130                         }
131                         catch (e:EOFError) {
132                         }
133                        
134                         return NaN;
135                 }
136                
137                 private function flagSWF9Bit(bytes:ByteArray):void
138                 {
139                         var pos:uint = findFileAttributesPosition(getBodyPosition(bytes), bytes);
140                         if (!isNaN(pos)) {
141                                 bytes[pos + 2] |= 0x08;
142                         }
143                 }
144                
145                 private function insertFileAttributesTag(bytes:ByteArray):void
146                 {
147                         var pos:uint = getBodyPosition(bytes);
148                         var afterBytes:ByteArray = new ByteArray();
149                         afterBytes.writeBytes(bytes, pos);
150                         bytes.length = pos;
151                         bytes.position = pos;
152                         bytes.writeByte(0x44);
153                         bytes.writeByte(0x11);
154                         bytes.writeByte(0x08);
155                         bytes.writeByte(0x00);
156                         bytes.writeByte(0x00);
157                         bytes.writeByte(0x00);
158                         bytes.writeBytes(afterBytes);
159                         afterBytes.length = 0;
160                 }
161                
162                 private function updateVersion(bytes:ByteArray, version:uint):void
163                 {
164                         bytes[3] = version;
165                 }
166                
167                 private function ioErrorHandler(event:IOErrorEvent):void
168                 {
169                         loader.contentLoaderInfo.dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
170                 }
171                
172                 private function securityErrorHandler(event:SecurityErrorEvent):void
173                 {
174                         loader.contentLoaderInfo.dispatchEvent(new SecurityErrorEvent(SecurityErrorEvent.SECURITY_ERROR));
175                 }
176         }
177 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。