From a48dabd42d1e6bc2a43ed047d920a5df3725e8ee Mon Sep 17 00:00:00 2001 From: Alan Kligman Date: Fri, 9 Nov 2012 11:10:55 -0500 Subject: [PATCH] Implemented open() and close(). --- examples/idbfs-test.html | 21 ++++-- src/fs.js | 159 +++++++++++++++++++++++++++++---------- src/path.js | 7 +- 3 files changed, 140 insertions(+), 47 deletions(-) diff --git a/examples/idbfs-test.html b/examples/idbfs-test.html index ac74a9a..6edb69f 100644 --- a/examples/idbfs-test.html +++ b/examples/idbfs-test.html @@ -19,20 +19,29 @@ require(["src/fs"], function(IDBFS) { IDBFS.mount("default", "FORMAT", function(error, fs) { if(error) { - console.error(error); - return; + return console.error(error); } fs.mkdir("/tmp", function() { if(error) { - console.error(error); - return; + return console.error(error); } fs.stat("/tmp", function(error, result) { if(error) { - console.error(error); - return; + return console.error(error); } console.info(result); + fs.open("/tmp/0", "create", "rw", function(error, fd) { + if(error) { + return console.error(error); + } + console.info(fd._openfile._handle); + fs.close(fd, function(error) { + if(error) { + return console.error(error); + } + console.info("done"); + }); + }); }); }); }); diff --git a/src/fs.js b/src/fs.js index 94d48d4..0968467 100644 --- a/src/fs.js +++ b/src/fs.js @@ -16,7 +16,7 @@ define(function(require) { var when = require("when"); var _ = require("lodash"); - var path = require("src/path"); + var Path = require("src/path"); var guid = require("src/guid"); var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; @@ -74,7 +74,7 @@ define(function(require) { function FileEntry(fullpath, file) { return { name: fullpath, - parent: path.dirname(fullpath), + parent: Path.dirname(fullpath), file: file, type: FILE_ENTRY_MIME_TYPE } @@ -85,7 +85,7 @@ define(function(require) { var now = Date.now(); return { name: fullpath, - parent: path.dirname(fullpath), + parent: Path.dirname(fullpath), atime: atime || now, ctime: ctime || now, mtime: mtime || now, @@ -95,50 +95,108 @@ define(function(require) { } function FileSystem(db) { - this._db = db; - this._deferred = when.defer(); - this._deferred.resolve(); + this._db = db; this._pending = 0; this._mounted = true; + this._descriptors = {}; + + this._deferred = when.defer(); + this._deferred.resolve(); this.Context = FileSystemContext.bind(undefined, this); } FileSystem.prototype._request = function _request(transaction) { var fs = this; - if(!fs._pending) { + if(0 === fs._pending) { fs._deferred = when.defer(); } ++ fs._pending; transaction.oncomplete = function(e) { -- fs._pending; - if(!fs._pending) { + if(0 === fs._pending) { fs._deferred.resolve(); } } }; - FileSystem.prototype.open = function open(path, flags, mode, callback) { + var OF_CREATE = "CREATE"; + var OF_APPEND = "APPEND"; + var OF_TRUNCATE = "TRUNCATE"; + var OM_RO = "RO"; + var OM_RW = "RW"; + FileSystem.prototype.open = function open(fullpath, flags, mode, callback, optTransaction) { + var fs = this; + fullpath = Path.normalize(fullpath); + var transaction = optTransaction || fs._db.transaction([METADATA_STORE_NAME, FILE_STORE_NAME], IDB_RW); + + var metadata = transaction.objectStore(METADATA_STORE_NAME); + var files = transaction.objectStore(FILE_STORE_NAME); + + flags = parseFlags(flags); + mode = mode.toUpperCase(); + + var getEntryRequest = metadata.get(fullpath); + getEntryRequest.onsuccess = function(e) { + var entry = e.target.result; + var file; + if(!entry) { + if(_(flags).contains(OF_CREATE)) { + file = new File(); + entry = new FileEntry(fullpath, file.handle); + var createFileRequest = files.put(file, file.handle); + createFileRequest.onsuccess = function(e) { + var createEntryRequest = metadata.put(entry, entry.name); + createEntryRequest.onsuccess = function(e) { + _createFileDescriptor(file.handle, flags, mode); + }; + createEntryRequest.onerror = function(e) { + runCallback(callback, e); + }; + }; + createFileRequest.onerror = function(e) { + runCallback(callback, e); + }; + } + } else { + if(OM_RW === mode && DIRECTORY_ENTRY_MIME_TYPE === entry.type) { + runCallback(callback, new error.EIsDirectory()); + } + _createFileDescriptor(); + } + }; + getEntryRequest.onerror = function(e) { + runCallback(callback, e); + }; + function _createFileDescriptor(handle, flags, mode) { + var openFile = new OpenFile(handle, flags, mode); + var descriptor = new FileDescriptor(openFile); + fs._descriptors[descriptor] = openFile; + runCallback(callback, null, descriptor); + } }; FileSystem.prototype.close = function close(descriptor, callback) { - + var fs = this; + var openFile = fs._descriptors[descriptor]; + openFile.valid = false; + openFile._deferred.then(callback); }; FileSystem.prototype.mkdir = function mkdir(fullpath, callback, optTransaction) { var fs = this; - fullpath = path.normalize(fullpath); + fullpath = Path.normalize(fullpath); var transaction = optTransaction || fs._db.transaction([METADATA_STORE_NAME], IDB_RW); this._request(transaction); - var metaStore = transaction.objectStore(METADATA_STORE_NAME); + var metadata = transaction.objectStore(METADATA_STORE_NAME); - var getRequest = metaStore.get(fullpath); - getRequest.onsuccess = function(e) { + var getEntryRequest = metadata.get(fullpath); + getEntryRequest.onsuccess = function(e) { var getResult = e.target.result; if(getResult) { handleError(transaction, new error.EPathExists()); } else { var entry = new DirectoryEntry(fullpath); - var putRequest = metaStore.put(entry, fullpath); + var putRequest = metadata.put(entry, fullpath); putRequest.onsuccess = function(e) { runCallback(callback); }; @@ -147,21 +205,21 @@ define(function(require) { }; } }; - getRequest.onerror = function(e) { + getEntryRequest.onerror = function(e) { runCallback(callback, e); } }; FileSystem.prototype.rmdir = function rmdir(fullpath, callback, optTransaction) { var fs = this; - fullpath = path.normalize(fullpath); + fullpath = Path.normalize(fullpath); var transaction = optTransaction || fs._db.transaction([METADATA_STORE_NAME], IDB_RW); this._request(transaction); - var metaStore = transaction.objectStore(METADATA_STORE_NAME); - var parentIndex = metaStore.index(PARENT_INDEX); + var metadata = transaction.objectStore(METADATA_STORE_NAME); + var parentIndex = metadata.index(PARENT_INDEX); - var getRequest = metaStore.get(fullpath); + var getRequest = metadata.get(fullpath); getRequest.onsuccess = function(e) { var getResult = e.target.result; if(!getResult) { @@ -173,7 +231,7 @@ define(function(require) { if(contentResult) { runCallback(callback, new error.ENotEmpty()); } else { - var removeRequest = metaStore.delete(fullpath); + var removeRequest = metadata.delete(fullpath); removeRequest.onsuccess = function(e) { runCallback(callback); }; @@ -193,14 +251,14 @@ define(function(require) { }; FileSystem.prototype.stat = function stat(fullpath, callback, optTransaction) { var fs = this; - fullpath = path.normalize(fullpath); + fullpath = Path.normalize(fullpath); var transaction = optTransaction || fs._db.transaction([METADATA_STORE_NAME], IDB_RW); this._request(transaction); - var metaStore = transaction.objectStore(METADATA_STORE_NAME); + var metadata = transaction.objectStore(METADATA_STORE_NAME); - var getRequest = metaStore.get(fullpath); + var getRequest = metadata.get(fullpath); getRequest.onsuccess = function(e) { var getResult = e.target.result; if(!getResult) { @@ -230,47 +288,68 @@ define(function(require) { this._fs = fs; this._cwd = optCwd || "/"; } - FileSystemContext.prototype.chdir = function chdir(rpath) { - + FileSystemContext.prototype.chdir = function chdir(path) { + if(Path.isAbsolute(path)) { + this._cwd = Path.normalize(path); + } else { + this._cwd = Path.normalize(this._cwd + "/" + path); + } }; FileSystemContext.prototype.getcwd = function getcwd() { return this._cwd; }; - FileSystemContext.prototype.open = function open(rpath, flags, mode, callback) { - + FileSystemContext.prototype.open = function open(path, flags, mode, callback) { + this._fs.open(Path.normalize(this._cwd + "/" + path), flags, mode, callback); }; FileSystemContext.prototype.close = function close(descriptor, callback) { - + this._fs.close(descriptor, callback); }; - FileSystemContext.prototype.mkdir = function mkdir(rpath, callback) { - this._fs.mkdir(path.normalize(this._cwd + "/" + rpath), callback); + FileSystemContext.prototype.mkdir = function mkdir(path, callback) { + this._fs.mkdir(Path.normalize(this._cwd + "/" + path), callback); }; - FileSystemContext.prototype.rmdir = function rmdir(rpath, callback) { - this._fs.rmdir(path.normalize(this._cwd + "/" + rpath), callback); + FileSystemContext.prototype.rmdir = function rmdir(path, callback) { + this._fs.rmdir(Path.normalize(this._cwd + "/" + path), callback); }; - FileSystemContext.prototype.stat = function stat(rpath, callback) { - this._fs.stat(path.normalize(this._cwd + "/" + rpath), callback); + FileSystemContext.prototype.stat = function stat(path, callback) { + this._fs.stat(Path.normalize(this._cwd + "/" + path), callback); }; FileSystemContext.prototype.link = function link(oldpath, newpath, callback) { }; - FileSystemContext.prototype.unlink = function unlink(rpath, callback) { + FileSystemContext.prototype.unlink = function unlink(path, callback) { }; - FileSystemContext.prototype.setxattr = function setxattr(rpath, name, value, callback) { + FileSystemContext.prototype.setxattr = function setxattr(path, name, value, callback) { }; - FileSystemContext.prototype.getxattr = function getxattr(rpath, name, callback) { + FileSystemContext.prototype.getxattr = function getxattr(path, name, callback) { }; function OpenFile(handle, flags, mode) { + this._handle = handle; this._pending = 0; this._valid = true; this._pointer = 0; this._flags = flags; this._mode = mode; + + this._deferred = when.defer(); + this._deferred.resolve(); } + OpenFile.prototype._request = function _request(deferred) { + var fs = this; + if(0 === fs._pending) { + fs._deferred = when.defer(); + } + ++ fs._pending; + deferred.then(function() { + -- fs._pending; + if(0 === fs._pending) { + fs._deferred.resolve(); + } + }) + }; function FileDescriptor(openfile, flags) { this._openfile = openfile; @@ -313,9 +392,9 @@ define(function(require) { if(format) { var transaction = db.transaction([METADATA_STORE_NAME], IDB_RW); - var metaStore = transaction.objectStore(METADATA_STORE_NAME); + var metadata = transaction.objectStore(METADATA_STORE_NAME); - var clearRequest = metaStore.clear(); + var clearRequest = metadata.clear(); clearRequest.onsuccess = function() { fs.mkdir("/", function(error) { if(error) { diff --git a/src/path.js b/src/path.js index 33ab668..9016546 100644 --- a/src/path.js +++ b/src/path.js @@ -113,10 +113,15 @@ define(function(require) { return f; }; + function isAbsolute(path) { + return path.charAt(0) === '/'; + } + return { normalize: normalize, dirname: dirname, - basename: basename + basename: basename, + isAbsolute: isAbsolute } }); \ No newline at end of file