Browse Source

Work to get C++ fast buffers. incomplete

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
1cf538a60a
  1. 70
      src/node_buffer.cc
  2. 9
      src/node_buffer.h
  3. 22
      src/node_file.cc
  4. 64
      src/node_net.cc

70
src/node_buffer.cc

@ -153,6 +153,40 @@ Buffer* Buffer::New(size_t size) {
} }
char* Buffer::Data(Handle<Object> obj) {
if (obj->HasIndexedPropertiesInPixelData()) {
return (char*)obj->GetIndexedPropertiesPixelData();
}
HandleScope scope;
// Return true for "SlowBuffer"
if (constructor_template->HasInstance(obj)) {
return ObjectWrap::Unwrap<Buffer>(obj)->data();
}
// Not a buffer.
return NULL;
}
size_t Buffer::Length(Handle<Object> obj) {
if (obj->HasIndexedPropertiesInPixelData()) {
return (size_t)obj->GetIndexedPropertiesPixelDataLength();
}
HandleScope scope;
// Return true for "SlowBuffer"
if (constructor_template->HasInstance(obj)) {
return ObjectWrap::Unwrap<Buffer>(obj)->length();
}
// Not a buffer.
return 0;
}
Handle<Value> Buffer::New(const Arguments &args) { Handle<Value> Buffer::New(const Arguments &args) {
HandleScope scope; HandleScope scope;
@ -274,7 +308,7 @@ Handle<Value> Buffer::BinarySlice(const Arguments &args) {
Buffer *parent = ObjectWrap::Unwrap<Buffer>(args.This()); Buffer *parent = ObjectWrap::Unwrap<Buffer>(args.This());
SLICE_ARGS(args[0], args[1]) SLICE_ARGS(args[0], args[1])
const char *data = const_cast<char*>(parent->data() + start); char *data = parent->data() + start;
//Local<String> string = String::New(data, end - start); //Local<String> string = String::New(data, end - start);
Local<Value> b = Encode(data, end - start, BINARY); Local<Value> b = Encode(data, end - start, BINARY);
@ -296,9 +330,8 @@ Handle<Value> Buffer::AsciiSlice(const Arguments &args) {
assert(parent->blob_->refs >= 2); assert(parent->blob_->refs >= 2);
#endif #endif
const char *data = const_cast<char*>(parent->data() + start); char* data = parent->data() + start;
Local<String> string = String::New(data, end - start); Local<String> string = String::New(reinterpret_cast<char*>(data), end - start);
return scope.Close(string); return scope.Close(string);
} }
@ -308,8 +341,8 @@ Handle<Value> Buffer::Utf8Slice(const Arguments &args) {
HandleScope scope; HandleScope scope;
Buffer *parent = ObjectWrap::Unwrap<Buffer>(args.This()); Buffer *parent = ObjectWrap::Unwrap<Buffer>(args.This());
SLICE_ARGS(args[0], args[1]) SLICE_ARGS(args[0], args[1])
const char *data = const_cast<char*>(parent->data() + start); char *data = parent->data() + start;
Local<String> string = String::New(data, end - start); Local<String> string = String::New(reinterpret_cast<char*>(data), end - start);
return scope.Close(string); return scope.Close(string);
} }
@ -489,11 +522,11 @@ Handle<Value> Buffer::Utf8Write(const Arguments &args) {
"Offset is out of bounds"))); "Offset is out of bounds")));
} }
const char *p = buffer->data() + offset; char* p = buffer->data() + offset;
int char_written; int char_written;
int written = s->WriteUtf8((char*)p, int written = s->WriteUtf8(reinterpret_cast<char*>(p),
buffer->length_ - offset, buffer->length_ - offset,
&char_written, &char_written,
String::HINT_MANY_WRITES_EXPECTED); String::HINT_MANY_WRITES_EXPECTED);
@ -527,11 +560,14 @@ Handle<Value> Buffer::AsciiWrite(const Arguments &args) {
"Offset is out of bounds"))); "Offset is out of bounds")));
} }
const char *p = buffer->data() + offset; char *p = buffer->data() + offset;
size_t towrite = MIN((unsigned long) s->Length(), buffer->length_ - offset); size_t towrite = MIN((unsigned long) s->Length(), buffer->length_ - offset);
int written = s->WriteAscii((char*)p, 0, towrite, String::HINT_MANY_WRITES_EXPECTED); int written = s->WriteAscii(reinterpret_cast<char*>(p),
0,
towrite,
String::HINT_MANY_WRITES_EXPECTED);
return scope.Close(Integer::New(written)); return scope.Close(Integer::New(written));
} }
@ -574,7 +610,7 @@ Handle<Value> Buffer::Base64Write(const Arguments &args) {
} }
char a, b, c, d; char a, b, c, d;
char *dst = buffer->data(); char* dst = buffer->data();
const char *src = *s; const char *src = *s;
const char *const srcEnd = src + s.length(); const char *const srcEnd = src + s.length();
@ -726,6 +762,18 @@ Handle<Value> Buffer::MakeFastBuffer(const Arguments &args) {
} }
bool Buffer::HasInstance(v8::Handle<v8::Value> val) {
if (!val->IsObject()) return false;
v8::Local<v8::Object> obj = val->ToObject();
if (obj->HasIndexedPropertiesInPixelData()) return true;
// Return true for "SlowBuffer"
if (constructor_template->HasInstance(obj)) return true;
return false;
}
void Buffer::Initialize(Handle<Object> target) { void Buffer::Initialize(Handle<Object> target) {
HandleScope scope; HandleScope scope;

9
src/node_buffer.h

@ -34,11 +34,10 @@ class Buffer : public ObjectWrap {
static void Initialize(v8::Handle<v8::Object> target); static void Initialize(v8::Handle<v8::Object> target);
static Buffer* New(size_t length); // public constructor static Buffer* New(size_t length); // public constructor
static inline bool HasInstance(v8::Handle<v8::Value> val) { static bool HasInstance(v8::Handle<v8::Value> val);
if (!val->IsObject()) return false;
v8::Local<v8::Object> obj = val->ToObject(); static char* Data(v8::Handle<v8::Object>);
return constructor_template->HasInstance(obj); static size_t Length(v8::Handle<v8::Object>);
}
char* data(); char* data();
size_t length() const { return length_; } size_t length() const { return length_; }

22
src/node_file.cc

@ -626,24 +626,26 @@ static Handle<Value> Write(const Arguments& args) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Second argument needs to be a buffer"))); String::New("Second argument needs to be a buffer")));
} }
Buffer * buffer = ObjectWrap::Unwrap<Buffer>(args[1]->ToObject()); Local<Object> buffer_obj = args[1]->ToObject();
char *buffer_data = Buffer::Data(buffer_obj);
size_t buffer_length = Buffer::Length(buffer_obj);
size_t off = args[2]->Int32Value(); size_t off = args[2]->Int32Value();
if (off >= buffer->length()) { if (off >= buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Offset is out of bounds"))); String::New("Offset is out of bounds")));
} }
ssize_t len = args[3]->Int32Value(); ssize_t len = args[3]->Int32Value();
if (off + len > buffer->length()) { if (off + len > buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Length is extends beyond buffer"))); String::New("Length is extends beyond buffer")));
} }
off_t pos = GET_OFFSET(args[4]); off_t pos = GET_OFFSET(args[4]);
char * buf = (char*)buffer->data() + off; char * buf = (char*)buffer_data + off;
Local<Value> cb = args[5]; Local<Value> cb = args[5];
if (cb->IsFunction()) { if (cb->IsFunction()) {
@ -688,23 +690,25 @@ static Handle<Value> Read(const Arguments& args) {
String::New("Second argument needs to be a buffer"))); String::New("Second argument needs to be a buffer")));
} }
Buffer * buffer = ObjectWrap::Unwrap<Buffer>(args[1]->ToObject()); Local<Object> buffer_obj = args[1]->ToObject();
char *buffer_data = Buffer::Data(buffer_obj);
size_t buffer_length = Buffer::Length(buffer_obj);
size_t off = args[2]->Int32Value(); size_t off = args[2]->Int32Value();
if (off >= buffer->length()) { if (off >= buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Offset is out of bounds"))); String::New("Offset is out of bounds")));
} }
len = args[3]->Int32Value(); len = args[3]->Int32Value();
if (off + len > buffer->length()) { if (off + len > buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Length is extends beyond buffer"))); String::New("Length is extends beyond buffer")));
} }
pos = GET_OFFSET(args[4]); pos = GET_OFFSET(args[4]);
buf = (char*)buffer->data() + off; buf = buffer_data + off;
cb = args[5]; cb = args[5];

