public
Last active

  • Download Gist
gistfile1.xml
XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
<?xml version="1.0" encoding="utf-8"?>
<!--
Show the compile date of a SWF.
See http://wahlers.com.br/claus/blog/undocumented-swf-tags-written-by-mxmlc/
-->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="600" minHeight="400"
creationComplete="creationCompleteHandler(event)">
 
<fx:Script>
<![CDATA[
import com.codeazur.as3swf.SWF;
import com.codeazur.as3swf.SWFData;
import com.codeazur.as3swf.data.SWFRawTag;
import com.codeazur.as3swf.data.SWFRecordHeader;
import com.codeazur.as3swf.tags.TagEnd;
import com.codeazur.as3swf.tags.TagProductInfo;
 
import mx.events.FlexEvent;
[Bindable]
protected var compileDate:Date;
protected function creationCompleteHandler(event:FlexEvent):void
{
compileDate = getCompileDateOptimized();
}
// if we're lazy and not concerned about performance/memory,
// we can just have as3swf parse the entire SWF
// and then loop over the tags to see if there's a ProductInfo tag
protected function getCompileDateSimple():Date
{
var swf:SWF = new SWF(systemManager.loaderInfo.bytes);
for(var i:uint = 0; i < swf.tags.length; i++) {
if(swf.tags[i] is TagProductInfo) {
var productInfo:TagProductInfo = swf.tags[i] as TagProductInfo;
return productInfo.compileDate;
}
}
return null;
}
 
// much better: do not parse the entire SWF, just the tag headers
// and bail out as soon as a ProductInfo tag is found
protected function getCompileDateOptimized():Date
{
var swfData:SWFData = new SWFData();
swfData.writeBytes(systemManager.loaderInfo.bytes);
swfData.position = 0;
// parse SWF header
var compressed:Boolean = false;
var signatureByte:uint = swfData.readUI8();
if (signatureByte == 0x43) {
compressed = true;
} else if (signatureByte != 0x46) {
throw(new Error("Not a SWF. First signature byte is 0x" + signatureByte.toString(16) + " (expected: 0x43 or 0x46)"));
}
signatureByte = swfData.readUI8();
if (signatureByte != 0x57) {
throw(new Error("Not a SWF. Second signature byte is 0x" + signatureByte.toString(16) + " (expected: 0x57)"));
}
signatureByte = swfData.readUI8();
if (signatureByte != 0x53) {
throw(new Error("Not a SWF. Third signature byte is 0x" + signatureByte.toString(16) + " (expected: 0x53)"));
}
swfData.readUI8(); // version
swfData.readUI32(); // fileLength
if (compressed) {
// the following data (up to end of file) is compressed
swfData.swfUncompress();
}
swfData.readRECT(); // frameSize
swfData.readFIXED8(); // frameRate
swfData.readUI16(); // frameCount
try {
// parse SWF tags
do {
// read the tag header
var tagRaw:SWFRawTag = swfData.readRawTag();
var tagHeader:SWFRecordHeader = tagRaw.header;
if(tagHeader.type == TagProductInfo.TYPE) {
// it's a ProductInfo tag: parse it
var productInfo:TagProductInfo = new TagProductInfo();
productInfo.parse(swfData, 0, 0);
// and return the compile date. we're done here.
return productInfo.compileDate;
} else {
// not a ProductInfo tag: just skip it
swfData.position += tagHeader.contentLength;
}
// loop until End tag is encountered
} while(tagHeader.type != TagEnd.TYPE);
} catch(error:Error) {
}
return null;
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout paddingLeft="8" paddingTop="8" />
</s:layout>
<s:Label text="{compileDate}" />
</s:Application>

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.