From a9f29cd18d9ffccc90d7b7eb51162ff5d38b4a13 Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 26 May 2009 11:39:40 +0200 Subject: [PATCH] File I/O documentation. Remove necessity of class="sh_javascript". --- src/file.cc | 6 +- website/node.html | 297 ++++++++++++++++++++++++++------------------- website/sh_main.js | 9 +- 3 files changed, 178 insertions(+), 134 deletions(-) diff --git a/src/file.cc b/src/file.cc index d5f261dbd14..f366ea6583a 100644 --- a/src/file.cc +++ b/src/file.cc @@ -139,7 +139,7 @@ AfterWrite (eio_req *req) * Wrapper for write(2). * * 0 fd integer. file descriptor - * 1 data the data to write + * 1 data the data to write (string = utf8, array = raw) * 2 position if integer, position to write at in the file. * if null, write from the current position * @@ -196,13 +196,11 @@ AfterUtf8Read (eio_req *req) argv[0] = Integer::New(req->errorno); char *buf = reinterpret_cast(req->ptr2); - if (req->result == 0) { // eof argv[1] = Local::New(Null()); } else { - size_t len = req->result; - argv[1] = String::New(buf, len); + argv[1] = String::New(buf, req->result); } CALL_CALLBACK_PTR(req, argc, argv); diff --git a/website/node.html b/website/node.html index a11115ae473..d0b5366d5b7 100644 --- a/website/node.html +++ b/website/node.html @@ -85,6 +85,10 @@ a:hover { text-decoration: underline; }
  1. Timers
  2. File I/O +
      +
    1. Wrappers +
    2. File +
  3. TCP
    1. Server @@ -115,16 +119,10 @@ a:hover { text-decoration: underline; }

      Purely asynchronous server-side I/O for V8 javascript. -

      Analogy -

      -Python     : Twisted
      -Ruby       : Event Machine
      -Javascript : Node
      -

      This is an example of a web server written with Node which responds with "Hello World" after waiting two seconds: -

      new node.http.Server(function (req, res) {
      +
      new node.http.Server(function (req, res) {
         setTimeout(function () {
           res.sendHeader(200, [["Content-Type", "text/plain"]]);
           res.sendBody("Hello World");
      @@ -152,6 +150,9 @@ puts("Server running at http://127.0.0.1:8000/");

      Build

      +

      Node currently targets the Linux and Macintosh operating systems using +IA-32 or ARM processors. The build system requires Python. +

      ./configure
       make
       make install
      @@ -160,7 +161,7 @@ make install

      API

      Conventions: Callbacks are object members which are prefixed with -on. All methods and members are camel cased. Constructors +on. All methods and members are camel cased. Constructors always have a capital first letter.

      Node uses strings to represent ASCII or UTF-8 encoded data. For the @@ -169,12 +170,12 @@ representation is rather inefficient. In the future, when V8 natively supports binary Blob objects, Node will use them. -

      The following are some global general purpose functions:

      +

      The following are global functions:

      -
      puts(string, callback)
      +
      puts(string, callback)
      - Alias for stdout.puts(). + Alias for stdout.puts(). Outputs the string and a trailing new-line to stdout.

      The callback argument is optional and mostly useless: it will @@ -186,49 +187,103 @@ Blob objects, Node will use them. output will be displayed in the order it was called.

      -
      print(string, callback)
      +
      print(string, callback)
      Like puts() but without the trailing new-line.
      -
      node.debug(string)
      +
      node.debug(string)
      A synchronous output function. Will block the process and output the string immediately to stdout. Use with care.
      -
      node.exit(code)
      +
      node.exit(code)
      Immediately ends the process with the specified code.

      Timers

      -
      setTimeout(callback, delay)
      +
      setTimeout(callback, delay)
      To schedule execution of callback after delay milliseconds. Returns a timeoutId for possible use with clearTimeout(). -
      clearTimeout(timeoutId)
      +
      clearTimeout(timeoutId)
      Prevents said timeout from triggering. -
      setInterval(callback, delay)
      +
      setInterval(callback, delay)
      To schedule the repeated execution of callback every delay milliseconds. Returns a intervalId for possible use with clearInterval(). -
      clearInterval(intervalId)
      +
      clearInterval(intervalId)
      Stops a interval from triggering.

      node.fs

      -

      Because there are not non-blocking ways to do it, asynchronous file I/O is -tricky. Node handles file I/O by employing an internal thread pool +

      File I/O is tricky because there are not simple non-blocking ways to do it. +Node handles file I/O by employing an internal thread +pool to execute file system calls. +

      This part of the API is split into two parts: simple wrappers around +standard POSIX file I/O functions, and a user-friendly File +object. + +

      POSIX Wrappers

      + +

      All POSIX wrappers have a similar form. They return +undefined and have a callback called on_completion +as their last argument. The on_completion callback may be +passed many parameters, but the first parameter is always an integer +indicating the error status. If the status integer is zero, then the call +was successful. Example: +

      +node.fs.unlink("/tmp/hello", function (status) {
      +  if (status == 0) 
      +    puts("successfully deleted /tmp/hello");
      +});
      +
      + +

      There is no guaranteed ordering to the POSIX wrappers. The following is +very much prone to error +

      +node.fs.rename("/tmp/hello", "/tmp/world");
      +node.fs.stat("/tmp/world", function (status, stats) {
      +  puts("stats: " + JSON.stringify(stats));
      +});
      +
      +because it could be that stat() is executed before the +rename(). The correct way to do this, is use the +on_completion callback for rename() +
      +node.fs.rename("/tmp/hello", "/tmp/world", function (status) {
      +  if (status != 0) return;
      +  node.fs.stat("/tmp/world", function (status, stats) {
      +    puts("stats: " + JSON.stringify(stats));
      +  });
      +});
      +
      + +
      +
      node.fs.rename(path1, path2, on_completion)
      +
      + on_completion(status) +
      + +
      node.fs.stat(path, on_completion)
      +
      + on_completion(status, stat_object) +
      +
      + +

      node.fs.File

      +

      Internal request queues exist for each file object so that multiple commands can be issued at once without worry that they will be executed out-of-order. Thus the following is safe: -

      +
       var file = new node.fs.File();
       file.open("/tmp/blah", "w+");
       file.write("hello");
      @@ -238,27 +293,27 @@ file.close();

      It's important to understand that the request queues are local to a single file. If one does -

      fileA.write("hello");
      +
      fileA.write("hello");
       fileB.write("world");
      it could be that fileB gets written to before fileA is written to. If a certain operation order is needed involving multiple files, use the completion callbacks: -
      fileA.write("hello", function () {
      +
      fileA.write("hello", function () {
         fileB.write("world");
       });
      -
      new node.fs.File
      +
      new node.fs.File
      Creates a new file object.
      -
      file.onError
      +
      file.onError
      Callback. This is called internally anytime an error occurs with this file. There are three arguments: the method name, the POSIX errno, and a string describing the error.

      Example

      -
      +
       var path = "/some/path/that/doesnt/exist";
       var file = new node.fs.File();
       file.onError = function (method, errno, msg) {
      @@ -269,7 +324,7 @@ file.onError = function (method, errno, msg) {
       file.open(path, "w+")
       
      -
      file.open(path, mode, on_completion)
      +
      file.open(path, mode, on_completion)
      Opens the file at path.

      mode is a string: "r" open for reading and writing. @@ -287,31 +342,19 @@ file.open(path, "w+") called, but the file.onError will be called.

      -
      file.read(length, position, on_completion)
      +
      file.read(length, position, on_completion)
      -
      file.write(data, position, on_completion)
      +
      file.write(data, position, on_completion)
      -
      file.close(on_completion)
      +
      file.close(on_completion)
      -

      File System Operations

      - -
      -
      node.fs.rename(path1, path2, on_completion)
      -
      -
      - -
      node.fs.stat(path1, on_completion)
      -
      -
      -
      -

      node.tcp

      @@ -328,7 +371,7 @@ careful to never buffer entire requests or responses—the user is able to stream data.

      HTTP message headers are represented by an array of 2-element arrays like this -

      +
       [ ["Content-Length", "123"]
       , ["Content-Type", "text/plain"]
       , ["Connection", "keep-alive"]
      @@ -340,53 +383,53 @@ an incorrect abstraction. It is rare, but possible, to have multiple header line
       with the same field. Setting multiple cookies in a single response, for
       example, can only be done with multiple Cookie lines.
       
      -

      node.http.Server

      +

      node.http.Server

      -
      new node.http.Server(request_handler, options);
      +
      new node.http.Server(request_handler, options);

      Creates a new web server.

      The options argument is optional. The options argument accepts the same values + >options argument accepts the same values as the options argument for node.tcp.Server does. + >node.tcp.Server does. -

      The request_handler is a +

      The request_handler is a callback which is made on each request with a ServerRequest and ServerResponse arguments.

      -
      server.listen(port, hostname) +
      server.listen(port, hostname)

      Begin accepting connections on the specified port and hostname. If the hostname is omitted, the server will accept connections directed to any address.

      -
      server.close() +
      server.close()

      Stops the server from accepting new connections.

      -

      node.http.ServerRequest

      +

      node.http.ServerRequest

      This object is created internally by a HTTP server—not by the user. It is passed to the user as the first argument to the request_handler callback. +>request_handler callback.

      -
      req.method -
      The request method as a string. Read only. Example: "GET", - "DELETE".
      +
      req.method +
      The request method as a string. Read only. Example: "GET", + "DELETE".
      -
      req.uri +
      req.uri
      Request URI. (Object.)
      req.uri.anchor
      req.uri.query @@ -404,17 +447,17 @@ class="sh_javascript">request_handler callback.
      req.uri.toString(), req.uri.source
      The original URI found in the status line. -
      req.headers +
      req.headers
      The request headers expressed as an array of 2-element arrays. Read only. -
      req.httpVersion
      -
      The HTTP protocol version as a string. Read only. Examples: "1.1", - "1.0" +
      req.httpVersion
      +
      The HTTP protocol version as a string. Read only. Examples: "1.1", + "1.0" -
      req.onBody
      +
      req.onBody
      Callback. Should be set by the user to be informed of when a piece of the message body is received. Example: -
      +
       req.onBody = function (chunk) {
         puts("part of the body: " + chunk);
       };
      @@ -424,61 +467,61 @@ req.onBody = function (chunk) {
       
         

      The body chunk is either a String in the case of UTF-8 encoding or an array of numbers in the case of raw encoding. The body encoding is set with - req.setBodyEncoding(). + req.setBodyEncoding(). -

      req.onBodyComplete
      +
      req.onBodyComplete
      Callback. Made exactly once for each message. No arguments. After - onBodyComplete is executed onBody will no longer be called. + onBodyComplete is executed onBody will no longer be called.
      -
      req.setBodyEncoding(encoding)
      +
      req.setBodyEncoding(encoding)
      - Set the encoding for the request body. Either "utf8" or - "raw". Defaults to raw. + Set the encoding for the request body. Either "utf8" or + "raw". Defaults to raw.
      -

      node.http.ServerResponse

      +

      node.http.ServerResponse

      This object is created internally by a HTTP server—not by the user. It is passed to the user as the second argument to the request_handler callback. +>request_handler callback.

      -
      res.sendHeader(statusCode, headers)
      +
      res.sendHeader(statusCode, headers)
      Sends a response header to the request. The status code is a 3-digit - HTTP status code, like 404. The second argument, - headers, should be an array of 2-element arrays, + HTTP status code, like 404. The second argument, + headers, should be an array of 2-element arrays, representing the response headers.

      Example: -

      +
       var body = "hello world";
       res.sendHeader(200, [ ["Content-Length", body.length]
                           , ["Content-Type", "text/plain"]
                           ]);
       
      This method must only be called once on a message and it must be called - before res.finish() is called. + before res.finish() is called.
      -
      res.sendBody(chunk)
      +
      res.sendBody(chunk)
      - This method must be called after sendHeader was called. It + This method must be called after sendHeader was called. It sends a chunk of the response body. This method may be called multiple times to provide successive parts of the body.
      -
      res.finish()
      +
      res.finish()
      This method signals that all of the response headers and body has been sent; that server should consider this message complete. - The method, res.finish(), MUST be called on each response. + The method, res.finish(), MUST be called on each response.
      -

      node.http.Client

      +

      node.http.Client

      An HTTP client is constructed with a server address as its argument, the returned handle is then used to issue one or more requests. Depending on the @@ -487,7 +530,7 @@ connection after each connection. Currently the implementation does not pipeline requests.

      Example of connecting to google.com -

      +
       var google = new node.http.Client(80, "google.com");
       var req = google.get("/");
       req.finish(function (res) {
      @@ -501,17 +544,17 @@ req.finish(function (res) {
       
      -
      new node.http.Client(port, host);
      +
      new node.http.Client(port, host);
      Constructs a new HTTP client. port and host refer to the server to be connected to. A connection is not established until a request is issued.
      -
      client.get(path, request_headers);
      -
      client.head(path, request_headers);
      -
      client.post(path, request_headers);
      -
      client.del(path, request_headers);
      -
      client.put(path, request_headers);
      +
      client.get(path, request_headers);
      +
      client.head(path, request_headers);
      +
      client.post(path, request_headers);
      +
      client.del(path, request_headers);
      +
      client.put(path, request_headers);
      Issues a request; if necessary establishes connection.

      @@ -524,7 +567,7 @@ request is issued. header of the request. One needs to call req.finish() to finalize the request and retrieve the response. (This sounds convoluted but it provides a chance for the user to stream a body to the server with req.sendBody().) +>req.sendBody().)

      GET and HEAD requests normally are without bodies but HTTP does not forbid @@ -532,17 +575,17 @@ it, so neither do we.

      -

      node.http.ClientRequest

      +

      node.http.ClientRequest

      This object is created internally and returned from the request methods of a node.http.Client. It represents an in-progress request whose header has already been sent.

      -
      req.sendBody(chunk, encoding)
      +
      req.sendBody(chunk, encoding)
      Sends a sucessive peice of the body. By calling this method many times, the user can stream a request body to a server—in that case it is -suggested to use the ["Transfer-Encoding", +suggested to use the ["Transfer-Encoding", "chunked"] header line when creating the request.

      The chunk argument should be an array of integers or a string. @@ -554,11 +597,11 @@ suggested to use the ["Transfer-Encoding",

      TODO -

      req.finish(response_handler)
      +
      req.finish(response_handler)
      Finishes sending the request. If any parts of the body are unsent, it will flush them to the socket. If the request is chunked, this - will send the terminating "0\r\n\r\n". + will send the terminating "0\r\n\r\n".

      The parameter response_handler is a user-supplied callback which will be executed exactly once when the server response headers have been received. @@ -566,7 +609,7 @@ suggested to use the ["Transfer-Encoding", ClientResponse object.

      -

      node.http.ClientResponse

      +

      node.http.ClientResponse

      This object is created internally and passed to the response_handler callback (is given to the client in @@ -575,19 +618,19 @@ header is completely received but before any part of the response body has been read.

      -
      res.statusCode
      -
      The 3-digit HTTP response status code. E.G. 404.
      +
      res.statusCode
      +
      The 3-digit HTTP response status code. E.G. 404.
      -
      res.httpVersion
      +
      res.httpVersion
      The HTTP version of the connected-to server. Probably either - "1.1" or - "1.0". + "1.1" or + "1.0".
      -
      res.headers
      +
      res.headers
      The response headers. An Array of 2-element arrays.
      -
      res.onBody
      +
      res.onBody
      Callback. Should be set by the user to be informed of when a piece of the response body is received. A chunk of the body is given as the single argument. The transfer-encoding @@ -595,18 +638,18 @@ read.

      The body chunk is either a String in the case of UTF-8 encoding or an array of numbers in the case of raw encoding. The body - encoding is set with res.setBodyEncoding(). + encoding is set with res.setBodyEncoding(). -

      res.onBodyComplete
      +
      res.onBodyComplete
      Callback. Made exactly once for each message. No arguments. After - onBodyComplete is executed - onBody will no longer be called. + onBodyComplete is executed + onBody will no longer be called.
      -
      res.setBodyEncoding(encoding)
      +
      res.setBodyEncoding(encoding)
      - Set the encoding for the response body. Either "utf8" or - "raw". Defaults to raw. + Set the encoding for the response body. Either "utf8" or + "raw". Defaults to raw.
      @@ -616,19 +659,19 @@ read. in one-to-one correspondence.

      As an example, -foo.js loads the module mjsunit.js. +foo.js loads the module mjsunit.js. -

      The contents of foo.js: +

      The contents of foo.js: -

      +
       include("mjsunit");
       function onLoad () {
         assertEquals(1, 2);
       }
       
      -

      The contents of mjsunit.js: +

      The contents of mjsunit.js: -

      +
       function fail (expected, found, name_opt) {
         // ...
       }
      @@ -642,39 +685,39 @@ exports.assertEquals = function (expected, found, name_opt) {
       };
       
      -

      Here the module mjsunit.js has exported the function -assertEquals(). mjsunit.js must be in the -same directory as foo.js for include() to find it. -The module path is relative to the file calling include(). -The module path does not include filename extensions like .js. +

      Here the module mjsunit.js has exported the function +assertEquals(). mjsunit.js must be in the +same directory as foo.js for include() to find it. +The module path is relative to the file calling include(). +The module path does not include filename extensions like .js. -

      include() inserts the exported objects +

      include() inserts the exported objects from the specified module into the global namespace.

      Because file loading does not happen instantaneously, and because Node has a policy of never blocking, the callback onLoad can be set and will notify the user +>onLoad can be set and will notify the user when all the included modules are loaded. Each file/module can have an onLoad callback. +>onLoad callback.

      To export an object, add to the special exports object. -

      The functions fail and deepEquals are not +

      The functions fail and deepEquals are not exported and remain private to the module.

      require() is like include() except does not polute the global namespace. It returns a namespace object. The exported objects -can only be guaranteed to exist after the onLoad() callback is +can only be guaranteed to exist after the onLoad() callback is made. For example: -

      +
       var mjsunit = require("mjsunit");
       function onLoad () {
         mjsunit.assertEquals(1, 2);
       }
       
      -

      include() and require() cannot be used after -onLoad() is called. So put them at the beginning of your file. +

      include() and require() cannot be used after +onLoad() is called. So put them at the beginning of your file. diff --git a/website/sh_main.js b/website/sh_main.js index 87182662c27..0a7764fe0a2 100644 --- a/website/sh_main.js +++ b/website/sh_main.js @@ -515,15 +515,15 @@ function highlight(prefix, suffix, tag) { for (var i = 0; i < nodeList.length; i++) { var element = nodeList.item(i); var htmlClasses = sh_getClasses(element); + var highlighted = false; for (var j = 0; j < htmlClasses.length; j++) { var htmlClass = htmlClasses[j].toLowerCase(); - if (htmlClass === 'sh_sourcecode') { - continue; - } + if (htmlClass === 'sh_none') break; if (htmlClass.substr(0, 3) === 'sh_') { var language = htmlClass.substring(3); if (language in sh_languages) { sh_highlightElement(element, sh_languages[language]); + highlighted = true; } else if (typeof(prefix) === 'string' && typeof(suffix) === 'string') { sh_load(language, element, prefix, suffix); @@ -534,6 +534,9 @@ function highlight(prefix, suffix, tag) { break; } } + if (highlighted === false) { + sh_highlightElement(element, sh_languages["javascript"]); + } } }