Actionscript GZIP Alternative

I really wish Actionscript 3 had a native decompression utility for opening GZIP compressed files. I really do. After reading (and trying to implement the advice of) numerous postings, I gave up on GZIP.

In my investigation, I walked byte-by-byte through numerous binary dumps. Somewhere along the way I noticed a pattern. Forget about the head and foot bytes, the basic GZIP compressed data is simply not the same as the actionscript base deflate-algorithm compressed data.

People argue with me on that one. They say the compressed bytes are simply deflate-algorithm compressed and that these bytes can be decompressed by actionscript. I have but one comment. “Good luck with that, Cowboy. Knock yourself out.”

I have working code in production. Who you gonna believe?

I’ll start with the flex side first (flex3, as3). Use a URLLoader and set the dataFormat to BINARY or it will not work. Since the source data is not GZIP, I’ve made up a new file extension ‘xmlz’.

The code in listing 1 fetches the compressed XML, decompresses it and dumps it in a TextArea.

Listing 1. Simple Flex app to load compressed XML

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    backgroundGradientColors="[#ffffff, #c0c0c0]"
    width="100%"
    height="100%">

  <mx:Script>
  <![CDATA[
    import flash.utils.ByteArray;

    [Bindable]
    private var bytes:String = "";

    private var loader:URLLoader = new URLLoader();

    private function urlLoaderSend():void
    {
      loader.addEventListener(Event.COMPLETE, setResult);
      loader.dataFormat = URLLoaderDataFormat.BINARY;
      loader.load(new URLRequest("http://example.com/data.xmlz"));
    }

    private function setResult(event:Event):void
    {
      var ba:ByteArray = loader.data as ByteArray;
      ba.position = 0;
      ba.uncompress();
      bytes = ba.toString();
    }
  ]]>
  </mx:Script>

  <mx:Button
      label="get playlist"
      click="urlLoaderSend()" />
  <mx:TextArea
      id="resultTA"
      width="600"
      height="600"
      text="{bytes}" />
</mx:Application>

The server-side java is quite simple. I use the StAX XMLStreamWriter to generate XML. The writer’s constructor takes an OutputStream as an argument. Simply wrap the original OutputStream in a DeflaterOutputStream. The trick is to explicitly create the Deflater. If you don’t, the default will produce bytes incompatible with actionscript’s uncompress().

Listing 2. Java DeflaterOutputStream fragment (with StAX writer)

OutputStream out = new OutputStream();
    ⋮

Deflater d = new Deflater(Deflater.BEST_COMPRESSION, false);
OutputStream zipper = new DeflaterOutputStream(out, d);

XMLOutputFactory factory = XMLOutputFactory.newInstance();

XMLStreamWriter writer;
writer = factory.createXMLStreamWriter(zipper, "utf-8");
    ⋮

And that’s it! The compression is size-equivalent with GZIP (within a few bytes). I would rather actionscript supported GZIP. Until it does, I’ll continue using ‘xmlz’.

1 Comment

  1. Thanks a lot! You saved me! I’ve spent my day to find a working server side Deflate algorithm without success.
    In addition it works without XMLOutputFactory
    zipper.write(“text”);

    Kamela

    2009.01.28
    10:14

Your email will never published nor shared. Required fields are marked *...

*

*

Type your comment out: