WIP
This commit is contained in:
parent
5bef87490c
commit
2d195ff6d6
|
@ -36,13 +36,13 @@ function remove_tmp_directory() {
|
||||||
};
|
};
|
||||||
|
|
||||||
function create_tmp_file() {
|
function create_tmp_file() {
|
||||||
return fs.open('/tmp/1', 'CREATE');
|
return fs.open('/tmp/1', 'w+');
|
||||||
};
|
};
|
||||||
|
|
||||||
fs.promise.then(make_tmp_directory)
|
fs.promise.then(make_tmp_directory)
|
||||||
.then(create_tmp_file)
|
.then(create_tmp_file)
|
||||||
.then(function() { console.log('done'); })
|
.then(function() { console.log('done'); })
|
||||||
.otherwise(function(error) { console.error(error, error.stack); });
|
.otherwise(function(error) { console.error(error, error.message); });
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
define(function(require) {
|
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 {
|
return {
|
||||||
METADATA_STORE_NAME: 'metadata',
|
METADATA_STORE_NAME: 'metadata',
|
||||||
FILE_STORE_NAME: 'files',
|
FILE_STORE_NAME: 'files',
|
||||||
|
@ -17,17 +24,28 @@ define(function(require) {
|
||||||
ROOT_DIRECTORY_NAME: '/', // basename(normalize(path))
|
ROOT_DIRECTORY_NAME: '/', // basename(normalize(path))
|
||||||
ROOT_NODE_ID: '8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1', // sha256(ROOT_DIRECTORY_NAME)
|
ROOT_NODE_ID: '8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1', // sha256(ROOT_DIRECTORY_NAME)
|
||||||
|
|
||||||
// FileSystem flags
|
|
||||||
FS_FORMAT: 'FORMAT',
|
FS_FORMAT: 'FORMAT',
|
||||||
|
|
||||||
// Open flags
|
O_READ: O_READ,
|
||||||
O_READONLY: 'READONLY',
|
O_WRITE: O_WRITE,
|
||||||
O_READWRITE: 'READWRITE',
|
O_CREATE: O_CREATE,
|
||||||
O_APPEND: 'APPEND',
|
O_EXCLUSIVE: O_EXCLUSIVE,
|
||||||
O_CREATE: 'CREATE',
|
O_TRUNCATE: O_TRUNCATE,
|
||||||
O_TRUNCATE: '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_READY: 'READY',
|
||||||
FS_PENDING: 'PENDING',
|
FS_PENDING: 'PENDING',
|
||||||
FS_ERROR: 'ERROR',
|
FS_ERROR: 'ERROR',
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
define(function(require) {
|
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 {
|
return {
|
||||||
Descriptor: Descriptor,
|
Descriptor: Descriptor
|
||||||
};
|
}
|
||||||
|
|
||||||
});
|
});
|
|
@ -7,7 +7,7 @@ define(function(require) {
|
||||||
|
|
||||||
var ENoEntry = require('src/error').ENoEntry;
|
var ENoEntry = require('src/error').ENoEntry;
|
||||||
var ENotDirectory = require('src/error').ENotDirectory;
|
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_FILE = require('src/constants').MODE_FILE;
|
||||||
var MODE_DIRECTORY = require('src/constants').MODE_DIRECTORY;
|
var MODE_DIRECTORY = require('src/constants').MODE_DIRECTORY;
|
||||||
|
@ -28,7 +28,7 @@ define(function(require) {
|
||||||
|
|
||||||
function write_directory_node(error, existingNode) {
|
function write_directory_node(error, existingNode) {
|
||||||
if(!error && existingNode) {
|
if(!error && existingNode) {
|
||||||
callback(new EPathExists());
|
callback(new EExists());
|
||||||
} else if(error && !error instanceof ENoEntry) {
|
} else if(error && !error instanceof ENoEntry) {
|
||||||
callback(error);
|
callback(error);
|
||||||
} else {
|
} else {
|
||||||
|
@ -62,7 +62,7 @@ define(function(require) {
|
||||||
|
|
||||||
function check_if_directory_exists(error, result) {
|
function check_if_directory_exists(error, result) {
|
||||||
if(!error && result) {
|
if(!error && result) {
|
||||||
callback(new EPathExists());
|
callback(new EExists());
|
||||||
} else if(error && !error instanceof ENoEntry) {
|
} else if(error && !error instanceof ENoEntry) {
|
||||||
callback(error);
|
callback(error);
|
||||||
} else {
|
} else {
|
||||||
|
|
66
src/error.js
66
src/error.js
|
@ -14,58 +14,85 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
define(function(require) {
|
define(function(require) {
|
||||||
// 'use strict';
|
// 'use strict';
|
||||||
|
|
||||||
function EPathExists(){ Error.apply(this, arguments); }
|
function EExists(message){
|
||||||
EPathExists.prototype = new Error();
|
this.message = message || '';
|
||||||
EPathExists.prototype.name = "EPathExists";
|
};
|
||||||
EPathExists.prototype.constructor = EPathExists;
|
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 = new Error();
|
||||||
EIsDirectory.prototype.name = "EIsDirectory";
|
EIsDirectory.prototype.name = "EIsDirectory";
|
||||||
EIsDirectory.prototype.constructor = EIsDirectory;
|
EIsDirectory.prototype.constructor = EIsDirectory;
|
||||||
|
|
||||||
function ENoEntry(){ Error.apply(this, arguments); }
|
function ENoEntry(message){
|
||||||
|
this.message = message || '';
|
||||||
|
};
|
||||||
ENoEntry.prototype = new Error();
|
ENoEntry.prototype = new Error();
|
||||||
ENoEntry.prototype.name = "ENoEntry";
|
ENoEntry.prototype.name = "ENoEntry";
|
||||||
ENoEntry.prototype.constructor = ENoEntry;
|
ENoEntry.prototype.constructor = ENoEntry;
|
||||||
|
|
||||||
function EBusy(){ Error.apply(this, arguments); }
|
function EBusy(message){
|
||||||
|
this.message = message || '';
|
||||||
|
};
|
||||||
EBusy.prototype = new Error();
|
EBusy.prototype = new Error();
|
||||||
EBusy.prototype.name = "EBusy";
|
EBusy.prototype.name = "EBusy";
|
||||||
EBusy.prototype.constructor = EBusy;
|
EBusy.prototype.constructor = EBusy;
|
||||||
|
|
||||||
function ENotEmpty(){ Error.apply(this, arguments); }
|
function ENotEmpty(message){
|
||||||
|
this.message = message || '';
|
||||||
|
};
|
||||||
ENotEmpty.prototype = new Error();
|
ENotEmpty.prototype = new Error();
|
||||||
ENotEmpty.prototype.name = "ENotEmpty";
|
ENotEmpty.prototype.name = "ENotEmpty";
|
||||||
ENotEmpty.prototype.constructor = ENotEmpty;
|
ENotEmpty.prototype.constructor = ENotEmpty;
|
||||||
|
|
||||||
function ENotDirectory(){ Error.apply(this, arguments); }
|
function ENotDirectory(message){
|
||||||
|
this.message = message || '';
|
||||||
|
};
|
||||||
ENotDirectory.prototype = new Error();
|
ENotDirectory.prototype = new Error();
|
||||||
ENotDirectory.prototype.name = "NotADirectoryError";
|
ENotDirectory.prototype.name = "ENotDirectory";
|
||||||
ENotDirectory.prototype.constructor = ENotDirectory;
|
ENotDirectory.prototype.constructor = ENotDirectory;
|
||||||
|
|
||||||
function EBadFileDescriptor(){ Error.apply(this, arguments); }
|
function EBadFileDescriptor(message){
|
||||||
|
this.message = message || '';
|
||||||
|
};
|
||||||
EBadFileDescriptor.prototype = new Error();
|
EBadFileDescriptor.prototype = new Error();
|
||||||
EBadFileDescriptor.prototype.name = "EBadFileDescriptor";
|
EBadFileDescriptor.prototype.name = "EBadFileDescriptor";
|
||||||
EBadFileDescriptor.prototype.constructor = EBadFileDescriptor;
|
EBadFileDescriptor.prototype.constructor = EBadFileDescriptor;
|
||||||
|
|
||||||
function ENotImplemented(){ Error.apply(this, arguments); }
|
function ENotImplemented(message){
|
||||||
|
this.message = message || '';
|
||||||
|
};
|
||||||
ENotImplemented.prototype = new Error();
|
ENotImplemented.prototype = new Error();
|
||||||
ENotImplemented.prototype.name = "ENotImplemented";
|
ENotImplemented.prototype.name = "ENotImplemented";
|
||||||
ENotImplemented.prototype.constructor = ENotImplemented;
|
ENotImplemented.prototype.constructor = ENotImplemented;
|
||||||
|
|
||||||
function ENotMounted(){ Error.apply(this, arguments); }
|
function ENotMounted(message){
|
||||||
|
this.message = message || '';
|
||||||
|
};
|
||||||
ENotMounted.prototype = new Error();
|
ENotMounted.prototype = new Error();
|
||||||
ENotMounted.prototype.name = "ENotMounted";
|
ENotMounted.prototype.name = "ENotMounted";
|
||||||
ENotMounted.prototype.constructor = ENotMounted;
|
ENotMounted.prototype.constructor = ENotMounted;
|
||||||
|
|
||||||
function EFileExists(){ Error.apply(this, arguments); }
|
function EInvalid(message){
|
||||||
EFileExists.prototype = new Error();
|
this.message = message || '';
|
||||||
EFileExists.prototype.name = "EFileExists";
|
};
|
||||||
EFileExists.prototype.constructor = EFileExists;
|
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 {
|
return {
|
||||||
EPathExists: EPathExists,
|
EExists: EExists,
|
||||||
EIsDirectory: EIsDirectory,
|
EIsDirectory: EIsDirectory,
|
||||||
ENoEntry: ENoEntry,
|
ENoEntry: ENoEntry,
|
||||||
EBusy: EBusy,
|
EBusy: EBusy,
|
||||||
|
@ -74,7 +101,8 @@ define(function(require) {
|
||||||
EBadFileDescriptor: EBadFileDescriptor,
|
EBadFileDescriptor: EBadFileDescriptor,
|
||||||
ENotImplemented: ENotImplemented,
|
ENotImplemented: ENotImplemented,
|
||||||
ENotMounted: ENotMounted,
|
ENotMounted: ENotMounted,
|
||||||
EFileExists: EFileExists
|
EInvalid: EInvalid,
|
||||||
|
EIO: EIO,
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
|
@ -9,7 +9,7 @@ define(function(require) {
|
||||||
var hash = require('src/shared').hash;
|
var hash = require('src/shared').hash;
|
||||||
var nop = require('src/shared').nop;
|
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 EIsDirectory = require('src/error').EIsDirectory;
|
||||||
var ENoEntry = require('src/error').ENoEntry;
|
var ENoEntry = require('src/error').ENoEntry;
|
||||||
var EBusy = require('src/error').EBusy;
|
var EBusy = require('src/error').EBusy;
|
||||||
|
@ -18,7 +18,7 @@ define(function(require) {
|
||||||
var EBadFileDescriptor = require('src/error').EBadFileDescriptor;
|
var EBadFileDescriptor = require('src/error').EBadFileDescriptor;
|
||||||
var ENotImplemented = require('src/error').ENotImplemented;
|
var ENotImplemented = require('src/error').ENotImplemented;
|
||||||
var ENotMounted = require('src/error').ENotMounted;
|
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;
|
var FS_FORMAT = require('src/constants').FS_FORMAT;
|
||||||
|
|
||||||
|
@ -100,21 +100,21 @@ define(function(require) {
|
||||||
this.readyState = FS_PENDING;
|
this.readyState = FS_PENDING;
|
||||||
this.db = null;
|
this.db = null;
|
||||||
};
|
};
|
||||||
FileSystem.prototype.open = function open(path, flags, mode) {
|
FileSystem.prototype.open = function open(path, flags) {
|
||||||
var deferred = when.defer();
|
var deferred = when.defer();
|
||||||
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
|
|
||||||
function check_result(error, fd) {
|
function check_result(error, fd) {
|
||||||
if(error) {
|
if(error) {
|
||||||
if(transaction.error) transaction.abort();
|
// if(transaction.error) transaction.abort();
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
open_file(files, path, flags, mode, check_result);
|
open_file(files, path, flags, check_result);
|
||||||
|
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
32
src/file.js
32
src/file.js
|
@ -16,7 +16,15 @@ define(function(require) {
|
||||||
var delete_object = require('src/object-store').delete_object;
|
var delete_object = require('src/object-store').delete_object;
|
||||||
var find_node = require('src/object-store').find_node;
|
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_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) {
|
function DirectoryEntry(id, type) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -39,15 +47,24 @@ define(function(require) {
|
||||||
this.data = hash(this.id) // id for data object
|
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);
|
path = normalize(path);
|
||||||
var name = basename(path);
|
var name = basename(path);
|
||||||
|
var parentPath = dirname(path);
|
||||||
|
|
||||||
var directoryNode;
|
var directoryNode;
|
||||||
var directoryData;
|
var directoryData;
|
||||||
var fileNode;
|
var fileNode;
|
||||||
var fileData;
|
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) {
|
function read_directory_data(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
callback(error);
|
callback(error);
|
||||||
|
@ -63,12 +80,14 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
directoryData = result;
|
directoryData = result;
|
||||||
if(_(directoryData).has(name)) {
|
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)) {
|
||||||
|
callback(new ENoEntry('O_CREATE is not set and the named file does not exist'));
|
||||||
} else {
|
} else {
|
||||||
if(_(flags).contains(O_CREATE)) {
|
|
||||||
write_file_node();
|
write_file_node();
|
||||||
} else {
|
|
||||||
callback(error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,9 +124,6 @@ define(function(require) {
|
||||||
callback(undefined, '!');
|
callback(undefined, '!');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var parentPath = dirname(path);
|
|
||||||
find_node(objectStore, parentPath, read_directory_data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -2,7 +2,7 @@ define(function(require) {
|
||||||
|
|
||||||
var ENoEntry = require('src/error').ENoEntry;
|
var ENoEntry = require('src/error').ENoEntry;
|
||||||
var ENotDirectory = require('src/error').ENotDirectory;
|
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 normalize = require('src/path').normalize;
|
||||||
var dirname = require('src/path').dirname;
|
var dirname = require('src/path').dirname;
|
||||||
|
@ -17,6 +17,9 @@ define(function(require) {
|
||||||
// out: node structure, or error
|
// out: node structure, or error
|
||||||
function find_node(objectStore, path, callback) {
|
function find_node(objectStore, path, callback) {
|
||||||
path = normalize(path);
|
path = normalize(path);
|
||||||
|
if(!path) {
|
||||||
|
return callback(new ENoEntry('path is an empty string'));
|
||||||
|
}
|
||||||
var name = basename(path);
|
var name = basename(path);
|
||||||
|
|
||||||
if(ROOT_DIRECTORY_NAME == name) {
|
if(ROOT_DIRECTORY_NAME == name) {
|
||||||
|
@ -24,7 +27,7 @@ define(function(require) {
|
||||||
if(error) {
|
if(error) {
|
||||||
callback(error);
|
callback(error);
|
||||||
} else if(!rootDirectoryNode) {
|
} else if(!rootDirectoryNode) {
|
||||||
callback(new ENoEntry());
|
callback(new ENoEntry('path does not exist'));
|
||||||
} else {
|
} else {
|
||||||
callback(undefined, rootDirectoryNode);
|
callback(undefined, rootDirectoryNode);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +41,7 @@ define(function(require) {
|
||||||
if(error) {
|
if(error) {
|
||||||
callback(error);
|
callback(error);
|
||||||
} else if(!_(parentDirectoryNode).has('data') || !parentDirectoryNode.type == MODE_DIRECTORY) {
|
} 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 {
|
} else {
|
||||||
read_object(objectStore, parentDirectoryNode.data, get_node_id_from_parent_directory_data);
|
read_object(objectStore, parentDirectoryNode.data, get_node_id_from_parent_directory_data);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +54,7 @@ define(function(require) {
|
||||||
callback(error);
|
callback(error);
|
||||||
} else {
|
} else {
|
||||||
if(!_(parentDirectoryData).has(name)) {
|
if(!_(parentDirectoryData).has(name)) {
|
||||||
callback(new ENoEntry());
|
callback(new ENoEntry('path does not exist'));
|
||||||
} else {
|
} else {
|
||||||
var nodeId = parentDirectoryData[name].id;
|
var nodeId = parentDirectoryData[name].id;
|
||||||
read_object(objectStore, nodeId, callback);
|
read_object(objectStore, nodeId, callback);
|
||||||
|
|
Loading…
Reference in New Issue