From 91bd3124adf84c5cc572cf67cd55f548441f9599 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 16 May 2009 12:44:49 +0200 Subject: [PATCH] Add sendUtf8 method to socket objects. Encoding UTF-16 (the native string representation) to UTF-8 is rather expensive, however just chopping off the second bit to convert UTF-16 to ASCII is rather fast. I've noticed major performance issues with String::WriteUtf8 and thus I'm going to explicitly separate in the API. Still need interfaces to this for the web server. --- src/net.cc | 34 ++++++++++++++++++++++++++-------- src/net.h | 1 + 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/net.cc b/src/net.cc index 889bb40f135..694e4cf05db 100644 --- a/src/net.cc +++ b/src/net.cc @@ -56,6 +56,7 @@ Connection::Initialize (v8::Handle target) NODE_SET_PROTOTYPE_METHOD(constructor_template, "connect", v8Connect); NODE_SET_PROTOTYPE_METHOD(constructor_template, "send", v8Send); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "sendUtf8", v8SendUtf8); NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", v8Close); NODE_SET_PROTOTYPE_METHOD(constructor_template, "fullClose", v8FullClose); NODE_SET_PROTOTYPE_METHOD(constructor_template, "forceClose", v8ForceClose); @@ -293,6 +294,25 @@ new_buf (size_t size) return b; } +Handle +Connection::v8SendUtf8 (const Arguments& args) +{ + HandleScope scope; + Connection *connection = NODE_UNWRAP(Connection, args.Holder()); + if (!connection) return Handle(); + + if (!args[0]->IsString()) + return ThrowException(String::New("Must have string argument")); + + // utf8 encoding + Local s = args[0]->ToString(); + size_t length = s->Utf8Length(); + oi_buf *buf = new_buf(length); + s->WriteUtf8(buf->base, length); + connection->Send(buf); + + return Undefined(); +} Handle Connection::v8Send (const Arguments& args) @@ -304,19 +324,17 @@ Connection::v8Send (const Arguments& args) // XXX // A lot of improvement can be made here. First of all we're allocating // oi_bufs for every send which is clearly inefficent - it should use a - // memory pool or ring buffer. In either case, v8 needs to be informed - // about our allocations deallocations via - // V8::AdjustAmountOfExternalAllocatedMemory to give the GC hints about - // what we're doing here. Of course, expressing binary data as an array - // of integers is extremely inefficent. This can improved when v8 bug 270 - // (http://code.google.com/p/v8/issues/detail?id=270) has been addressed. + // memory pool or ring buffer. Of course, expressing binary data as an + // array of integers is extremely inefficent. This can improved when v8 + // bug 270 (http://code.google.com/p/v8/issues/detail?id=270) has been + // addressed. if (args[0]->IsString()) { - // utf8 encoding + // ASCII encoding Local s = args[0]->ToString(); size_t length = s->Utf8Length(); oi_buf *buf = new_buf(length); - s->WriteUtf8(buf->base, length); + s->WriteAscii(buf->base, 0, length); connection->Send(buf); } else if (args[0]->IsArray()) { diff --git a/src/net.h b/src/net.h index 149bae4fe0b..f6b5332ca5c 100644 --- a/src/net.h +++ b/src/net.h @@ -21,6 +21,7 @@ protected: static v8::Handle v8New (const v8::Arguments& args); static v8::Handle v8Connect (const v8::Arguments& args); static v8::Handle v8Send (const v8::Arguments& args); + static v8::Handle v8SendUtf8 (const v8::Arguments& args); static v8::Handle v8Close (const v8::Arguments& args); static v8::Handle v8FullClose (const v8::Arguments& args); static v8::Handle v8ForceClose (const v8::Arguments& args);