diff --git a/demo/fsfh-demo.html b/demo/fsfh-demo.html new file mode 100644 index 00000000..8be5b2ea --- /dev/null +++ b/demo/fsfh-demo.html @@ -0,0 +1,147 @@ + + + + + + LibAV.JS FileSystemFileHandle writer demo + + + + + diff --git a/funcs.json b/funcs.json index 482f3317..39da79b1 100644 --- a/funcs.json +++ b/funcs.json @@ -140,6 +140,8 @@ "mkwriterdev", "mkstreamwriterdev", "mountwriterfs", + "mkfsfhfile", + "unlinkfsfhfile", "mkworkerfsfile", "unlinkworkerfsfile" ], diff --git a/post.in.js b/post.in.js index ec8c6366..cf19406d 100644 --- a/post.in.js +++ b/post.in.js @@ -357,7 +357,7 @@ var preReadaheadOnBlockRead = null; function readaheadOnBlockRead(name, position, length) { if (!(name in readaheads)) { if (preReadaheadOnBlockRead) - preReadaheadOnBlockRead(name, position, length); + return preReadaheadOnBlockRead(name, position, length); return; } @@ -438,7 +438,7 @@ Module.unlinkreadaheadfile = function(name) { * @param mode Unix permissions */ /// @types mkwriterdev@sync(name: string, mode?: number): @promise@void@ -Module.mkwriterdev = function(loc, mode) { +var mkwriterdev = Module.mkwriterdev = function(loc, mode) { FS.mkdev(loc, mode?mode:0x1FF, writerDev); return 0; }; @@ -498,6 +498,94 @@ Module.unlinkworkerfsfile = function(name) { FS.rmdir("/" + name + ".d"); }; +// FileSystemFileHandle devices +var fsfhs = {}; + +// Original onwrite +var preFSFHOnWrite = null; + +// Passthru for FSFH writing. +function fsfhOnWrite(name, position, buffer) { + if (!(name in fsfhs)) { + if (preFSFHOnWrite) + return preFSFHOnWrite(name, position, buffer); + return; + } + + var h = fsfhs[name]; + buffer = buffer.slice(0); + + if (h.syncHandle) { + h.syncHandle.write(buffer.buffer, { + at: position + }); + return; + } + + var p = h.promise.then(function() { + return h.handle.write({ + type: "write", + position: position, + data: buffer + }); + }); + + h.promise = p.catch(console.error); + return p; +} + +/** + * Make a FileSystemFileHandle device. This writes via a FileSystemFileHandle, + * synchronously if possible. Note that this overrides onwrite, so if you want + * to support both kinds of files, make sure you set onwrite before calling + * this. + * @param name Filename to create. + * @param fsfh FileSystemFileHandle corresponding to this filename. + */ +/// @types mkfsfhfile(name: string, fsfh: FileSystemFileHandle): Promise +Module.mkfsfhfile = function(name, fsfh) { + if (Module.onwrite !== fsfhOnWrite) { + preFSFHOnWrite = Module.onwrite; + Module.onwrite = fsfhOnWrite; + } + + mkwriterdev(name); + + var h = fsfhs[name] = { + promise: Promise.all([]) + }; + h.promise = h.promise.then(function() { + return fsfh.createSyncAccessHandle(); + }).then(function(syncHandle) { + h.syncHandle = syncHandle; + }).catch(function() { + return fsfh.createWritable(); + }).then(function(handle) { + h.handle = handle; + }); + return h.promise; +}; + +/** + * Unlink a FileSystemFileHandle file. Also closes the file handle. + * @param name Filename to unlink. + */ +/// @types unlinkfsfhfile(name: string): Promise +Module.unlinkfsfhfile = function(name) { + FS.unlink(name); + var h = fsfhs[name]; + delete fsfhs[name]; + + if (h.syncHandle) { + h.syncHandle.close(); + return Promise.all([]); + } + + return h.promise.then(function() { + return h.handle.close(); + }); +} + /** * Send some data to a reader device. To indicate EOF, send null. To indicate an * error, send EOF and include an error code in the options.