ServerJS/API/file: Difference between revisions

From MozillaWiki
< ServerJS‎ | API
Jump to navigation Jump to search
m (→‎Tier 1: added another open syntax option)
(New draft.)
Line 1: Line 1:
= Tier 1 =
= Tier 1 =
This tier establishes a basis with binary IO and basic string manipulation for paths.


The require('file') module would provide support the File System API.  In turn, the File System API would provide all methods that deal with path strings.  File System API functions would return file stream objects, directory objects, and file stat objects.  File stream objects would, for securability, be unaware of their corresponding path, and keep their underlying file system connection, albeit a file descriptor or FILE*, and their parent directory link, secret.
The require('file') module would provide support the File System API.  In turn, the File System API would provide all methods that deal with path strings.  File System API functions would return file stream objects, directory objects, and file stat objects.  File stream objects would, for securability, be unaware of their corresponding path, and keep their underlying file system connection, albeit a file descriptor or FILE*, and their parent directory link, secret.
The File System API would provide the following constants:
* SEPARATOR "/" or system specific analog, like ":" or "\".
* PARENT ".." or system specific analog.
* SELF "." or system specific analog.
* ROOT "/" or system specific analog, like "C:\".


The File System API would provide the following methods:
The File System API would provide the following methods:


* normal: removes '.' path components and simplifies '..' paths, if possible for a given path.  If the file system is case sensitive, transforms all letters to lower-case to make them unambiguous.
* join(...paths:Strings...): takes a variadic list of path Strings, joins them on the directory separator, and normalizes the result.
 
* split(path:String): returns a string split on the file system's directory separator.
 
* resolve(...paths:Strings...): marches through a list of variadic absolute or relative path Strings, resolving the next path relative to the previous and returning the ultimate destination path.  This is analogous to navigating to the fully qualified URL of a relative URL on a given page.  Unlike "join", which presumes that the base path is always a directory, "resolve" considers a directory separator at the end of a path an indication that the path must be resolved off of the directory rather than the leaf "file".  For example, resolve("a", "b") returns "b", but resolve("a/", "b") returns "a/b" on a system with "/" as its directory separator.  Resolving a fully qualified path relative to any base path returns the fully qualified path, like resolve("a", "/") == "/"Resolve is purely a string manipulation routine and does not use information about the underlying file system.


* absolute: returns the absolute path, starting with the root of this file system object, for the given path, resolved relative to the current working directory. If the file system supports home directory aliases, absolute resolves those from the root of the file system. The resulting path is in normal form.  On most systems, this is equivalent to expanding any user directory alias, joining the path to the current working directory, and normalizing the result.
* relative(from, to): returns the relative path from one path to another using only ".." to traverse up to the two paths' common ancestor.


* canonical: returns the canonical path to a given abstract path.  Canonical paths are both absolute and intrinsic, such that all paths that refer to a given file (whether it exists or not) have the same corresponding canonical path.  This function may not communicate information about the true parent directories of files in chroot environments.  This function is equivalent to expanding a user directory alias, joining the given path to the current working directory, joining all symbolic links along the path, and normalizing the result.
* normal(path:String): removes '.' path components and simplifies '..' paths, if possible for a given path.  If the file system is case sensitive, transforms all letters to lower-case to make them unambiguous.  "normal" may be implemented in terms of "resolve".
 
* absolute(path:String): returns the absolute path, starting with the root of this file system object, for the given path, resolved relative to the current working directory.  If the file system supports home directory aliases, absolute resolves those from the root of the file system.  The resulting path is in normal form.  On most systems, this is equivalent to expanding any user directory alias, joining the path to the current working directory, and normalizing the result.  "absolute" can be implemented in terms of "resolve" and "cwd".
 
* canonical(path:String): returns the canonical path to a given abstract path.  Canonical paths are both absolute and intrinsic, such that all paths that refer to a given file (whether it exists or not) have the same corresponding canonical path.  This function may not communicate information about the true parent directories of files in chroot environments.  This function is equivalent to expanding a user directory alias, joining the given path to the current working directory, joining all symbolic links along the path, and normalizing the result.  "canonical" can be implemented in terms of "cwd", "resolve", and "readlink".


