Browse Source

Introduce "raws" encoding. Raw String.

This allows you to have binary data imported into your application via
strings instead of arrays of numbers! This needs testing before release.
v0.7.4-release
Ryan 16 years ago
parent
commit
8890070b88
  1. 6
      src/net.cc
  2. 35
      src/node.cc
  3. 4
      src/node.h
  4. 8
      src/node_stdio.cc
  5. 56
      test/mjsunit/test-tcp-raws.js

6
src/net.cc

@ -19,6 +19,7 @@ using namespace node;
#define UTF8_SYMBOL String::NewSymbol("utf8") #define UTF8_SYMBOL String::NewSymbol("utf8")
#define RAW_SYMBOL String::NewSymbol("raw") #define RAW_SYMBOL String::NewSymbol("raw")
#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")
@ -288,9 +289,12 @@ Connection::SetEncoding (const Arguments& args)
return scope.Close(UTF8_SYMBOL); return scope.Close(UTF8_SYMBOL);
case RAW: case RAW:
default:
connection->encoding_ = RAW; connection->encoding_ = RAW;
return scope.Close(RAW_SYMBOL); return scope.Close(RAW_SYMBOL);
case RAWS:
connection->encoding_ = RAWS;
return scope.Close(RAWS_SYMBOL);
} }
} }

35
src/node.cc

@ -47,6 +47,17 @@ node::Encode (const void *buf, size_t len, enum encoding encoding)
return scope.Close(array); return scope.Close(array);
} }
if (encoding == RAWS) {
const unsigned char *cbuf = static_cast<const unsigned char*>(buf);
uint16_t twobytebuf[len];
for (size_t i = 0; i < len; i++) {
// XXX is the following line platform independent?
twobytebuf[i] = cbuf[i];
}
Local<String> chunk = String::New(twobytebuf, len);
return scope.Close(chunk);
}
// utf8 or ascii encoding // utf8 or ascii encoding
Local<String> chunk = String::New((const char*)buf, len); Local<String> chunk = String::New((const char*)buf, len);
return scope.Close(chunk); return scope.Close(chunk);
@ -109,10 +120,26 @@ node::DecodeWrite (char *buf, size_t buflen, v8::Handle<v8::Value> val, enum enc
return buflen; return buflen;
} }
if (encoding == ASCII) {
string->WriteAscii(buf, 0, buflen); string->WriteAscii(buf, 0, buflen);
return buflen; return buflen;
} }
// THIS IS AWFUL!!! FIXME
uint16_t twobytebuf[buflen];
string->Write(twobytebuf, 0, buflen);
for (size_t i = 0; i < buflen; i++) {
unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
assert(b[1] == 0);
buf[i] = b[0];
}
return buflen;
}
// Extracts a C string from a V8 Utf8Value. // Extracts a C string from a V8 Utf8Value.
const char* const char*
ToCString(const v8::String::Utf8Value& value) ToCString(const v8::String::Utf8Value& value)
@ -300,7 +327,7 @@ eio_want_poll (void)
} }
enum encoding enum encoding
node::ParseEncoding (Handle<Value> encoding_v) node::ParseEncoding (Handle<Value> encoding_v, enum encoding _default)
{ {
HandleScope scope; HandleScope scope;
@ -313,8 +340,12 @@ node::ParseEncoding (Handle<Value> encoding_v)
return UTF8; return UTF8;
} else if (strcasecmp(*encoding, "ascii") == 0) { } else if (strcasecmp(*encoding, "ascii") == 0) {
return ASCII; return ASCII;
} else { } else if (strcasecmp(*encoding, "raw") == 0) {
return RAW; return RAW;
} else if (strcasecmp(*encoding, "raws") == 0) {
return RAWS;
} else {
return _default;
} }
} }

4
src/node.h

@ -32,8 +32,8 @@ do { \
__callback##_TEM); \ __callback##_TEM); \
} while(0) } while(0)
enum encoding {ASCII, UTF8, RAW}; enum encoding {ASCII, UTF8, RAW, RAWS};
enum encoding ParseEncoding (v8::Handle<v8::Value> encoding_v); enum encoding ParseEncoding (v8::Handle<v8::Value> encoding_v, enum encoding _default = RAW);
void FatalException (v8::TryCatch &try_catch); void FatalException (v8::TryCatch &try_catch);
v8::Local<v8::Value> v8::Local<v8::Value>

8
src/node_stdio.cc

@ -67,7 +67,13 @@ Write (const Arguments& args)
{ {
HandleScope scope; HandleScope scope;
enum encoding enc = ParseEncoding(args[1]); if (args.Length() == 0) {
return ThrowException(Exception::Error(String::New("Bad argument")));
}
enum encoding enc = UTF8;
if (args.Length() > 1) enc = ParseEncoding(args[1], UTF8);
ssize_t len = DecodeBytes(args[0], enc); ssize_t len = DecodeBytes(args[0], enc);
if (len < 0) { if (len < 0) {

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

@ -0,0 +1,56 @@
include("mjsunit.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