Merge pull request #6 from humphd/utf8
Add fs.readFile, fs.writeFile with tests
This commit is contained in:
commit
c590f930e5
|
@ -1 +1,2 @@
|
||||||
node_modules
|
node_modules
|
||||||
|
*~
|
||||||
|
|
34
README.md
34
README.md
|
@ -97,12 +97,46 @@ Write bytes from `buffer` to the file specified by `fd`, where `offset` and `len
|
||||||
|
|
||||||
The callback gets `(error, nbytes)`, where `nbytes` is the number of bytes written.
|
The callback gets `(error, nbytes)`, where `nbytes` is the number of bytes written.
|
||||||
|
|
||||||
|
#### fs.writeFile(filename, data, [options], callback)
|
||||||
|
|
||||||
|
Asynchronously writes data to a file. `data` can be a string or a buffer, in which case any encoding option is ignored. The `options` argument is optional, and can take the form `"utf8"` (i.e., an encoding) or be an object literal: `{ encoding: "utf8", flag: "w" }`. If no encoding is specified, and `data` is a string, the encoding defaults to `'utf8'`. The callback gets `(error)`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Write UTF8 text file
|
||||||
|
fs.writeFile('/myfile.txt', "...data...", function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Write binary file
|
||||||
|
fs.writeFile('/myfile', buffer, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
#### fs.read(fd, buffer, offset, length, position, callback)
|
#### fs.read(fd, buffer, offset, length, position, callback)
|
||||||
|
|
||||||
Read bytes from the file specified by `fd` into `buffer`, where `offset` and `length` describe the part of the buffer to be used. The `position` refers to the offset from the beginning of the file where this data should be read. If `position` is `null`, the data will be written at the current position. See pread(2).
|
Read bytes from the file specified by `fd` into `buffer`, where `offset` and `length` describe the part of the buffer to be used. The `position` refers to the offset from the beginning of the file where this data should be read. If `position` is `null`, the data will be written at the current position. See pread(2).
|
||||||
|
|
||||||
The callback gets `(error, nbytes)`, where `nbytes` is the number of bytes read.
|
The callback gets `(error, nbytes)`, where `nbytes` is the number of bytes read.
|
||||||
|
|
||||||
|
#### fs.readFile(filename, [options], callback)
|
||||||
|
|
||||||
|
Asynchronously reads the entire contents of a file. The `options` argument is optional, and can take the form `"utf8"` (i.e., an encoding) or be an object literal: `{ encoding: "utf8", flag: "r" }`. If no encoding is specified, the raw binary buffer is returned on the callback. The callback gets `(error, data)`, where data is the contents of the file.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Read UTF8 text file
|
||||||
|
fs.readFile('/myfile.txt', 'utf8', function (err, data) {
|
||||||
|
if (err) throw err;
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Read binary file
|
||||||
|
fs.readFile('/myfile.txt', function (err, data) {
|
||||||
|
if (err) throw err;
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
#### fs.lseek(fd, offset, whence, callback)
|
#### fs.lseek(fd, offset, whence, callback)
|
||||||
|
|
||||||
Asynchronous lseek(2), where `whence` can be `SET`, `CUR`, or `END`. Callback gets `(error, pos)`, where `pos` is the resulting offset, in bytes, from the beginning of the file.
|
Asynchronous lseek(2), where `whence` can be `SET`, `CUR`, or `END`. Callback gets `(error, pos)`, where `pos` is the resulting offset, in bytes, from the beginning of the file.
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -16,6 +16,11 @@ module.exports = function(grunt) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
jshint: {
|
||||||
|
// Don't bother with src/path.js
|
||||||
|
all: ['gruntfile.js', 'src/constants.js', 'src/error.js', 'src/fs.js', 'srs/shared.js']
|
||||||
|
},
|
||||||
|
|
||||||
requirejs: {
|
requirejs: {
|
||||||
develop: {
|
develop: {
|
||||||
options: {
|
options: {
|
||||||
|
@ -40,9 +45,11 @@ module.exports = function(grunt) {
|
||||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||||
grunt.loadNpmTasks('grunt-contrib-requirejs');
|
grunt.loadNpmTasks('grunt-contrib-requirejs');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||||
|
|
||||||
grunt.registerTask('develop', ['clean', 'requirejs']);
|
grunt.registerTask('develop', ['clean', 'requirejs']);
|
||||||
grunt.registerTask('release', ['develop', 'uglify']);
|
grunt.registerTask('release', ['develop', 'uglify']);
|
||||||
|
grunt.registerTask('check', ['jshint']);
|
||||||
|
|
||||||
grunt.registerTask('default', ['develop']);
|
grunt.registerTask('default', ['develop']);
|
||||||
};
|
};
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -10,6 +10,7 @@
|
||||||
"grunt-contrib-compress": "~0.4.1",
|
"grunt-contrib-compress": "~0.4.1",
|
||||||
"grunt-contrib-connect": "~0.1.2",
|
"grunt-contrib-connect": "~0.1.2",
|
||||||
"grunt-contrib-jasmine": "~0.3.3",
|
"grunt-contrib-jasmine": "~0.3.3",
|
||||||
"grunt-contrib-concat": "~0.1.3"
|
"grunt-contrib-concat": "~0.1.3",
|
||||||
|
"grunt-contrib-jshint": "~0.7.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ define(function(require) {
|
||||||
|
|
||||||
FS_READY: 'READY',
|
FS_READY: 'READY',
|
||||||
FS_PENDING: 'PENDING',
|
FS_PENDING: 'PENDING',
|
||||||
FS_ERROR: 'ERROR',
|
FS_ERROR: 'ERROR'
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
26
src/error.js
26
src/error.js
|
@ -16,84 +16,84 @@ define(function(require) {
|
||||||
|
|
||||||
function EExists(message){
|
function EExists(message){
|
||||||
this.message = message || '';
|
this.message = message || '';
|
||||||
};
|
}
|
||||||
EExists.prototype = new Error();
|
EExists.prototype = new Error();
|
||||||
EExists.prototype.name = "EExists";
|
EExists.prototype.name = "EExists";
|
||||||
EExists.prototype.constructor = EExists;
|
EExists.prototype.constructor = EExists;
|
||||||
|
|
||||||
function EIsDirectory(message){
|
function EIsDirectory(message){
|
||||||
this.message = 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(message){
|
function ENoEntry(message){
|
||||||
this.message = 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(message){
|
function EBusy(message){
|
||||||
this.message = 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(message){
|
function ENotEmpty(message){
|
||||||
this.message = 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(message){
|
function ENotDirectory(message){
|
||||||
this.message = message || '';
|
this.message = message || '';
|
||||||
};
|
}
|
||||||
ENotDirectory.prototype = new Error();
|
ENotDirectory.prototype = new Error();
|
||||||
ENotDirectory.prototype.name = "ENotDirectory";
|
ENotDirectory.prototype.name = "ENotDirectory";
|
||||||
ENotDirectory.prototype.constructor = ENotDirectory;
|
ENotDirectory.prototype.constructor = ENotDirectory;
|
||||||
|
|
||||||
function EBadFileDescriptor(message){
|
function EBadFileDescriptor(message){
|
||||||
this.message = 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(message){
|
function ENotImplemented(message){
|
||||||
this.message = 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(message){
|
function ENotMounted(message){
|
||||||
this.message = 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 EInvalid(message){
|
function EInvalid(message){
|
||||||
this.message = message || '';
|
this.message = message || '';
|
||||||
};
|
}
|
||||||
EInvalid.prototype = new Error();
|
EInvalid.prototype = new Error();
|
||||||
EInvalid.prototype.name = "EInvalid";
|
EInvalid.prototype.name = "EInvalid";
|
||||||
EInvalid.prototype.constructor = EInvalid;
|
EInvalid.prototype.constructor = EInvalid;
|
||||||
|
|
||||||
function EIO(message){
|
function EIO(message){
|
||||||
this.message = message || '';
|
this.message = message || '';
|
||||||
};
|
}
|
||||||
EIO.prototype = new Error();
|
EIO.prototype = new Error();
|
||||||
EIO.prototype.name = "EIO";
|
EIO.prototype.name = "EIO";
|
||||||
EIO.prototype.constructor = EIO;
|
EIO.prototype.constructor = EIO;
|
||||||
|
|
||||||
function EFileSystemError(message){
|
function EFileSystemError(message){
|
||||||
this.message = message || '';
|
this.message = message || '';
|
||||||
};
|
}
|
||||||
EFileSystemError.prototype = new Error();
|
EFileSystemError.prototype = new Error();
|
||||||
EFileSystemError.prototype.name = "EFileSystemError";
|
EFileSystemError.prototype.name = "EFileSystemError";
|
||||||
EFileSystemError.prototype.constructor = EFileSystemError;
|
EFileSystemError.prototype.constructor = EFileSystemError;
|
||||||
|
@ -109,7 +109,7 @@ define(function(require) {
|
||||||
ENotImplemented: ENotImplemented,
|
ENotImplemented: ENotImplemented,
|
||||||
ENotMounted: ENotMounted,
|
ENotMounted: ENotMounted,
|
||||||
EInvalid: EInvalid,
|
EInvalid: EInvalid,
|
||||||
EIO: EIO,
|
EIO: EIO
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
305
src/fs.js
305
src/fs.js
|
@ -5,6 +5,11 @@ define(function(require) {
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var when = require('when');
|
var when = require('when');
|
||||||
|
|
||||||
|
// TextEncoder and TextDecoder will either already be present, or use this shim.
|
||||||
|
// Because of the way the spec is defined, we need to get them off the global.
|
||||||
|
require('encoding-indexes');
|
||||||
|
require('encoding');
|
||||||
|
|
||||||
var normalize = require('src/path').normalize;
|
var normalize = require('src/path').normalize;
|
||||||
var dirname = require('src/path').dirname;
|
var dirname = require('src/path').dirname;
|
||||||
var basename = require('src/path').basename;
|
var basename = require('src/path').basename;
|
||||||
|
@ -53,7 +58,7 @@ define(function(require) {
|
||||||
function DirectoryEntry(id, type) {
|
function DirectoryEntry(id, type) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.type = type || MODE_FILE;
|
this.type = type || MODE_FILE;
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OpenFileDescription
|
* OpenFileDescription
|
||||||
|
@ -63,7 +68,7 @@ define(function(require) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.flags = flags;
|
this.flags = flags;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Node
|
* Node
|
||||||
|
@ -72,7 +77,7 @@ define(function(require) {
|
||||||
function Node(id, mode, size, atime, ctime, mtime, flags, xattrs, nlinks, version) {
|
function Node(id, mode, size, atime, ctime, mtime, flags, xattrs, nlinks, version) {
|
||||||
var now = Date.now();
|
var now = Date.now();
|
||||||
|
|
||||||
this.id = id || hash(guid()),
|
this.id = id || hash(guid());
|
||||||
this.mode = mode || MODE_FILE; // node type (file, directory, etc)
|
this.mode = mode || MODE_FILE; // node type (file, directory, etc)
|
||||||
this.size = size || 0; // size (bytes for files, entries for directories)
|
this.size = size || 0; // size (bytes for files, entries for directories)
|
||||||
this.atime = atime || now; // access time
|
this.atime = atime || now; // access time
|
||||||
|
@ -85,7 +90,7 @@ define(function(require) {
|
||||||
this.blksize = undefined; // block size
|
this.blksize = undefined; // block size
|
||||||
this.nblocks = 1; // blocks count
|
this.nblocks = 1; // blocks count
|
||||||
this.data = hash(guid()); // id for data object
|
this.data = hash(guid()); // id for data object
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stats
|
* Stats
|
||||||
|
@ -100,7 +105,7 @@ define(function(require) {
|
||||||
this.mtime = fileNode.mtime;
|
this.mtime = fileNode.mtime;
|
||||||
this.ctime = fileNode.ctime;
|
this.ctime = fileNode.ctime;
|
||||||
this.type = fileNode.mode;
|
this.type = fileNode.mode;
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find_node
|
* find_node
|
||||||
|
@ -125,7 +130,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
callback(undefined, rootDirectoryNode);
|
callback(undefined, rootDirectoryNode);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
read_object(objectStore, ROOT_NODE_ID, check_root_directory_node);
|
read_object(objectStore, ROOT_NODE_ID, check_root_directory_node);
|
||||||
} else {
|
} else {
|
||||||
|
@ -139,7 +144,7 @@ define(function(require) {
|
||||||
} 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);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// in: parent directory data
|
// in: parent directory data
|
||||||
// out: searched node id
|
// out: searched node id
|
||||||
|
@ -154,11 +159,11 @@ define(function(require) {
|
||||||
read_object(objectStore, nodeId, callback);
|
read_object(objectStore, nodeId, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
find_node(objectStore, parentPath, read_parent_directory_data);
|
find_node(objectStore, parentPath, read_parent_directory_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read_object
|
* read_object
|
||||||
|
@ -177,7 +182,7 @@ define(function(require) {
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
callback(new EIO(error.message));
|
callback(new EIO(error.message));
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* write_object
|
* write_object
|
||||||
|
@ -196,7 +201,7 @@ define(function(require) {
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
callback(new EIO(error.message));
|
callback(new EIO(error.message));
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* delete_object
|
* delete_object
|
||||||
|
@ -211,7 +216,7 @@ define(function(require) {
|
||||||
deleteRequest.onerror = function(error) {
|
deleteRequest.onerror = function(error) {
|
||||||
callback(error);
|
callback(error);
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* make_root_directory
|
* make_root_directory
|
||||||
|
@ -232,7 +237,7 @@ define(function(require) {
|
||||||
directoryNode.nlinks += 1;
|
directoryNode.nlinks += 1;
|
||||||
write_object(objectStore, directoryNode, directoryNode.id, write_directory_data);
|
write_object(objectStore, directoryNode, directoryNode.id, write_directory_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function write_directory_data(error) {
|
function write_directory_data(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -241,10 +246,10 @@ define(function(require) {
|
||||||
directoryData = {};
|
directoryData = {};
|
||||||
write_object(objectStore, directoryData, directoryNode.data, callback);
|
write_object(objectStore, directoryData, directoryNode.data, callback);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
find_node(objectStore, ROOT_DIRECTORY_NAME, write_directory_node);
|
find_node(objectStore, ROOT_DIRECTORY_NAME, write_directory_node);
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* make_directory
|
* make_directory
|
||||||
|
@ -277,7 +282,7 @@ define(function(require) {
|
||||||
parentDirectoryNode = result;
|
parentDirectoryNode = result;
|
||||||
read_object(objectStore, parentDirectoryNode.data, write_directory_node);
|
read_object(objectStore, parentDirectoryNode.data, write_directory_node);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function write_directory_node(error, result) {
|
function write_directory_node(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -288,7 +293,7 @@ define(function(require) {
|
||||||
directoryNode.nlinks += 1;
|
directoryNode.nlinks += 1;
|
||||||
write_object(objectStore, directoryNode, directoryNode.id, write_directory_data);
|
write_object(objectStore, directoryNode, directoryNode.id, write_directory_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function write_directory_data(error) {
|
function write_directory_data(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -297,7 +302,7 @@ define(function(require) {
|
||||||
directoryData = {};
|
directoryData = {};
|
||||||
write_object(objectStore, directoryData, directoryNode.data, update_parent_directory_data);
|
write_object(objectStore, directoryData, directoryNode.data, update_parent_directory_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function update_parent_directory_data(error) {
|
function update_parent_directory_data(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -309,7 +314,7 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
|
|
||||||
find_node(objectStore, path, check_if_directory_exists);
|
find_node(objectStore, path, check_if_directory_exists);
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remove_directory
|
* remove_directory
|
||||||
|
@ -349,7 +354,7 @@ define(function(require) {
|
||||||
find_node(objectStore, parentPath, read_parent_directory_data);
|
find_node(objectStore, parentPath, read_parent_directory_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_parent_directory_data(error, result) {
|
function read_parent_directory_data(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -358,7 +363,7 @@ define(function(require) {
|
||||||
parentDirectoryNode = result;
|
parentDirectoryNode = result;
|
||||||
read_object(objectStore, parentDirectoryNode.data, remove_directory_entry_from_parent_directory_node);
|
read_object(objectStore, parentDirectoryNode.data, remove_directory_entry_from_parent_directory_node);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function remove_directory_entry_from_parent_directory_node(error, result) {
|
function remove_directory_entry_from_parent_directory_node(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -368,7 +373,7 @@ define(function(require) {
|
||||||
delete parentDirectoryData[name];
|
delete parentDirectoryData[name];
|
||||||
write_object(objectStore, parentDirectoryData, parentDirectoryNode.data, remove_directory_node);
|
write_object(objectStore, parentDirectoryData, parentDirectoryNode.data, remove_directory_node);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function remove_directory_node(error) {
|
function remove_directory_node(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -376,7 +381,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
delete_object(objectStore, directoryNode.id, remove_directory_data);
|
delete_object(objectStore, directoryNode.id, remove_directory_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function remove_directory_data(error) {
|
function remove_directory_data(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -384,10 +389,10 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
delete_object(objectStore, directoryNode.data, callback);
|
delete_object(objectStore, directoryNode.data, callback);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
find_node(objectStore, path, check_if_directory_exists);
|
find_node(objectStore, path, check_if_directory_exists);
|
||||||
};
|
}
|
||||||
|
|
||||||
function open_file(fs, objectStore, path, flags, callback) {
|
function open_file(fs, objectStore, path, flags, callback) {
|
||||||
path = normalize(path);
|
path = normalize(path);
|
||||||
|
@ -402,7 +407,7 @@ define(function(require) {
|
||||||
|
|
||||||
if(ROOT_DIRECTORY_NAME == name) {
|
if(ROOT_DIRECTORY_NAME == name) {
|
||||||
if(_(flags).contains(O_WRITE)) {
|
if(_(flags).contains(O_WRITE)) {
|
||||||
callback(new EIsDirectory('the named file is a directory and O_WRITE is set'))
|
callback(new EIsDirectory('the named file is a directory and O_WRITE is set'));
|
||||||
} else {
|
} else {
|
||||||
find_node(objectStore, path, set_file_node);
|
find_node(objectStore, path, set_file_node);
|
||||||
}
|
}
|
||||||
|
@ -417,7 +422,7 @@ define(function(require) {
|
||||||
directoryNode = result;
|
directoryNode = result;
|
||||||
read_object(objectStore, directoryNode.data, check_if_file_exists);
|
read_object(objectStore, directoryNode.data, check_if_file_exists);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function check_if_file_exists(error, result) {
|
function check_if_file_exists(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -426,11 +431,11 @@ define(function(require) {
|
||||||
directoryData = result;
|
directoryData = result;
|
||||||
if(_(directoryData).has(name)) {
|
if(_(directoryData).has(name)) {
|
||||||
if(_(flags).contains(O_EXCLUSIVE)) {
|
if(_(flags).contains(O_EXCLUSIVE)) {
|
||||||
callback(new ENoEntry('O_CREATE and O_EXCLUSIVE are set, and the named file exists'))
|
callback(new ENoEntry('O_CREATE and O_EXCLUSIVE are set, and the named file exists'));
|
||||||
} else {
|
} else {
|
||||||
directoryEntry = directoryData[name];
|
directoryEntry = directoryData[name];
|
||||||
if(directoryEntry.type == MODE_DIRECTORY && _(flags).contains(O_WRITE)) {
|
if(directoryEntry.type == MODE_DIRECTORY && _(flags).contains(O_WRITE)) {
|
||||||
callback(new EIsDirectory('the named file is a directory and O_WRITE is set'))
|
callback(new EIsDirectory('the named file is a directory and O_WRITE is set'));
|
||||||
} else {
|
} else {
|
||||||
read_object(objectStore, directoryEntry.id, set_file_node);
|
read_object(objectStore, directoryEntry.id, set_file_node);
|
||||||
}
|
}
|
||||||
|
@ -443,7 +448,7 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function set_file_node(error, result) {
|
function set_file_node(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -452,13 +457,13 @@ define(function(require) {
|
||||||
fileNode = result;
|
fileNode = result;
|
||||||
callback(undefined, fileNode);
|
callback(undefined, fileNode);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function write_file_node() {
|
function write_file_node() {
|
||||||
fileNode = new Node(undefined, MODE_FILE);
|
fileNode = new Node(undefined, MODE_FILE);
|
||||||
fileNode.nlinks += 1;
|
fileNode.nlinks += 1;
|
||||||
write_object(objectStore, fileNode, fileNode.id, write_file_data);
|
write_object(objectStore, fileNode, fileNode.id, write_file_data);
|
||||||
};
|
}
|
||||||
|
|
||||||
function write_file_data(error) {
|
function write_file_data(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -467,7 +472,7 @@ define(function(require) {
|
||||||
fileData = new Uint8Array(0);
|
fileData = new Uint8Array(0);
|
||||||
write_object(objectStore, fileData, fileNode.data, update_directory_data);
|
write_object(objectStore, fileData, fileNode.data, update_directory_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function update_directory_data(error) {
|
function update_directory_data(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -476,7 +481,7 @@ define(function(require) {
|
||||||
directoryData[name] = new DirectoryEntry(fileNode.id, MODE_FILE);
|
directoryData[name] = new DirectoryEntry(fileNode.id, MODE_FILE);
|
||||||
write_object(objectStore, directoryData, directoryNode.data, handle_update_result);
|
write_object(objectStore, directoryData, directoryNode.data, handle_update_result);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function handle_update_result(error) {
|
function handle_update_result(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -484,8 +489,8 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
callback(undefined, fileNode);
|
callback(undefined, fileNode);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function write_data(objectStore, ofd, buffer, offset, length, position, callback) {
|
function write_data(objectStore, ofd, buffer, offset, length, position, callback) {
|
||||||
var fileNode;
|
var fileNode;
|
||||||
|
@ -500,7 +505,7 @@ define(function(require) {
|
||||||
fileNode = result;
|
fileNode = result;
|
||||||
read_object(objectStore, fileNode.data, update_file_data);
|
read_object(objectStore, fileNode.data, update_file_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function update_file_data(error, result) {
|
function update_file_data(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -524,7 +529,7 @@ define(function(require) {
|
||||||
|
|
||||||
write_object(objectStore, newData, fileNode.data, update_file_node);
|
write_object(objectStore, newData, fileNode.data, update_file_node);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function update_file_node(error) {
|
function update_file_node(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -532,7 +537,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
write_object(objectStore, fileNode, fileNode.id, return_nbytes);
|
write_object(objectStore, fileNode, fileNode.id, return_nbytes);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function return_nbytes(error) {
|
function return_nbytes(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -540,8 +545,8 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
callback(undefined, length);
|
callback(undefined, length);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_data(objectStore, ofd, buffer, offset, length, position, callback) {
|
function read_data(objectStore, ofd, buffer, offset, length, position, callback) {
|
||||||
var fileNode;
|
var fileNode;
|
||||||
|
@ -556,7 +561,7 @@ define(function(require) {
|
||||||
fileNode = result;
|
fileNode = result;
|
||||||
read_object(objectStore, fileNode.data, handle_file_data);
|
read_object(objectStore, fileNode.data, handle_file_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function handle_file_data(error, result) {
|
function handle_file_data(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -572,8 +577,8 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
callback(undefined, length);
|
callback(undefined, length);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function stat_file(objectStore, path, callback) {
|
function stat_file(objectStore, path, callback) {
|
||||||
path = normalize(path);
|
path = normalize(path);
|
||||||
|
@ -587,8 +592,8 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
callback(undefined, result);
|
callback(undefined, result);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function fstat_file(objectStore, ofd, callback) {
|
function fstat_file(objectStore, ofd, callback) {
|
||||||
read_object(objectStore, ofd.id, check_file);
|
read_object(objectStore, ofd.id, check_file);
|
||||||
|
@ -599,8 +604,8 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
callback(undefined, result);
|
callback(undefined, result);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function link_node(objectStore, oldpath, newpath, callback) {
|
function link_node(objectStore, oldpath, newpath, callback) {
|
||||||
oldpath = normalize(oldpath);
|
oldpath = normalize(oldpath);
|
||||||
|
@ -626,7 +631,7 @@ define(function(require) {
|
||||||
oldDirectoryNode = result;
|
oldDirectoryNode = result;
|
||||||
read_object(objectStore, oldDirectoryNode.data, check_if_old_file_exists);
|
read_object(objectStore, oldDirectoryNode.data, check_if_old_file_exists);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function check_if_old_file_exists(error, result) {
|
function check_if_old_file_exists(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -639,7 +644,7 @@ define(function(require) {
|
||||||
find_node(objectStore, newParentPath, read_new_directory_data);
|
find_node(objectStore, newParentPath, read_new_directory_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_new_directory_data(error, result) {
|
function read_new_directory_data(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -648,7 +653,7 @@ define(function(require) {
|
||||||
newDirectoryNode = result;
|
newDirectoryNode = result;
|
||||||
read_object(objectStore, newDirectoryNode.data, check_if_new_file_exists);
|
read_object(objectStore, newDirectoryNode.data, check_if_new_file_exists);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function check_if_new_file_exists(error, result) {
|
function check_if_new_file_exists(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -662,7 +667,7 @@ define(function(require) {
|
||||||
write_object(objectStore, newDirectoryData, newDirectoryNode.data, read_directory_entry);
|
write_object(objectStore, newDirectoryData, newDirectoryNode.data, read_directory_entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_directory_entry(error, result) {
|
function read_directory_entry(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -677,11 +682,11 @@ define(function(require) {
|
||||||
callback(error);
|
callback(error);
|
||||||
} else {
|
} else {
|
||||||
fileNode = result;
|
fileNode = result;
|
||||||
fileNode.nlinks += 1
|
fileNode.nlinks += 1;
|
||||||
write_object(objectStore, fileNode, fileNode.id, callback);
|
write_object(objectStore, fileNode, fileNode.id, callback);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function unlink_node(objectStore, path, callback) {
|
function unlink_node(objectStore, path, callback) {
|
||||||
path = normalize(path);
|
path = normalize(path);
|
||||||
|
@ -701,7 +706,7 @@ define(function(require) {
|
||||||
directoryNode = result;
|
directoryNode = result;
|
||||||
read_object(objectStore, directoryNode.data, check_if_file_exists);
|
read_object(objectStore, directoryNode.data, check_if_file_exists);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function check_if_file_exists(error, result) {
|
function check_if_file_exists(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -714,7 +719,7 @@ define(function(require) {
|
||||||
read_object(objectStore, directoryData[name].id, update_file_node);
|
read_object(objectStore, directoryData[name].id, update_file_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function update_file_node(error, result) {
|
function update_file_node(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -728,7 +733,7 @@ define(function(require) {
|
||||||
write_object(objectStore, fileNode, fileNode.id, update_directory_data);
|
write_object(objectStore, fileNode, fileNode.id, update_directory_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function delete_file_data(error) {
|
function delete_file_data(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -736,7 +741,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
delete_object(objectStore, fileNode.data, update_directory_data);
|
delete_object(objectStore, fileNode.data, update_directory_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function update_directory_data(error) {
|
function update_directory_data(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -746,7 +751,7 @@ define(function(require) {
|
||||||
write_object(objectStore, directoryData, directoryNode.data, callback);
|
write_object(objectStore, directoryData, directoryNode.data, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_directory(objectStore, path, callback) {
|
function read_directory(objectStore, path, callback) {
|
||||||
path = normalize(path);
|
path = normalize(path);
|
||||||
|
@ -764,7 +769,7 @@ define(function(require) {
|
||||||
directoryNode = result;
|
directoryNode = result;
|
||||||
read_object(objectStore, directoryNode.data, handle_directory_data);
|
read_object(objectStore, directoryNode.data, handle_directory_data);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function handle_directory_data(error, result) {
|
function handle_directory_data(error, result) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
@ -774,8 +779,16 @@ define(function(require) {
|
||||||
var files = Object.keys(directoryData);
|
var files = Object.keys(directoryData);
|
||||||
callback(undefined, files);
|
callback(undefined, files);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function validate_flags(flags) {
|
||||||
|
if(!_(O_FLAGS).has(flags)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return O_FLAGS[flags];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FileSystem
|
* FileSystem
|
||||||
|
@ -818,7 +831,7 @@ define(function(require) {
|
||||||
that.readyState = FS_READY;
|
that.readyState = FS_READY;
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
if(format) {
|
if(format) {
|
||||||
var clearRequest = files.clear();
|
var clearRequest = files.clear();
|
||||||
|
@ -845,7 +858,7 @@ define(function(require) {
|
||||||
this.nextDescriptor = nextDescriptor;
|
this.nextDescriptor = nextDescriptor;
|
||||||
this.openFiles = openFiles;
|
this.openFiles = openFiles;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
};
|
}
|
||||||
FileSystem.prototype._allocate_descriptor = function _allocate_descriptor(openFileDescription) {
|
FileSystem.prototype._allocate_descriptor = function _allocate_descriptor(openFileDescription) {
|
||||||
var fd = this.nextDescriptor ++;
|
var fd = this.nextDescriptor ++;
|
||||||
this.openFiles[fd] = openFileDescription;
|
this.openFiles[fd] = openFileDescription;
|
||||||
|
@ -877,12 +890,11 @@ define(function(require) {
|
||||||
var fd = that._allocate_descriptor(openFileDescription);
|
var fd = that._allocate_descriptor(openFileDescription);
|
||||||
deferred.resolve(fd);
|
deferred.resolve(fd);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
if(!_(O_FLAGS).has(flags)) {
|
flags = validate_flags(flags);
|
||||||
|
if(!flags) {
|
||||||
deferred.reject(new EInvalid('flags is not valid'));
|
deferred.reject(new EInvalid('flags is not valid'));
|
||||||
} else {
|
|
||||||
flags = O_FLAGS[flags];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open_file(this, files, path, flags, check_result);
|
open_file(this, files, path, flags, check_result);
|
||||||
|
@ -934,7 +946,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
make_directory(files, path, check_result);
|
make_directory(files, path, check_result);
|
||||||
deferred.promise.then(
|
deferred.promise.then(
|
||||||
|
@ -966,7 +978,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
remove_directory(files, path, check_result);
|
remove_directory(files, path, check_result);
|
||||||
deferred.promise.then(
|
deferred.promise.then(
|
||||||
|
@ -999,7 +1011,7 @@ define(function(require) {
|
||||||
var stats = new Stats(result, that.name);
|
var stats = new Stats(result, that.name);
|
||||||
deferred.resolve(stats);
|
deferred.resolve(stats);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
stat_file(files, path, check_result);
|
stat_file(files, path, check_result);
|
||||||
deferred.promise.then(
|
deferred.promise.then(
|
||||||
|
@ -1032,7 +1044,7 @@ define(function(require) {
|
||||||
var stats = new Stats(result, that.name);
|
var stats = new Stats(result, that.name);
|
||||||
deferred.resolve(stats);
|
deferred.resolve(stats);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
var ofd = that.openFiles[fd];
|
var ofd = that.openFiles[fd];
|
||||||
|
|
||||||
|
@ -1071,7 +1083,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
link_node(files, oldpath, newpath, check_result);
|
link_node(files, oldpath, newpath, check_result);
|
||||||
|
|
||||||
|
@ -1104,7 +1116,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
unlink_node(files, path, check_result);
|
unlink_node(files, path, check_result);
|
||||||
|
|
||||||
|
@ -1140,7 +1152,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve(nbytes);
|
deferred.resolve(nbytes);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
var ofd = that.openFiles[fd];
|
var ofd = that.openFiles[fd];
|
||||||
|
|
||||||
|
@ -1166,6 +1178,79 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
FileSystem.prototype.readFile = function readFile(path, options, callback) {
|
||||||
|
var that = this;
|
||||||
|
this.promise.then(
|
||||||
|
function() {
|
||||||
|
var deferred = when.defer();
|
||||||
|
var transaction = that.db.transaction([FILE_STORE_NAME], IDB_RO);
|
||||||
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
|
|
||||||
|
if(!options) {
|
||||||
|
options = { encoding: null, flag: 'r' };
|
||||||
|
} else if(typeof options === "function") {
|
||||||
|
callback = options;
|
||||||
|
options = { encoding: null, flag: 'r' };
|
||||||
|
} else if(typeof options === "string") {
|
||||||
|
options = { encoding: options, flag: 'r' };
|
||||||
|
}
|
||||||
|
|
||||||
|
var flags = validate_flags(options.flag || 'r');
|
||||||
|
if(!flags) {
|
||||||
|
deferred.reject(new EInvalid('flags is not valid'));
|
||||||
|
}
|
||||||
|
|
||||||
|
open_file(this, files, path, flags, function(err, fileNode) {
|
||||||
|
if(err) {
|
||||||
|
// TODO: abort transaction?
|
||||||
|
return deferred.reject(err);
|
||||||
|
}
|
||||||
|
var ofd = new OpenFileDescription(fileNode.id, flags, 0);
|
||||||
|
var fd = that._allocate_descriptor(ofd);
|
||||||
|
|
||||||
|
fstat_file(files, ofd, function(err2, fstatResult) {
|
||||||
|
if(err2) {
|
||||||
|
// TODO: abort transaction?
|
||||||
|
return deferred.reject(err2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var stats = new Stats(fstatResult, that.name);
|
||||||
|
var size = stats.size;
|
||||||
|
var buffer = new Uint8Array(size);
|
||||||
|
|
||||||
|
read_data(files, ofd, buffer, 0, size, 0, function(err3, nbytes) {
|
||||||
|
if(err3) {
|
||||||
|
// TODO: abort transaction?
|
||||||
|
return deferred.reject(err3);
|
||||||
|
}
|
||||||
|
that._release_descriptor(fd);
|
||||||
|
|
||||||
|
var data;
|
||||||
|
if(options.encoding === 'utf8') {
|
||||||
|
data = new TextDecoder('utf-8').decode(buffer);
|
||||||
|
} else {
|
||||||
|
data = buffer;
|
||||||
|
}
|
||||||
|
deferred.resolve(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
deferred.promise.then(
|
||||||
|
function(result) {
|
||||||
|
callback(undefined, result);
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
callback(new EFileSystemError('unknown error'));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
FileSystem.prototype.write = function write(fd, buffer, offset, length, position, callback) {
|
FileSystem.prototype.write = function write(fd, buffer, offset, length, position, callback) {
|
||||||
var that = this;
|
var that = this;
|
||||||
this.promise.then(
|
this.promise.then(
|
||||||
|
@ -1183,7 +1268,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve(nbytes);
|
deferred.resolve(nbytes);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
var ofd = that.openFiles[fd];
|
var ofd = that.openFiles[fd];
|
||||||
|
|
||||||
|
@ -1211,6 +1296,64 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
FileSystem.prototype.writeFile = function writeFile(path, data, options, callback) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
if(!options) {
|
||||||
|
options = { encoding: 'utf8', flag: 'w' };
|
||||||
|
} else if(typeof options === "function") {
|
||||||
|
callback = options;
|
||||||
|
options = { encoding: 'utf8', flag: 'w' };
|
||||||
|
} else if(typeof options === "string") {
|
||||||
|
options = { encoding: options, flag: 'w' };
|
||||||
|
}
|
||||||
|
|
||||||
|
var flags = validate_flags(options.flag || 'w');
|
||||||
|
if(!flags) {
|
||||||
|
deferred.reject(new EInvalid('flags is not valid'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof data === "string" && options.encoding === 'utf8') {
|
||||||
|
data = new TextEncoder('utf-8').encode(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
open_file(this, files, path, flags, function(err, fileNode) {
|
||||||
|
if(err) {
|
||||||
|
// TODO: abort transaction?
|
||||||
|
return deferred.reject(err);
|
||||||
|
}
|
||||||
|
var ofd = new OpenFileDescription(fileNode.id, flags, 0);
|
||||||
|
var fd = that._allocate_descriptor(ofd);
|
||||||
|
|
||||||
|
write_data(files, ofd, data, 0, data.length, 0, function(err2, nbytes) {
|
||||||
|
if(err2) {
|
||||||
|
// TODO: abort transaction?
|
||||||
|
return deferred.reject(err2);
|
||||||
|
}
|
||||||
|
that._release_descriptor(fd);
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
deferred.promise.then(
|
||||||
|
function() {
|
||||||
|
callback(undefined);
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
callback(new EFileSystemError('unknown error'));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
FileSystem.prototype.getxattr = function getxattr(path, name, callback) {
|
FileSystem.prototype.getxattr = function getxattr(path, name, callback) {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1229,7 +1372,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve(offset);
|
deferred.resolve(offset);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
var ofd = that.openFiles[fd];
|
var ofd = that.openFiles[fd];
|
||||||
|
|
||||||
|
@ -1266,7 +1409,7 @@ define(function(require) {
|
||||||
deferred.resolve(ofd.position);
|
deferred.resolve(ofd.position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
fstat_file(files, ofd, update_descriptor_position);
|
fstat_file(files, ofd, update_descriptor_position);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1302,7 +1445,7 @@ define(function(require) {
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve(files);
|
deferred.resolve(files);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
read_directory(files, path, check_result);
|
read_directory(files, path, check_result);
|
||||||
|
|
||||||
|
@ -1347,7 +1490,7 @@ define(function(require) {
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
FileSystem: FileSystem,
|
FileSystem: FileSystem
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
|
@ -7,18 +7,18 @@ define(function(require) {
|
||||||
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
||||||
return v.toString(16);
|
return v.toString(16);
|
||||||
}).toUpperCase();
|
}).toUpperCase();
|
||||||
};
|
}
|
||||||
|
|
||||||
function hash(string) {
|
function hash(string) {
|
||||||
return Crypto.SHA256(string).toString(Crypto.enc.hex);
|
return Crypto.SHA256(string).toString(Crypto.enc.hex);
|
||||||
};
|
}
|
||||||
|
|
||||||
function nop() {};
|
function nop() {}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
guid: guid,
|
guid: guid,
|
||||||
hash: hash,
|
hash: hash,
|
||||||
nop: nop,
|
nop: nop
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
|
@ -714,6 +714,153 @@ describe('fs.write', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('fs.writeFile, fs.readFile', 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.writeFile).toEqual('function');
|
||||||
|
expect(typeof this.fs.readFile).toEqual('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error when path is wrong to readFile', function() {
|
||||||
|
var complete = false;
|
||||||
|
var _error, _result;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var contents = "This is a file.";
|
||||||
|
|
||||||
|
that.fs.readFile('/no-such-file', 'utf8', function(error, data) {
|
||||||
|
_error = error;
|
||||||
|
_result = data;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(_error).toBeDefined();
|
||||||
|
expect(_result).not.toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should write, read a utf8 file without specifying utf8 in writeFile', function() {
|
||||||
|
var complete = false;
|
||||||
|
var _error, _result;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var contents = "This is a file.";
|
||||||
|
|
||||||
|
that.fs.writeFile('/myfile', contents, function(error) {
|
||||||
|
if(error) throw error;
|
||||||
|
that.fs.readFile('/myfile', 'utf8', function(error2, data) {
|
||||||
|
if(error2) throw error2;
|
||||||
|
_result = data;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(_error).not.toBeDefined();
|
||||||
|
expect(_result).toEqual(contents);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should write, read a utf8 file with "utf8" option to writeFile', function() {
|
||||||
|
var complete = false;
|
||||||
|
var _error, _result;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var contents = "This is a file.";
|
||||||
|
|
||||||
|
that.fs.writeFile('/myfile', contents, 'utf8', function(error) {
|
||||||
|
if(error) throw error;
|
||||||
|
that.fs.readFile('/myfile', 'utf8', function(error2, data) {
|
||||||
|
if(error2) throw error2;
|
||||||
|
_result = data;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(_error).not.toBeDefined();
|
||||||
|
expect(_result).toEqual(contents);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should write, read a utf8 file with {encoding: "utf8"} option to writeFile', function() {
|
||||||
|
var complete = false;
|
||||||
|
var _error, _result;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var contents = "This is a file.";
|
||||||
|
|
||||||
|
that.fs.writeFile('/myfile', contents, { encoding: 'utf8' }, function(error) {
|
||||||
|
if(error) throw error;
|
||||||
|
that.fs.readFile('/myfile', 'utf8', function(error2, data) {
|
||||||
|
if(error2) throw error2;
|
||||||
|
_result = data;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(_error).not.toBeDefined();
|
||||||
|
expect(_result).toEqual(contents);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should write, read a binary file', function() {
|
||||||
|
var complete = false;
|
||||||
|
var _error, _result;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
// String and utf8 binary encoded versions of the same thing:
|
||||||
|
var contents = "This is a file.";
|
||||||
|
var binary = new Uint8Array([84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 102, 105, 108, 101, 46]);
|
||||||
|
|
||||||
|
that.fs.writeFile('/myfile', binary, function(error) {
|
||||||
|
if(error) throw error;
|
||||||
|
that.fs.readFile('/myfile', function(error2, data) {
|
||||||
|
if(error2) throw error2;
|
||||||
|
_result = data;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(_error).not.toBeDefined();
|
||||||
|
expect(_result).toEqual(binary);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('fs.read', function() {
|
describe('fs.read', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.db_name = mk_db_name();
|
this.db_name = mk_db_name();
|
||||||
|
|
Loading…
Reference in New Issue