Skip to content

Instantly share code, notes, and snippets.

@cambiata
Created May 13, 2014 14:32
Show Gist options
  • Save cambiata/471575a42676b27719e3 to your computer and use it in GitHub Desktop.
Save cambiata/471575a42676b27719e3 to your computer and use it in GitHub Desktop.
Haxe BytesLoader - binary data loader that works on Flash, JS, Neko, Cpp - Status: Proof of conept
package cx.data;
import haxe.io.Bytes;
import haxe.io.BytesData;
import haxe.io.BytesInput;
#if js
import js.html.ArrayBuffer;
import js.html.DataView;
import js.html.XMLHttpRequest;
import js.html.XMLHttpRequestProgressEvent;
import js.html.EventTarget;
#end
#if flash
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.utils.ByteArray;
#end
/**
* ...
* @author Jonas Nyström
*/
class BytesLoader
{
var filename:String;
var callbck: Bytes->Void;
public function new(filename:String, callbck:Bytes->Void)
{
this.filename = filename;
this.callbck = callbck;
}
#if (sys)
public function load():Void
{
var bytes = sys.io.File.getBytes(filename);
//trace(bytes.length);
var str = '';
for (i in 0...40) str += bytes.get(i) + ', ';
//trace(str);
this.callbck(bytes);
}
#elseif js
// All js-stuff: credits to Joshua Granick and the creators of OpenFL!
public function load():Void
{
var xmlHttpRequest:XMLHttpRequest = untyped __new__("XMLHttpRequest");
registerEvents (cast xmlHttpRequest);
var url = this.filename;
try {
xmlHttpRequest.open ( "GET", url, true);
} catch (e:Dynamic) {
onError (e.toString ());
return;
}
untyped xmlHttpRequest.responseType = 'arraybuffer';
xmlHttpRequest.send (this.filename);
onOpen ();
getData = function () {
if (xmlHttpRequest.response != null) {
return xmlHttpRequest.response;
} else {
return xmlHttpRequest.responseText;
}
};
}
#elseif flash
public function load():Void
{
var req = new flash.net.URLLoader();
req.dataFormat = flash.net.URLLoaderDataFormat.BINARY;
req.addEventListener(
flash.events.Event.COMPLETE
, function ( e: Event )
{
var arr: ByteArray = cast( e.target, flash.net.URLLoader ).data;
var bytes = Bytes.ofData( arr );
this.callbck(bytes);
}
);
req.load( new flash.net.URLRequest(this.filename) );
}
#end
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
// JS stuff here:
#if js
function registerEvents (subject:EventTarget):Void
{
var self = this;
if (untyped __js__("typeof XMLHttpRequestProgressEvent") != __js__('"undefined"')) {
subject.addEventListener ("progress", onProgress, false);
}
untyped subject.onreadystatechange = function () {
if (subject.readyState != 4) return;
var s = try subject.status catch (e:Dynamic) null;
if (s == untyped __js__("undefined")) {
s = null;
}
if (s != null) {
self.onStatus (s);
}
if (s != null && s >= 200 && s < 400) {
self.onData (subject.response);
} else {
if (s == null) {
self.onError ("Failed to connect or resolve host");
} else if (s == 12029) {
self.onError ("Failed to connect to host");
} else if (s == 12007) {
self.onError ("Unknown host");
} else if (s == 0) {
self.onError ("Unable to make request (may be blocked due to cross-domain permissions)");
self.onSecurityError ("Unable to make request (may be blocked due to cross-domain permissions)");
} else {
self.onError ("Http Error #" + subject.status);
}
}
};
}
dynamic function getData ():Dynamic return null;
private function onData (_):Void {
var content:Dynamic = getData ();
if (Std.is(content, ArrayBuffer))
{
var ab:ArrayBuffer = cast content;
var dataview:DataView = untyped __new__("DataView", ab);
var bytesData = new BytesData();
for (i in 0...dataview.byteLength) bytesData.push( dataview.getUint8(i));
var bytes = Bytes.ofData(bytesData);
this.callbck(bytes);
}
else
{
onError('Not binary data');
}
}
private function onError (msg:String) trace('onError: $msg');
private function onOpen (){} // { trace('onOpen'); }
private function onProgress (event:XMLHttpRequestProgressEvent)trace('onProgress');
private function onSecurityError(msg:String) {trace('onSecurityError: $msg');}
private function onStatus (status:Int) trace('onStatus: $status');
#end
}
// Usage example
public static function main()
{
var dl = new BytesLoader('test.data', function(bytes:Bytes) {
trace('Binary data loaded!');
trace(bytes.length);
var str = '';
for (i in 0...40) str += bytes.get(i) + ', ';
trace(str);
});
dl.load();
}
@jakelewis3d
Copy link

For some reason the javascript progress events aren't compiling.
Also the javascript onData method didn't compile with modern haxe, so I simplified it to:

private function onData (_):Void {
var content:Dynamic = getData ();
if (Std.is(content, ArrayBuffer))
{
var ab:ArrayBuffer = cast content;
this.callbck(Bytes.ofData(ab));
}
else
{
onError('Not binary data');
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment