Browse Source

Remove "raw" encoding. Rename "raws" to "binary".

Deprecation warnings have been added to help the conversion to this new API.
v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
07792afe0a
  1. 54
      doc/api.html
  2. 52
      doc/api.txt
  3. 30
      doc/node.1
  4. 2
      src/file.js
  5. 4
      src/http.js
  6. 17
      src/net.cc
  7. 2
      src/net.h
  8. 89
      src/node.cc
  9. 10
      src/node.h
  10. 27
      src/util.js
  11. 9
      test/mjsunit/test-encode-utf8.js
  12. 73
      test/mjsunit/test-tcp-binary.js
  13. 45
      test/mjsunit/test-tcp-raw.js
  14. 56
      test/mjsunit/test-tcp-raws.js

54
doc/api.html

@ -55,12 +55,10 @@ Server running at http://127.0.0.1:8000/</tt></pre>
</div> </div>
<h2 id="_api">API</h2> <h2 id="_api">API</h2>
<div class="sectionbody"> <div class="sectionbody">
<div class="paragraph"><p>Node supports 4 byte-string encodings. ASCII (<tt>"ascii"</tt>), UTF-8 (<tt>"utf8"</tt>) <div class="paragraph"><p>Node supports 3 string encodings. UTF-8 (<tt>"utf8"</tt>), ASCII (<tt>"ascii"</tt>), and
both use the string object, obviously. Then two "raw binary" encodings - one Binary (<tt>"binary"</tt>). <tt>"ascii"</tt> and <tt>"binary"</tt> only look at the first 8 bits
uses an array of integers (<tt>"raw"</tt>) and the other uses a string (<tt>"raws"</tt>). of the 16bit javascript string characters. Both are relatively fast&#8212;use
Neither raw encodings are perfect and their implementations are rather them if you can. <tt>"utf8"</tt> is slower and should be avoided when possible.</p></div>
inefficient. Hopefully the raw encoding situation will improve in the
future.</p></div>
<div class="paragraph"><p>Unless otherwise noted, functions are all asynchronous and do not block <div class="paragraph"><p>Unless otherwise noted, functions are all asynchronous and do not block
execution.</p></div> execution.</p></div>
<h3 id="_helpers">Helpers</h3><div style="clear:left"></div> <h3 id="_helpers">Helpers</h3><div style="clear:left"></div>
@ -373,10 +371,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><tt>data</tt></p></td> <td align="left" valign="top"><p class="table"><tt>data</tt></p></td>
<td align="left" valign="top"><p class="table">Made when stdin has received a chunk of data. <td align="left" valign="top"><p class="table">Made when stdin has received a chunk of data.
Depending on the encoding that stdin was opened Depending on the encoding that stdin was opened
with, <tt>data</tt> will be either an array of integers with, <tt>data</tt> will be a string. This event will
(raw encoding) or a string (ascii or utf8 only be emited after <tt>node.stdio.open()</tt> has
encoding). This event will only be emited after been called.</p></td>
<tt>node.stdio.open()</tt> has been called.</p></td>
</tr> </tr>
<tr> <tr>
<td align="left" valign="top"><p class="table"><tt>"close"</tt></p></td> <td align="left" valign="top"><p class="table"><tt>"close"</tt></p></td>
@ -599,7 +596,8 @@ The PID of the child process.
<dd> <dd>
<p> <p>
Write data to the child process&#8217;s <tt>stdin</tt>. The second argument is optional and Write data to the child process&#8217;s <tt>stdin</tt>. The second argument is optional and
specifies the encoding: possible values are <tt>"utf8"</tt>, <tt>"ascii"</tt>, and <tt>"raw"</tt>. specifies the encoding: possible values are <tt>"utf8"</tt>, <tt>"ascii"</tt>, and
<tt>"binary"</tt>.
</p> </p>
</dd> </dd>
<dt class="hdlist1"> <dt class="hdlist1">
@ -1050,8 +1048,7 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><tt>chunk</tt></p></td> <td align="left" valign="top"><p class="table"><tt>chunk</tt></p></td>
<td align="left" valign="top"><p class="table">Emitted when a piece of the message body is received. Example: A chunk of <td align="left" valign="top"><p class="table">Emitted when a piece of the message body is received. Example: A chunk of
the body is given as the single argument. The transfer-encoding has been the body is given as the single argument. The transfer-encoding has been
decoded. The body chunk is either a String in the case of UTF-8 encoding or decoded. The body chunk is a String. The body encoding is set
an array of numbers in the case of raw encoding. The body encoding is set
with <tt>request.setBodyEncoding()</tt>.</p></td> with <tt>request.setBodyEncoding()</tt>.</p></td>
</tr> </tr>
<tr> <tr>
@ -1123,8 +1120,8 @@ The HTTP protocol version as a string. Read only. Examples:
</dt> </dt>
<dd> <dd>
<p> <p>
Set the encoding for the request body. Either <tt>"utf8"</tt> or <tt>"raw"</tt>. Defaults Set the encoding for the request body. Either <tt>"utf8"</tt> or <tt>"binary"</tt>. Defaults
to raw. to <tt>"binary"</tt>.
</p> </p>
</dd> </dd>
<dt class="hdlist1"> <dt class="hdlist1">
@ -1380,9 +1377,8 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><tt>chunk</tt></p></td> <td align="left" valign="top"><p class="table"><tt>chunk</tt></p></td>
<td align="left" valign="top"><p class="table">Emitted when a piece of the message body is received. Example: A chunk of <td align="left" valign="top"><p class="table">Emitted when a piece of the message body is received. Example: A chunk of
the body is given as the single argument. The transfer-encoding has been the body is given as the single argument. The transfer-encoding has been
decoded. The body chunk is either a String in the case of UTF-8 encoding or decoded. The body chunk a String. The body encoding is set with
an array of numbers in the case of raw encoding. The body encoding is set <tt>response.setBodyEncoding()</tt>.</p></td>
with <tt>response.setBodyEncoding()</tt>.</p></td>
</tr> </tr>
<tr> <tr>
<td align="left" valign="top"><p class="table"><tt>"complete"</tt></p></td> <td align="left" valign="top"><p class="table"><tt>"complete"</tt></p></td>
@ -1424,8 +1420,8 @@ After emitted no other events will be emitted on the response.</p></td>
</dt> </dt>
<dd> <dd>
<p> <p>
Set the encoding for the response body. Either <tt>"utf8"</tt> or <tt>"raw"</tt>. Set the encoding for the response body. Either <tt>"utf8"</tt> or <tt>"binary"</tt>.
Defaults to raw. Defaults to <tt>"binary"</tt>.
</p> </p>
</dd> </dd>
<dt class="hdlist1"> <dt class="hdlist1">
@ -1574,11 +1570,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><tt>"receive"</tt></p></td> <td align="left" valign="top"><p class="table"><tt>"receive"</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>data</tt></p></td> <td align="left" valign="top"><p class="table"><tt>data</tt></p></td>
<td align="left" valign="top"><p class="table">Called when data is received on the <td align="left" valign="top"><p class="table">Called when data is received on the
connection. Encoding of data is set connection. <tt>data</tt> will be a string.
by <tt>connection.setEncoding()</tt>. <tt>data</tt> Encoding of data is set by
will either be a string, in the case of <tt>connection.setEncoding()</tt>.</p></td>
utf8, or an array of integer in the case
of raw encoding.</p></td>
</tr> </tr>
<tr> <tr>
<td align="left" valign="top"><p class="table"><tt>"eof"</tt></p></td> <td align="left" valign="top"><p class="table"><tt>"eof"</tt></p></td>
@ -1658,7 +1652,7 @@ Either <tt>"closed"</tt>, <tt>"open"</tt>, <tt>"opening"</tt>, <tt>"readOnly"</t
</dt> </dt>
<dd> <dd>
<p> <p>
Sets the encoding (either <tt>"utf8"</tt> or <tt>"raw"</tt>) for data that is received. Sets the encoding (either <tt>"ascii"</tt>, <tt>"utf8"</tt>, or <tt>"binary"</tt>) for data that is received.
</p> </p>
</dd> </dd>
<dt class="hdlist1"> <dt class="hdlist1">
@ -1666,10 +1660,8 @@ Sets the encoding (either <tt>"utf8"</tt> or <tt>"raw"</tt>) for data that is re
</dt> </dt>
<dd> <dd>
<p> <p>
Sends data on the connection. The data should be eithre an array Sends data on the connection. The second parameter specifies the encoding
of integers (for raw binary) or a string (for utf8 or ascii). in the case of a string&#8212;it defaults to ASCII because encoding to UTF8 is
The second parameter specifies the encoding in the case of a
string&#8212;it defaults to ASCII because encoding to UTF8 is
rather slow. rather slow.
</p> </p>
</dd> </dd>
@ -1930,7 +1922,7 @@ init (Handle&lt;Object&gt; target)
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Version 0.1.11<br /> Version 0.1.11<br />
Last updated 2009-09-18 18:31:06 CEST Last updated 2009-09-21 12:26:35 CEST
</div> </div>
</div> </div>
</body> </body>

52
doc/api.txt

@ -38,12 +38,10 @@ Server running at http://127.0.0.1:8000/
== API == API
Node supports 4 byte-string encodings. ASCII (+"ascii"+), UTF-8 (+"utf8"+) Node supports 3 string encodings. UTF-8 (+"utf8"+), ASCII (+"ascii"+), and
both use the string object, obviously. Then two "raw binary" encodings - one Binary (+"binary"+). +"ascii"+ and +"binary"+ only look at the first 8 bits
uses an array of integers (+"raw"+) and the other uses a string (+"raws"+). of the 16bit javascript string characters. Both are relatively fast--use
Neither raw encodings are perfect and their implementations are rather them if you can. +"utf8"+ is slower and should be avoided when possible.
inefficient. Hopefully the raw encoding situation will improve in the
future.
Unless otherwise noted, functions are all asynchronous and do not block Unless otherwise noted, functions are all asynchronous and do not block
execution. execution.
@ -222,10 +220,9 @@ synchronous.
| +"data"+ | +data+ | Made when stdin has received a chunk of data. | +"data"+ | +data+ | Made when stdin has received a chunk of data.
Depending on the encoding that stdin was opened Depending on the encoding that stdin was opened
with, +data+ will be either an array of integers with, +data+ will be a string. This event will
(raw encoding) or a string (ascii or utf8 only be emited after +node.stdio.open()+ has
encoding). This event will only be emited after been called.
+node.stdio.open()+ has been called.
| +"close"+ | | Made when stdin has been closed. | +"close"+ | | Made when stdin has been closed.
|========================================================= |=========================================================
@ -394,7 +391,8 @@ The PID of the child process.
+child.write(data, encoding="ascii")+ :: +child.write(data, encoding="ascii")+ ::
Write data to the child process's +stdin+. The second argument is optional and Write data to the child process's +stdin+. The second argument is optional and
specifies the encoding: possible values are +"utf8"+, +"ascii"+, and +"raw"+. specifies the encoding: possible values are +"utf8"+, +"ascii"+, and
+"binary"+.
+child.close()+ :: +child.close()+ ::
@ -640,8 +638,7 @@ the user--and passed as the first argument to a +"request"+ listener.
|+"body"+ | +chunk+ | |+"body"+ | +chunk+ |
Emitted when a piece of the message body is received. Example: A chunk of Emitted when a piece of the message body is received. Example: A chunk of
the body is given as the single argument. The transfer-encoding has been the body is given as the single argument. The transfer-encoding has been
decoded. The body chunk is either a String in the case of UTF-8 encoding or decoded. The body chunk is a String. The body encoding is set
an array of numbers in the case of raw encoding. The body encoding is set
with +request.setBodyEncoding()+. with +request.setBodyEncoding()+.
|+"complete"+ | | |+"complete"+ | |
@ -692,8 +689,8 @@ The HTTP protocol version as a string. Read only. Examples:
+request.setBodyEncoding(encoding)+ :: +request.setBodyEncoding(encoding)+ ::
Set the encoding for the request body. Either +"utf8"+ or +"raw"+. Defaults Set the encoding for the request body. Either +"utf8"+ or +"binary"+. Defaults
to raw. to +"binary"+.
+request.pause()+ :: +request.pause()+ ::
@ -895,9 +892,8 @@ This object is created internally and passed to the +"response"+ event.
|+"body"+ | +chunk+ | |+"body"+ | +chunk+ |
Emitted when a piece of the message body is received. Example: A chunk of Emitted when a piece of the message body is received. Example: A chunk of
the body is given as the single argument. The transfer-encoding has been the body is given as the single argument. The transfer-encoding has been
decoded. The body chunk is either a String in the case of UTF-8 encoding or decoded. The body chunk a String. The body encoding is set with
an array of numbers in the case of raw encoding. The body encoding is set +response.setBodyEncoding()+.
with +response.setBodyEncoding()+.
|+"complete"+ | | |+"complete"+ | |
Emitted exactly once for each message. No arguments. Emitted exactly once for each message. No arguments.
@ -916,8 +912,8 @@ After emitted no other events will be emitted on the response.
The response headers. The response headers.
+response.setBodyEncoding(encoding)+ :: +response.setBodyEncoding(encoding)+ ::
Set the encoding for the response body. Either +"utf8"+ or +"raw"+. Set the encoding for the response body. Either +"utf8"+ or +"binary"+.
Defaults to raw. Defaults to +"binary"+.
+response.pause()+ :: +response.pause()+ ::
Pauses response from emitting events. Useful to throttle back a download. Pauses response from emitting events. Useful to throttle back a download.
@ -1005,11 +1001,9 @@ socket for +node.tcp.Server+.
after a call to +createConnection()+ or after a call to +createConnection()+ or
+connect()+. +connect()+.
|+"receive"+ | +data+ | Called when data is received on the |+"receive"+ | +data+ | Called when data is received on the
connection. Encoding of data is set connection. +data+ will be a string.
by +connection.setEncoding()+. +data+ Encoding of data is set by
will either be a string, in the case of +connection.setEncoding()+.
utf8, or an array of integer in the case
of raw encoding.
|+"eof"+ | | Called when the other end of the |+"eof"+ | | Called when the other end of the
connection sends a FIN packet. connection sends a FIN packet.
After this is emitted the +readyState+ After this is emitted the +readyState+
@ -1055,13 +1049,11 @@ Either +"closed"+, +"open"+, +"opening"+, +"readOnly"+, or +"writeOnly"+.
+connection.setEncoding(encoding)+:: +connection.setEncoding(encoding)+::
Sets the encoding (either +"utf8"+ or +"raw"+) for data that is received. Sets the encoding (either +"ascii"+, +"utf8"+, or +"binary"+) for data that is received.
+connection.send(data, encoding="ascii")+:: +connection.send(data, encoding="ascii")+::
Sends data on the connection. The data should be eithre an array Sends data on the connection. The second parameter specifies the encoding
of integers (for raw binary) or a string (for utf8 or ascii). in the case of a string--it defaults to ASCII because encoding to UTF8 is
The second parameter specifies the encoding in the case of a
string--it defaults to ASCII because encoding to UTF8 is
rather slow. rather slow.

30
doc/node.1

@ -1,11 +1,11 @@
.\" Title: node .\" Title: node
.\" Author: .\" Author:
.\" Generator: DocBook XSL Stylesheets v1.73.2 <http://docbook.sf.net/> .\" Generator: DocBook XSL Stylesheets v1.73.2 <http://docbook.sf.net/>
.\" Date: 09/18/2009 .\" Date: 09/21/2009
.\" Manual: .\" Manual:
.\" Source: .\" Source:
.\" .\"
.TH "NODE" "1" "09/18/2009" "" "" .TH "NODE" "1" "09/21/2009" "" ""
.\" disable hyphenation .\" disable hyphenation
.nh .nh
.\" disable justification (adjust text to left margin only) .\" disable justification (adjust text to left margin only)
@ -38,7 +38,7 @@ Server running at http://127\.0\.0\.1:8000/
.fi .fi
.RE .RE
.SH "API" .SH "API"
Node supports 4 byte\-string encodings\. ASCII ("ascii"), UTF\-8 ("utf8") both use the string object, obviously\. Then two "raw binary" encodings \- one uses an array of integers ("raw") and the other uses a string ("raws")\. Neither raw encodings are perfect and their implementations are rather inefficient\. Hopefully the raw encoding situation will improve in the future\. Node supports 3 string encodings\. UTF\-8 ("utf8"), ASCII ("ascii"), and Binary ("binary")\. "ascii" and "binary" only look at the first 8 bits of the 16bit javascript string characters\. Both are relatively fast\(emuse them if you can\. "utf8" is slower and should be avoided when possible\.
.sp .sp
Unless otherwise noted, functions are all asynchronous and do not block execution\. Unless otherwise noted, functions are all asynchronous and do not block execution\.
.sp .sp
@ -329,7 +329,7 @@ T}:T{
data data
.sp .sp
T}:T{ T}:T{
Made when stdin has received a chunk of data\. Depending on the encoding that stdin was opened with, data will be either an array of integers (raw encoding) or a string (ascii or utf8 encoding)\. This event will only be emited after node\.stdio\.open() has been called\. Made when stdin has received a chunk of data\. Depending on the encoding that stdin was opened with, data will be a string\. This event will only be emited after node\.stdio\.open() has been called\.
.sp .sp
T} T}
T{ T{
@ -558,7 +558,7 @@ Write data to the child process\(cqs
stdin\. The second argument is optional and specifies the encoding: possible values are stdin\. The second argument is optional and specifies the encoding: possible values are
"utf8", "utf8",
"ascii", and "ascii", and
"raw"\. "binary"\.
.RE .RE
.PP .PP
child\.close() child\.close()
@ -946,7 +946,7 @@ T}:T{
chunk chunk
.sp .sp
T}:T{ T}:T{
Emitted when a piece of the message body is received\. Example: A chunk of the body is given as the single argument\. The transfer\-encoding has been decoded\. 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 request\.setBodyEncoding()\. Emitted when a piece of the message body is received\. Example: A chunk of the body is given as the single argument\. The transfer\-encoding has been decoded\. The body chunk is a String\. The body encoding is set with request\.setBodyEncoding()\.
.sp .sp
T} T}
T{ T{
@ -1030,7 +1030,8 @@ request\.setBodyEncoding(encoding)
Set the encoding for the request body\. Either Set the encoding for the request body\. Either
"utf8" "utf8"
or or
"raw"\. Defaults to raw\. "binary"\. Defaults to
"binary"\.
.RE .RE
.PP .PP
request\.pause() request\.pause()
@ -1300,7 +1301,7 @@ T}:T{
chunk chunk
.sp .sp
T}:T{ T}:T{
Emitted when a piece of the message body is received\. Example: A chunk of the body is given as the single argument\. The transfer\-encoding has been decoded\. 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 response\.setBodyEncoding()\. Emitted when a piece of the message body is received\. Example: A chunk of the body is given as the single argument\. The transfer\-encoding has been decoded\. The body chunk a String\. The body encoding is set with response\.setBodyEncoding()\.
.sp .sp
T} T}
T{ T{
@ -1338,7 +1339,8 @@ response\.setBodyEncoding(encoding)
Set the encoding for the response body\. Either Set the encoding for the response body\. Either
"utf8" "utf8"
or or
"raw"\. Defaults to raw\. "binary"\. Defaults to
"binary"\.
.RE .RE
.PP .PP
response\.pause() response\.pause()
@ -1502,7 +1504,7 @@ T}:T{
data data
.sp .sp
T}:T{ T}:T{
Called when data is received on the connection\. Encoding of data is set by connection\.setEncoding()\. data will either be a string, in the case of utf8, or an array of integer in the case of raw encoding\. Called when data is received on the connection\. data will be a string\. Encoding of data is set by connection\.setEncoding()\.
.sp .sp
T} T}
T{ T{
@ -1589,14 +1591,14 @@ Either
connection\.setEncoding(encoding) connection\.setEncoding(encoding)
.RS 4 .RS 4
Sets the encoding (either Sets the encoding (either
"utf8" "ascii",
or "utf8", or
"raw") for data that is received\. "binary") for data that is received\.
.RE .RE
.PP .PP
connection\.send(data, encoding="ascii") connection\.send(data, encoding="ascii")
.RS 4 .RS 4
Sends data on the connection\. The data should be eithre an array of integers (for raw binary) or a string (for utf8 or ascii)\. The second parameter specifies the encoding in the case of a string\(emit defaults to ASCII because encoding to UTF8 is rather slow\. Sends data on the connection\. The second parameter specifies the encoding in the case of a string\(emit defaults to ASCII because encoding to UTF8 is rather slow\.
.RE .RE
.PP .PP
connection\.close() connection\.close()

2
src/file.js

@ -14,7 +14,7 @@ node.fs.cat = function (path, encoding) {
cat_promise.emitError(new Error("Could not open " + path)); cat_promise.emitError(new Error("Could not open " + path));
}); });
open_promise.addCallback(function (fd) { open_promise.addCallback(function (fd) {
var content = (encoding === "raw" ? [] : ""); var content = "";
var pos = 0; var pos = 0;
function readChunk () { function readChunk () {

4
src/http.js

@ -178,7 +178,7 @@ OutgoingMessage.prototype.send = function (data, encoding) {
if (length === 0) { if (length === 0) {
this.output.push(data); this.output.push(data);
encoding = encoding || (data.constructor === Array ? "raw" : "ascii"); encoding = encoding || "ascii";
this.outputEncodings.push(encoding); this.outputEncodings.push(encoding);
return; return;
} }
@ -197,7 +197,7 @@ OutgoingMessage.prototype.send = function (data, encoding) {
} }
this.output.push(data); this.output.push(data);
encoding = encoding || (data.constructor === Array ? "raw" : "ascii"); encoding = encoding || "ascii";
this.outputEncodings.push(encoding); this.outputEncodings.push(encoding);
}; };

17
src/net.cc

@ -17,8 +17,7 @@ using namespace v8;
namespace node { namespace node {
#define UTF8_SYMBOL String::NewSymbol("utf8") #define UTF8_SYMBOL String::NewSymbol("utf8")
#define RAW_SYMBOL String::NewSymbol("raw") #define BINARY_SYMBOL String::NewSymbol("binary")
#define RAWS_SYMBOL String::NewSymbol("raws")
#define ASCII_SYMBOL String::NewSymbol("ascii") #define ASCII_SYMBOL String::NewSymbol("ascii")
#define SERVER_SYMBOL String::NewSymbol("server") #define SERVER_SYMBOL String::NewSymbol("server")
@ -257,8 +256,8 @@ Handle<Value> Connection::SetEncoding(const Arguments& args) {
assert(connection); assert(connection);
if (!args[0]->IsString()) { if (!args[0]->IsString()) {
connection->encoding_ = RAW; connection->encoding_ = BINARY;
return scope.Close(RAW_SYMBOL); return scope.Close(BINARY_SYMBOL);
} }
switch (ParseEncoding(args[0])) { switch (ParseEncoding(args[0])) {
@ -270,13 +269,9 @@ Handle<Value> Connection::SetEncoding(const Arguments& args) {
connection->encoding_ = UTF8; connection->encoding_ = UTF8;
return scope.Close(UTF8_SYMBOL); return scope.Close(UTF8_SYMBOL);
case RAW: case BINARY:
connection->encoding_ = RAW; connection->encoding_ = BINARY;
return scope.Close(RAW_SYMBOL); return scope.Close(BINARY_SYMBOL);
case RAWS:
connection->encoding_ = RAWS;
return scope.Close(RAWS_SYMBOL);
} }
assert(0 && "this shouldn't happen"); assert(0 && "this shouldn't happen");
return ThrowException(Exception::Error( return ThrowException(Exception::Error(

2
src/net.h

@ -33,7 +33,7 @@ class Connection : public EventEmitter {
const v8::AccessorInfo& info); const v8::AccessorInfo& info);
Connection() : EventEmitter() { Connection() : EventEmitter() {
encoding_ = RAW; encoding_ = BINARY;
host_ = NULL; host_ = NULL;
port_ = NULL; port_ = NULL;

89
src/node.cc

@ -30,22 +30,38 @@ namespace node {
static int dash_dash_index = 0; static int dash_dash_index = 0;
Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) { enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
HandleScope scope; HandleScope scope;
if (!len) return scope.Close(Null()); if (!encoding_v->IsString()) return _default;
if (encoding == RAW) { String::Utf8Value encoding(encoding_v->ToString());
// raw encoding
Local<Array> array = Array::New(len); if (strcasecmp(*encoding, "utf8") == 0) {
for (size_t i = 0; i < len; i++) { return UTF8;
unsigned char val = static_cast<const unsigned char*>(buf)[i]; } else if (strcasecmp(*encoding, "ascii") == 0) {
array->Set(Integer::New(i), Integer::New(val)); return ASCII;
} } else if (strcasecmp(*encoding, "binary") == 0) {
return scope.Close(array); return BINARY;
} else if (strcasecmp(*encoding, "raw") == 0) {
fprintf(stderr, "'raw' (array of integers) has been removed. "
"Use 'binary'.\n");
return BINARY;
} else if (strcasecmp(*encoding, "raws") == 0) {
fprintf(stderr, "'raws' encoding has been renamed to 'binary'. "
"Please update your code.\n");
return BINARY;
} else {
return _default;
} }
}
Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) {
HandleScope scope;
if (!len) return scope.Close(Null());
if (encoding == RAWS) { if (encoding == BINARY) {
const unsigned char *cbuf = static_cast<const unsigned char*>(buf); const unsigned char *cbuf = static_cast<const unsigned char*>(buf);
uint16_t * twobytebuf = new uint16_t[len]; uint16_t * twobytebuf = new uint16_t[len];
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
@ -53,7 +69,7 @@ Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) {
twobytebuf[i] = cbuf[i]; twobytebuf[i] = cbuf[i];
} }
Local<String> chunk = String::New(twobytebuf, len); Local<String> chunk = String::New(twobytebuf, len);
delete twobytebuf; delete twobytebuf; // TODO use ExternalTwoByteString?
return scope.Close(chunk); return scope.Close(chunk);
} }
@ -67,14 +83,13 @@ ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
HandleScope scope; HandleScope scope;
if (val->IsArray()) { if (val->IsArray()) {
if (encoding != RAW) return -1; fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
Handle<Array> array = Handle<Array>::Cast(val); "Use 'binary'.\n");
return array->Length(); assert(0);
return -1;
} }
if (!val->IsString()) return -1; Local<String> str = val->ToString();
Handle<String> str = Handle<String>::Cast(val);
if (encoding == UTF8) return str->Utf8Length(); if (encoding == UTF8) return str->Utf8Length();
@ -99,18 +114,13 @@ ssize_t DecodeWrite(char *buf, size_t buflen,
// http://groups.google.com/group/v8-users/browse_thread/thread/1f83b0ba1f0a611 // http://groups.google.com/group/v8-users/browse_thread/thread/1f83b0ba1f0a611
if (val->IsArray()) { if (val->IsArray()) {
if (encoding != RAW) return -1; fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
Handle<Array> array = Handle<Array>::Cast(val); "Use 'binary'.\n");
size_t array_len = array->Length(); assert(0);
for (i = 0; i < MIN(buflen, array_len); i++) { return -1;
Local<Value> int_value = array->Get(Integer::New(i));
buf[i] = int_value->IntegerValue();
}
return i;
} }
assert(val->IsString()); Local<String> str = val->ToString();
Handle<String> str = Handle<String>::Cast(val);
if (encoding == UTF8) { if (encoding == UTF8) {
str->WriteUtf8(buf, buflen); str->WriteUtf8(buf, buflen);
@ -124,6 +134,8 @@ ssize_t DecodeWrite(char *buf, size_t buflen,
// THIS IS AWFUL!!! FIXME // THIS IS AWFUL!!! FIXME
assert(encoding == BINARY);
uint16_t * twobytebuf = new uint16_t[buflen]; uint16_t * twobytebuf = new uint16_t[buflen];
str->Write(twobytebuf, 0, buflen); str->Write(twobytebuf, 0, buflen);
@ -310,27 +322,6 @@ static void EIOWantPoll(void) {
ev_async_send(EV_DEFAULT_UC_ &eio_watcher); ev_async_send(EV_DEFAULT_UC_ &eio_watcher);
} }
enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
HandleScope scope;
if (!encoding_v->IsString())
return RAW;
String::Utf8Value encoding(encoding_v->ToString());
if (strcasecmp(*encoding, "utf8") == 0) {
return UTF8;
} else if (strcasecmp(*encoding, "ascii") == 0) {
return ASCII;
} else if (strcasecmp(*encoding, "raw") == 0) {
return RAW;
} else if (strcasecmp(*encoding, "raws") == 0) {
return RAWS;
} else {
return _default;
}
}
static void ExecuteNativeJS(const char *filename, const char *data) { static void ExecuteNativeJS(const char *filename, const char *data) {
HandleScope scope; HandleScope scope;
TryCatch try_catch; TryCatch try_catch;

10
src/node.h

@ -34,23 +34,23 @@ do { \
__callback##_TEM); \ __callback##_TEM); \
} while (0) } while (0)
enum encoding {ASCII, UTF8, RAW, RAWS}; enum encoding {ASCII, UTF8, BINARY};
enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v, enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v,
enum encoding _default = RAW); enum encoding _default = BINARY);
void FatalException(v8::TryCatch &try_catch); void FatalException(v8::TryCatch &try_catch);
v8::Local<v8::Value> Encode(const void *buf, size_t len, v8::Local<v8::Value> Encode(const void *buf, size_t len,
enum encoding encoding = RAW); enum encoding encoding = BINARY);
// Returns -1 if the handle was not valid for decoding // Returns -1 if the handle was not valid for decoding
ssize_t DecodeBytes(v8::Handle<v8::Value>, ssize_t DecodeBytes(v8::Handle<v8::Value>,
enum encoding encoding = RAW); enum encoding encoding = BINARY);
// returns bytes written. // returns bytes written.
ssize_t DecodeWrite(char *buf, ssize_t DecodeWrite(char *buf,
size_t buflen, size_t buflen,
v8::Handle<v8::Value>, v8::Handle<v8::Value>,
enum encoding encoding = RAW); enum encoding encoding = BINARY);
} // namespace node } // namespace node

27
src/util.js

@ -23,33 +23,6 @@ node.assert = function (x, msg) {
if (!(x)) throw new Error(msg || "assertion error"); if (!(x)) throw new Error(msg || "assertion error");
}; };
// This is useful for dealing with raw encodings.
node.encodeUtf8 = function (array) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while (i < array.length) {
c = array[i];
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = array[i+1];
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = array[i+1];
c3 = array[i+2];
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
};
node.cat = function(location, encoding) { node.cat = function(location, encoding) {
var url_re = new RegExp("^http:\/\/"); var url_re = new RegExp("^http:\/\/");
var f = url_re.exec(location) ? node.http.cat : node.fs.cat; var f = url_re.exec(location) ? node.http.cat : node.fs.cat;

9
test/mjsunit/test-encode-utf8.js

@ -1,9 +0,0 @@
include("common.js");
var a = [116,101,115,116,32,206,163,207,131,207,128,206,177,32,226,161,140,226,160, 129,226,160,167,226,160,145];
var s = node.encodeUtf8(a);
assertEquals("test Σσπα ⡌⠁⠧⠑", s);
a = [104, 101, 108, 108, 111];
s = node.encodeUtf8(a);
assertEquals("hello", s);

73
test/mjsunit/test-tcp-binary.js

@ -0,0 +1,73 @@
include("common.js");
PORT = 23123;
binaryString = "";
for (var i = 255; i >= 0; i--) {
var s = "'\\" + i.toString(8) + "'";
S = eval(s);
node.error( s
+ " "
+ JSON.stringify(S)
+ " "
+ JSON.stringify(String.fromCharCode(i))
+ " "
+ S.charCodeAt(0)
);
node.assert(S.charCodeAt(0) == i);
node.assert(S == String.fromCharCode(i));
binaryString += S;
}
var echoServer = node.tcp.createServer(function (connection) {
connection.setEncoding("binary");
connection.addListener("receive", function (chunk) {
node.error("recved: " + JSON.stringify(chunk));
connection.send(chunk, "binary");
});
connection.addListener("eof", function () {
connection.close();
});
});
echoServer.listen(PORT);
var recv = "";
var j = 0;
var c = node.tcp.createConnection(PORT);
c.setEncoding("binary");
c.addListener("receive", function (chunk) {
if (j < 256) {
node.error("send " + j);
c.send(String.fromCharCode(j), "binary");
j++;
} else {
c.close();
}
recv += chunk;
});
c.addListener("connect", function () {
c.send(binaryString, "binary");
});
c.addListener("close", function () {
p(recv);
echoServer.close();
});
process.addListener("exit", function () {
puts("recv: " + JSON.stringify(recv));
assertEquals(2*256, recv.length);
var a = recv.split("");
var first = a.slice(0,256).reverse().join("");
puts("first: " + JSON.stringify(first));
var second = a.slice(256,2*256).join("");
puts("second: " + JSON.stringify(second));
assertEquals(first, second);
});

45
test/mjsunit/test-tcp-raw.js

@ -1,45 +0,0 @@
include("common.js");
PORT = 23123;
var echoServer = node.tcp.createServer(function (connection) {
connection.addListener("receive", function (chunk) {
connection.send(chunk, "raw");
});
connection.addListener("eof", function () {
connection.close();
});
});
echoServer.listen(PORT);
var recv = [];
var j = 0;
var c = node.tcp.createConnection(PORT);
c.addListener("receive", function (chunk) {
if (++j < 256) {
c.send([j], "raw");
} else {
c.close();
}
for (var i = 0; i < chunk.length; i++) {
recv.push(chunk[i]);
}
});
c.addListener("connect", function () {
c.send([j], "raw");
});
c.addListener("close", function () {
p(recv);
echoServer.close();
});
process.addListener("exit", function () {
var expected = [];
for (var i = 0; i < 256; i++) {
expected.push(i);
}
assertEquals(expected, recv);
});

56
test/mjsunit/test-tcp-raws.js

@ -1,56 +0,0 @@
include("common.js");
PORT = 23123;
binaryString = "";
for (var i = 0; i < 256; i++) {
var j = 255 - i;
var s = "'\\" + j.toString(8) + "'";
S = eval(s);
puts(s + " " + JSON.stringify(S) + " " + S.charCodeAt(0));
node.assert(S.charCodeAt(0) == j);
binaryString += S;
}
var echoServer = node.tcp.createServer(function (connection) {
connection.setEncoding("raws");
connection.addListener("receive", function (chunk) {
puts("recved: " + JSON.stringify(chunk));
connection.send(chunk, "raws");
});
connection.addListener("eof", function () {
connection.close();
});
});
echoServer.listen(PORT);
var recv = "";
var j = 0;
var c = node.tcp.createConnection(PORT);
c.setEncoding("raws");
c.addListener("receive", function (chunk) {
if (j++ < 256) {
c.send([j]);
} else {
c.close();
}
recv += chunk;
});
c.addListener("connect", function () {
c.send(binaryString, "raws");
});
c.addListener("close", function () {
p(recv);
echoServer.close();
});
process.addListener("exit", function () {
assertEquals(2*256, recv.length);
for (var i = 0; i < 256; i++) {
assertEquals(i, recv.charCodeAt(255+i));
assertEquals(i, recv.charCodeAt(255-i));
}
});
Loading…
Cancel
Save