Created
May 13, 2014 14:32
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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');
}
}