* exists(path): whether a file exists at a given path: receives a path and returns whether that path, joined on the current working directory, corresponds to a file that exists.  If the file is a broken symbolic link, returns false.
* exists(path): whether a file exists at a given path: receives a path and returns whether that path, joined on the current working directory, corresponds to a file that exists.  If the file is a broken symbolic link, returns false.
Line 20: Line 39:
*# Throws an error if the corresponding file does not exist or is inaccessible.
*# Throws an error if the corresponding file does not exist or is inaccessible.


* list(path): returns a traversable, indexable representation of the names of files in a particular directory.
* list(path): returns an Array of file name strings.
*# The returned object implements the Array API for indexing, and may in fact be an Array if the underlying implementation is not sophhisticated enough to do lazy indexing.  The prototype of the returned object contains all of the Array generics like "push", "pop", and such.
*# The returned object may be immutable.
*# The returned object may be immutable.
*# The returned object must implement "next" and "prev", which walk backward and forward among the file names in the directory.  Both throw an exception when they are beyond the bounds of the directory.
*# The path is resolved relative to the current working directory.
*# The path is resolved relative to the current working directory.
*# Throws an error if the directory does not exist or is inaccessible.
*# Throws an error if the directory does not exist or is inaccessible.


* open(path, mode, permissions, encoding) or open(path, mode, {keywords}) or open(path, {keywords}) or open({keywords}): returns an IO stream object that supports the requested mode and encoding.
* open(path, mode) or open({options})
*# The encoding must be undefined, "utf-8", or "utf-16".  Other encodings may be specified in the future.
*# options may include {path, mode} and more in a later, more detailed specification.
*## An undefined encoding means "binary", and implies that read and write methods will operate on byte array objects (not yet specified) instead of strings.  The "cookie" returned by "tell" and accepted by "seek" can only be an integer for binary encoding (although this tier does not specify those methods).
*# The mode is a String and may contain:
*# The mode is a String and may contain:
*## "r" that means that the stream may be read, and implies that the "read", "readLine", "readLines", "next", and "iter" methods must be supported by the returned stream object.  "readLine" returns "" on EOF, and "next" throws an error instead.  "iter" returns the stream object itself.  "readLine" returns a string excluding the newline character.
*## "r" that means that the stream may be read, and implies that the "read", "readLine", "readLines", "next", and "iter" methods must be supported by the returned stream object.  "readLine" returns "" on EOF, and "next" throws an error instead.  "iter" returns the stream object itself.  "readLine" returns a string excluding the newline character.
Line 35: Line 51:
*## "a" that means that the stream's position will begin at the end of the stream, and that the file will be created but not truncated.
*## "a" that means that the stream's position will begin at the end of the stream, and that the file will be created but not truncated.
*## "+" that means that the stream will not be truncated.
*## "+" that means that the stream will not be truncated.
*## other options may be added in the future for advisory locks.
*## the "b" option known in other languages will not be implemented since it is really an encoding argument.
*# The permissions must be an integer of Unix style permissions.  Other objects may be permitted in a later specification, like a Stat object or duck-type thereof.
*# The path is resolved relative to the current working directory.
*# The path is resolved relative to the current working directory.
*# Throws an error if the specified stream cannot be created.
*# Throws an error if the specified stream cannot be created.
*# close(): Closes the stream. Should be called automatically when the mode is changed, and when the garbage collector collects its last reference.
*# close(): Closes the stream. Should be called automatically when the mode is changed, and when the garbage collector collects its last reference.
* read(path, [mode, [options]]): opens, reads, and closes a file, returning its content.
* write(path, content, [mode, [options]]): opens, writes, flushes, and closes a file with the given content.


