src: use StringBytes for DecodeWrite/DecodeBytes/Encode
Bonus: this makes node::Encode actually work properly with base64, ucs2, hex, etc.
This commit is contained in:
parent
69dac92c36
commit
4e8cddddcb
97
src/node.cc
97
src/node.cc
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user