diff --git a/examples/refactoring-test.html b/examples/refactoring-test.html
index 2a72c71..7a1148d 100644
--- a/examples/refactoring-test.html
+++ b/examples/refactoring-test.html
@@ -36,13 +36,13 @@ function remove_tmp_directory() {
};
function create_tmp_file() {
- return fs.open('/tmp/1', 'CREATE');
+ return fs.open('/tmp/1', 'w+');
};
fs.promise.then(make_tmp_directory)
.then(create_tmp_file)
.then(function() { console.log('done'); })
- .otherwise(function(error) { console.error(error, error.stack); });
+ .otherwise(function(error) { console.error(error, error.message); });
});
diff --git a/src/constants.js b/src/constants.js
index a2f9512..6946629 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -1,5 +1,12 @@
define(function(require) {
+ var O_READ = 'READ';
+ var O_WRITE = 'WRITE';
+ var O_CREATE = 'CREATE';
+ var O_EXCLUSIVE = 'EXCLUSIVE';
+ var O_TRUNCATE = 'TRUNCATE';
+ var O_APPEND = 'APPEND';
+
return {
METADATA_STORE_NAME: 'metadata',
FILE_STORE_NAME: 'files',
@@ -17,17 +24,28 @@ define(function(require) {
ROOT_DIRECTORY_NAME: '/', // basename(normalize(path))
ROOT_NODE_ID: '8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1', // sha256(ROOT_DIRECTORY_NAME)
- // FileSystem flags
FS_FORMAT: 'FORMAT',
- // Open flags
- O_READONLY: 'READONLY',
- O_READWRITE: 'READWRITE',
- O_APPEND: 'APPEND',
- O_CREATE: 'CREATE',
- O_TRUNCATE: 'TRUNCATE',
+ O_READ: O_READ,
+ O_WRITE: O_WRITE,
+ O_CREATE: O_CREATE,
+ O_EXCLUSIVE: O_EXCLUSIVE,
+ O_TRUNCATE: O_TRUNCATE,
+ O_APPEND: O_APPEND,
+
+ O_FLAGS: {
+ 'r': [O_READ],
+ 'r+': [O_READ, O_WRITE],
+ 'w': [O_WRITE, O_CREATE, O_TRUNCATE],
+ 'w+': [O_WRITE, O_READ, O_CREATE, O_TRUNCATE],
+ 'wx': [O_WRITE, O_CREATE, O_EXCLUSIVE, O_TRUNCATE],
+ 'wx+': [O_WRITE, O_READ, O_CREATE, O_EXCLUSIVE, O_TRUNCATE],
+ 'a': [O_WRITE, O_CREATE, O_APPEND],
+ 'a+': [O_WRITE, O_READ, O_CREATE, O_APPEND],
+ 'ax': [O_WRITE, O_CREATE, O_EXCLUSIVE, O_APPEND],
+ 'ax+': [O_WRITE, O_READ, O_CREATE, O_EXCLUSIVE, O_APPEND],
+ },
- // FileSystem readyState
FS_READY: 'READY',
FS_PENDING: 'PENDING',
FS_ERROR: 'ERROR',
diff --git a/src/descriptor.js b/src/descriptor.js
index e4ee30b..50e8de5 100644
--- a/src/descriptor.js
+++ b/src/descriptor.js
@@ -1,10 +1,16 @@
define(function(require) {
- function Descriptor() {
+ function Descriptor(db, id, flags, mode, size) {
+ this.db = db;
+ this.id = id;
+ this.flags = flags;
+ this.mode = mode;
+ this.size = size || 0;
+ this.position = 0;
};
return {
- Descriptor: Descriptor,
- };
+ Descriptor: Descriptor
+ }
});
\ No newline at end of file
diff --git a/src/directory.js b/src/directory.js
index 164be9d..5db0b7e 100644
--- a/src/directory.js
+++ b/src/directory.js
@@ -7,7 +7,7 @@ define(function(require) {
var ENoEntry = require('src/error').ENoEntry;
var ENotDirectory = require('src/error').ENotDirectory;
- var EPathExists = require('src/error').EPathExists;
+ var EExists = require('src/error').EExists;
var MODE_FILE = require('src/constants').MODE_FILE;
var MODE_DIRECTORY = require('src/constants').MODE_DIRECTORY;
@@ -28,7 +28,7 @@ define(function(require) {
function write_directory_node(error, existingNode) {
if(!error && existingNode) {
- callback(new EPathExists());
+ callback(new EExists());
} else if(error && !error instanceof ENoEntry) {
callback(error);
} else {
@@ -62,7 +62,7 @@ define(function(require) {
function check_if_directory_exists(error, result) {
if(!error && result) {
- callback(new EPathExists());
+ callback(new EExists());
} else if(error && !error instanceof ENoEntry) {
callback(error);
} else {
diff --git a/src/error.js b/src/error.js
index 29fec28..26ffaf9 100644
--- a/src/error.js
+++ b/src/error.js
@@ -14,58 +14,85 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
define(function(require) {
// 'use strict';
- function EPathExists(){ Error.apply(this, arguments); }
- EPathExists.prototype = new Error();
- EPathExists.prototype.name = "EPathExists";
- EPathExists.prototype.constructor = EPathExists;
+ function EExists(message){
+ this.message = message || '';
+ };
+ EExists.prototype = new Error();
+ EExists.prototype.name = "EExists";
+ EExists.prototype.constructor = EExists;
- function EIsDirectory(){ Error.apply(this, arguments); }
+ function EIsDirectory(message){
+ this.message = message || '';
+ };
EIsDirectory.prototype = new Error();
EIsDirectory.prototype.name = "EIsDirectory";
EIsDirectory.prototype.constructor = EIsDirectory;
- function ENoEntry(){ Error.apply(this, arguments); }
+ function ENoEntry(message){
+ this.message = message || '';
+ };
ENoEntry.prototype = new Error();
ENoEntry.prototype.name = "ENoEntry";
ENoEntry.prototype.constructor = ENoEntry;
- function EBusy(){ Error.apply(this, arguments); }
+ function EBusy(message){
+ this.message = message || '';
+ };
EBusy.prototype = new Error();
EBusy.prototype.name = "EBusy";
EBusy.prototype.constructor = EBusy;
- function ENotEmpty(){ Error.apply(this, arguments); }
+ function ENotEmpty(message){
+ this.message = message || '';
+ };
ENotEmpty.prototype = new Error();
ENotEmpty.prototype.name = "ENotEmpty";
ENotEmpty.prototype.constructor = ENotEmpty;
- function ENotDirectory(){ Error.apply(this, arguments); }
+ function ENotDirectory(message){
+ this.message = message || '';
+ };
ENotDirectory.prototype = new Error();
- ENotDirectory.prototype.name = "NotADirectoryError";
+ ENotDirectory.prototype.name = "ENotDirectory";
ENotDirectory.prototype.constructor = ENotDirectory;
- function EBadFileDescriptor(){ Error.apply(this, arguments); }
+ function EBadFileDescriptor(message){
+ this.message = message || '';
+ };
EBadFileDescriptor.prototype = new Error();
EBadFileDescriptor.prototype.name = "EBadFileDescriptor";
EBadFileDescriptor.prototype.constructor = EBadFileDescriptor;
- function ENotImplemented(){ Error.apply(this, arguments); }
+ function ENotImplemented(message){
+ this.message = message || '';
+ };
ENotImplemented.prototype = new Error();
ENotImplemented.prototype.name = "ENotImplemented";
ENotImplemented.prototype.constructor = ENotImplemented;
- function ENotMounted(){ Error.apply(this, arguments); }
+ function ENotMounted(message){
+ this.message = message || '';
+ };
ENotMounted.prototype = new Error();
ENotMounted.prototype.name = "ENotMounted";
ENotMounted.prototype.constructor = ENotMounted;
- function EFileExists(){ Error.apply(this, arguments); }
- EFileExists.prototype = new Error();
- EFileExists.prototype.name = "EFileExists";
- EFileExists.prototype.constructor = EFileExists;
+ function EInvalid(message){
+ this.message = message || '';
+ };
+ EInvalid.prototype = new Error();
+ EInvalid.prototype.name = "EInvalid";
+ EInvalid.prototype.constructor = EInvalid;
+
+ function EIO(message){
+ this.message = message || '';
+ };
+ EIO.prototype = new Error();
+ EIO.prototype.name = "EIO";
+ EIO.prototype.constructor = EIO;
return {
- EPathExists: EPathExists,
+ EExists: EExists,
EIsDirectory: EIsDirectory,
ENoEntry: ENoEntry,
EBusy: EBusy,
@@ -74,7 +101,8 @@ define(function(require) {
EBadFileDescriptor: EBadFileDescriptor,
ENotImplemented: ENotImplemented,
ENotMounted: ENotMounted,
- EFileExists: EFileExists
+ EInvalid: EInvalid,
+ EIO: EIO,
};
});
\ No newline at end of file
diff --git a/src/file-system.js b/src/file-system.js
index f3cc63b..c3b0943 100644
--- a/src/file-system.js
+++ b/src/file-system.js
@@ -9,7 +9,7 @@ define(function(require) {
var hash = require('src/shared').hash;
var nop = require('src/shared').nop;
- var EPathExists = require('src/error').EPathExists;
+ var EExists = require('src/error').EExists;
var EIsDirectory = require('src/error').EIsDirectory;
var ENoEntry = require('src/error').ENoEntry;
var EBusy = require('src/error').EBusy;
@@ -18,7 +18,7 @@ define(function(require) {
var EBadFileDescriptor = require('src/error').EBadFileDescriptor;
var ENotImplemented = require('src/error').ENotImplemented;
var ENotMounted = require('src/error').ENotMounted;
- var EFileExists = require('src/error').EFileExists;
+ var EInvalid = require('src/error').EInvalid;
var FS_FORMAT = require('src/constants').FS_FORMAT;
@@ -100,21 +100,21 @@ define(function(require) {
this.readyState = FS_PENDING;
this.db = null;
};
- FileSystem.prototype.open = function open(path, flags, mode) {
+ FileSystem.prototype.open = function open(path, flags) {
var deferred = when.defer();
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
function check_result(error, fd) {
if(error) {
- if(transaction.error) transaction.abort();
+ // if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve();
}
};
- open_file(files, path, flags, mode, check_result);
+ open_file(files, path, flags, check_result);
return deferred.promise;
};
diff --git a/src/file.js b/src/file.js
index 803027c..bb0df9b 100644
--- a/src/file.js
+++ b/src/file.js
@@ -16,7 +16,15 @@ define(function(require) {
var delete_object = require('src/object-store').delete_object;
var find_node = require('src/object-store').find_node;
+ var O_READ = require('src/constants').O_READ;
+ var O_WRITE = require('src/constants').O_WRITE;
var O_CREATE = require('src/constants').O_CREATE;
+ var O_EXCLUSIVE = require('src/constants').O_EXCLUSIVE;
+ var O_TRUNCATE = require('src/constants').O_TRUNCATE;
+ var O_APPEND = require('src/constants').O_APPEND;
+ var O_FLAGS = require('src/constants').O_FLAGS;
+
+ var EInvalid = require('src/error').EInvalid;
function DirectoryEntry(id, type) {
this.id = id;
@@ -39,15 +47,24 @@ define(function(require) {
this.data = hash(this.id) // id for data object
};
- function open_file(objectStore, path, flags, mode, callback) {
+ function open_file(objectStore, path, flags, callback) {
path = normalize(path);
var name = basename(path);
+ var parentPath = dirname(path);
var directoryNode;
var directoryData;
var fileNode;
var fileData;
+ if(!_(O_FLAGS).has(flags)) {
+ return callback(new EInvalid('flags is not valid'));
+ } else {
+ flags = O_FLAGS[flags];
+ }
+
+ find_node(objectStore, parentPath, read_directory_data);
+
function read_directory_data(error, result) {
if(error) {
callback(error);
@@ -63,12 +80,14 @@ define(function(require) {
} else {
directoryData = result;
if(_(directoryData).has(name)) {
- // file exists
+ if(_(flags).contains(O_EXCLUSIVE)) {
+ callback(new ENoEntry('O_CREATE and O_EXCLUSIVE are set, and the named file exists'))
+ }
} else {
- if(_(flags).contains(O_CREATE)) {
- write_file_node();
+ if(!_(flags).contains(O_CREATE)) {
+ callback(new ENoEntry('O_CREATE is not set and the named file does not exist'));
} else {
- callback(error);
+ write_file_node();
}
}
}
@@ -105,9 +124,6 @@ define(function(require) {
callback(undefined, '!');
}
};
-
- var parentPath = dirname(path);
- find_node(objectStore, parentPath, read_directory_data);
};
return {
diff --git a/src/object-store.js b/src/object-store.js
index 1022377..8e6e944 100644
--- a/src/object-store.js
+++ b/src/object-store.js
@@ -2,7 +2,7 @@ define(function(require) {
var ENoEntry = require('src/error').ENoEntry;
var ENotDirectory = require('src/error').ENotDirectory;
- var EPathExists = require('src/error').EPathExists;
+ var EExists = require('src/error').EExists;
var normalize = require('src/path').normalize;
var dirname = require('src/path').dirname;
@@ -17,6 +17,9 @@ define(function(require) {
// out: node structure, or error
function find_node(objectStore, path, callback) {
path = normalize(path);
+ if(!path) {
+ return callback(new ENoEntry('path is an empty string'));
+ }
var name = basename(path);
if(ROOT_DIRECTORY_NAME == name) {
@@ -24,7 +27,7 @@ define(function(require) {
if(error) {
callback(error);
} else if(!rootDirectoryNode) {
- callback(new ENoEntry());
+ callback(new ENoEntry('path does not exist'));
} else {
callback(undefined, rootDirectoryNode);
}
@@ -38,7 +41,7 @@ define(function(require) {
if(error) {
callback(error);
} else if(!_(parentDirectoryNode).has('data') || !parentDirectoryNode.type == MODE_DIRECTORY) {
- callback(new ENotDirectory());
+ callback(new ENotDirectory('a component of the path prefix is not a directory'));
} else {
read_object(objectStore, parentDirectoryNode.data, get_node_id_from_parent_directory_data);
}
@@ -51,7 +54,7 @@ define(function(require) {
callback(error);
} else {
if(!_(parentDirectoryData).has(name)) {
- callback(new ENoEntry());
+ callback(new ENoEntry('path does not exist'));
} else {
var nodeId = parentDirectoryData[name].id;
read_object(objectStore, nodeId, callback);