Browse Source

src: use StringBytes for DecodeWrite/DecodeBytes/Encode

Bonus: this makes node::Encode actually work properly with base64,
ucs2, hex, etc.
v0.10.6-release
isaacs 12 years ago
parent
commit
4e8cddddcb
  1. 97
      src/node.cc

97
src/node.cc

@ -22,6 +22,7 @@
#include "node.h" #include "node.h"
#include "req_wrap.h" #include "req_wrap.h"
#include "handle_wrap.h" #include "handle_wrap.h"
#include "string_bytes.h"
#include "ares.h" #include "ares.h"
#include "uv.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) { Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) {
HandleScope scope; return StringBytes::Encode(static_cast<const char*>(buf),
len,
if (encoding == BUFFER) { encoding);
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);
} }
// Returns -1 if the handle was not valid for decoding // 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; return -1;
} }
if ((encoding == BUFFER || encoding == BINARY) && Buffer::HasInstance(val)) { return StringBytes::Size(val, encoding);
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();
} }
#ifndef MIN #ifndef MIN
@ -1198,66 +1168,13 @@ ssize_t DecodeWrite(char *buf,
enum encoding encoding) { enum encoding encoding) {
HandleScope scope; 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()) { if (val->IsArray()) {
fprintf(stderr, "'raw' encoding (array of integers) has been removed. " fprintf(stderr, "'raw' encoding (array of integers) has been removed.\n");
"Use 'binary'.\n");
assert(0); assert(0);
return -1; return -1;
} }
bool is_buffer = Buffer::HasInstance(val); return StringBytes::Write(buf, buflen, val, encoding, NULL);
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;
} }
void DisplayExceptionLine (TryCatch &try_catch) { void DisplayExceptionLine (TryCatch &try_catch) {

Loading…
Cancel
Save