From 69dac92c36b8e0981a2afd1fc8dd9483cba8aad5 Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 1 May 2013 15:40:13 -0700 Subject: [PATCH] src: Use StringBytes in StreamWrap --- src/stream_wrap.cc | 69 ++++++++-------------------------------------- src/stream_wrap.h | 11 ++------ 2 files changed, 14 insertions(+), 66 deletions(-) diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index fb6edbc3a3..a1e7ded177 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -331,7 +331,7 @@ Handle StreamWrap::WriteBuffer(const Arguments& args) { } -template +template Handle StreamWrap::WriteStringImpl(const Arguments& args) { HandleScope scope; int r; @@ -344,38 +344,13 @@ Handle StreamWrap::WriteStringImpl(const Arguments& args) { Local string = args[0]->ToString(); // Compute the size of the storage that the string will be flattened into. + // For UTF8 strings that are very long, go ahead and take the hit for + // computing their actual size, rather than tripling the storage. size_t storage_size; - switch (encoding) { - case kAscii: - storage_size = string->Length(); - break; - - case kUtf8: - if (!(string->MayContainNonAscii())) { - // If the string has only ascii characters, we know exactly how big - // the storage should be. - storage_size = string->Length(); - } else if (string->Length() < 65536) { - // A single UCS2 codepoint never takes up more than 3 utf8 bytes. - // Unless the string is really long we just allocate so much space that - // we're certain the string fits in there entirely. - // TODO: maybe check handle->write_queue_size instead of string length? - storage_size = 3 * string->Length(); - } else { - // The string is really long. Compute the allocation size that we - // actually need. - storage_size = string->Utf8Length(); - } - break; - - case kUcs2: - storage_size = string->Length() * sizeof(uint16_t); - break; - - default: - // Unreachable. - assert(0); - } + if (encoding == UTF8 && string->Length() > 65535) + storage_size = StringBytes::Size(string, encoding); + else + storage_size = StringBytes::StorageSize(string, encoding); if (storage_size > INT_MAX) { uv_err_t err; @@ -389,29 +364,9 @@ Handle StreamWrap::WriteStringImpl(const Arguments& args) { char* data = reinterpret_cast(ROUND_UP( reinterpret_cast(storage) + sizeof(WriteWrap), 16)); - size_t data_size; - switch (encoding) { - case kAscii: - data_size = string->WriteAscii(data, 0, -1, - String::NO_NULL_TERMINATION | String::HINT_MANY_WRITES_EXPECTED); - break; - - case kUtf8: - data_size = string->WriteUtf8(data, -1, NULL, - String::NO_NULL_TERMINATION | String::HINT_MANY_WRITES_EXPECTED); - break; - - case kUcs2: { - int chars_copied = string->Write((uint16_t*) data, 0, -1, - String::NO_NULL_TERMINATION | String::HINT_MANY_WRITES_EXPECTED); - data_size = chars_copied * sizeof(uint16_t); - break; - } - default: - // Unreachable - assert(0); - } + size_t data_size; + data_size = StringBytes::Write(data, storage_size, string, encoding); assert(data_size <= storage_size); @@ -479,17 +434,17 @@ Handle StreamWrap::WriteStringImpl(const Arguments& args) { Handle StreamWrap::WriteAsciiString(const Arguments& args) { - return WriteStringImpl(args); + return WriteStringImpl(args); } Handle StreamWrap::WriteUtf8String(const Arguments& args) { - return WriteStringImpl(args); + return WriteStringImpl(args); } Handle StreamWrap::WriteUcs2String(const Arguments& args) { - return WriteStringImpl(args); + return WriteStringImpl(args); } diff --git a/src/stream_wrap.h b/src/stream_wrap.h index 77bd234a9d..5c122e58d7 100644 --- a/src/stream_wrap.h +++ b/src/stream_wrap.h @@ -25,17 +25,10 @@ #include "v8.h" #include "node.h" #include "handle_wrap.h" +#include "string_bytes.h" namespace node { - -enum WriteEncoding { - kAscii, - kUtf8, - kUcs2 -}; - - class StreamWrap : public HandleWrap { public: uv_stream_t* GetStream() { return stream_; } @@ -75,7 +68,7 @@ class StreamWrap : public HandleWrap { static void OnReadCommon(uv_stream_t* handle, ssize_t nread, uv_buf_t buf, uv_handle_type pending); - template + template static v8::Handle WriteStringImpl(const v8::Arguments& args); size_t slab_offset_;