= Tier 2 =
= Tier 2 =
This tier adds support for encoded and buffered text IO and a chainable Path type.
* open(path, mode, {options}) or open({options})
*# options may include {path, mode, charset, recordSeparator, fieldSeparator} and more in a later, more detailed specification.
*# The mode is a String and may contain:
*## "b" for ByteArray and ByteString streams.
*## "t" for String and Array streams (default)
*# "charset" may be any IANA charset identifier, case-insensitive.  "open" may throw an error if the charset is not supported.  "charset" defaults to a system-specific encoding if the stream is in text mode with no charset provided.
*# returns a stream type.  While the type names need not correspond to these name, these are used as an interal reference in this document for what the minimum interface of those streams must contain.
*## Returns a BinaryReadStream for "b" and "r" modes.
*## Returns a BinaryWriteStream for "b" and "w" or "a" modes.
*## Returns a BinaryRandomStream for "b" and "+" modes.
*## Returns a TextReadStream wrapper for "t"  and "r" modes.
*## Returns a TextWriteStream wrapper for "t" and "w" modes.
* BinaryReadStream
** read() -> all:ByteString
** read(max:Number) -> actual:Number
** readInto(buffer:Array|ByteArray, [begin:Number, [end:Number]]) -> actual:Number
* BinaryWriteStream
** write(buffer:Array|ByteArray|ByteString)
** flush()
* BinaryRandomStream < BinaryReadStream < BinaryWriteStream
** tell() -> position:Number)
** seek(position:Number, whence:enumerated)
* TextReadStream
** raw -> a BinaryReadStream
** readLine() -> String -- returns "" if no data is available before EOF.  Otherwise, includes the "recordSeparator".
** readLines() -> Array * String
** next() -> String -- throws a StopIteration if no data is available before EOF.
** input() -> returns "readLine" without the "recordSeparator".
* TextWriteStream
** raw -> a BinaryWriteStream
** write(buffer:String)
** writeLine(buffer:String)
** print(...String...) -- writes a "fieldSeparator" delimited and "recordSeparator" terminated line.
** flush()
The File System API would provide the following additional methods:
* basename(path:String) -> String
* copy(from:String, to:String) -> copies a file by reading one and writing the other in binary modes.
* dirname(path:String) -> String
* extname(path:String) -> String
* isDirectory(path:String) -> Boolean
* isFile(path:String) -> Boolean
* isLink(path:String) -> Boolean
* isReadable(path:String) -> Boolean
* isWritable(path:String) -> Boolean
* mkdir(path:String)
* mkdirs(path:String)
* move(from:String, to:String)
* mtime() -> lastModification:Date|null
* remove(path:String)
* rename(path:String, name:String)
* rmdir(path:String)
* rmtree(path:String)
* same(from:String, to:String) -> Boolean -- whether the two files are identical, in that they come from the same file system, same device, and have the same node and corresponding storage, such that modifying one would modify the other.
* size(path:String) -> bytes:Number
* touch(path:String, [mtime:Date])
The Path object closes on both a file system and a path String.  The file system mediates all interaction with the underlying storage, so a Path only provides a convenient interface for chaining operations that manipulate a path string.  All of the methods of path are polymorphic (meaning late-bound) and curried (meaning the enclosed path String is passed to the corresponding file system method).
* path(path:String) -> path:Path
* new Path(path:String, [fs:FileSystem]) -> path:Path
*# absolute() -> path:Path
*# basename() -> path:Path
*# canonical() -> path:Path
*# copy(to:Path)
*# dirname() -> path:Path
*# exists() -> Boolean
*# extname() -> String
*# from(path:String|Path) -> path:Path -- an alias for "relative" that finds the relative path from the given path to this one.
*# isDirectory() -> Boolean
*# isFile() -> Boolean
*# isLink() -> Boolean
*# isReadable() -> Boolean
*# isWritable() -> Boolean
*# join(...paths...) -> path:Path
*# list() -> Array * Path
*# mkdir()
*# mkdirs()
*# move(to:String)
*# mtime() -> Date
*# normal() -> path:Path
*# open(mode, [options]) -> stream:{Text,Binary}{Read,Write,RW,Random}Stream
*# read([mode, [options]]) -> {Byte,}String
*# remove()
*# rename(name:String) -- rename is distinct from move only in that the new name is resolved relative to the former path, rather than the current working directory.
*# resolve(...paths...) -> path:Path
*# rmdir()
*# rmtree()
*# same(as:Path|String) -> Boolean
*# size() -> Number
*# split() -> parts:(Array * String)
*# stat() -> stat:Object {mtime:Date, size:Number}
*# to(path:String|Path) -> path:Path -- an alias for "relative" that finds the relative path from this path to the given one.
*# touch([mtime:Date])
*# write(data:ByteString|ByteArray|Array|String, [mode, [options]])
= Tier 3 =
This tier adds support for random access IO, locks, canonical IO (non-blocking), more comprehensive stat access and mutation, and temporary files and directories, and symbolic links.
* open(path, mode, {options}) or open({options})
*# options may include {path, mode, charset, permissions, owner, groupOwner} and more in a later, more detailed specification.
*# The permissions must be an integer of Unix style permissions.  Other objects may be permitted in a later specification, like a Stat object or duck-type thereof.
* copyStat(from:String, to:String)
Path:
* copyStat(to:String|Path)


