From c6367e7f2a68b2418a98dfe9e829f17f62ba403a Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 30 Jan 2015 15:05:28 +0300 Subject: [PATCH] node: speed up ParseEncoding Handle most popular cases in a trie-style, branching on a first character. Remove useless HandleScope which was only eating time without producing any value. PR-URL: https://github.com/iojs/io.js/pull/664 Reviewed-By: Ben Noordhuis --- src/node.cc | 86 +++++++++++++++++++++++++++++++++++++++-------------- src/node.h | 6 ++-- 2 files changed, 66 insertions(+), 26 deletions(-) diff --git a/src/node.cc b/src/node.cc index 72ddbe178e37b9..463b69936afd88 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1148,55 +1148,95 @@ Handle MakeCallback(Isolate* isolate, } -enum encoding ParseEncoding(Isolate* isolate, - Handle encoding_v, - enum encoding _default) { - HandleScope scope(isolate); - - if (!encoding_v->IsString()) - return _default; - - node::Utf8Value encoding(isolate, encoding_v); +enum encoding ParseEncoding(const char* encoding, + enum encoding default_encoding) { + switch (encoding[0]) { + case 'u': + // utf8, utf16le + if (encoding[1] == 't' && encoding[2] == 'f') { + // Skip `-` + encoding += encoding[3] == '-' ? 4 : 3; + if (encoding[0] == '8' && encoding[1] == '\0') + return UTF8; + if (strncmp(encoding, "16le", 4) == 0) + return UCS2; + + // ucs2 + } else if (encoding[1] == 'c' && encoding[2] == 's') { + encoding += encoding[3] == '-' ? 4 : 3; + if (encoding[0] == '2' && encoding[1] == '\0') + return UCS2; + } + break; + case 'b': + // binary + if (encoding[1] == 'i') { + if (strncmp(encoding + 2, "nary", 4) == 0) + return BINARY; + + // buffer + } else if (encoding[1] == 'u') { + if (strncmp(encoding + 2, "ffer", 4) == 0) + return BUFFER; + } + break; + case '\0': + return default_encoding; + default: + break; + } - if (strcasecmp(*encoding, "utf8") == 0) { + if (strcasecmp(encoding, "utf8") == 0) { return UTF8; - } else if (strcasecmp(*encoding, "utf-8") == 0) { + } else if (strcasecmp(encoding, "utf-8") == 0) { return UTF8; - } else if (strcasecmp(*encoding, "ascii") == 0) { + } else if (strcasecmp(encoding, "ascii") == 0) { return ASCII; - } else if (strcasecmp(*encoding, "base64") == 0) { + } else if (strcasecmp(encoding, "base64") == 0) { return BASE64; - } else if (strcasecmp(*encoding, "ucs2") == 0) { + } else if (strcasecmp(encoding, "ucs2") == 0) { return UCS2; - } else if (strcasecmp(*encoding, "ucs-2") == 0) { + } else if (strcasecmp(encoding, "ucs-2") == 0) { return UCS2; - } else if (strcasecmp(*encoding, "utf16le") == 0) { + } else if (strcasecmp(encoding, "utf16le") == 0) { return UCS2; - } else if (strcasecmp(*encoding, "utf-16le") == 0) { + } else if (strcasecmp(encoding, "utf-16le") == 0) { return UCS2; - } else if (strcasecmp(*encoding, "binary") == 0) { + } else if (strcasecmp(encoding, "binary") == 0) { return BINARY; - } else if (strcasecmp(*encoding, "buffer") == 0) { + } else if (strcasecmp(encoding, "buffer") == 0) { return BUFFER; - } else if (strcasecmp(*encoding, "hex") == 0) { + } else if (strcasecmp(encoding, "hex") == 0) { return HEX; - } else if (strcasecmp(*encoding, "raw") == 0) { + } else if (strcasecmp(encoding, "raw") == 0) { if (!no_deprecation) { fprintf(stderr, "'raw' (array of integers) has been removed. " "Use 'binary'.\n"); } return BINARY; - } else if (strcasecmp(*encoding, "raws") == 0) { + } else if (strcasecmp(encoding, "raws") == 0) { if (!no_deprecation) { fprintf(stderr, "'raws' encoding has been renamed to 'binary'. " "Please update your code.\n"); } return BINARY; } else { - return _default; + return default_encoding; } } + +enum encoding ParseEncoding(Isolate* isolate, + Handle encoding_v, + enum encoding default_encoding) { + if (!encoding_v->IsString()) + return default_encoding; + + node::Utf8Value encoding(isolate, encoding_v); + + return ParseEncoding(*encoding, default_encoding); +} + Local Encode(Isolate* isolate, const char* buf, size_t len, diff --git a/src/node.h b/src/node.h index 6a25f9740a412c..7d80dc35e0bb04 100644 --- a/src/node.h +++ b/src/node.h @@ -231,12 +231,12 @@ inline void NODE_SET_PROTOTYPE_METHOD(v8::Handle recv, enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER}; enum encoding ParseEncoding(v8::Isolate* isolate, v8::Handle encoding_v, - enum encoding _default = BINARY); + enum encoding default_encoding = BINARY); NODE_DEPRECATED("Use ParseEncoding(isolate, ...)", inline enum encoding ParseEncoding( v8::Handle encoding_v, - enum encoding _default = BINARY) { - return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, _default); + enum encoding default_encoding = BINARY) { + return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, default_encoding); }) NODE_EXTERN void FatalException(v8::Isolate* isolate,