src: use StringBytes for DecodeWrite/DecodeBytes/Encode
authorisaacs <i@izs.me>
Thu, 2 May 2013 17:49:20 +0000 (10:49 -0700)
committerisaacs <i@izs.me>
Tue, 14 May 2013 20:51:42 +0000 (13:51 -0700)
Bonus: this makes node::Encode actually work properly with base64,
ucs2, hex, etc.

src/node.cc

index 97e64a7..9b27bfd 100644 (file)
@@ -22,6 +22,7 @@
 #include "node.h"
 #include "req_wrap.h"
 #include "handle_wrap.h"
+#include "string_bytes.h"
 
 #include "ares.h"
 #include "uv.h"
@@ -1137,30 +1138,9 @@ enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
 }
 
 Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) {
-  HandleScope scope;
-
-  if (encoding == BUFFER) {
-    return scope.Close(
-        Buffer::New(static_cast<const char*>(buf), len)->handle_);
-  }
-
-  if (!len) return scope.Close(String::Empty());
-
-  if (encoding == BINARY) {
-    const unsigned char *cbuf = static_cast<const unsigned char*>(buf);
-    uint16_t * twobytebuf = new uint16_t[len];
-    for (size_t i = 0; i < len; i++) {
-      // XXX is the following line platform independent?
-      twobytebuf[i] = cbuf[i];
-    }
-    Local<String> chunk = String::New(twobytebuf, len);
-    delete [] twobytebuf; // TODO use ExternalTwoByteString?
-    return scope.Close(chunk);
-  }
-
-  // utf8 or ascii encoding
-  Local<String> chunk = String::New((const char*)buf, len);
-  return scope.Close(chunk);
+  return StringBytes::Encode(static_cast<const char*>(buf),
+                             len,
+                             encoding);
 }
 
 // Returns -1 if the handle was not valid for decoding
@@ -1174,17 +1154,7 @@ ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
     return -1;
   }
 
-  if ((encoding == BUFFER || encoding == BINARY) && Buffer::HasInstance(val)) {
-    return Buffer::Length(val->ToObject());
-  }
-
-  Local<String> str = val->ToString();
-
-  if (encoding == UTF8) return str->Utf8Length();
-  else if (encoding == UCS2) return str->Length() * 2;
-  else if (encoding == HEX) return str->Length() / 2;
-
-  return str->Length();
+  return StringBytes::Size(val, encoding);
 }
 
 #ifndef MIN
@@ -1198,66 +1168,13 @@ ssize_t DecodeWrite(char *buf,
                     enum encoding encoding) {
   HandleScope scope;
 
-  // XXX
-  // A lot of improvement can be made here. See:
-  // http://code.google.com/p/v8/issues/detail?id=270
-  // http://groups.google.com/group/v8-dev/browse_thread/thread/dba28a81d9215291/ece2b50a3b4022c
-  // http://groups.google.com/group/v8-users/browse_thread/thread/1f83b0ba1f0a611
-
   if (val->IsArray()) {
-    fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
-                    "Use 'binary'.\n");
+    fprintf(stderr, "'raw' encoding (array of integers) has been removed.\n");
     assert(0);
     return -1;
   }
 
-  bool is_buffer = Buffer::HasInstance(val);
-
-  if (is_buffer && (encoding == BINARY || encoding == BUFFER)) {
-    // fast path, copy buffer data
-    const char* data = Buffer::Data(val.As<Object>());
-    size_t size = Buffer::Length(val.As<Object>());
-    size_t len = size < buflen ? size : buflen;
-    memcpy(buf, data, len);
-    return len;
-  }
-
-  Local<String> str;
-
-  if (is_buffer) { // slow path, convert to binary string
-    Local<Value> arg = String::New("binary");
-    str = MakeCallback(val.As<Object>(), "toString", 1, &arg)->ToString();
-  }
-  else {
-    str = val->ToString();
-  }
-
-  if (encoding == UTF8) {
-    str->WriteUtf8(buf, buflen, NULL, String::HINT_MANY_WRITES_EXPECTED);
-    return buflen;
-  }
-
-  if (encoding == ASCII) {
-    str->WriteAscii(buf, 0, buflen, String::HINT_MANY_WRITES_EXPECTED);
-    return buflen;
-  }
-
-  // THIS IS AWFUL!!! FIXME
-
-  assert(encoding == BINARY);
-
-  uint16_t * twobytebuf = new uint16_t[buflen];
-
-  str->Write(twobytebuf, 0, buflen, String::HINT_MANY_WRITES_EXPECTED);
-
-  for (size_t i = 0; i < buflen; i++) {
-    unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
-    buf[i] = b[0];
-  }
-
-  delete [] twobytebuf;
-
-  return buflen;
+  return StringBytes::Write(buf, buflen, val, encoding, NULL);
 }
 
 void DisplayExceptionLine (TryCatch &try_catch) {