Skip to content

Instantly share code, notes, and snippets.

@shadybones
Last active January 2, 2016 13:29
Show Gist options
  • Save shadybones/8310382 to your computer and use it in GitHub Desktop.
Save shadybones/8310382 to your computer and use it in GitHub Desktop.
Saving a Typed Array ( ArrayBuffer ) to a file in Firefox Extension / Addon. What sucks: --1) FOS.write converts to a string (toString()) whatever buffer you pass and uses the returned primitive as the memory location of the buffer. --2) NetUtil.asyncCopy only accepts nsIInputStreams --3) Can't implement a nsIInputStream in javascript. --4) data…
function read2Buffer(from, to, maxN, offset){
if(!from || !to || !maxN) throw "Invalid Arguments";
from = from.buffer || from;
if(from.byteLength) from = new Uint8Array(from);
var tot = Math.min((from.length && (from.length - offset)) || (from.available && from.available()), maxN) + offset;
for(var i = offset; i < tot; i++){
to[i] = String.fromCharCode(from[i]);
}
return tot - offset;
};
//setup
var file = FileUtils.getFile("ProfD", ["myfile.data"]);
var v = new Uint8Array(THE_DATA);
var fos = FileUtils.openSafeFileOutputStream(file, FileUtils.MODE_WRONLY|FileUtils.MODE_CREATE|FileUtils.MODE_TRUNCATE);
var done = 2048, offset=0, buff = new Array(done);
//action - synchronous
while(done == 2048){
offset+= (done = read2Buffer(v,buff,done,offset));
fos.write(buff.join(""),done);
}
////fos.close() doesn't seem to work - actually, it deletes the file ~~??
//fos.flush(); //one can access the file via an inputstream at this point, but file will get canned by FF
FileUtils.closeSafeFileOutputStream(fos); //apparently, when you open with FU.oSFOS, you have to close with FU.cSFOS
//action - aynchronous
var fun = function(){
if(done == 2048){
offset+= (done = read2Buffer(v,buff,done,offset));
fos.write(buff.join(""),done);
setTimeout(fun,10); //arguments.callee, if you like
}else fos.close();
};
fun();
@shadybones
Copy link
Author

Discovered a third write option: BinaryOutputStream. I knew about BIS so guess I should have figured there was a match for output. Anyways, BOS DOES accept arrays (or array accessible objects like Typed Arrays). So all the (non-setup code) above could be reduced to:

var bos = Components.classes["@mozilla.org/binaryoutputstream;1"].createInstance(Components.interfaces.nsIBinaryOutputStream);
bos.setOutputStream(fos);
bos.writeByteArray(v,v.length);
bos.close();

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