sproutit-narwhal 0.1.106
Sign up to get free protection for your applications and to get access to all the features.
- data/DISTRIBUTION.yml +15 -0
- data/README.md +86 -0
- data/Rakefile +349 -0
- data/VERSION.yml +7 -0
- data/bin/activate +50 -0
- data/bin/activate.bash +50 -0
- data/bin/activate.cmd +3 -0
- data/bin/js +67 -0
- data/bin/json +2 -0
- data/bin/narwhal +67 -0
- data/bin/narwhal.cmd +29 -0
- data/bin/sea +45 -0
- data/bin/sea.cmd +25 -0
- data/bin/tusk +2 -0
- data/bin/tusk.cmd +5 -0
- data/catalog.json +902 -0
- data/docs/available-packages.md +32 -0
- data/docs/browser-api-plan.md +290 -0
- data/docs/browser-api.md +153 -0
- data/docs/download.md +25 -0
- data/docs/engines.md +32 -0
- data/docs/json-tool.md +121 -0
- data/docs/lib/binary.wiki +242 -0
- data/docs/lib/file.wiki +325 -0
- data/docs/lib/os/popen.md +70 -0
- data/docs/modules.md +38 -0
- data/docs/narwhal.md +487 -0
- data/docs/packages-howto.md +32 -0
- data/docs/packages.md +30 -0
- data/docs/posts/2009-07-29-hello-0.1.md +19 -0
- data/docs/quick-start.md +69 -0
- data/docs/sea.md +49 -0
- data/engines/browser/lib/binary.js +2 -0
- data/engines/browser/lib/reactor.js +21 -0
- data/engines/browser/lib/system.js +3 -0
- data/engines/default/lib/array.js +164 -0
- data/engines/default/lib/binary-engine.js +53 -0
- data/engines/default/lib/binary.js +755 -0
- data/engines/default/lib/date.js +8 -0
- data/engines/default/lib/file-engine.js +119 -0
- data/engines/default/lib/function.js +119 -0
- data/engines/default/lib/global.js +11 -0
- data/engines/default/lib/io-engine.js +26 -0
- data/engines/default/lib/json.js +488 -0
- data/engines/default/lib/object.js +69 -0
- data/engines/default/lib/os-engine.js +3 -0
- data/engines/default/lib/reactor.js +12 -0
- data/engines/default/lib/string.js +84 -0
- data/engines/default/lib/system.js +20 -0
- data/engines/default/lib/worker.js +133 -0
- data/engines/jsc/README.md +18 -0
- data/engines/jsc/bootstrap.js +53 -0
- data/engines/jsc/deps/http-parser/LICENSE +77 -0
- data/engines/jsc/deps/http-parser/README.md +145 -0
- data/engines/jsc/deps/http-parser/http_parser.c +6087 -0
- data/engines/jsc/deps/http-parser/http_parser.h +141 -0
- data/engines/jsc/deps/http-parser/http_parser.rl +500 -0
- data/engines/jsc/deps/http-parser/test.c +858 -0
- data/engines/jsc/include/binary-engine.h +11 -0
- data/engines/jsc/include/io-engine.h +23 -0
- data/engines/jsc/include/narwhal.h +427 -0
- data/engines/jsc/lib/file-engine.js +31 -0
- data/engines/jsc/lib/http.js +1 -0
- data/engines/jsc/lib/io-engine.js +202 -0
- data/engines/jsc/lib/os-engine.js +25 -0
- data/engines/jsc/lib/system.js +18 -0
- data/engines/jsc/lib/zip.js +1 -0
- data/engines/jsc/narwhal-jsc.c +273 -0
- data/engines/jsc/narwhal.c +29 -0
- data/engines/jsc/package.json +8 -0
- data/engines/jsc/src/binary-engine.cc +290 -0
- data/engines/jsc/src/file-engine.cc +405 -0
- data/engines/jsc/src/io-engine.cc +423 -0
- data/engines/jsc/src/jack/handler/jill.cc +710 -0
- data/engines/jsc/src/os-engine.cc +210 -0
- data/engines/rhino/bin/narwhal-rhino +68 -0
- data/engines/rhino/bin/narwhal-rhino.cmd +34 -0
- data/engines/rhino/bootstrap.js +119 -0
- data/engines/rhino/jars/jline.jar +0 -0
- data/engines/rhino/jars/jna.jar +0 -0
- data/engines/rhino/jars/js.jar +0 -0
- data/engines/rhino/lib/binary-engine.js +83 -0
- data/engines/rhino/lib/concurrency.js +6 -0
- data/engines/rhino/lib/event-queue.js +18 -0
- data/engines/rhino/lib/file-engine.js +216 -0
- data/engines/rhino/lib/http-client-engine.js +90 -0
- data/engines/rhino/lib/http-engine.js +10 -0
- data/engines/rhino/lib/io-engine.js +347 -0
- data/engines/rhino/lib/md5-engine.js +40 -0
- data/engines/rhino/lib/os-engine.js +150 -0
- data/engines/rhino/lib/packages-engine.js +71 -0
- data/engines/rhino/lib/sandbox-engine.js +70 -0
- data/engines/rhino/lib/system.js +38 -0
- data/engines/rhino/lib/worker-engine.js +23 -0
- data/engines/rhino/lib/zip.js +78 -0
- data/engines/rhino/package.json +4 -0
- data/engines/secure/lib/file.js +6 -0
- data/engines/secure/lib/system.js +6 -0
- data/engines/template/bin/narwhal-engine-name +32 -0
- data/engines/template/bootstrap.js +40 -0
- data/engines/template/lib/file-engine.js +118 -0
- data/engines/template/lib/system.js +17 -0
- data/examples/browser-deployment-jackconfig.js +35 -0
- data/examples/fibonacci-worker.js +35 -0
- data/examples/fibonacci.js +19 -0
- data/examples/hello +2 -0
- data/examples/narwhal +3 -0
- data/examples/not-quite-a-quine.js +1 -0
- data/extconf.rb +44 -0
- data/gem_bin/narwhal +5 -0
- data/gem_bin/sea +4 -0
- data/gem_bin/tusk +4 -0
- data/lib/args.js +849 -0
- data/lib/base16.js +16 -0
- data/lib/base64.js +120 -0
- data/lib/codec/base64.js +8 -0
- data/lib/crc32.js +60 -0
- data/lib/file-bootstrap.js +187 -0
- data/lib/file.js +659 -0
- data/lib/hash.js +28 -0
- data/lib/hashp.js +65 -0
- data/lib/html.js +16 -0
- data/lib/http-client.js +134 -0
- data/lib/http.js +17 -0
- data/lib/io.js +98 -0
- data/lib/jsmin.js +315 -0
- data/lib/jsonpath.js +89 -0
- data/lib/logger.js +55 -0
- data/lib/md4.js +146 -0
- data/lib/md5.js +164 -0
- data/lib/mime.js +166 -0
- data/lib/narwhal.js +102 -0
- data/lib/narwhal/client.js +261 -0
- data/lib/narwhal/compile.js +99 -0
- data/lib/narwhal/env.js +140 -0
- data/lib/narwhal/inline.js +106 -0
- data/lib/narwhal/json.js +324 -0
- data/lib/narwhal/json.md +178 -0
- data/lib/narwhal/repl.js +96 -0
- data/lib/narwhal/server-test.js +6 -0
- data/lib/narwhal/server.js +270 -0
- data/lib/narwhal/tusk.js +170 -0
- data/lib/narwhal/tusk/bin.js +13 -0
- data/lib/narwhal/tusk/bundle.js +0 -0
- data/lib/narwhal/tusk/catalog.js +22 -0
- data/lib/narwhal/tusk/clone.js +66 -0
- data/lib/narwhal/tusk/consolidate.js +25 -0
- data/lib/narwhal/tusk/create-catalog.js +80 -0
- data/lib/narwhal/tusk/engine.js +42 -0
- data/lib/narwhal/tusk/freeze.js +0 -0
- data/lib/narwhal/tusk/init.js +56 -0
- data/lib/narwhal/tusk/install.js +288 -0
- data/lib/narwhal/tusk/list.js +20 -0
- data/lib/narwhal/tusk/orphans.js +0 -0
- data/lib/narwhal/tusk/reheat.js +15 -0
- data/lib/narwhal/tusk/remove.js +15 -0
- data/lib/narwhal/tusk/search.js +145 -0
- data/lib/narwhal/tusk/update.js +21 -0
- data/lib/narwhal/tusk/upgrade.js +0 -0
- data/lib/os.js +33 -0
- data/lib/packages.js +423 -0
- data/lib/printf.js +169 -0
- data/lib/promise.js +352 -0
- data/lib/querystring.js +176 -0
- data/lib/ref-send.js +257 -0
- data/lib/regexp.js +12 -0
- data/lib/sandbox.js +422 -0
- data/lib/sha.js +112 -0
- data/lib/sha256.js +102 -0
- data/lib/struct.js +228 -0
- data/lib/term.js +179 -0
- data/lib/test/assert.js +95 -0
- data/lib/test/equiv.js +188 -0
- data/lib/test/jsdump.js +165 -0
- data/lib/test/runner.js +129 -0
- data/lib/unload.js +13 -0
- data/lib/uri.js +378 -0
- data/lib/url.js +5 -0
- data/lib/utf8.js +64 -0
- data/lib/util.js +985 -0
- data/lib/uuid.js +89 -0
- data/lib/xregexp.js +521 -0
- data/local.json.template +1 -0
- data/narwhal.gemspec +105 -0
- data/narwhal.js +213 -0
- data/package.json +26 -0
- data/packages/readline/engines/default/lib/readline.js +4 -0
- data/packages/readline/engines/rhino/lib/readline.js +6 -0
- data/packages/readline/package.json +5 -0
- data/sources.json +207 -0
- data/tests/all-tests.js +17 -0
- data/tests/args.js +31 -0
- data/tests/args/domain.js +215 -0
- data/tests/args/options.js +36 -0
- data/tests/args/shifting.js +92 -0
- data/tests/args/validation.js +31 -0
- data/tests/base64.js +23 -0
- data/tests/commonjs.js +3 -0
- data/tests/commonjs/all-tests.js +12 -0
- data/tests/commonjs/bytearray-encodings-tests.js +69 -0
- data/tests/commonjs/bytearray-tests.js +465 -0
- data/tests/commonjs/bytestring-encodings-tests.js +89 -0
- data/tests/commonjs/bytestring-tests.js +263 -0
- data/tests/commonjs/es5/all-tests.js +3 -0
- data/tests/commonjs/es5/bind.js +29 -0
- data/tests/commonjs/file-tests.js +315 -0
- data/tests/commonjs/file/dirname.js +31 -0
- data/tests/commonjs/file/extension.js +45 -0
- data/tests/commonjs/file/is-absolute.js +11 -0
- data/tests/commonjs/file/iterator.js +101 -0
- data/tests/commonjs/file/normal.js +27 -0
- data/tests/commonjs/file/path.js +17 -0
- data/tests/commonjs/file/relative.js +42 -0
- data/tests/commonjs/file/resolve.js +44 -0
- data/tests/commonjs/module-tests.js +9 -0
- data/tests/commonjs/modules/absolute/b.js +1 -0
- data/tests/commonjs/modules/absolute/program.js +5 -0
- data/tests/commonjs/modules/absolute/submodule/a.js +3 -0
- data/tests/commonjs/modules/absolute/test.js +9 -0
- data/tests/commonjs/modules/all-tests.js +47 -0
- data/tests/commonjs/modules/config.js +11 -0
- data/tests/commonjs/modules/cyclic/a.js +4 -0
- data/tests/commonjs/modules/cyclic/b.js +4 -0
- data/tests/commonjs/modules/cyclic/program.js +10 -0
- data/tests/commonjs/modules/cyclic/test.js +9 -0
- data/tests/commonjs/modules/determinism/program.js +3 -0
- data/tests/commonjs/modules/determinism/submodule/a.js +8 -0
- data/tests/commonjs/modules/determinism/submodule/b.js +2 -0
- data/tests/commonjs/modules/determinism/test.js +9 -0
- data/tests/commonjs/modules/exactExports/a.js +3 -0
- data/tests/commonjs/modules/exactExports/program.js +4 -0
- data/tests/commonjs/modules/exactExports/test.js +9 -0
- data/tests/commonjs/modules/hasOwnProperty/hasOwnProperty.js +0 -0
- data/tests/commonjs/modules/hasOwnProperty/program.js +3 -0
- data/tests/commonjs/modules/hasOwnProperty/test.js +9 -0
- data/tests/commonjs/modules/hasOwnProperty/toString.js +0 -0
- data/tests/commonjs/modules/method/a.js +12 -0
- data/tests/commonjs/modules/method/program.js +8 -0
- data/tests/commonjs/modules/method/test.js +9 -0
- data/tests/commonjs/modules/missing/program.js +8 -0
- data/tests/commonjs/modules/missing/test.js +9 -0
- data/tests/commonjs/modules/monkeys/a.js +1 -0
- data/tests/commonjs/modules/monkeys/program.js +4 -0
- data/tests/commonjs/modules/monkeys/test.js +9 -0
- data/tests/commonjs/modules/nested/a/b/c/d.js +3 -0
- data/tests/commonjs/modules/nested/program.js +3 -0
- data/tests/commonjs/modules/nested/test.js +9 -0
- data/tests/commonjs/modules/relative/program.js +5 -0
- data/tests/commonjs/modules/relative/submodule/a.js +1 -0
- data/tests/commonjs/modules/relative/submodule/b.js +2 -0
- data/tests/commonjs/modules/relative/test.js +9 -0
- data/tests/commonjs/modules/transitive/a.js +1 -0
- data/tests/commonjs/modules/transitive/b.js +1 -0
- data/tests/commonjs/modules/transitive/c.js +3 -0
- data/tests/commonjs/modules/transitive/program.js +3 -0
- data/tests/commonjs/modules/transitive/test.js +9 -0
- data/tests/file/all-tests.js +61 -0
- data/tests/file/fnmatch.js +102 -0
- data/tests/file/glob.js +466 -0
- data/tests/file/match.js +102 -0
- data/tests/global.js +6 -0
- data/tests/global/array.js +19 -0
- data/tests/hashes.js +94 -0
- data/tests/html.js +13 -0
- data/tests/io/stringio.js +21 -0
- data/tests/os/all-tests.js +4 -0
- data/tests/os/popen.js +41 -0
- data/tests/os/system.js +22 -0
- data/tests/printf.js +123 -0
- data/tests/query-string.js +87 -0
- data/tests/sandbox/byte-io.js +20 -0
- data/tests/sandbox/fileName.js +3 -0
- data/tests/sandbox/foo.js +0 -0
- data/tests/sandbox/reload.js +79 -0
- data/tests/string.js +35 -0
- data/tests/uri.js +41 -0
- data/tests/util/all-tests.js +79 -0
- data/tests/util/array.js +207 -0
- data/tests/util/array/is-arguments.js +29 -0
- data/tests/util/array/is-array-like.js +29 -0
- data/tests/util/case.js +9 -0
- data/tests/util/collection.js +104 -0
- data/tests/util/eq.js +57 -0
- data/tests/util/expand.js +45 -0
- data/tests/util/object.js +125 -0
- data/tests/util/operator.js +25 -0
- data/tests/util/range.js +19 -0
- data/tests/util/repr.js +26 -0
- data/tests/util/string.js +34 -0
- data/tests/util/unique.js +12 -0
- metadata +434 -0
data/docs/download.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
Narwhal Downloads
|
3
|
+
=================
|
4
|
+
|
5
|
+
Download a version of Narwhal then follow the [quick start guide](http://narwhaljs.org/quick-start.html) to get running!
|
6
|
+
|
7
|
+
Bleeding Edge
|
8
|
+
-------------
|
9
|
+
|
10
|
+
* [Download zip](http://github.com/tlrobinson/narwhal/zipball/master)
|
11
|
+
* [Download tar](http://github.com/tlrobinson/narwhal/tarball/master)
|
12
|
+
|
13
|
+
* Git: `git clone git://github.com/tlrobinson/narwhal.git`
|
14
|
+
|
15
|
+
* [View tree](http://github.com/tlrobinson/narwhal/tree/master)
|
16
|
+
* [View commit](http://github.com/tlrobinson/narwhal/commit/master)
|
17
|
+
|
18
|
+
|
19
|
+
Releases
|
20
|
+
--------
|
21
|
+
|
22
|
+
<div id="releases-list">Loading...</div>
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/releases.js"></script>
|
24
|
+
<script type="text/javascript" charset="utf-8" src="http://github.com/api/v2/json/repos/show/tlrobinson/narwhal/tags?callback=showreleases"></script>
|
25
|
+
|
data/docs/engines.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
Engines
|
3
|
+
=======
|
4
|
+
|
5
|
+
Narwhal is a standard library and tools for multiple JavaScript engines; each engine has its own library. Use `tusk engine {name}` to select an engine, or edit `narwhal.conf`. The following engines are presently in development:
|
6
|
+
|
7
|
+
* `rhino`: is the default and most complete engine, based on Mozilla Rhino for Java, used for out-of-the-box functionality.
|
8
|
+
* `k7`: is a `v8` based engine, in development by Sébastien Pierre.
|
9
|
+
* `helma`: is based on Rhino with extensions, being developed by Hannes Wallnöefer.
|
10
|
+
* `xulrunner`: is in development for Firefox extensions and XULRunner applications on the Spidermonkey engine by Irakli Gozalishvili, Christoph Dorn, and Zach Carter.
|
11
|
+
* `jaxer`: is an engine based on Mozilla SpiderMonkey, for deploying web pages with both server and client side scripts, being developed by Nathan L Smith.
|
12
|
+
* `v8cgi`: is based on the work of Ondrej Zara, and has not been updated in a long while.
|
13
|
+
* `default`: is a catchall engine that implements modules that can be shared among engines.
|
14
|
+
* `browser`: will eventually be available for client side loading of modules with various techniques.
|
15
|
+
* `secure`: will eventually be available for dependency injection sandboxed module systems within some other engines.
|
16
|
+
|
17
|
+
|
18
|
+
Creating new Engine Adapters
|
19
|
+
----------------------------
|
20
|
+
|
21
|
+
We have a template for new engines at `engines/template` that you can copy to `engines/{name}` and fill in the blanks. These consist of:
|
22
|
+
|
23
|
+
1. An executable (shell script or binary) at `engines/{name}/bin/narwhal-{name}` that executes the interpreter engine of choice and causes it to load a bootstrap script. This script will be loaded by `bin/narwhal` with the environment variable `NARWHAL_HOME` set to the Narwhal project directory and `NARWHAL_ENGINE_HOME` set to the engine directory. This script will be run if `NARWHAL_ENGINE` is set to your engine name. You can set `NARWHAL_DEFAULT_ENGINE` or `NARWHAL_ENGINE` in a `narwhal.conf` in your Narwhal project directory (template provided).
|
24
|
+
|
25
|
+
2. A "thunk", at `engines/{name}/bootstrap.js` that evaluates `narwhal.js` and passes the returned function a preliminary `system` object with a few required properties (`global`, `evalGlobal`, `engine`, `engines`, `print`, `evaluate`, `prefix`, `fs.read`, and `fs.isFile`). This should be enough to get to an interactive console.
|
26
|
+
|
27
|
+
3. Engine implementations for core modules, such as `file` and `system` located in `engines/{name}/lib/`. You can implement `file-engine` instead of `file` if you implement the subset of the ServerJS file API used by `lib/file.js` (and similar for `io`, `os`, `binary`, etc). The next steps are:
|
28
|
+
|
29
|
+
* system: You must implement `system.args` to be able to pass command line options to Narwhal.
|
30
|
+
|
31
|
+
* file: To enable the package system you must implement `list`, `canonical`, `mtime`, `isDirectory`, `isFile`.
|
32
|
+
|
data/docs/json-tool.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
JSON Tool Recipes
|
3
|
+
=================
|
4
|
+
|
5
|
+
List the module search paths:
|
6
|
+
|
7
|
+
json -e require.paths -np
|
8
|
+
|
9
|
+
List the package search prefixes:
|
10
|
+
|
11
|
+
json -e system.prefixes -np
|
12
|
+
|
13
|
+
List the active engine names:
|
14
|
+
|
15
|
+
json -e system.engines -np
|
16
|
+
|
17
|
+
List the prefix paths of every installed package:
|
18
|
+
|
19
|
+
json -e 'require("packages").order' -n -f directory -p
|
20
|
+
|
21
|
+
Visit the home page of every contributor to every installed package. "open" is
|
22
|
+
on Mac OS X only, but you can use "gnome-open" or "xdg-open" on Linux, or
|
23
|
+
"kde-open" on Kubuntu specifically:
|
24
|
+
|
25
|
+
json -e 'require("packages").order'
|
26
|
+
-n
|
27
|
+
-e _.contributors
|
28
|
+
-A # flatten the array
|
29
|
+
-w _.url # if they've got one
|
30
|
+
-e _.url # extract it from their Author object
|
31
|
+
-p
|
32
|
+
| sort | uniq | xargs open
|
33
|
+
|
34
|
+
List the contributors to Narwhal with field selection:
|
35
|
+
|
36
|
+
json -i package.json -j -f contributors -Anp
|
37
|
+
|
38
|
+
Use JSONPath to list the contributors:
|
39
|
+
|
40
|
+
json -i package.json -j -$ $.contributors -Anp
|
41
|
+
|
42
|
+
Enquote all of the MP3s in your collection, line by line:
|
43
|
+
|
44
|
+
find . -name '*.mp3' | json -nJp
|
45
|
+
|
46
|
+
find . -name '*.mp3' -print0 | json -n0Jp
|
47
|
+
|
48
|
+
Rename all of your MP3s so that URL encoded patterns are unescaped:
|
49
|
+
|
50
|
+
find .
|
51
|
+
-name '*.mp3'
|
52
|
+
-print0 # write null-terminated lines
|
53
|
+
| json
|
54
|
+
-n # line by line
|
55
|
+
-z0 # both read and write null-terminated lines
|
56
|
+
-c # this forces an array to
|
57
|
+
# be accumulated for reprint
|
58
|
+
-p # print in escaped form
|
59
|
+
-e 'unescape(_)' -p # reprint unescaped
|
60
|
+
| xargs
|
61
|
+
-0 # read null-terminated lines
|
62
|
+
-n 2 # one command for each adjacent pair
|
63
|
+
mv
|
64
|
+
|
65
|
+
Convert `/etc/passwd` to JSON:
|
66
|
+
|
67
|
+
json -i /etc/passwd -nd: -NTJp
|
68
|
+
|
69
|
+
Convert `/etc/passwd` to JSON with Objects instead of Arrays:
|
70
|
+
|
71
|
+
cat /etc/passwd | json
|
72
|
+
-n
|
73
|
+
-d:
|
74
|
+
-F name,password,uid,gid,class,change,expire,gecos,home,shell
|
75
|
+
-x _.uid=+_.uid
|
76
|
+
-x _.gid=+_.gid
|
77
|
+
-f name,_
|
78
|
+
-N
|
79
|
+
-O
|
80
|
+
-TJp
|
81
|
+
|
82
|
+
Create a JSON mapping from user name to UID and format it as CSV:
|
83
|
+
|
84
|
+
cat /etc/passwd | json -nd: -f 0,2 -D, -p
|
85
|
+
|
86
|
+
Create a JSON mapping from user name to UID and write it out as a single line of JSON:
|
87
|
+
|
88
|
+
json -i /etc/passwd -nd: -f 0,2 -NOJp
|
89
|
+
|
90
|
+
Grab the UID of the "root" user:
|
91
|
+
|
92
|
+
json -i /etc/passwd -nd: -f0,2 -N -O -f root -p
|
93
|
+
|
94
|
+
Reverse engineer a package catalog from installed packages:
|
95
|
+
|
96
|
+
json
|
97
|
+
-e 'require("packages").order'
|
98
|
+
-n # line input mode
|
99
|
+
-e '[_.name || _.directory.dirname().basename(), JSON.decode(_.directory.resolve("package.json").read())'
|
100
|
+
-N # object input mode
|
101
|
+
-O
|
102
|
+
-v '{version:1,packages:_}'
|
103
|
+
-TJ
|
104
|
+
-p
|
105
|
+
|
106
|
+
Use the JSON tool as a pointless pipe buffer:
|
107
|
+
|
108
|
+
json -np
|
109
|
+
|
110
|
+
Print the number '1' thrice.
|
111
|
+
|
112
|
+
json -e 1 -ppp
|
113
|
+
|
114
|
+
Find the largest number from 1 to 10:
|
115
|
+
|
116
|
+
$(which jot) $(which seq) 10 | json -njNe 'Math.max.apply(this, _)' -p
|
117
|
+
|
118
|
+
Put all your eggs in one basket:
|
119
|
+
|
120
|
+
json -e 'require("narwhal")' -f LEFT,RIGHT -np
|
121
|
+
|
@@ -0,0 +1,242 @@
|
|
1
|
+
All engines must support two types for interacting with binary data: ByteArray and ByteString. The ByteArray type resembles the interface of Array in that it is mutable, extensible, and indexing will return number values for the byte in the given position, zero by default, or undefined if the index is out of bounds. The ByteString type resembles the interface of String in that it is immutable and indexing returns a ByteString of length 1. These types are exported by the 'binary' top-level module and both types are subtypes of Binary, which is not instantiable but exists only for the convenience of referring to both ByteArray and ByteString. (The idea of using these particular two types and their respective names originated with Jason Orendorff in the [http://groups.google.com/group/serverjs/msg/89808c05d46b92d0 Binary API Brouhaha] discussion.)
|
2
|
+
|
3
|
+
= Philosophy =
|
4
|
+
|
5
|
+
This proposal is not an object oriented variation on pack and unpack with notions of inherent endianness, read/write head position, or intrinsic codec or charset information. The objects described in this proposal are merely for the storage and direct manipulation of strings and arrays of byte data. Some object oriented conveniences are made, but the exercise of implementing pack, unpack, or an object-oriented analog thereof are left as an exercise for a future proposal of a more abstract type or a 'struct' module (as mentioned by Ionut Gabriel Stan on [http://groups.google.com/group/serverjs/msg/592442ba98c6c70e the list]). This goes against most mentioned [[ServerJS/Binary|prior art]].
|
6
|
+
|
7
|
+
This proposal also does not provide named member functions for any particular subset of the possible charsets, codecs, compression algorithms, or consistent hash digests that might operate on a byte string or array. Instead, convenience member functions are provided for interfacing with any named charset, with the IANA charset name space, and with the possibility of eventually employing a system of modular extensions for other codecs or digests, requiring that the given module exports a specified interface. (As supported originally by Robert Schultz, Davey Waterson, Ross Boucher, and tacitly myself, Kris Kowal, on the [http://groups.google.com/group/serverjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst First proposition] thread on the mailing list). This proposal does not address the need for stream objects to support pipelined codecs and hash digests (mentioned by Tom Robinson and Robert Schultz in the same conversation).
|
8
|
+
|
9
|
+
This proposal also reflects both group sentiment and a pragmatic point about properties. This isn't a decree that properties like "length" should be consistently used throughout the ServerJS APIs. However, given that all engines support properties at the native level (to host String and Array objects) and that byte strings and arrays will require support at the native level, pursuing client-side interoperability is beyond the scope of this proposal and therefore properties have been specified. (See comments by Kris Zyp about the implementability of properties in all engines, comments by Davey Waterson from Aptana about the counter-productivity of attempting to support this API in browsers, and support properties over accessor and mutator functions by Ionut Gabriel Stand and Cameron McCormack on the [http://groups.google.com/group/serverjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst mailing list]).
|
10
|
+
|
11
|
+
The byte types provide functions for encoding, decoding, and transcoding, but they are all shallow interfaces that defer to a charset manager module, and may in turn use a system level charset or use a pair of pure JavaScript modules to transcode through an array or stream of canonical Unicode code points. This behavior may be specified further in the future.
|
12
|
+
|
13
|
+
= Specification =
|
14
|
+
|
15
|
+
The "binary" top-level module must export "Binary", "ByteArray" and "ByteString".
|
16
|
+
|
17
|
+
|
18
|
+
== ByteString ==
|
19
|
+
|
20
|
+
A ByteString is an immutable, fixed-width representation of a C unsigned char (byte) array. ByteString supports the String API, and indexing returns a byte substring of length 1.
|
21
|
+
|
22
|
+
=== Constructor ===
|
23
|
+
|
24
|
+
; ByteString()
|
25
|
+
: Construct an empty byte string.
|
26
|
+
; ByteString(byteString)
|
27
|
+
: Copies byteString.
|
28
|
+
; ByteString(byteArray)
|
29
|
+
: Use the contents of byteArray.
|
30
|
+
; ByteString(arrayOfNumbers)
|
31
|
+
: Use the numbers in arrayOfNumbers as the bytes.
|
32
|
+
: If any element is outside the range 0...255, an exception (''TODO'') is thrown.
|
33
|
+
; ByteString(string, charset)
|
34
|
+
: Convert a string. The ByteString will contain string encoded with charset.
|
35
|
+
|
36
|
+
=== Constructor methods ===
|
37
|
+
|
38
|
+
; join(array, delimiter)
|
39
|
+
: Like Array.prototype.join, but for Binarys. Returns a ByteString.
|
40
|
+
|
41
|
+
=== Instance properties ===
|
42
|
+
|
43
|
+
; length
|
44
|
+
: The length in bytes. Immutable.
|
45
|
+
|
46
|
+
=== Instance methods (in prototype) ===
|
47
|
+
|
48
|
+
; toByteArray()
|
49
|
+
: Returns a byte for byte copy in a ByteArray.
|
50
|
+
; toByteArray(sourceCharset, targetCharset)
|
51
|
+
: Returns a transcoded copy in a ByteArray.
|
52
|
+
; toByteString()
|
53
|
+
: Returns itself, since there's no need to copy an immutable ByteString.
|
54
|
+
; toByteString(sourceCharset, targetCharset)
|
55
|
+
: Returns a transcoded copy.
|
56
|
+
; toArray()
|
57
|
+
: Returns an array containing the bytes as numbers.
|
58
|
+
; toArray(charset)
|
59
|
+
: Returns an array containing the decoded Unicode code points.
|
60
|
+
; toString()
|
61
|
+
: Returns a debug representation like "[ByteString 10]", where 10 is the length of the Array. Alternative debug representations are valid too, as long as (1) this method will never fail, (2) the length is included.
|
62
|
+
; decodeToString(charset)
|
63
|
+
: Returns the decoded ByteArray as a string.
|
64
|
+
; indexOf(byte)
|
65
|
+
; indexOf(byte, start)
|
66
|
+
; indexOf(byte, start, stop)
|
67
|
+
: Returns the index of the first occurance of byte (a Number or a single element ByteString or ByteArray) or -1 if none was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.
|
68
|
+
; lastIndexOf(byte)
|
69
|
+
; lastIndexOf(byte, start)
|
70
|
+
; lastIndexOf(byte, start, stop)
|
71
|
+
: Returns the index of the last occurance of byte (a Number or a single element ByteString or ByteArray) or -1 if none was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.
|
72
|
+
; charCodeAt(offset)
|
73
|
+
; <u>get(offset)</u>
|
74
|
+
: Return the byte at offset as a Number.
|
75
|
+
; byteAt(offset) ByteString
|
76
|
+
; charAt(offset) ByteString
|
77
|
+
: Return the byte at offset as a ByteString.
|
78
|
+
; split(delimiter, [options])
|
79
|
+
: Split at delimiter, which can by a Number, a ByteString, a ByteArray or an Array of the prior (containing multiple delimiters, i.e., "split at any of these delimiters"). Delimiters can have arbitrary size.
|
80
|
+
: Options is an optional object parameter with the following optional properties:
|
81
|
+
* ''count'' - Maximum number of elements (ignoring delimiters) to return. The last returned element may contain delimiters.
|
82
|
+
* ''includeDelimiter'' - Whether the delimiter should be included in the result.
|
83
|
+
: Returns an array of ByteStrings.
|
84
|
+
; slice()
|
85
|
+
; slice(begin)
|
86
|
+
; slice(begin, end)
|
87
|
+
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/slice Array.prototype.slice]
|
88
|
+
|
89
|
+
|
90
|
+
; substr(start)
|
91
|
+
:
|
92
|
+
; substr(start, length)
|
93
|
+
:
|
94
|
+
; substring(first)
|
95
|
+
:
|
96
|
+
; substring(first, last)
|
97
|
+
|
98
|
+
; [] ByteString
|
99
|
+
: the immutable [] operator returning ByteStrings
|
100
|
+
; toSource()
|
101
|
+
: which would return "ByteString([])" for a null byte string
|
102
|
+
|
103
|
+
ByteString does not implement toUpperCase() or toLowerCase() since they are not meaningful without the context of a charset.
|
104
|
+
|
105
|
+
== ByteArray ==
|
106
|
+
|
107
|
+
A ByteArray is a mutable, flexible representation of a C unsigned char (byte) array.
|
108
|
+
|
109
|
+
=== Constructor ===
|
110
|
+
|
111
|
+
; ByteArray()
|
112
|
+
: New, empty ByteArray.
|
113
|
+
; ByteArray(length)
|
114
|
+
: New ByteArray filled with length zero bytes.
|
115
|
+
; ByteArray(byteArray)
|
116
|
+
: Copy byteArray.
|
117
|
+
; ByteArray(byteString)
|
118
|
+
: Copy contents of byteString.
|
119
|
+
; ByteArray(arrayOfBytes)
|
120
|
+
: Use numbers in arrayOfBytes as contents.
|
121
|
+
: Throws an exception if any element is outside the range 0...255 (''TODO'').
|
122
|
+
; ByteArray(string, charset)
|
123
|
+
: Create a ByteArray from a Javascript string, the result being encoded with charset.
|
124
|
+
|
125
|
+
Unlike the Array, the ByteArray is not variadic so that its initial length constructor is not ambiguous with its copy constructor.
|
126
|
+
|
127
|
+
All values within the length of the array are numbers stored as bytes that default to 0 if they have not been explicitly set. Assigning beyond the bounds of a ByteArray implicitly grows the array, just like an Array. Retrieving a value from an index that is out of the bounds of the Array, lower than 0 or at or beyond the length, the returned value is "undefined". Assigning an index with a value that is larger than fits in a byte will be implicitly and silently masked against 0xFF. Negative numbers will be bit extended to a byte in two's complement form and likewise masked.
|
128
|
+
|
129
|
+
=== Instance properties ===
|
130
|
+
|
131
|
+
; mutable length property
|
132
|
+
: extending a byte array fills the new entries with 0.
|
133
|
+
|
134
|
+
=== Instance methods (in prototype) ===
|
135
|
+
|
136
|
+
; toArray()
|
137
|
+
: n array of the byte values
|
138
|
+
; toArray(charset)
|
139
|
+
: an array of the code points, decoded
|
140
|
+
; toString()
|
141
|
+
: A string debug representation like "[ByteArray 10]". Alternative debug representations are valid too, as long as (1) this method will never fail, (2) the length is included.
|
142
|
+
; decodeToString(charset)
|
143
|
+
: returns a String from its decoded bytes in a given charset.
|
144
|
+
; toByteArray()
|
145
|
+
: just a copy
|
146
|
+
; toByteArray(sourceCharset, targetCharset)
|
147
|
+
: transcoded
|
148
|
+
; toByteString()
|
149
|
+
: byte for byte copy
|
150
|
+
; toByteString(sourceCharset, targetCharset)
|
151
|
+
: transcoded
|
152
|
+
; <u>byteAt(offset) ByteString</u>
|
153
|
+
: Return the byte at offset as a ByteString.
|
154
|
+
; <u>get(offset) Number</u>
|
155
|
+
: Return the byte at offset as a Number.
|
156
|
+
; concat(other:ByteArray|ByteString|Array)
|
157
|
+
; pop() byte:Number
|
158
|
+
:
|
159
|
+
; push(...variadic Numbers...) -> count(Number)
|
160
|
+
:
|
161
|
+
; <u>extendRight(...variadic Numbers / Arrays / ByteArrays / ByteStrings ...)</u>
|
162
|
+
:
|
163
|
+
; shift() byte:Number
|
164
|
+
:
|
165
|
+
; unshift(...variadic Numbers...) count:Number
|
166
|
+
:
|
167
|
+
; <u>extendLeft(...variadic Numbers / Arrays / ByteArrays / ByteStrings ...)</u>
|
168
|
+
:
|
169
|
+
; reverse() in place reversal
|
170
|
+
:
|
171
|
+
; slice()
|
172
|
+
:
|
173
|
+
; sort()
|
174
|
+
:
|
175
|
+
; splice()
|
176
|
+
:
|
177
|
+
; <u>indexOf()</u>
|
178
|
+
:
|
179
|
+
; <u>lastIndexOf()</u>
|
180
|
+
:
|
181
|
+
; <u>split()</u>
|
182
|
+
: Returns an array of ByteArrays instead of ByteStrings.
|
183
|
+
; <u>filter()</u>
|
184
|
+
:
|
185
|
+
; <u>forEach()</u>
|
186
|
+
:
|
187
|
+
; <u>every()</u>
|
188
|
+
:
|
189
|
+
; <u>some()</u>
|
190
|
+
:
|
191
|
+
; <u>map()</u>
|
192
|
+
:
|
193
|
+
; <u>reduce()</u>
|
194
|
+
:
|
195
|
+
; <u>reduceRight()</u>
|
196
|
+
:
|
197
|
+
; <u>displace(begin, end, values/ByteStrings/ByteArrays/Arrays...) -> length</u>
|
198
|
+
: begin/end are specified like for slice. Can be used like splice but does not return the removed elements.
|
199
|
+
; toSource()
|
200
|
+
: Returns a string like "ByteArray([])" for a null byte-array.
|
201
|
+
; [] Number
|
202
|
+
: The mutable [] operator for numbers
|
203
|
+
|
204
|
+
== String ==
|
205
|
+
|
206
|
+
The String prototype will be extended with the following members:
|
207
|
+
|
208
|
+
; toByteArray(charset)
|
209
|
+
: Converts a string to a ByteArray encoded in charset.
|
210
|
+
; toByteString(charset)
|
211
|
+
: Converts a string to a ByteString encoded in charset.
|
212
|
+
; charCodes()
|
213
|
+
: Returns an array of Unicode code points (as numbers).
|
214
|
+
|
215
|
+
== Array ==
|
216
|
+
|
217
|
+
The Array prototype will be extended with the following members:
|
218
|
+
|
219
|
+
; toByteArray(charset)
|
220
|
+
: Converts an array of Unicode code points to a ByteArray encoded in charset.
|
221
|
+
; toByteString(charset)
|
222
|
+
: Converts an array of Unicode code points to a ByteString encoded in charset.
|
223
|
+
|
224
|
+
== General Requirements ==
|
225
|
+
|
226
|
+
None of the specified prototypes or augmentations to existing prototypes are enumerable.
|
227
|
+
|
228
|
+
<u>Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation. All implementations MUST support "us-ascii" and "utf-8".</u>
|
229
|
+
|
230
|
+
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.
|
231
|
+
|
232
|
+
<u>Charsets are case insensitive.</u>
|
233
|
+
|
234
|
+
= Tests =
|
235
|
+
|
236
|
+
* [http://github.com/tlrobinson/narwhal/tree/master/tests/serverjs ServerJS tests] compatible with [http://github.com/tlrobinson/narwhal/tree/master/lib/test this test framework].
|
237
|
+
|
238
|
+
= Relevant Discussions =
|
239
|
+
|
240
|
+
* [http://groups.google.com/group/serverjs/browse_thread/thread/f8ad81201f7b121b ByteArray and ByteString proposal]
|
241
|
+
* [http://groups.google.com/group/serverjs/browse_thread/thread/a8d3a91af37fd355 ByteArray: byteAt method]
|
242
|
+
* [http://groups.google.com/group/serverjs/browse_thread/thread/45190ac89d7b422a Binary/B Extension Proposals and Implementation Notes]
|
data/docs/lib/file.wiki
ADDED
@@ -0,0 +1,325 @@
|
|
1
|
+
Proposal A, Draft 5 (in development)
|
2
|
+
|
3
|
+
The "file" module supports the File System API, providing an interface for path, directory, file, link, file stat, and file stream manipulation.
|
4
|
+
|
5
|
+
For the purpose of this documentation, "fs" is a variable name for any object that implements the File System API, including the exports of the "file" module, and objects returned by "fs.chroot(path)".
|
6
|
+
|
7
|
+
|
8
|
+
=== Security ===
|
9
|
+
|
10
|
+
Objects implementing the File System API, including the "file" module object, are capability bearing objects that carry and mediate authority to read and write to the underlying storage. As such, the "file" module can return other objects that implement and attenuate the File System API for sandboxing. Furthermore, streams returned by the file system object are implicitly attenuated to only give the receiver authority to manipulate the given file, without knowledge of the path on which it resides or access to references that would permit it to manipulate other parts of the file system.
|
11
|
+
|
12
|
+
|
13
|
+
=== Interface ===
|
14
|
+
|
15
|
+
The "file" module must export the following:
|
16
|
+
|
17
|
+
==== Files ====
|
18
|
+
|
19
|
+
; open(path String, mode|options)
|
20
|
+
: returns a stream object that supports an appropriate interface for the given options and mode, which include reading, writing, updating, byte, character, unbuffered, buffered, and line buffered streams. More details follow in the [#Stream] section of this document.
|
21
|
+
* path
|
22
|
+
* mode: "rwa+bxc", or
|
23
|
+
* options
|
24
|
+
** mode String
|
25
|
+
** charset String
|
26
|
+
** read Boolean
|
27
|
+
** write Boolean
|
28
|
+
** append Boolean
|
29
|
+
** update Boolean
|
30
|
+
** binary Boolean
|
31
|
+
** exclusive Boolean
|
32
|
+
** canonical Boolean
|
33
|
+
; read(path String, [mode|options])
|
34
|
+
: opens, reads, and closes a file, returning its content.
|
35
|
+
; write(path String, content String|Binary, [mode|options])
|
36
|
+
: opens, writes, flushes, and closes a file with the given content. If the content is a ByteArray or ByteString, the binary mode is implied.
|
37
|
+
; copy(source String, target String)
|
38
|
+
: reads one file and writes another in byte mode.
|
39
|
+
; move(from String, to String)
|
40
|
+
:
|
41
|
+
; remove(path String)
|
42
|
+
:
|
43
|
+
; rename(path String, name String)
|
44
|
+
:
|
45
|
+
; touch(path, [mtime Date])
|
46
|
+
:
|
47
|
+
|
48
|
+
==== Directories ====
|
49
|
+
|
50
|
+
('''TODO''' Should the methods in this section use "mkdir" or "makeDir" style names? [http://groups.google.com/group/serverjs/browse_thread/thread/851fea66620bae13 discussion])
|
51
|
+
|
52
|
+
; list(path String) Iterator
|
53
|
+
: returns an iterator that yields the names of the entries in a directory. Throws an error if the directory is inaccessible or does not exist.
|
54
|
+
; mkdir(path String)
|
55
|
+
: Create a single directory specified by ''path''. If the directory cannot be created for any reason an exception will be thrown. This includes if the parent directories of "path" are not present.
|
56
|
+
:
|
57
|
+
; mktree(path String)
|
58
|
+
: '''TODO''' Decide upon the name of this function. "mkdirs" or "mktree" or "makeTree"
|
59
|
+
: Will create the directory specified by "path" including any missing parent directories.
|
60
|
+
:
|
61
|
+
; rmdir(path String)
|
62
|
+
: Removes a directory if it is empty. If it is not, or cannot be removed for another reason an exception will be thrown.
|
63
|
+
:
|
64
|
+
; rmtree(path String)
|
65
|
+
:
|
66
|
+
: This does its best to remove the directory "path", akin to "rm -r" on Unix or "del /s" on Windows. That is it will recursively delete all directories and files under "path".
|
67
|
+
|
68
|
+
==== Links ====
|
69
|
+
|
70
|
+
==== Paths ====
|
71
|
+
|
72
|
+
; [new] Path(path String|Path|Array, [fs FileSystem]) Path
|
73
|
+
: returns a Path object that closes on a File System object and a "path" representation. The path object is a chainable shorthand for working with paths in the context of the "file" module. "Path" objects have no more or less authority to manipulate the file system than the FileSystem object that they are attached to, as any path string is reachable by chaining operations on a path instance. The FileSystem object defaults to the "file" module if the argument is omitted or undefined. More details follow in the [#Path Path] section of this document.
|
74
|
+
; path(path String|Path, fs FileSystem) Path
|
75
|
+
: "fs.path(path)" is a shorthand for "new fs.Path(path, fs)".
|
76
|
+
|
77
|
+
===== Working Path =====
|
78
|
+
|
79
|
+
The current working directory is used by all routines that resolve relative paths to absolute file system paths, including "open", and "absolute".
|
80
|
+
|
81
|
+
; cwd() String
|
82
|
+
: returns the current working directory.
|
83
|
+
; chdir(path String)
|
84
|
+
: changes the current working directory.
|
85
|
+
|
86
|
+
===== Traditional =====
|
87
|
+
|
88
|
+
; join(...)
|
89
|
+
: takes a variadic list of path Strings, joins them on the file system's path separator, and normalizes the result.
|
90
|
+
; split(path String) Array
|
91
|
+
: returns an array of path components. If the path is absolute, the first component will be an indicator of the root of the file system; for file systems with drives (such as Windows), this is the drive identifier with a colon, like "c:"; on Unix, this is an empty string "". The intent is that calling "join.apply" with the result of "split" as arguments will reconstruct the path.
|
92
|
+
; normal(path String)
|
93
|
+
: removes '.' path components and simplifies '..' paths, if possible, for a given path.
|
94
|
+
; absolute(path String)
|
95
|
+
: returns the absolute path, starting with the root of this file system object, for the given path, resolved from 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 "cwd", "join", and "normal".
|
96
|
+
; canonical(path String)
|
97
|
+
: 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 must 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", "join", "normal" and "readlink".
|
98
|
+
; dirname(path String) String
|
99
|
+
: returns the path of a file's containing directory, albeit the parent directory if the file is a directory. A terminal directory separator is ignored.
|
100
|
+
; basename(path String, [extension String]) String
|
101
|
+
: returns the part of the path that is after the last directory separator. If an extension is provided and is equal to the file's extension, the extension is removed from the result.
|
102
|
+
; extension(path String) String
|
103
|
+
: returns the extension of a file. The extension of a file is the last dot (excluding any number of initial dots) followed by one or more non-dot characters. Returns an empty string if no valid extension exists. [http://github.com/kriskowal/narwhal-test/blob/master/src/test/file/extension.js unit test].
|
104
|
+
|
105
|
+
===== URL-like =====
|
106
|
+
|
107
|
+
; resolve(...)
|
108
|
+
: a function like "join" except that it treats each argument as as either an absolute or relative path and, as is the convention with URL's, treats everything up to the final directory separator as a location, and everything afterward as an entry in that directory, even if the entry refers to a directory in the underlying storage. Resolve starts at the location "" and walks to the locations referenced by each path, and returns the path of the last file. Thus, resolve(file, "") idempotently refers to the location containing a file or directory entry, and resolve(file, neighbor) always gives the path of a file in the same directory. "resolve" is useful for finding paths in the "neighborhood" of a given file, while gracefully accepting both absolute and relative paths at each stage. [http://github.com/kriskowal/narwhal-test/blob/master/src/test/file/resolve.js unit test].
|
109
|
+
; relative(from, to)
|
110
|
+
: returns the relative path from one path to another using only ".." to traverse up to the two paths' common ancestor.
|
111
|
+
|
112
|
+
==== Tests ====
|
113
|
+
|
114
|
+
; exists(path)
|
115
|
+
: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.
|
116
|
+
; isFile(path)
|
117
|
+
:returns whether a path exists and that it corresponds to a file.
|
118
|
+
; isDirectory(path)
|
119
|
+
:returns whether a path exists and that it corresponds to a directory.
|
120
|
+
; isLink(path)
|
121
|
+
:returns whether a path exists and that it corresponds to a symbolic link (TODO or shortcut?).
|
122
|
+
; isReadable(path)
|
123
|
+
:returns whether a path exists, that it corresponds to a file, and that it can be opened for reading by "fs.open".
|
124
|
+
; isWritable(path)
|
125
|
+
:If a path exists, returns whether a file may be opened for writing, or entries added or removed from an existing directory. If the path does not exist, returns whether entries for files, directories, or links can be created at its location.
|
126
|
+
|
127
|
+
==== Metadata ====
|
128
|
+
|
129
|
+
; stat(path String)
|
130
|
+
:Returns an object that contains the file's metadata, including all of the following that are applicable in the target platform's file system
|
131
|
+
;; device Number
|
132
|
+
:device number of the file system
|
133
|
+
;; inode Number
|
134
|
+
:virtual node number
|
135
|
+
;; mode Number
|
136
|
+
:type and permissions, numeric
|
137
|
+
;; linkCount Number
|
138
|
+
:number of hard links to the file
|
139
|
+
;; uid Number
|
140
|
+
:numeric id of the owner user
|
141
|
+
;; rdev Number
|
142
|
+
:the device identifier for special files
|
143
|
+
;; size Number
|
144
|
+
:total size in bytes
|
145
|
+
;; blockSize Number
|
146
|
+
:preferred block size for file system IO, in bytes
|
147
|
+
;; blockCount Number
|
148
|
+
:number of blocks allocated
|
149
|
+
;; mtime Date
|
150
|
+
:time of last modification (write)
|
151
|
+
;; atime Date
|
152
|
+
:time of last access (read, write, update)
|
153
|
+
;; ctime Date
|
154
|
+
:(TODO created vs. stat changed. is /.time/ really the best pattern for expressing these times?)
|
155
|
+
;; xattrs
|
156
|
+
:extended attributes (reserved)
|
157
|
+
;; acls
|
158
|
+
:access control lists (reserved)
|
159
|
+
|
160
|
+
; size(path String)
|
161
|
+
:Number
|
162
|
+
; mtime(path String)
|
163
|
+
:Date
|
164
|
+
; atime(path String)
|
165
|
+
:Date
|
166
|
+
; ctime(path String)
|
167
|
+
:Date
|
168
|
+
; same(pathA String, pathB String) Boolean
|
169
|
+
: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 implicitly and atomically modify the other.
|
170
|
+
|
171
|
+
==== Security ====
|
172
|
+
|
173
|
+
; chroot(path String)
|
174
|
+
: returns an object that conforms to the File System API, like the "file" module or the "system.fs" variable, that can be safely passed into a sandbox as the "file" module and "system.fs" objects.
|
175
|
+
|
176
|
+
|
177
|
+
== Path ==
|
178
|
+
|
179
|
+
; [new] Path(path String|Path|Array, [fs FileSystem]) Path
|
180
|
+
:
|
181
|
+
|
182
|
+
The prototype for the Path constructor is a String object.
|
183
|
+
|
184
|
+
The path constructor accepts as its first argument either a String, Path, or Array. If the path is an Array (as tested by Array.isArray, not merely typeof path == "array"), it must conform to the specification for values returned by "fs.split".
|
185
|
+
|
186
|
+
Every path object has the members "normal", "absolute", "canonical", "dirname", "basename", "join", and "resolve". All of these return new Path objects constructed by converting the path to a string, passing it through the likewise named method of "fs", and converting it back to a Path. Thus, all of these methods are chainable. In addition, "join" and "resolve" are variadic, so additional paths can be passed as arguments in either String, Path, or Array form.
|
187
|
+
|
188
|
+
Every path object has "chroot", "copy", "exists", "extension", "isDirectory", "isFile", "isLink", "isReadable", "isWritable", "mkdir", "mkdirs", "move", "mtime", "open", "read", "remove", "rename", "rmdir", "rmtree", "same", "size", "split", "stat", "touch", and "write". All of these functions convert themselves to strings and pass the results through the likewise named method of "fs".
|
189
|
+
|
190
|
+
In addition, paths implement:
|
191
|
+
|
192
|
+
; toString()
|
193
|
+
:
|
194
|
+
; to(path)
|
195
|
+
: uses "fs.relative" to return a Path from this path to another one.
|
196
|
+
; from(path)
|
197
|
+
: uses "fs.relative" to return a Path to this path from another one.
|
198
|
+
; list()
|
199
|
+
: returns an iterator of Path objects for the contained directory entries.
|
200
|
+
|
201
|
+
(TODO resolve whether it's more proper to make "Path" foundational and eliminate "fs". Wrapping the "Path" object around a central "fs" object will be necessary for "chroot" whether we expose that level of the API or not, and having routines that work with strings on one architectural layer and paths on the next up gives the programmer an oppoertunity to program at the level that makes sense for their task. It also, however, gives the programmer more to learn.)
|
202
|
+
|
203
|
+
|
204
|
+
== Streams ==
|
205
|
+
|
206
|
+
The "open" function mediates the construction of various kinds of streams. As "open" is the only method with the authority to manipulate files, it constructs these types on behalf of a potentially unpriviledged caller. Stream constructors are not directly callable in a secure sandbox, so where and how these stream types are implemented is beyond the necessary scope of this specification. The "open" function always creates a byte level stream, and by default wraps that in a textual IO wrapper.
|
207
|
+
|
208
|
+
* create a "raw" byte stream. If "x" mode (with either "w" or "a" mode), only open if the file does not already exist. Create the file and open the stream atomically.
|
209
|
+
** if "r" mode, make "raw" a ByteReader
|
210
|
+
** if "w" mode, make "raw" a ByteWriter
|
211
|
+
** if "u" mode, make "raw" a ByteUpdater
|
212
|
+
* if "+", seek to end.
|
213
|
+
* if not "b" mode, return "raw".
|
214
|
+
* return a wrapper encoded/decoded string stream around "raw" with specified buffering, line buffering, and charset.
|
215
|
+
** if "r" mode, wrap "raw" in a TextReader
|
216
|
+
** if "w" mode, wrap "raw" in a TextWriter
|
217
|
+
** if "u" mode, wrap "raw" in a TextUpdater
|
218
|
+
|
219
|
+
; ByteReader
|
220
|
+
: appropriate for reading binary opaque struct records or other binary data or protocols
|
221
|
+
; ByteWriter
|
222
|
+
: appropriate for writing binary opaque struct records or other binary data or protocols
|
223
|
+
; ByteUpdater
|
224
|
+
: appropriate for a database
|
225
|
+
; ByteReaderWriter
|
226
|
+
: appropriate for sockets
|
227
|
+
; TextReader
|
228
|
+
: appropriate for standard input
|
229
|
+
; TextWriter
|
230
|
+
: appropriate for standard output
|
231
|
+
; TextUpdater
|
232
|
+
:
|
233
|
+
; TextReaderWriter
|
234
|
+
: appropriate for a TTY
|
235
|
+
|
236
|
+
(TODO: resolve whether it is necessary for all stream types to have a common prototype, or whether it makes sense for them to be arranged in a class hierarchy.)
|
237
|
+
|
238
|
+
=== *Reader, *Updater ===
|
239
|
+
|
240
|
+
TextReader, ByteReader, TextUpdater, ByteUpdater, TextReaderWriter, and ByteReaderWriter have the following properties and methods:
|
241
|
+
|
242
|
+
; read() *String
|
243
|
+
: reads and returns all of the file until EOF is encountered. Return ByteStrings for Byte* types, and Strings for Text* types.
|
244
|
+
; read(max Number) *String
|
245
|
+
:
|
246
|
+
; readInto(buffer *Array, [begin Number], [end Number]) Number
|
247
|
+
:
|
248
|
+
; canRead() Boolean
|
249
|
+
:
|
250
|
+
; skip(n Number) Number
|
251
|
+
:
|
252
|
+
|
253
|
+
=== *Writer, *Updater ===
|
254
|
+
|
255
|
+
TextWriter, ByteWriter, TextUpdater, ByteUpdater, TextReaderWriter, and ByteReaderWriter have the following properties and methods:
|
256
|
+
|
257
|
+
; canWrite() Boolean
|
258
|
+
:
|
259
|
+
; flush()
|
260
|
+
:
|
261
|
+
|
262
|
+
=== ByteUpdater ===
|
263
|
+
|
264
|
+
; tell() Number
|
265
|
+
:
|
266
|
+
; seek(position Number, whence Number)
|
267
|
+
:
|
268
|
+
; truncate([length Number=0])
|
269
|
+
:
|
270
|
+
; rewind()
|
271
|
+
: a shortcut for seek(0)
|
272
|
+
|
273
|
+
=== Text* ===
|
274
|
+
|
275
|
+
TextReader, TextWriter, TextUpdater, and TextReaderWriter have the following properties and methods:
|
276
|
+
|
277
|
+
; raw Byte*
|
278
|
+
: the underlying byte stream, ByteReader for TextReaders, ByteWriter for TextWriters, and so on.
|
279
|
+
|
280
|
+
=== TextReader ===
|
281
|
+
|
282
|
+
; readLine() String
|
283
|
+
: reads a line from the reader. If EOF is encountered before any data is gathered, returns "". Otherwise, returns the line including the "newLine".
|
284
|
+
; readLines() Array*String
|
285
|
+
: returns an Array of Strings accumulated by calling readLine until an empty string turns up. Does not include the final empty string, and does include "newLine" at the end of every line.
|
286
|
+
; next() String or throws StopIteration
|
287
|
+
: returns the next line of input without its "newLine". Throws StopIteration if EOF is encountered.
|
288
|
+
; iterator() Iterator
|
289
|
+
: returns the reader itself
|
290
|
+
|
291
|
+
=== TextWriter ===
|
292
|
+
|
293
|
+
; writeLine(line String)
|
294
|
+
:
|
295
|
+
; print(...)
|
296
|
+
: writes a "delimiter" delimited array of Strings terminated with a "newLine"
|
297
|
+
|
298
|
+
=== TextUpdater ===
|
299
|
+
|
300
|
+
; tell() OpaqueCookie
|
301
|
+
:
|
302
|
+
; seek(position OpaqueCookie)
|
303
|
+
:
|
304
|
+
; truncate([position OpaqueCookie)
|
305
|
+
:
|
306
|
+
; rewind()
|
307
|
+
: seeks to the beginning of the file.
|
308
|
+
|
309
|
+
|
310
|
+
== Notes ==
|
311
|
+
|
312
|
+
* Path separators, and other file-system-specific constants are not included in this specification.
|
313
|
+
|
314
|
+
= Todo =
|
315
|
+
|
316
|
+
* <s>random access IO</s>
|
317
|
+
* locks
|
318
|
+
* <s>canonical IO (non-blocking)</s>
|
319
|
+
* comprehensive stat <s>access</s> and modification
|
320
|
+
* temporary files and directories
|
321
|
+
* symbolic links
|
322
|
+
* more open options: permissions, owner, groupOwner
|
323
|
+
* copy with metadata
|
324
|
+
* glob
|
325
|
+
* other [https://wiki.mozilla.org/ServerJS/API/file/Names proposed names].
|