JSFileApi: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
(Second generation prototype API) |
||
Line 1: | Line 1: | ||
/** | |||
* {1 Low-level API for file access.} | |||
*/ | |||
const FileUtilities = | |||
{ | |||
/** | |||
* {2 Access a file or a directory} | |||
*/ | |||
// | |||
/** | |||
* Open a file | |||
* | |||
* @param {string} fileName A platform-dependent name. To create a file in a directory, use [DirectoryDescriptor.openFile]. | |||
* @param {number} accessMode A or-ing of flags, as specified by [FileUtilities.Open.Access]. | |||
* @param {number} contentMode A or-ing of flags, as specified by [FileUtilities.Open.Content] | |||
* @param {number} pragmaMode A or-ing of flags, as specified by [FileUtilities.Open.Pragma] | |||
* @return {FileDescriptor} a FileDescriptor | |||
* | |||
* @throws FileDescriptorError | |||
*/ | |||
openFile: function(fullName, accessMode, contentMode, pragmaMode) { | |||
//Unix: maps to [open] | |||
//Windows: maps to [CreateFile] | |||
//Windows note: we probably want flags FLAG_SHARE_READ, FLAG_SHARE_WRITE, FLAG_SHARE_DELETE to allow moving files that are currently open | |||
}, | |||
/** | |||
* Create a temporary file. This file is deleted when the process closes, when the file is closed or when the FileDescriptor is garbage-collected. | |||
* | |||
* @return {FileDescriptor} a FileDescriptor | |||
*/ | |||
createTempFile: function() { | |||
//Unix: [FileUtilities.tmpdir] followed by [mkstemp] and [FileUtilities.openFile] | |||
//Windows: [FileUtilities.tmpdir] followed by [GetTempFileName] and [FileUtilities.openFile] | |||
//Alternative version: | |||
//Unix minus Android: maps to [tmpfile] | |||
//Android: need to implement custom [tmpfile] | |||
//Windows: maps to [GetTempPath] + [GetTempFileName] + [CreateFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa363875%28v=vs.85%29.aspx | |||
}, | |||
/** | |||
* @param {string} fullName The platform-specific name of the directory. | |||
* @param {number=} accessMode A or-ing of flags, as specified by [FileDescriptor.OpenDir.Access] | |||
* | |||
* @returns {DirectoryDescriptor} a descriptor which may be used to access this directory | |||
*/ | |||
openDirectory: function(fullName, accessMode) { | |||
//Unix: lazy | |||
//Windows: lazy | |||
}, | |||
/** | |||
* Create a temporary directory. | |||
* | |||
* Note: For the time being, there is no guarantee that the temporary directory will be cleaned | |||
* | |||
* @returns {DirectoryDescriptor} a descriptor which may be used to access this directory | |||
*/ | |||
createTempDirectory: function() { | |||
//Unix: [FileUtilities.tmpdir] followed by [mkstemp] and [FileUtilities.openDirectory] | |||
//Windows: [FileUtilities.tmpdir] followed by [GetTempFileName] and [FileUtilities.openDirectory] | |||
}, | |||
/** | |||
* Open a copy of a file. | |||
* | |||
* If neither [directory] nor [name] is provided, the destination file is first created as with [createTemp] | |||
* | |||
* @param {DirectoryDescriptor=} destination Optionally, the directory in which to place the file. | |||
* @param {string=} name Optionally, the name of the file in the directory. | |||
* @return {FileDescriptor} The copy. | |||
*/ | |||
openFileCopy: function(directory, name) { | |||
//Unix: need to implement -- note that some file systems support an [ioctl] for copy-on-write. | |||
//Windows: maps to [CopyFile] http://msdn.microsoft.com/en-us/library/aa363851(v=VS.85).aspx | |||
}, | |||
/** | |||
* {2 General utilities} | |||
*/ | |||
/** | |||
* @param {string} source The name of the file/directory to copy. | |||
* @param {string} target The name of the file/directory to be created. | |||
* @throws FileDescriptorError | |||
*/ | |||
copy: function(source, target) | |||
{ | |||
//Unix: need to implement with [open], [read], [write], [close] | |||
//Windows: maps to [CopyFile] http://msdn.microsoft.com/en-us/library/aa363851(v=VS.85).aspx | |||
//Check if it works with directories | |||
}, | |||
/** | |||
* @param {string} source The name of the file/directory to move. | |||
* @param {string} target The name of the file/directory to be created. | |||
* @throws FileDescriptorError | |||
*/ | |||
move: function(source, target) | |||
{ | |||
//Unix: maps to [rename] | |||
//Windows: maps to [MoveFile] http://msdn.microsoft.com/en-us/library/aa365239(v=VS.85).aspx | |||
}, | |||
//TODO: doc | |||
link: function(name) | |||
{ | |||
//Unix: maps to [link] | |||
//Windows: maps to [CreateHardLink] http://msdn.microsoft.com/en-us/library/aa363860(v=VS.85).aspx | |||
}, | |||
/** | |||
* Remove a file/directory. | |||
*/ | |||
remove: function(name) | |||
{ | |||
//Unix: maps to [unlink] | |||
//Windows: maps to [DeleteFile] | |||
}, | |||
//TODO: doc | |||
symlink: function(name) | |||
{ | |||
//Unix: maps to [symlink] | |||
//Windows: maps to [CreateSymbolicLink] http://msdn.microsoft.com/en-us/library/aa363866(v=VS.85).aspx | |||
}, | |||
/** | |||
* {3 Constants} | |||
*/ | |||
get stdin: function() { | |||
//... | |||
}, | |||
get stdout: function() { | |||
//... | |||
}, | |||
get stderr: function() { | |||
//... | |||
}, | |||
/** | |||
* Return the location of the directory/folder used to store temporary files. | |||
* | |||
* Computed lazily. | |||
* | |||
* @return {DirectoryDescriptor} | |||
*/ | |||
get tmpdir: function () { | |||
//All platforms: use [nsIDirectoryService] [NS_OS_TEMP_DIR] to get the directory the first time | |||
//Alternative solution: | |||
//Unix minus Android: maps to [getenv] for "TMPDIR" | |||
//Android: TODO - probably somewhere in the Moz preferences directory - check with nsIDirectoryService | |||
//Windows: maps to [GetTempPath] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx | |||
//Note: Perhaps we should check with nsIDirectoryServi | |||
}, | |||
/** | |||
* {3 Flags} | |||
*/ | |||
Open: { | |||
/** | |||
* @enum {number} | |||
*/ | |||
Access: { | |||
READ: ..., | |||
WRITE: ..., | |||
}, | |||
/** | |||
* @enum {number} | |||
*/ | |||
Content: { | |||
MAY_CREATE:..., | |||
APPEND: ..., | |||
OVERWRITE: ..., | |||
}, | |||
/** | |||
* @enum {number} | |||
*/ | |||
Pragma: { | |||
POSIX_SEMANTICS: ..., | |||
SEQUENTIAL_ACCESS: .... | |||
RANDOM_ACCESS: ..., | |||
WRITE_THROUGH: ... | |||
} | |||
}, | |||
Seek: { | |||
/** | |||
* Possible methods for seeking. | |||
* | |||
* @enum {number} | |||
*/ | |||
Method: { | |||
/** | |||
* Seek from file start | |||
*/ | |||
SET: ..., | |||
/** | |||
* Seek from current position | |||
*/ | |||
CUR: ..., | |||
/** | |||
* Seek from file end | |||
*/ | |||
END: ... | |||
}, | |||
}, | |||
/** | |||
* The kind of information that can be found by calling [FileDescroptor.info] or [DirectoryDescriptor.forEachFile]. | |||
* | |||
* Note that some or all fields may be computed lazily. | |||
* | |||
* @interface | |||
*/ | |||
FileInfo: { | |||
/** | |||
* @return {FileDescriptor} the file descriptor for this file | |||
*/ | |||
get descriptor(): { | |||
... | |||
}, | |||
/** | |||
* @TODO Not available on all platforms. Should we still allow it? | |||
* | |||
* @return {number} milliseconds | |||
*/ | |||
get creationTime(): { | |||
... | |||
}, | |||
/** | |||
* @return {number} milliseconds | |||
*/ | |||
get lastAccessTime() : { | |||
... | |||
}, | |||
/** | |||
* @return {number} milliseconds | |||
*/ | |||
get lastModificationTime() : { | |||
... | |||
}, | |||
/** | |||
* @return {number} bytes | |||
*/ | |||
get fileSize() : { | |||
... | |||
}, | |||
/** | |||
* @return {boolean} | |||
*/ | |||
get isExecutable(): { | |||
//Windows: [GetBinaryType] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364819(v=VS.85).aspx | |||
//Unix: contents of [stat] | |||
}, | |||
}, | |||
/** | |||
* An exception launched by this module. | |||
* | |||
* @constructor | |||
* @extends {Error} | |||
*/ | |||
Error: function(){} | |||
} | |||
FileUtilities.Error.prototype = new Error(); | |||
FileUtilities.Error.prototype.constructor = FileDescriptor.Error; | |||
FileDescriptor.prototype = | |||
{ | |||
/** | |||
* {3 Reading} | |||
*/ | |||
/** | |||
* Read some content from a file from the current position, advance. | |||
* | |||
* @param {ArrayBuffer} buf The buffer which will receive the data. | |||
* @param {number} offset The position in the array at which to start putting data, in bytes. | |||
* @param {number} size The maximal number of bytes to read. This method can read less bytes if the file is shorter. | |||
* @return {number} The number of bytes read. | |||
* @throws {FileDescriptorException} In case of error. | |||
*/ | |||
read: function(buf, offset, size) { | |||
//Unix: [read] | |||
//Windows: [ReadFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=VS.85%29.aspx | |||
}, | |||
/** | |||
* As [read], but returns a string instead of filling a buffer. | |||
* | |||
* @return {string} The content read from the file. Note that its length may be shorter than [size] | |||
* @throws {FileDescriptorException} In case of error. | |||
*/ | |||
readString: function(size) { | |||
//as [read] | |||
}, | |||
/** | |||
* As [read], but do not advance | |||
*/ | |||
pread: function(...) { | |||
//Unix: [pread] | |||
//Windows: [ReadFile] + [SetFilePointer] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365541(v=VS.85).aspx | |||
}, | |||
/** | |||
* As [pread], but returns a string instead of filling a buffer. | |||
* | |||
* @return {string} The content read from the file. Note that its length may be shorter than [size] | |||
* @throws {FileDescriptorException} In case of error. | |||
*/ | |||
preadString: function(size) { | |||
//as [pread] | |||
}, | |||
/** | |||
* {3 Writing} | |||
*/ | |||
/** | |||
* Write some content to a file, advance. | |||
* | |||
* @param {ArrayBuffer} buf The buffer containing the data. | |||
* @param {number} offset The position in the array at which the data starts, in bytes. | |||
* @param {number} size The maximal number of bytes to read. This method can write less bytes, depending on buffering. | |||
* | |||
* @return {number} The number of bytes written. | |||
* @throws {FileDescriptorException} In case of error. | |||
*/ | |||
write: function(buf, offset, size) { | |||
//Unix: [write] | |||
//Windows: [WriteFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747%28v=VS.85%29.aspx | |||
}, | |||
/** | |||
* As [write], but with a [string] | |||
*/ | |||
writeString: function(buf, offset, size) { | |||
//as [write] | |||
}, | |||
/** | |||
* As [write] but do not advance | |||
*/ | |||
pwrite: function(buf, offset, size) { | |||
//Unix: [pwrite] | |||
//Windows: [WriteFile] + [SetFilePointer] | |||
}, | |||
pwriteString: function(buf, offset, size) { | |||
//as [pwrite] | |||
}, | |||
/** | |||
* {3 File attributes} | |||
*/ | |||
/** | |||
* Gather information about the file | |||
* | |||
* @return {FileDescriptor.FileInfo} information about the file. | |||
*/ | |||
stat: function() { | |||
//Unix: [lstat] | |||
//Windows: [GetFileInformationByHandle] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364952(v=VS.85).aspx | |||
}, | |||
/** | |||
* Set the size of the file | |||
* | |||
* @param {number} newSize The size to give to the file. | |||
*/ | |||
setSize: function(newSize) { | |||
//Unix: [truncate] | |||
//Windows: [SetFileValidData] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365544%28v=VS.85%29.aspx | |||
}, | |||
/** | |||
* {3 Misc} | |||
*/ | |||
/** | |||
* Change the position in the current file | |||
* | |||
* @param {number} delta Number of bytes. Can be positive or negative. | |||
* @param {FileDescriptor.Seek.Methodmethod} Determine whether [delta] is to be taken from the start of the file, from the end or from the current position. | |||
*/ | |||
seek: function(delta, method) { | |||
//Unix: [lseek] | |||
//Windows: [SetFilePointer] | |||
}, | |||
/** | |||
* Close a file descriptor. | |||
* | |||
* Any further operation on that file descriptor will launch an exception | |||
*/ | |||
close: function() { | |||
//Unix: [close] | |||
//Windows: [CloseHandle] | |||
}, | |||
/** | |||
* Flush the buffer | |||
*/ | |||
flush: function() { | |||
//Unix: [fsync] | |||
//Windows: [FlushFileBuffers] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439(v=VS.85).aspx | |||
}, | |||
/** | |||
* {3 Locking} | |||
*/ | |||
//TODO: Understand differences between Unix and Windows locking better. | |||
//TODO: Don't forget to unlock when leaving the process and/or closing the file. | |||
lock: function() { | |||
//Unix: [flock] | |||
//Windows: [LockFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365202%28v=VS.85%29.aspx | |||
}, | |||
unlock: function() { | |||
//Unix: [funlock] | |||
//Windows: [UnlockFile] http://msdn.microsoft.com/en-us/library/aa365715%28v=VS.85%29.aspx | |||
} | |||
/** | |||
* {3 Not implemented} | |||
*/ | |||
//Not implemented: chmod, chown -- very different between platforms - might implement platform-specific functions | |||
//Not implemented: select -- very different between platforms, higher level | |||
//Not implemented: mmap -- probably feasible, just might require additional API | |||
} | |||
DirectoryDescriptor.prototype = | |||
{ | |||
/** | |||
* Open a file from a directory | |||
* | |||
* @param {string} leafName The name of the file. | |||
* @param {number} accessMode A or-ing of flags, as specified by [FileDescriptor.Open.Access]. | |||
* @param {number} contentMode A or-ing of flags, as specified by [FileDescriptor.Content.Access] | |||
* @param {number} pragmaMode A or-ing of flags, as specified by [FileDescriptor.Pragma.Access] | |||
* @return {FileDescriptor} a FileDescriptor | |||
* | |||
* @throws FileDescriptorError | |||
*/ | |||
openFile: function(leafName, accessMode, contentMode, pragmaMode) { | |||
//Unix: maps to [openat] (warning, this requires gnulib on non-Linux platforms) | |||
//Windows: cf. [FileDescriptor.open] | |||
}, | |||
/** | |||
* Create a temporary file in this directory. This file is deleted when the process closes, when the file is closed. | |||
*/ | |||
createTempFile: function() { | |||
//Unix: uses [mkstemp] and [this.openFile] | |||
//Windows: maps to [GetTempFileName] + [CreateFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa363875%28v=vs.85%29.aspx | |||
}, | |||
/** | |||
* Open a subdirectory of this directory. | |||
* | |||
* @param {string} leafName The platform-specific name of the directory. | |||
* @param {number=} accessMode A or-ing of flags, as specified by [FileDescriptor.OpenDir.Access] | |||
* | |||
* @returns {DirectoryDescriptor} a descriptor which may be used to access this directory | |||
*/ | |||
openDirectory: function(leafName, accessMode) { | |||
//Unix: lazy | |||
//Windows: lazy | |||
}, | |||
/** | |||
* Create a temporary directory. | |||
* | |||
* Note: For the time being, there is no guarantee that the temporary directory will be cleaned | |||
* | |||
* @returns {DirectoryDescriptor} a descriptor which may be used to access this directory | |||
*/ | |||
createTempDirectory: function() | |||
{ | |||
}, | |||
/** | |||
* Apply a treatment to all files in the directory. | |||
* | |||
* Note: objects of type DirectoryDescriptor are iterable. Therefore, you can also loop through them using a standard [for..in]. | |||
* | |||
* @param {(string|regexp|(function(string): boolean)) =} filter. If a [string], uses platform-specific filtering. | |||
* @param {function(string, FileDescriptor.FileInfo, number)} onFile A function called for each file in the directory, with the name of the file, a (lazy) file info for that file and a file number. If the function returns anything [null], the loop stops immediately and returns the value returned by that function. | |||
* | |||
* @returns The first value returned by [onFile], or [undefined] otherwise. | |||
*/ | |||
forEachFile: function(filter, onFile) { | |||
//Unix: maps to [opendir], [dfd], [readdir]/[readdir64], lazy calls to [stat] | |||
//Windows: maps to [FindFirstFile], [FindNextFile], [Close] | |||
} | |||
} | } | ||
Revision as of 14:09, 30 September 2011
/** * {1 Low-level API for file access.} */ const FileUtilities = { /** * {2 Access a file or a directory} */ /** * Open a file * * @param {string} fileName A platform-dependent name. To create a file in a directory, use [DirectoryDescriptor.openFile]. * @param {number} accessMode A or-ing of flags, as specified by [FileUtilities.Open.Access]. * @param {number} contentMode A or-ing of flags, as specified by [FileUtilities.Open.Content] * @param {number} pragmaMode A or-ing of flags, as specified by [FileUtilities.Open.Pragma] * @return {FileDescriptor} a FileDescriptor * * @throws FileDescriptorError */ openFile: function(fullName, accessMode, contentMode, pragmaMode) { //Unix: maps to [open] //Windows: maps to [CreateFile] //Windows note: we probably want flags FLAG_SHARE_READ, FLAG_SHARE_WRITE, FLAG_SHARE_DELETE to allow moving files that are currently open }, /** * Create a temporary file. This file is deleted when the process closes, when the file is closed or when the FileDescriptor is garbage-collected. * * @return {FileDescriptor} a FileDescriptor */ createTempFile: function() { //Unix: [FileUtilities.tmpdir] followed by [mkstemp] and [FileUtilities.openFile] //Windows: [FileUtilities.tmpdir] followed by [GetTempFileName] and [FileUtilities.openFile] //Alternative version: //Unix minus Android: maps to [tmpfile] //Android: need to implement custom [tmpfile] //Windows: maps to [GetTempPath] + [GetTempFileName] + [CreateFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa363875%28v=vs.85%29.aspx }, /** * @param {string} fullName The platform-specific name of the directory. * @param {number=} accessMode A or-ing of flags, as specified by [FileDescriptor.OpenDir.Access] * * @returns {DirectoryDescriptor} a descriptor which may be used to access this directory */ openDirectory: function(fullName, accessMode) { //Unix: lazy //Windows: lazy }, /** * Create a temporary directory. * * Note: For the time being, there is no guarantee that the temporary directory will be cleaned * * @returns {DirectoryDescriptor} a descriptor which may be used to access this directory */ createTempDirectory: function() { //Unix: [FileUtilities.tmpdir] followed by [mkstemp] and [FileUtilities.openDirectory] //Windows: [FileUtilities.tmpdir] followed by [GetTempFileName] and [FileUtilities.openDirectory] }, /** * Open a copy of a file. * * If neither [directory] nor [name] is provided, the destination file is first created as with [createTemp] * * @param {DirectoryDescriptor=} destination Optionally, the directory in which to place the file. * @param {string=} name Optionally, the name of the file in the directory. * @return {FileDescriptor} The copy. */ openFileCopy: function(directory, name) { //Unix: need to implement -- note that some file systems support an [ioctl] for copy-on-write. //Windows: maps to [CopyFile] http://msdn.microsoft.com/en-us/library/aa363851(v=VS.85).aspx }, /** * {2 General utilities} */ /** * @param {string} source The name of the file/directory to copy. * @param {string} target The name of the file/directory to be created. * @throws FileDescriptorError */ copy: function(source, target) { //Unix: need to implement with [open], [read], [write], [close] //Windows: maps to [CopyFile] http://msdn.microsoft.com/en-us/library/aa363851(v=VS.85).aspx //Check if it works with directories }, /** * @param {string} source The name of the file/directory to move. * @param {string} target The name of the file/directory to be created. * @throws FileDescriptorError */ move: function(source, target) { //Unix: maps to [rename] //Windows: maps to [MoveFile] http://msdn.microsoft.com/en-us/library/aa365239(v=VS.85).aspx }, //TODO: doc link: function(name) { //Unix: maps to [link] //Windows: maps to [CreateHardLink] http://msdn.microsoft.com/en-us/library/aa363860(v=VS.85).aspx }, /** * Remove a file/directory. */ remove: function(name) { //Unix: maps to [unlink] //Windows: maps to [DeleteFile] }, //TODO: doc symlink: function(name) { //Unix: maps to [symlink] //Windows: maps to [CreateSymbolicLink] http://msdn.microsoft.com/en-us/library/aa363866(v=VS.85).aspx }, /** * {3 Constants} */ get stdin: function() { //... }, get stdout: function() { //... }, get stderr: function() { //... }, /** * Return the location of the directory/folder used to store temporary files. * * Computed lazily. * * @return {DirectoryDescriptor} */ get tmpdir: function () { //All platforms: use [nsIDirectoryService] [NS_OS_TEMP_DIR] to get the directory the first time //Alternative solution: //Unix minus Android: maps to [getenv] for "TMPDIR" //Android: TODO - probably somewhere in the Moz preferences directory - check with nsIDirectoryService //Windows: maps to [GetTempPath] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx //Note: Perhaps we should check with nsIDirectoryServi }, /** * {3 Flags} */ Open: { /** * @enum {number} */ Access: { READ: ..., WRITE: ..., }, /** * @enum {number} */ Content: { MAY_CREATE:..., APPEND: ..., OVERWRITE: ..., }, /** * @enum {number} */ Pragma: { POSIX_SEMANTICS: ..., SEQUENTIAL_ACCESS: .... RANDOM_ACCESS: ..., WRITE_THROUGH: ... } }, Seek: { /** * Possible methods for seeking. * * @enum {number} */ Method: { /** * Seek from file start */ SET: ..., /** * Seek from current position */ CUR: ..., /** * Seek from file end */ END: ... }, }, /** * The kind of information that can be found by calling [FileDescroptor.info] or [DirectoryDescriptor.forEachFile]. * * Note that some or all fields may be computed lazily. * * @interface */ FileInfo: { /** * @return {FileDescriptor} the file descriptor for this file */ get descriptor(): { ... }, /** * @TODO Not available on all platforms. Should we still allow it? * * @return {number} milliseconds */ get creationTime(): { ... }, /** * @return {number} milliseconds */ get lastAccessTime() : { ... }, /** * @return {number} milliseconds */ get lastModificationTime() : { ... }, /** * @return {number} bytes */ get fileSize() : { ... }, /** * @return {boolean} */ get isExecutable(): { //Windows: [GetBinaryType] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364819(v=VS.85).aspx //Unix: contents of [stat] }, }, /** * An exception launched by this module. * * @constructor * @extends {Error} */ Error: function(){} } FileUtilities.Error.prototype = new Error(); FileUtilities.Error.prototype.constructor = FileDescriptor.Error; FileDescriptor.prototype = { /** * {3 Reading} */ /** * Read some content from a file from the current position, advance. * * @param {ArrayBuffer} buf The buffer which will receive the data. * @param {number} offset The position in the array at which to start putting data, in bytes. * @param {number} size The maximal number of bytes to read. This method can read less bytes if the file is shorter. * @return {number} The number of bytes read. * @throws {FileDescriptorException} In case of error. */ read: function(buf, offset, size) { //Unix: [read] //Windows: [ReadFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=VS.85%29.aspx }, /** * As [read], but returns a string instead of filling a buffer. * * @return {string} The content read from the file. Note that its length may be shorter than [size] * @throws {FileDescriptorException} In case of error. */ readString: function(size) { //as [read] }, /** * As [read], but do not advance */ pread: function(...) { //Unix: [pread] //Windows: [ReadFile] + [SetFilePointer] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365541(v=VS.85).aspx }, /** * As [pread], but returns a string instead of filling a buffer. * * @return {string} The content read from the file. Note that its length may be shorter than [size] * @throws {FileDescriptorException} In case of error. */ preadString: function(size) { //as [pread] }, /** * {3 Writing} */ /** * Write some content to a file, advance. * * @param {ArrayBuffer} buf The buffer containing the data. * @param {number} offset The position in the array at which the data starts, in bytes. * @param {number} size The maximal number of bytes to read. This method can write less bytes, depending on buffering. * * @return {number} The number of bytes written. * @throws {FileDescriptorException} In case of error. */ write: function(buf, offset, size) { //Unix: [write] //Windows: [WriteFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747%28v=VS.85%29.aspx }, /** * As [write], but with a [string] */ writeString: function(buf, offset, size) { //as [write] }, /** * As [write] but do not advance */ pwrite: function(buf, offset, size) { //Unix: [pwrite] //Windows: [WriteFile] + [SetFilePointer] }, pwriteString: function(buf, offset, size) { //as [pwrite] }, /** * {3 File attributes} */ /** * Gather information about the file * * @return {FileDescriptor.FileInfo} information about the file. */ stat: function() { //Unix: [lstat] //Windows: [GetFileInformationByHandle] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364952(v=VS.85).aspx }, /** * Set the size of the file * * @param {number} newSize The size to give to the file. */ setSize: function(newSize) { //Unix: [truncate] //Windows: [SetFileValidData] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365544%28v=VS.85%29.aspx }, /** * {3 Misc} */ /** * Change the position in the current file * * @param {number} delta Number of bytes. Can be positive or negative. * @param {FileDescriptor.Seek.Methodmethod} Determine whether [delta] is to be taken from the start of the file, from the end or from the current position. */ seek: function(delta, method) { //Unix: [lseek] //Windows: [SetFilePointer] }, /** * Close a file descriptor. * * Any further operation on that file descriptor will launch an exception */ close: function() { //Unix: [close] //Windows: [CloseHandle] }, /** * Flush the buffer */ flush: function() { //Unix: [fsync] //Windows: [FlushFileBuffers] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439(v=VS.85).aspx }, /** * {3 Locking} */ //TODO: Understand differences between Unix and Windows locking better. //TODO: Don't forget to unlock when leaving the process and/or closing the file. lock: function() { //Unix: [flock] //Windows: [LockFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa365202%28v=VS.85%29.aspx }, unlock: function() { //Unix: [funlock] //Windows: [UnlockFile] http://msdn.microsoft.com/en-us/library/aa365715%28v=VS.85%29.aspx } /** * {3 Not implemented} */ //Not implemented: chmod, chown -- very different between platforms - might implement platform-specific functions //Not implemented: select -- very different between platforms, higher level //Not implemented: mmap -- probably feasible, just might require additional API } DirectoryDescriptor.prototype = { /** * Open a file from a directory * * @param {string} leafName The name of the file. * @param {number} accessMode A or-ing of flags, as specified by [FileDescriptor.Open.Access]. * @param {number} contentMode A or-ing of flags, as specified by [FileDescriptor.Content.Access] * @param {number} pragmaMode A or-ing of flags, as specified by [FileDescriptor.Pragma.Access] * @return {FileDescriptor} a FileDescriptor * * @throws FileDescriptorError */ openFile: function(leafName, accessMode, contentMode, pragmaMode) { //Unix: maps to [openat] (warning, this requires gnulib on non-Linux platforms) //Windows: cf. [FileDescriptor.open] }, /** * Create a temporary file in this directory. This file is deleted when the process closes, when the file is closed. */ createTempFile: function() { //Unix: uses [mkstemp] and [this.openFile] //Windows: maps to [GetTempFileName] + [CreateFile] http://msdn.microsoft.com/en-us/library/windows/desktop/aa363875%28v=vs.85%29.aspx }, /** * Open a subdirectory of this directory. * * @param {string} leafName The platform-specific name of the directory. * @param {number=} accessMode A or-ing of flags, as specified by [FileDescriptor.OpenDir.Access] * * @returns {DirectoryDescriptor} a descriptor which may be used to access this directory */ openDirectory: function(leafName, accessMode) { //Unix: lazy //Windows: lazy }, /** * Create a temporary directory. * * Note: For the time being, there is no guarantee that the temporary directory will be cleaned * * @returns {DirectoryDescriptor} a descriptor which may be used to access this directory */ createTempDirectory: function() { }, /** * Apply a treatment to all files in the directory. * * Note: objects of type DirectoryDescriptor are iterable. Therefore, you can also loop through them using a standard [for..in]. * * @param {(string|regexp|(function(string): boolean)) =} filter. If a [string], uses platform-specific filtering. * @param {function(string, FileDescriptor.FileInfo, number)} onFile A function called for each file in the directory, with the name of the file, a (lazy) file info for that file and a file number. If the function returns anything [null], the loop stops immediately and returns the value returned by that function. * * @returns The first value returned by [onFile], or [undefined] otherwise. */ forEachFile: function(filter, onFile) { //Unix: maps to [opendir], [dfd], [readdir]/[readdir64], lazy calls to [stat] //Windows: maps to [FindFirstFile], [FindNextFile], [Close] } }