JSFileApi

From MozillaWiki
Revision as of 14:15, 30 September 2011 by Yoric (talk | contribs)
Jump to navigation Jump to search

Module FileUtilities

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
    },


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
    },

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
    },

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(){}

Instances of FileDescriptor

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]
    },

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]
    },

Attributes

    /**
     * Gather information about the file
     *
     * @return {FileUtilities.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
    },

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
    },

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
    }

Not implemented

  • chmod, chown -- very different between platforms - might implement platform-specific functions
  • select, poll, ... -- very different between platforms, higher level
  • mmap -- probably feasible, just might require additional API

Instances of DirectoryDescriptor

Opening/creating

    /**
     * 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()
    {
    },

Accessing contents

    /**
     * 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. If a regexp or a function, uses high-level 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]