src: replace naive search in Buffer::IndexOf
[platform/upstream/nodejs.git] / lib / buffer.js
index 2da61f6..c2bcc76 100644 (file)
@@ -414,20 +414,53 @@ Buffer.prototype.compare = function compare(b) {
   return binding.compare(this, b);
 };
 
+function slowIndexOf(buffer, val, byteOffset, encoding) {
+  var loweredCase = false;
+  for (;;) {
+    switch (encoding) {
+      case 'utf8':
+      case 'utf-8':
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+      case 'binary':
+        return binding.indexOfString(buffer, val, byteOffset, encoding);
 
-Buffer.prototype.indexOf = function indexOf(val, byteOffset) {
+      case 'base64':
+      case 'ascii':
+      case 'hex':
+        return binding.indexOfBuffer(
+            buffer, Buffer(val, encoding), byteOffset, encoding);
+
+      default:
+        if (loweredCase) {
+          throw new TypeError('Unknown encoding: ' + encoding);
+        }
+
+        encoding = ('' + encoding).toLowerCase();
+        loweredCase = true;
+    }
+  }
+}
+
+Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
   if (byteOffset > 0x7fffffff)
     byteOffset = 0x7fffffff;
   else if (byteOffset < -0x80000000)
     byteOffset = -0x80000000;
   byteOffset >>= 0;
 
-  if (typeof val === 'string')
-    return binding.indexOfString(this, val, byteOffset);
-  if (val instanceof Buffer)
-    return binding.indexOfBuffer(this, val, byteOffset);
-  if (typeof val === 'number')
+  if (typeof val === 'string') {
+    if (encoding === undefined) {
+      return binding.indexOfString(this, val, byteOffset, encoding);
+    }
+    return slowIndexOf(this, val, byteOffset, encoding);
+  } else if (val instanceof Buffer) {
+    return binding.indexOfBuffer(this, val, byteOffset, encoding);
+  } else if (typeof val === 'number') {
     return binding.indexOfNumber(this, val, byteOffset);
+  }
 
   throw new TypeError('val must be string, number or Buffer');
 };