In progress.  More information about other potential additions, please refer to the [https://wiki.mozilla.org/ServerJS/API/file/Names proposed names].
In progress.  More information about other potential additions, please refer to the [https://wiki.mozilla.org/ServerJS/API/file/Names proposed names].

Revision as of 05:44, 25 April 2009

Tier 1

This tier establishes a basis with binary IO and basic string manipulation for paths.

The require('file') module would provide support the File System API. In turn, the File System API would provide all methods that deal with path strings. File System API functions would return file stream objects, directory objects, and file stat objects. File stream objects would, for securability, be unaware of their corresponding path, and keep their underlying file system connection, albeit a file descriptor or FILE*, and their parent directory link, secret.


The File System API would provide the following constants:

  • SEPARATOR "/" or system specific analog, like ":" or "\".
  • PARENT ".." or system specific analog.
  • SELF "." or system specific analog.
  • ROOT "/" or system specific analog, like "C:\".


The File System API would provide the following methods:

  • join(...paths:Strings...): takes a variadic list of path Strings, joins them on the directory separator, and normalizes the result.
  • split(path:String): returns a string split on the file system's directory separator.
  • resolve(...paths:Strings...): marches through a list of variadic absolute or relative path Strings, resolving the next path relative to the previous and returning the ultimate destination path. This is analogous to navigating to the fully qualified URL of a relative URL on a given page. Unlike "join", which presumes that the base path is always a directory, "resolve" considers a directory separator at the end of a path an indication that the path must be resolved off of the directory rather than the leaf "file". For example, resolve("a", "b") returns "b", but resolve("a/", "b") returns "a/b" on a system with "/" as its directory separator. Resolving a fully qualified path relative to any base path returns the fully qualified path, like resolve("a", "/") == "/". Resolve is purely a string manipulation routine and does not use information about the underlying file system.
  • relative(from, to): returns the relative path from one path to another using only ".." to traverse up to the two paths' common ancestor.
  • normal(path:String): removes '.' path components and simplifies '..' paths, if possible for a given path. If the file system is case sensitive, transforms all letters to lower-case to make them unambiguous. "normal" may be implemented in terms of "resolve".
  • absolute(path:String): returns the absolute path, starting with the root of this file system object, for the given path, resolved relative to the current working directory. If the file system supports home directory aliases, absolute resolves those from the root of the file system. The resulting path is in normal form. On most systems, this is equivalent to expanding any user directory alias, joining the path to the current working directory, and normalizing the result. "absolute" can be implemented in terms of "resolve" and "cwd".
  • canonical(path:String): returns the canonical path to a given abstract path. Canonical paths are both absolute and intrinsic, such that all paths that refer to a given file (whether it exists or not) have the same corresponding canonical path. This function may not communicate information about the true parent directories of files in chroot environments. This function is equivalent to expanding a user directory alias, joining the given path to the current working directory, joining all symbolic links along the path, and normalizing the result. "canonical" can be implemented in terms of "cwd", "resolve", and "readlink".
  • exists(path): whether a file exists at a given path: receives a path and returns whether that path, joined on the current working directory, corresponds to a file that exists. If the file is a broken symbolic link, returns false.
  • stat(path): returns an object that represents a snapshot of the information about given file.
    1. The stat file must contain the following properties:
      1. mtime: the time that the file was last modified
      2. other properties will be specified in a future specification, including other times, ownership, permissions, and size.
    2. The path is resolved relative to the current working directory.
    3. Throws an error if the corresponding file does not exist or is inaccessible.
  • list(path): returns an Array of file name strings.
    1. The returned object may be immutable.
    2. The path is resolved relative to the current working directory.
    3. Throws an error if the directory does not exist or is inaccessible.
  • open(path, mode) or open({options})
    1. options may include {path, mode} and more in a later, more detailed specification.
    2. The mode is a String and may contain:
      1. "r" that means that the stream may be read, and implies that the "read", "readLine", "readLines", "next", and "iter" methods must be supported by the returned stream object. "readLine" returns "" on EOF, and "next" throws an error instead. "iter" returns the stream object itself. "readLine" returns a string excluding the newline character.
      2. "w" that means that the stream may be written to, and implies that the "write", "writeLine", and "writeLines" methods must be supported by the stream object. Also implies that the file will be created or truncated if necessary, if not overridden by the "a" or "+" flags.
      3. "a" that means that the stream's position will begin at the end of the stream, and that the file will be created but not truncated.
      4. "+" that means that the stream will not be truncated.
    3. The path is resolved relative to the current working directory.
    4. Throws an error if the specified stream cannot be created.
    5. close(): Closes the stream. Should be called automatically when the mode is changed, and when the garbage collector collects its last reference.
  • read(path, [mode, [options]]): opens, reads, and closes a file, returning its content.
  • write(path, content, [mode, [options]]): opens, writes, flushes, and closes a file with the given content.


Tier 2

This tier adds support for encoded and buffered text IO and a chainable Path type.

  • open(path, mode, {options}) or open({options})
    1. options may include {path, mode, charset, recordSeparator, fieldSeparator} and more in a later, more detailed specification.
    2. The mode is a String and may contain:
      1. "b" for ByteArray and ByteString streams.
      2. "t" for String and Array streams (default)
    3. "charset" may be any IANA charset identifier, case-insensitive. "open" may throw an error if the charset is not supported. "charset" defaults to a system-specific encoding if the stream is in text mode with no charset provided.
    4. returns a stream type. While the type names need not correspond to these name, these are used as an interal reference in this document for what the minimum interface of those streams must contain.
      1. Returns a BinaryReadStream for "b" and "r" modes.
      2. Returns a BinaryWriteStream for "b" and "w" or "a" modes.
      3. Returns a BinaryRandomStream for "b" and "+" modes.
      4. Returns a TextReadStream wrapper for "t" and "r" modes.
      5. Returns a TextWriteStream wrapper for "t" and "w" modes.
  • BinaryReadStream
    • read() -> all:ByteString
    • read(max:Number) -> actual:Number
    • readInto(buffer:Array|ByteArray, [begin:Number, [end:Number]]) -> actual:Number
  • BinaryWriteStream
    • write(buffer:Array|ByteArray|ByteString)
    • flush()
  • BinaryRandomStream < BinaryReadStream < BinaryWriteStream
    • tell() -> position:Number)
    • seek(position:Number, whence:enumerated)
  • TextReadStream
    • raw -> a BinaryReadStream
    • readLine() -> String -- returns "" if no data is available before EOF. Otherwise, includes the "recordSeparator".
    • readLines() -> Array * String
    • next() -> String -- throws a StopIteration if no data is available before EOF.
    • input() -> returns "readLine" without the "recordSeparator".
  • TextWriteStream
    • raw -> a BinaryWriteStream
    • write(buffer:String)
    • writeLine(buffer:String)
    • print(...String...) -- writes a "fieldSeparator" delimited and "recordSeparator" terminated line.
    • flush()

The File System API would provide the following additional methods:

  • basename(path:String) -> String
  • copy(from:String, to:String) -> copies a file by reading one and writing the other in binary modes.
  • dirname(path:String) -> String
  • extname(path:String) -> String
  • isDirectory(path:String) -> Boolean
  • isFile(path:String) -> Boolean
  • isLink(path:String) -> Boolean
  • isReadable(path:String) -> Boolean
  • isWritable(path:String) -> Boolean
  • mkdir(path:String)
  • mkdirs(path:String)
  • move(from:String, to:String)
  • mtime() -> lastModification:Date|null
  • remove(path:String)
  • rename(path:String, name:String)
  • rmdir(path:String)
  • rmtree(path:String)
  • same(from:String, to:String) -> Boolean -- whether the two files are identical, in that they come from the same file system, same device, and have the same node and corresponding storage, such that modifying one would modify the other.
  • size(path:String) -> bytes:Number
  • touch(path:String, [mtime:Date])

The Path object closes on both a file system and a path String. The file system mediates all interaction with the underlying storage, so a Path only provides a convenient interface for chaining operations that manipulate a path string. All of the methods of path are polymorphic (meaning late-bound) and curried (meaning the enclosed path String is passed to the corresponding file system method).

  • path(path:String) -> path:Path
  • new Path(path:String, [fs:FileSystem]) -> path:Path
    1. absolute() -> path:Path
    2. basename() -> path:Path
    3. canonical() -> path:Path
    4. copy(to:Path)
    5. dirname() -> path:Path
    6. exists() -> Boolean
    7. extname() -> String
    8. from(path:String|Path) -> path:Path -- an alias for "relative" that finds the relative path from the given path to this one.
    9. isDirectory() -> Boolean
    10. isFile() -> Boolean
    11. isLink() -> Boolean
    12. isReadable() -> Boolean
    13. isWritable() -> Boolean
    14. join(...paths...) -> path:Path
    15. list() -> Array * Path
    16. mkdir()
    17. mkdirs()
    18. move(to:String)
    19. mtime() -> Date
    20. normal() -> path:Path
    21. open(mode, [options]) -> stream:{Text,Binary}{Read,Write,RW,Random}Stream
    22. read([mode, [options]]) -> {Byte,}String
    23. remove()
    24. rename(name:String) -- rename is distinct from move only in that the new name is resolved relative to the former path, rather than the current working directory.
    25. resolve(...paths...) -> path:Path
    26. rmdir()
    27. rmtree()
    28. same(as:Path|String) -> Boolean
    29. size() -> Number
    30. split() -> parts:(Array * String)
    31. stat() -> stat:Object {mtime:Date, size:Number}
    32. to(path:String|Path) -> path:Path -- an alias for "relative" that finds the relative path from this path to the given one.
    33. touch([mtime:Date])
    34. write(data:ByteString|ByteArray|Array|String, [mode, [options]])


Tier 3

This tier adds support for random access IO, locks, canonical IO (non-blocking), more comprehensive stat access and mutation, and temporary files and directories, and symbolic links.

  • open(path, mode, {options}) or open({options})
    1. options may include {path, mode, charset, permissions, owner, groupOwner} and more in a later, more detailed specification.
    2. The permissions must be an integer of Unix style permissions. Other objects may be permitted in a later specification, like a Stat object or duck-type thereof.
  • copyStat(from:String, to:String)

Path:

  • copyStat(to:String|Path)

In progress. More information about other potential additions, please refer to the proposed names.