Skip to content

Commit

Permalink
node: speed up ParseEncoding
Browse files Browse the repository at this point in the history
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: #664
Reviewed-By: Ben Noordhuis <[email protected]>
  • Loading branch information
indutny committed Jan 30, 2015
1 parent 7604e6d commit c6367e7
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 26 deletions.
86 changes: 63 additions & 23 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1148,55 +1148,95 @@ Handle<Value> MakeCallback(Isolate* isolate,
}


enum encoding ParseEncoding(Isolate* isolate,
Handle<Value> 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<Value> 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<Value> Encode(Isolate* isolate,
const char* buf,
size_t len,
Expand Down
6 changes: 3 additions & 3 deletions src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,12 @@ inline void NODE_SET_PROTOTYPE_METHOD(v8::Handle<v8::FunctionTemplate> recv,
enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
enum encoding ParseEncoding(v8::Isolate* isolate,
v8::Handle<v8::Value> encoding_v,
enum encoding _default = BINARY);
enum encoding default_encoding = BINARY);
NODE_DEPRECATED("Use ParseEncoding(isolate, ...)",
inline enum encoding ParseEncoding(
v8::Handle<v8::Value> 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,
Expand Down

0 comments on commit c6367e7

Please sign in to comment.