javascriptxmlhttprequestoperaxmlhttprequest-level2

How do I access 8-bit binary data from Javascript in Opera?


This question is an extension of this StackOverflow question about IE to the Opera 12 browser.

The root problem is an issue in geoxml3 handling kmz (zipped kml) files.

Example that fails in Opera 12

The binary data is being processed with TypedArrays in a modified version of ZipFile.complete.js

After the binary file is transferred the Uint8Array is not populated correctly in Opera 12, it is as if the data is being imported as 16-bit elements.

The request is configured like this:

this.req.responseType = 'arraybuffer';
this.req.overrideMimeType('text/plain; charset=x-user-defined');

The value returned is handled like this:

var fileContents = binStream.req.response;
binStream.length = fileContents.byteLength;
binStream.array = new Uint8Array(fileContents);

the first eight bytes are populated like this in Opera 12:

0x004B0050; giving a decimal value of 4915280

but should be:

0x4034B50; a decimal value of 67324752.

This works correctly in Firefox, Chrome and IE (with a workaround).

Does anyone know how I can convince Opera 12 to populate the Uint8Array correctly? Or a workaround so that it will work (some way to convert the array of 16-bit bytes into an array of 8-bit bytes, discarding the unneeded upper 8-bits as efficiently as possible)? Is this a known bug in the recent implementation of the TypedArray/XmlHttpRequest in Opera 12?


Solution

  • Opera 12.00 introduced support for responseType; unfortunately, there's a bug in it that means given a text/* MIME type you'll end up the file as 16-bit words. It's fixed in 12.01, but the simplest fix is to set the override type as application/octet-stream. (This is CORE-46938 for those of you desiring to stalk a closed bug-tracker.)