More tests, updated implementation.

This commit is contained in:
Alan Kligman 2013-07-22 13:08:35 -04:00
parent d3d7dcabde
commit 40d3f25d9a
4 changed files with 363 additions and 119 deletions

151
dist/idbfs.js vendored
View File

@ -6185,7 +6185,15 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p
var fileNode;
var fileData;
find_node(objectStore, parentPath, read_directory_data);
if(ROOT_DIRECTORY_NAME == name) {
if(_(flags).contains(O_WRITE)) {
callback(new EIsDirectory('the named file is a directory and O_WRITE is set'))
} else {
find_node(objectStore, path, set_file_node);
}
} else {
find_node(objectStore, parentPath, read_directory_data);
}
function read_directory_data(error, result) {
if(error) {
@ -6241,7 +6249,7 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p
if(error) {
callback(error);
} else {
fileData = {};
fileData = new Uint8Array(0);
write_object(objectStore, fileData, fileNode.data, update_directory_data);
}
};
@ -6299,7 +6307,7 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p
fileNode.mtime = Date.now();
fileNode.version += 1;
write_object(objectStore, fileNode.data, update_file_node);
write_object(objectStore, newData, fileNode.data, update_file_node);
}
};
@ -6307,7 +6315,7 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p
if(error) {
callback(error);
} else {
write_object(objectStore, fileNode.id, return_nbytes);
write_object(objectStore, fileNode, fileNode.id, return_nbytes);
}
};
@ -6315,7 +6323,7 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p
if(error) {
callback(error);
} else {
callback(undefined, nbytes);
callback(undefined, length);
}
};
};
@ -6343,6 +6351,7 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p
var _position = (undefined !== position) ? position : ofd.position;
length = (_position + length > buffer.length) ? length - _position : length;
var dataView = fileData.subarray(_position, _position + length);
buffer.set(dataView, offset);
if(undefined === position) {
ofd.position += length;
}
@ -6624,67 +6633,93 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p
};
FileSystem.prototype.read = function read(fd, buffer, offset, length, position, callback) {
var deferred = when.defer();
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
var that = this;
this.promise.then(
function() {
var deferred = when.defer();
var transaction = that.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
offset = (undefined === offset) ? 0 : offset;
length = (undefined === length) ? buffer.length - offset : length;
offset = (undefined === offset) ? 0 : offset;
length = (undefined === length) ? buffer.length - offset : length;
function check_result(error, nbytes) {
if(error) {
// if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve(nbytes);
function check_result(error, nbytes) {
if(error) {
// if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve(nbytes);
}
};
var ofd = that.openFiles[fd];
if(!ofd) {
deferred.reject(new EBadFileDescriptor('invalid file descriptor'));
} else if(!_(ofd.flags).contains(O_READ)) {
deferred.reject(new EBadFileDescriptor('descriptor does not permit reading'));
} else {
read_data(files, ofd, buffer, offset, length, position, check_result);
}
deferred.promise.then(
function(result) {
callback(undefined, result);
},
function(error) {
callback(error);
}
);
},
function() {
callback(new EFileSystemError('unknown error'));
}
};
var ofd = this.openFiles[fd];
if(!ofd) {
deferred.reject(new EBadFileDescriptor('invalid file descriptor'));
} else if(!_(flags).contains(O_READ)) {
deferred.reject(new EBadFileDescriptor('descriptor does not permit reading'));
} else {
read_data(files, ofd, buffer, offset, length, position, check_result);
}
// TODO: check buffer length
return deferred.promise;
);
};
FileSystem.prototype.write = function write(fd, buffer, offset, length, position, callback) {
var deferred = when.defer();
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
var that = this;
this.promise.then(
function() {
var deferred = when.defer();
var transaction = that.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
offset = (undefined === offset) ? 0 : offset;
length = (undefined === length) ? buffer.length - offset : length;
offset = (undefined === offset) ? 0 : offset;
length = (undefined === length) ? buffer.length - offset : length;
function check_result(error, nbytes) {
if(error) {
deferred.reject(error);
} else {
deferred.resolve(nbytes);
function check_result(error, nbytes) {
if(error) {
deferred.reject(error);
} else {
deferred.resolve(nbytes);
}
};
var ofd = that.openFiles[fd];
if(!ofd) {
deferred.reject(new EBadFileDescriptor('invalid file descriptor'));
} else if(!_(ofd.flags).contains(O_WRITE)) {
deferred.reject(new EBadFileDescriptor('descriptor does not permit writing'));
} else if(buffer.length - offset < length) {
deferred.reject(new EIO('intput buffer is too small'));
} else {
write_data(files, ofd, buffer, offset, length, position, check_result);
}
deferred.promise.then(
function(result) {
callback(undefined, result);
},
function(error) {
callback(error);
}
);
},
function() {
callback(new EFileSystemError('unknown error'));
}
};
var ofd = this.openFiles[fd];
if(!ofd) {
deferred.reject(new EBadFileDescriptor('invalid file descriptor'));
} else if(!_(flags).contains(O_WRITE)) {
deferred.reject(new EBadFileDescriptor('descriptor does not permit writing'));
} else if(buffer.length - offset < length) {
deferred.reject(new EIO('intput buffer is too small'));
} else {
write_data(files, ofd, buffer, offset, length, position, check_result);
}
// TODO: check buffer length
return deferred.promise;
);
};
FileSystem.prototype.seek = function seek(fd, offset, origin) {

View File

@ -21,8 +21,22 @@ var flags = 'FORMAT';
//var flags;
var fs = new IDBFS.FileSystem('local', flags);
fs.open('/', 'r', function(error, result) {
console.log('1', error, result);
var buffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
console.log('buffer', buffer);
var data = new Uint8Array(buffer.length);
console.log('data', data);
debugger;
fs.open('/myfile', 'w+', function(error, fd) {
if(error) throw error;
console.log('descriptor:', fd);
fs.write(fd, buffer, 0, buffer.length, 0, function(error, nbytes) {
console.log('write:', nbytes)
if(error) throw error;
fs.read(fd, data, 0, data.length, 0, function(error, nbytes) {
console.log('read:', nbytes);
console.log('data', data);
});
});
});
/*

View File

@ -449,7 +449,7 @@ define(function(require) {
if(error) {
callback(error);
} else {
fileData = {};
fileData = new Uint8Array(0);
write_object(objectStore, fileData, fileNode.data, update_directory_data);
}
};
@ -507,7 +507,7 @@ define(function(require) {
fileNode.mtime = Date.now();
fileNode.version += 1;
write_object(objectStore, fileNode.data, update_file_node);
write_object(objectStore, newData, fileNode.data, update_file_node);
}
};
@ -515,7 +515,7 @@ define(function(require) {
if(error) {
callback(error);
} else {
write_object(objectStore, fileNode.id, return_nbytes);
write_object(objectStore, fileNode, fileNode.id, return_nbytes);
}
};
@ -523,7 +523,7 @@ define(function(require) {
if(error) {
callback(error);
} else {
callback(undefined, nbytes);
callback(undefined, length);
}
};
};
@ -551,6 +551,7 @@ define(function(require) {
var _position = (undefined !== position) ? position : ofd.position;
length = (_position + length > buffer.length) ? length - _position : length;
var dataView = fileData.subarray(_position, _position + length);
buffer.set(dataView, offset);
if(undefined === position) {
ofd.position += length;
}
@ -832,67 +833,93 @@ define(function(require) {
};
FileSystem.prototype.read = function read(fd, buffer, offset, length, position, callback) {
var deferred = when.defer();
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
var that = this;
this.promise.then(
function() {
var deferred = when.defer();
var transaction = that.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
offset = (undefined === offset) ? 0 : offset;
length = (undefined === length) ? buffer.length - offset : length;
offset = (undefined === offset) ? 0 : offset;
length = (undefined === length) ? buffer.length - offset : length;
function check_result(error, nbytes) {
if(error) {
// if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve(nbytes);
function check_result(error, nbytes) {
if(error) {
// if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve(nbytes);
}
};
var ofd = that.openFiles[fd];
if(!ofd) {
deferred.reject(new EBadFileDescriptor('invalid file descriptor'));
} else if(!_(ofd.flags).contains(O_READ)) {
deferred.reject(new EBadFileDescriptor('descriptor does not permit reading'));
} else {
read_data(files, ofd, buffer, offset, length, position, check_result);
}
deferred.promise.then(
function(result) {
callback(undefined, result);
},
function(error) {
callback(error);
}
);
},
function() {
callback(new EFileSystemError('unknown error'));
}
};
var ofd = this.openFiles[fd];
if(!ofd) {
deferred.reject(new EBadFileDescriptor('invalid file descriptor'));
} else if(!_(flags).contains(O_READ)) {
deferred.reject(new EBadFileDescriptor('descriptor does not permit reading'));
} else {
read_data(files, ofd, buffer, offset, length, position, check_result);
}
// TODO: check buffer length
return deferred.promise;
);
};
FileSystem.prototype.write = function write(fd, buffer, offset, length, position, callback) {
var deferred = when.defer();
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
var that = this;
this.promise.then(
function() {
var deferred = when.defer();
var transaction = that.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
offset = (undefined === offset) ? 0 : offset;
length = (undefined === length) ? buffer.length - offset : length;
offset = (undefined === offset) ? 0 : offset;
length = (undefined === length) ? buffer.length - offset : length;
function check_result(error, nbytes) {
if(error) {
deferred.reject(error);
} else {
deferred.resolve(nbytes);
function check_result(error, nbytes) {
if(error) {
deferred.reject(error);
} else {
deferred.resolve(nbytes);
}
};
var ofd = that.openFiles[fd];
if(!ofd) {
deferred.reject(new EBadFileDescriptor('invalid file descriptor'));
} else if(!_(ofd.flags).contains(O_WRITE)) {
deferred.reject(new EBadFileDescriptor('descriptor does not permit writing'));
} else if(buffer.length - offset < length) {
deferred.reject(new EIO('intput buffer is too small'));
} else {
write_data(files, ofd, buffer, offset, length, position, check_result);
}
deferred.promise.then(
function(result) {
callback(undefined, result);
},
function(error) {
callback(error);
}
);
},
function() {
callback(new EFileSystemError('unknown error'));
}
};
var ofd = this.openFiles[fd];
if(!ofd) {
deferred.reject(new EBadFileDescriptor('invalid file descriptor'));
} else if(!_(flags).contains(O_WRITE)) {
deferred.reject(new EBadFileDescriptor('descriptor does not permit writing'));
} else if(buffer.length - offset < length) {
deferred.reject(new EIO('intput buffer is too small'));
} else {
write_data(files, ofd, buffer, offset, length, position, check_result);
}
// TODO: check buffer length
return deferred.promise;
);
};
FileSystem.prototype.seek = function seek(fd, offset, origin) {

View File

@ -24,6 +24,24 @@ function mk_db_name() {
return name;
};
function array_buffer_equal(left, right) {
if(!(left instanceof ArrayBuffer && right instanceof ArrayBuffer)) {
return false;
}
if(left.byteLength !== right.byteLength) {
return false;
}
for(var i = 0; i < left.byteLength; ++ i) {
if(left[i] !== right[i]) {
return false;
}
}
return true;
};
describe("IDBFS", function() {
it("is defined", function() {
expect(typeof IDBFS).not.toEqual(undefined);
@ -431,8 +449,158 @@ describe('fs.open', function() {
expect(_result).not.toBeDefined();
});
});
/*
it('should return a unique file descriptor', function() {
var complete1 = false;
var complete2 = false;
var _error, _result1, _result2;
var that = this;
that.fs.open('/file1', 'w+', function(error, fd) {
if(error) throw error;
_error = error;
_result1 = fd;
complete1 = true;
});
that.fs.open('/file2', 'w+', function(error, fd) {
if(error) throw error;
_error = error;
_result2 = fd;
complete2 = true;
});
waitsFor(function() {
return complete1 && complete2;
}, 'test to complete', DEFAULT_TIMEOUT);
runs(function() {
expect(_error).not.toBeDefined();
expect(_result1).toBeDefined();
expect(_result2).toBeDefined();
expect(_result1).not.toEqual(_result2);
});
});
it('should create a new file when flagged for write', function() {
var complete = false;
var _error, _result;
var that = this;
that.fs.open('/myfile', 'w', function(error, result) {
if(error) throw error;
that.fs.stat('/myfile', function(error, result) {
_error = error;
_result = result;
complete = true;
})
});
waitsFor(function() {
return complete;
}, 'test to complete', DEFAULT_TIMEOUT);
runs(function() {
expect(_error).not.toBeDefined();
expect(_result).toBeDefined();
});
});
});
describe('fs.write', function() {
beforeEach(function() {
this.db_name = mk_db_name();
this.fs = new IDBFS.FileSystem(this.db_name, 'FORMAT');
});
afterEach(function() {
indexedDB.deleteDatabase(this.db_name);
delete this.fs;
});
it('should be a function', function() {
expect(typeof this.fs.write).toEqual('function');
});
it('should write data to a file', function() {
var complete = false;
var _error, _result;
var that = this;
var buffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
that.fs.open('/myfile', 'w', function(error, result) {
if(error) throw error;
var fd = result;
that.fs.write(fd, buffer, 0, buffer.length, 0, function(error, result) {
_error = error;
_result = result;
complete = true;
})
});
waitsFor(function() {
return complete;
}, 'test to complete', DEFAULT_TIMEOUT);
runs(function() {
expect(_error).not.toBeDefined();
expect(_result).toEqual(buffer.length);
});
});
});
describe('fs.read', function() {
beforeEach(function() {
this.db_name = mk_db_name();
this.fs = new IDBFS.FileSystem(this.db_name, 'FORMAT');
});
afterEach(function() {
indexedDB.deleteDatabase(this.db_name);
delete this.fs;
});
it('should be a function', function() {
expect(typeof this.fs.read).toEqual('function');
});
it('should read data from a file', function() {
var complete = false;
var _error, _result;
var that = this;
var wbuffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
var rbuffer = new Uint8Array(wbuffer.length);
that.fs.open('/myfile', 'w+', function(error, result) {
if(error) throw error;
var fd = result;
that.fs.write(fd, wbuffer, 0, wbuffer.length, 0, function(error, result) {
if(error) throw error;
that.fs.read(fd, rbuffer, 0, rbuffer.length, 0, function(error, result) {
_error = error;
_result = result;
complete = true;
});
})
});
waitsFor(function() {
return complete;
}, 'test to complete', DEFAULT_TIMEOUT);
runs(function() {
expect(_error).not.toBeDefined();
expect(_result).toEqual(rbuffer.length);
expect(array_buffer_equal(wbuffer.buffer, rbuffer.buffer)).toEqual(true);
});
});
*/
});