diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 326a97ad71..813f5657ed 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -47,19 +47,24 @@ Persistent Buffer::constructor_template; struct Blob_ { unsigned int refs; size_t length; - char data[1]; + char *data; }; typedef struct Blob_ Blob; static inline Blob * blob_new(size_t length) { - size_t s = sizeof(Blob) - 1 + length; - Blob * blob = (Blob*) malloc(s); + Blob * blob = (Blob*) malloc(sizeof(Blob)); if (!blob) return NULL; - V8::AdjustAmountOfExternalAllocatedMemory(s); + + blob->data = (char*) malloc(length); + if (!blob->data) { + free(blob); + return NULL; + } + + V8::AdjustAmountOfExternalAllocatedMemory(sizeof(Blob) + length); blob->length = length; blob->refs = 0; - //fprintf(stderr, "alloc %d bytes\n", length); return blob; } @@ -73,8 +78,8 @@ static inline void blob_unref(Blob *blob) { assert(blob->refs > 0); if (--blob->refs == 0) { //fprintf(stderr, "free %d bytes\n", blob->length); - size_t s = sizeof(Blob) - 1 + blob->length; - V8::AdjustAmountOfExternalAllocatedMemory(-s); + V8::AdjustAmountOfExternalAllocatedMemory(-(sizeof(Blob) + blob->length)); + free(blob->data); free(blob); } } @@ -133,9 +138,9 @@ Handle Buffer::New(const Arguments &args) { } buffer->Wrap(args.This()); - args.This()->SetIndexedPropertiesToExternalArrayData((void*)buffer->data_, + args.This()->SetIndexedPropertiesToExternalArrayData(buffer->data(), kExternalUnsignedByteArray, - buffer->length_); + buffer->length()); args.This()->Set(length_symbol, Integer::New(buffer->length_)); return args.This(); } @@ -143,8 +148,9 @@ Handle Buffer::New(const Arguments &args) { Buffer::Buffer(size_t length) : ObjectWrap() { blob_ = blob_new(length); + off_ = 0; length_ = length; - data_ = blob_->data; + blob_ref(blob_); V8::AdjustAmountOfExternalAllocatedMemory(sizeof(Buffer)); @@ -157,9 +163,9 @@ Buffer::Buffer(Buffer *parent, size_t start, size_t end) : ObjectWrap() { blob_ref(blob_); assert(start <= end); + off_ = start; length_ = end - start; assert(length_ <= parent->length_); - data_ = parent->data_ + start; V8::AdjustAmountOfExternalAllocatedMemory(sizeof(Buffer)); } @@ -173,12 +179,17 @@ Buffer::~Buffer() { } +char* Buffer::data() { + return blob_->data + off_; +} + + Handle Buffer::BinarySlice(const Arguments &args) { HandleScope scope; Buffer *parent = ObjectWrap::Unwrap(args.This()); SLICE_ARGS(args[0], args[1]) - const char *data = const_cast(parent->data_ + start); + const char *data = const_cast(parent->data() + start); //Local string = String::New(data, end - start); Local b = Encode(data, end - start, BINARY); @@ -200,7 +211,7 @@ Handle Buffer::AsciiSlice(const Arguments &args) { assert(parent->blob_->refs >= 2); #endif - const char *data = const_cast(parent->data_ + start); + const char *data = const_cast(parent->data() + start); Local string = String::New(data, end - start); @@ -212,7 +223,7 @@ Handle Buffer::Utf8Slice(const Arguments &args) { HandleScope scope; Buffer *parent = ObjectWrap::Unwrap(args.This()); SLICE_ARGS(args[0], args[1]) - const char *data = const_cast(parent->data_ + start); + const char *data = const_cast(parent->data() + start); Local string = String::New(data, end - start); return scope.Close(string); } @@ -295,7 +306,7 @@ Handle Buffer::Utf8Write(const Arguments &args) { "Offset is out of bounds"))); } - const char *p = buffer->data_ + offset; + const char *p = buffer->data() + offset; int written = s->WriteUtf8((char*)p, buffer->length_ - offset); @@ -323,7 +334,7 @@ Handle Buffer::AsciiWrite(const Arguments &args) { "Offset is out of bounds"))); } - const char *p = buffer->data_ + offset; + const char *p = buffer->data() + offset; size_t towrite = MIN((unsigned long) s->Length(), buffer->length_ - offset); @@ -351,7 +362,7 @@ Handle Buffer::BinaryWrite(const Arguments &args) { "Offset is out of bounds"))); } - char *p = (char*)buffer->data_ + offset; + char *p = (char*)buffer->data() + offset; size_t towrite = MIN((unsigned long) s->Length(), buffer->length_ - offset); @@ -393,7 +404,7 @@ Handle Buffer::Unpack(const Arguments &args) { // 32bit unsigned integer in network byte order case 'N': if (index + 3 >= buffer->length_) return OUT_OF_BOUNDS; - uint32 = htonl(*(uint32_t*)(buffer->data_ + index)); + uint32 = htonl(*(uint32_t*)(buffer->data() + index)); array->Set(Integer::New(i), Integer::NewFromUnsigned(uint32)); index += 4; break; @@ -401,7 +412,7 @@ Handle Buffer::Unpack(const Arguments &args) { // 16bit unsigned integer in network byte order case 'n': if (index + 1 >= buffer->length_) return OUT_OF_BOUNDS; - uint16 = htons(*(uint16_t*)(buffer->data_ + index)); + uint16 = htons(*(uint16_t*)(buffer->data() + index)); array->Set(Integer::New(i), Integer::NewFromUnsigned(uint16)); index += 2; break; @@ -409,7 +420,7 @@ Handle Buffer::Unpack(const Arguments &args) { // a single octet, unsigned. case 'o': if (index >= buffer->length_) return OUT_OF_BOUNDS; - uint8 = (uint8_t)buffer->data_[index]; + uint8 = (uint8_t)buffer->data()[index]; array->Set(Integer::New(i), Integer::NewFromUnsigned(uint8)); index += 1; break; diff --git a/src/node_buffer.h b/src/node_buffer.h index e746cdebe1..24ead8701a 100644 --- a/src/node_buffer.h +++ b/src/node_buffer.h @@ -37,7 +37,7 @@ class Buffer : public ObjectWrap { return constructor_template->HasInstance(obj); } - const char* data() const { return data_; } + char* data(); size_t length() const { return length_; } struct Blob_* blob() const { return blob_; } @@ -63,8 +63,8 @@ class Buffer : public ObjectWrap { Buffer(Buffer *parent, size_t start, size_t end); ~Buffer(); - const char *data_; - size_t length_; + size_t off_; // offset inside blob_ + size_t length_; // length inside blob_ struct Blob_ *blob_; };