11const ras = require ( 'random-access-storage' )
2+ const mutexify = require ( 'mutexify' )
23
34const TYPE = { type : 'octet/stream' }
45const requestFileSystem = window . requestFileSystem || window . webkitRequestFileSystem
@@ -29,19 +30,20 @@ function createFile (name, opts) {
2930
3031 var fs = null
3132 var entry = null
33+ var file = null
3234 var toDestroy = null
3335 var readers = [ ]
3436 var writers = [ ]
3537
3638 return ras ( { read, write, open, stat, close, destroy} )
3739
3840 function read ( req ) {
39- const r = readers . pop ( ) || new ReadRequest ( readers , entry , mutex )
41+ const r = readers . pop ( ) || new ReadRequest ( readers , entry , file , mutex )
4042 r . run ( req )
4143 }
4244
4345 function write ( req ) {
44- const w = writers . pop ( ) || new WriteRequest ( writers , entry , mutex )
46+ const w = writers . pop ( ) || new WriteRequest ( writers , entry , file , mutex )
4547 w . run ( req )
4648 }
4749
@@ -51,9 +53,10 @@ function createFile (name, opts) {
5153 }
5254
5355 function stat ( req ) {
54- entry . file ( file => {
56+ file . get ( ( err , file ) => {
57+ if ( err ) return req . callback ( err )
5558 req . callback ( null , file )
56- } , err => req . callback ( err ) )
59+ } )
5760 }
5861
5962 function destroy ( req ) {
@@ -78,7 +81,11 @@ function createFile (name, opts) {
7881 mkdirp ( parentFolder ( name ) , function ( ) {
7982 fs . root . getFile ( name , { create : true } , function ( e ) {
8083 entry = toDestroy = e
81- req . callback ( null )
84+ file = new EntryFile ( entry )
85+ file . get ( ( err ) => {
86+ if ( err ) return onerror ( err )
87+ req . callback ( null )
88+ } )
8289 } , onerror )
8390 } )
8491 } , onerror )
@@ -107,9 +114,10 @@ function parentFolder (path) {
107114 return / ^ \w : $ / . test ( p ) ? '' : p
108115}
109116
110- function WriteRequest ( pool , entry , mutex ) {
117+ function WriteRequest ( pool , entry , file , mutex ) {
111118 this . pool = pool
112119 this . entry = entry
120+ this . file = file
113121 this . mutex = mutex
114122 this . writer = null
115123 this . req = null
@@ -122,7 +130,8 @@ WriteRequest.prototype.makeWriter = function () {
122130 this . entry . createWriter ( function ( writer ) {
123131 self . writer = writer
124132
125- writer . onwriteend = function ( ) {
133+ writer . onwriteend = function ( e ) {
134+ self . file . updateSize ( e . currentTarget . length )
126135 self . onwrite ( null )
127136 }
128137
@@ -164,21 +173,21 @@ WriteRequest.prototype.lock = function () {
164173}
165174
166175WriteRequest . prototype . run = function ( req ) {
167- this . entry . file ( file => {
168- this . req = req
169- if ( ! this . writer || this . writer . length !== file . size ) return this . makeWriter ( )
176+ var file = this . file
170177
171- const end = req . offset + req . size
172- if ( end > file . size && ! this . lock ( ) ) return
178+ this . req = req
179+ if ( ! this . writer || this . writer . length !== file . size ) return this . makeWriter ( )
173180
174- if ( req . offset > this . writer . length ) {
175- if ( req . offset > file . size ) return this . truncate ( )
176- return this . makeWriter ( )
177- }
181+ const end = req . offset + req . size
182+ if ( end > file . size && ! this . lock ( ) ) return
183+
184+ if ( req . offset > this . writer . length ) {
185+ if ( req . offset > file . size ) return this . truncate ( )
186+ return this . makeWriter ( )
187+ }
178188
179- this . writer . seek ( req . offset )
180- this . writer . write ( new Blob ( [ req . data ] , TYPE ) )
181- } , err => req . callback ( err ) )
189+ this . writer . seek ( req . offset )
190+ this . writer . write ( new Blob ( [ req . data ] , TYPE ) )
182191}
183192
184193function Mutex ( ) {
@@ -202,9 +211,10 @@ Mutex.prototype.lock = function (req) {
202211 return true
203212}
204213
205- function ReadRequest ( pool , entry , mutex ) {
214+ function ReadRequest ( pool , entry , file , mutex ) {
206215 this . pool = pool
207216 this . entry = entry
217+ this . file = file
208218 this . mutex = mutex
209219 this . reader = new FileReader ( )
210220 this . req = null
@@ -251,10 +261,53 @@ ReadRequest.prototype.onread = function (err, buf) {
251261}
252262
253263ReadRequest . prototype . run = function ( req ) {
254- this . entry . file ( file => {
264+ this . file . get ( ( err , file ) => {
265+ if ( err ) return req . callback ( err )
266+
255267 const end = req . offset + req . size
256268 this . req = req
257269 if ( end > file . size ) return this . onread ( new Error ( 'Could not satisfy length' ) , null )
258270 this . reader . readAsArrayBuffer ( file . slice ( req . offset , end ) )
259- } , err => req . callback ( err ) )
271+ } )
272+ }
273+
274+ class EntryFile {
275+ constructor ( entry ) {
276+ this . _entry = entry
277+ this . _lock = mutexify ( )
278+ this . _file = null
279+ this . _size = 0
280+ }
281+
282+ get locked ( ) {
283+ return this . _lock . locked
284+ }
285+
286+ get size ( ) {
287+ return this . _size
288+ }
289+
290+ updateSize ( size ) {
291+ this . _size = size
292+ this . _file = null
293+ }
294+
295+ get ( cb ) {
296+ if ( this . _file ) {
297+ cb ( null , this . _file )
298+ return
299+ }
300+
301+ this . _lock ( release => {
302+ if ( this . _file ) {
303+ return release ( cb , null , this . _file )
304+ }
305+
306+ this . _entry . file ( file => {
307+ this . _file = file
308+ this . _size = file . size
309+ release ( cb , null , file )
310+ } , err => release ( cb , err ) )
311+ } )
312+ }
260313}
0 commit comments