buffer: don't call ByteLength for simple encodings
authorTrevor Norris <trev.norris@gmail.com>
Fri, 16 Aug 2013 18:32:56 +0000 (11:32 -0700)
committerTrevor Norris <trev.norris@gmail.com>
Fri, 16 Aug 2013 19:42:33 +0000 (12:42 -0700)
For several encodings the byte length is simple arithmetic. Don't call
into C++ in those cases.

lib/buffer.js
src/node_buffer.cc

index b6dfc52..9bdf7c9 100644 (file)
@@ -25,13 +25,14 @@ var util = require('util');
 var alloc = smalloc.alloc;
 var sliceOnto = smalloc.sliceOnto;
 var kMaxLength = smalloc.kMaxLength;
+var internal = {};
 
 exports.Buffer = Buffer;
 exports.SlowBuffer = SlowBuffer;
 exports.INSPECT_MAX_BYTES = 50;
 
 // add methods to Buffer prototype
-buffer.setupBufferJS(Buffer);
+buffer.setupBufferJS(Buffer, internal);
 
 Buffer.poolSize = 8 * 1024;
 var poolSize = Buffer.poolSize;
@@ -163,6 +164,31 @@ Buffer.concat = function(list, length) {
 };
 
 
+Buffer.byteLength = function(str, enc) {
+  var ret;
+  str = str + '';
+  switch (enc) {
+    case 'ascii':
+    case 'binary':
+    case 'raw':
+      ret = str.length;
+      break;
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      ret = str.length * 2;
+      break;
+    case 'hex':
+      ret = str.length >>> 1;
+      break;
+    default:
+      ret = internal.byteLength(str, enc);
+  }
+  return ret;
+}
+
+
 // pre-set for values that may exist in the future
 Buffer.prototype.length = undefined;
 Buffer.prototype.parent = undefined;
index b69ff63..1a9e128 100644 (file)
@@ -566,9 +566,6 @@ void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
 
   Local<Object> proto = proto_v.As<Object>();
 
-  bv->Set(FIXED_ONE_BYTE_STRING(node_isolate, "byteLength"),
-          FunctionTemplate::New(ByteLength)->GetFunction());
-
   NODE_SET_METHOD(proto, "asciiSlice", AsciiSlice);
   NODE_SET_METHOD(proto, "base64Slice", Base64Slice);
   NODE_SET_METHOD(proto, "binarySlice", BinarySlice);
@@ -600,6 +597,14 @@ void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
   proto->Set(FIXED_ONE_BYTE_STRING(node_isolate, "offset"),
              Uint32::New(0, node_isolate),
              v8::ReadOnly);
+
+  assert(args[1]->IsObject());
+
+  Local<Object> internal = args[1].As<Object>();
+
+  internal->Set(FIXED_ONE_BYTE_STRING(node_isolate, "byteLength"),
+                FunctionTemplate::New(ByteLength)->GetFunction());
+
 }