64
src/node_net.cc

@ -538,21 +538,23 @@ static Handle<Value> Read(const Arguments& args) {
String::New("Second argument should be a buffer"))); String::New("Second argument should be a buffer")));
} }
Buffer * buffer = ObjectWrap::Unwrap<Buffer>(args[1]->ToObject()); Local<Object> buffer_obj = args[1]->ToObject();
char *buffer_data = Buffer::Data(buffer_obj);
size_t buffer_length = Buffer::Length(buffer_obj);
size_t off = args[2]->Int32Value(); size_t off = args[2]->Int32Value();
if (off >= buffer->length()) { if (off >= buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Offset is out of bounds"))); String::New("Offset is out of bounds")));
} }
size_t len = args[3]->Int32Value(); size_t len = args[3]->Int32Value();
if (off + len > buffer->length()) { if (off + len > buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Length is extends beyond buffer"))); String::New("Length is extends beyond buffer")));
} }
ssize_t bytes_read = read(fd, (char*)buffer->data() + off, len); ssize_t bytes_read = read(fd, (char*)buffer_data + off, len);
if (bytes_read < 0) { if (bytes_read < 0) {
if (errno == EAGAIN || errno == EINTR) return Null(); if (errno == EAGAIN || errno == EINTR) return Null();
@ -583,16 +585,18 @@ static Handle<Value> RecvFrom(const Arguments& args) {
String::New("Second argument should be a buffer"))); String::New("Second argument should be a buffer")));
} }
Buffer * buffer = ObjectWrap::Unwrap<Buffer>(args[1]->ToObject()); Local<Object> buffer_obj = args[1]->ToObject();
char *buffer_data = Buffer::Data(buffer_obj);
size_t buffer_length = Buffer::Length(buffer_obj);
size_t off = args[2]->Int32Value(); size_t off = args[2]->Int32Value();
if (off >= buffer->length()) { if (off >= buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Offset is out of bounds"))); String::New("Offset is out of bounds")));
} }
size_t len = args[3]->Int32Value(); size_t len = args[3]->Int32Value();
if (off + len > buffer->length()) { if (off + len > buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Length is extends beyond buffer"))); String::New("Length is extends beyond buffer")));
} }
@ -602,7 +606,7 @@ static Handle<Value> RecvFrom(const Arguments& args) {
struct sockaddr_storage address_storage; struct sockaddr_storage address_storage;
socklen_t addrlen = sizeof(struct sockaddr_storage); socklen_t addrlen = sizeof(struct sockaddr_storage);
ssize_t bytes_read = recvfrom(fd, (char*)buffer->data() + off, len, flags, ssize_t bytes_read = recvfrom(fd, (char*)buffer_data + off, len, flags,
(struct sockaddr*) &address_storage, &addrlen); (struct sockaddr*) &address_storage, &addrlen);
if (bytes_read < 0) { if (bytes_read < 0) {
@ -639,22 +643,24 @@ static Handle<Value> RecvMsg(const Arguments& args) {
String::New("Second argument should be a buffer"))); String::New("Second argument should be a buffer")));
} }
Buffer * buffer = ObjectWrap::Unwrap<Buffer>(args[1]->ToObject()); Local<Object> buffer_obj = args[1]->ToObject();
char *buffer_data = Buffer::Data(buffer_obj);
size_t buffer_length = Buffer::Length(buffer_obj);
size_t off = args[2]->Int32Value(); size_t off = args[2]->Int32Value();
if (off >= buffer->length()) { if (off >= buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Offset is out of bounds"))); String::New("Offset is out of bounds")));
} }
size_t len = args[3]->Int32Value(); size_t len = args[3]->Int32Value();
if (off + len > buffer->length()) { if (off + len > buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Length is extends beyond buffer"))); String::New("Length is extends beyond buffer")));
} }
struct iovec iov[1]; struct iovec iov[1];
iov[0].iov_base = (char*)buffer->data() + off; iov[0].iov_base = (char*)buffer_data + off;
iov[0].iov_len = len; iov[0].iov_len = len;
struct msghdr msg; struct msghdr msg;
@ -732,21 +738,23 @@ static Handle<Value> Write(const Arguments& args) {
String::New("Second argument should be a buffer"))); String::New("Second argument should be a buffer")));
} }
Buffer * buffer = ObjectWrap::Unwrap<Buffer>(args[1]->ToObject()); Local<Object> buffer_obj = args[1]->ToObject();
char *buffer_data = Buffer::Data(buffer_obj);
size_t buffer_length = Buffer::Length(buffer_obj);
size_t off = args[2]->Int32Value(); size_t off = args[2]->Int32Value();
if (off >= buffer->length()) { if (off >= buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Offset is out of bounds"))); String::New("Offset is out of bounds")));
} }
size_t len = args[3]->Int32Value(); size_t len = args[3]->Int32Value();
if (off + len > buffer->length()) { if (off + len > buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Length is extends beyond buffer"))); String::New("Length is extends beyond buffer")));
} }
ssize_t written = write(fd, (char*)buffer->data() + off, len); ssize_t written = write(fd, buffer_data + off, len);
if (written < 0) { if (written < 0) {
if (errno == EAGAIN || errno == EINTR) { if (errno == EAGAIN || errno == EINTR) {
@ -790,7 +798,9 @@ static Handle<Value> SendMsg(const Arguments& args) {
String::New("Expected either a string or a buffer"))); String::New("Expected either a string or a buffer")));
} }
Buffer *buf = ObjectWrap::Unwrap<Buffer>(args[1]->ToObject()); Local<Object> buffer_obj = args[1]->ToObject();
char *buffer_data = Buffer::Data(buffer_obj);
size_t buffer_length = Buffer::Length(buffer_obj);
size_t offset = 0; size_t offset = 0;
if (args.Length() >= 3 && !args[2]->IsUndefined()) { if (args.Length() >= 3 && !args[2]->IsUndefined()) {
@ -800,13 +810,13 @@ static Handle<Value> SendMsg(const Arguments& args) {
} }
offset = args[2]->Uint32Value(); offset = args[2]->Uint32Value();
if (offset >= buf->length()) { if (offset >= buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Offset into buffer too large"))); String::New("Offset into buffer too large")));
} }
} }
size_t length = buf->length() - offset; size_t length = buffer_length - offset;
if (args.Length() >= 4 && !args[3]->IsUndefined()) { if (args.Length() >= 4 && !args[3]->IsUndefined()) {
if (!args[3]->IsUint32()) { if (!args[3]->IsUint32()) {
return ThrowException(Exception::TypeError( return ThrowException(Exception::TypeError(
@ -814,13 +824,13 @@ static Handle<Value> SendMsg(const Arguments& args) {
} }
length = args[3]->Uint32Value(); length = args[3]->Uint32Value();
if (offset + length > buf->length()) { if (offset + length > buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("offset + length beyond buffer length"))); String::New("offset + length beyond buffer length")));
} }
} }
iov.iov_base = buf->data() + offset; iov.iov_base = buffer_data + offset;
iov.iov_len = length; iov.iov_len = length;
int fd_to_send = -1; int fd_to_send = -1;
@ -911,7 +921,9 @@ static Handle<Value> SendTo(const Arguments& args) {
String::New("Expected either a string or a buffer"))); String::New("Expected either a string or a buffer")));
} }
Buffer *buf = ObjectWrap::Unwrap<Buffer>(args[1]->ToObject()); Local<Object> buffer_obj = args[1]->ToObject();
char *buffer_data = Buffer::Data(buffer_obj);
size_t buffer_length = Buffer::Length(buffer_obj);
size_t offset = 0; size_t offset = 0;
if (args.Length() >= 3 && !args[2]->IsUndefined()) { if (args.Length() >= 3 && !args[2]->IsUndefined()) {
@ -921,13 +933,13 @@ static Handle<Value> SendTo(const Arguments& args) {
} }
offset = args[2]->Uint32Value(); offset = args[2]->Uint32Value();
if (offset >= buf->length()) { if (offset >= buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("Offset into buffer too large"))); String::New("Offset into buffer too large")));
} }
} }
size_t length = buf->length() - offset; size_t length = buffer_length - offset;
if (args.Length() >= 4 && !args[3]->IsUndefined()) { if (args.Length() >= 4 && !args[3]->IsUndefined()) {
if (!args[3]->IsUint32()) { if (!args[3]->IsUint32()) {
return ThrowException(Exception::TypeError( return ThrowException(Exception::TypeError(
@ -935,7 +947,7 @@ static Handle<Value> SendTo(const Arguments& args) {
} }
length = args[3]->Uint32Value(); length = args[3]->Uint32Value();
if (offset + length > buf->length()) { if (offset + length > buffer_length) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("offset + length beyond buffer length"))); String::New("offset + length beyond buffer length")));
} }
@ -954,7 +966,7 @@ static Handle<Value> SendTo(const Arguments& args) {
Handle<Value> error = ParseAddressArgs(args[5], args[6], false); Handle<Value> error = ParseAddressArgs(args[5], args[6], false);
if (!error.IsEmpty()) return ThrowException(error); if (!error.IsEmpty()) return ThrowException(error);
ssize_t written = sendto(fd, buf->data() + offset, length, flags, addr, addrlen); ssize_t written = sendto(fd, buffer_data + offset, length, flags, addr, addrlen);
if (written < 0) { if (written < 0) {
if (errno == EAGAIN || errno == EINTR) return Null(); if (errno == EAGAIN || errno == EINTR) return Null();

Loading…
Cancel
Save