Make a function where you pass in a buffer and buffer size, and which returns a length.
If the passed buffer is large enough, it will write to the buffer and return the length it wrote.
If the passed buffer is to small, it will only return the required length.
So, you can call it once passing 0 as buffer length, get the required length in the return value, allocate an array of that size and pass that when you call the function again.
I did it… if someone’s curious, here’s my hacky way to do it
the part in the html template
<script type='text/javascript'>
function sendfile(e){
var files = e.target.files;
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = (function(file) {
return function(e) {
(window.filedata = window.filedata ? window.filedata : {})[file.name] = e.target.result;
SendMessage("DaefObject", "FileUpload", file.name);
}
})(f);
reader.readAsArrayBuffer(f);
}
}
</script>
<input style="color:#ccc;" type="file" multiple="false" id="fileuploader" onchange="sendfile(event);return false;">
the unity part
public void FileUpload(string filename) {
var length = GetFileDataLength(filename);
Alert(length.ToString());
var ptr = GetFileData(filename);
var data = new byte[length];
Marshal.Copy(ptr, data, 0, data.Length);
FreeFileData(filename);
Alert(Encoding.ASCII.GetString(data));
}
the jslib part
var LibraryFileOpen = {
Alert: function(msgptr) {
window.alert(Pointer_stringify(msgptr));
},
GetFileData: function(filenameptr) {
var filename = Pointer_stringify(filenameptr);
var filedata = window.filedata[filename];
var ptr = (window.fileptr = window.fileptr ? window.fileptr : {})[filename] = _malloc(filedata.byteLength);
var dataHeap = new Uint8Array(HEAPU8.buffer, ptr, filedata.byteLength);
dataHeap.set(new Uint8Array(filedata));
return ptr;
},
GetFileDataLength: function(filenameptr) {
var filename = Pointer_stringify(filenameptr);
console.log("GetFileDataLength");
console.log(filename);
console.log(window);
console.log(window.filedata);
return window.filedata[filename].byteLength;
},
FreeFileData: function(filenameptr) {
var filename = Pointer_stringify(filenameptr);
_free(window.fileptr[filename]);
delete window.fileptr[filename];
delete window.filedata[filename];
}
};
mergeInto(LibraryManager.library, LibraryFileOpen);
Sorry for necroposting… This is pretty much the only resource i could find about this topic, so here goes.
For some reason, SendMessage doesn’t work for me. It did earlier, when I tried to do it in a different way, but now I copied your code to test it out and i get an alert (“ReferenceError: SendMessage is not defined”).
As I said, I was able to SendMessage before, but in the context of your HTML it just won’t work.
goddamn, is there any documentation of the JSlib functionality in unity? its the 3rd time something should’ve worked that got changed some time along the way.
@mnml Thanks a lot for this code, saved me a ton of time! One thing though - does the heap allocated in GetFileData ever get freed? [EDIT: after re-reading the code, yes it does!]