From 0a539865dd5e94d1403bd15c43a644f4cd1958cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Mon, 17 May 2010 09:33:56 -0400 Subject: [PATCH] Support arrays and strings in buffer constructor This is be very useful for testing code that deals with buffers. --- doc/api.markdown | 8 ++++++++ src/node_buffer.cc | 34 ++++++++++++++++++++++++++++++++++ test/simple/test-buffer.js | 13 +++++++++++++ 3 files changed, 55 insertions(+) diff --git a/doc/api.markdown b/doc/api.markdown index b6ff2748a1..732e8e02c4 100644 --- a/doc/api.markdown +++ b/doc/api.markdown @@ -68,6 +68,14 @@ strip the high bit if set. Allocates a new buffer of `size` octets. +### new Buffer(array) + +Allocates a new buffer using an `array` of octets. + +### new Buffer(str, encoding = 'utf8') + +Allocates a new buffer containing the given `str`. + ### buffer.write(string, encoding, offset) Writes `string` to the buffer at `offset` using the given encoding. Returns diff --git a/src/node_buffer.cc b/src/node_buffer.cc index d757b9623c..5d5a389fb1 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -39,6 +39,7 @@ using namespace v8; static Persistent length_symbol; static Persistent chars_written_sym; +static Persistent write_sym; Persistent Buffer::constructor_template; @@ -128,6 +129,18 @@ Handle Buffer::New(const Arguments &args) { size_t length = args[0]->Uint32Value(); buffer = new Buffer(length); + } else if (args[0]->IsArray()) { + Local a = Local::Cast(args[0]); + buffer = new Buffer(a->Length()); + char *p = buffer->data(); + for (int i = 0; i < a->Length(); i++) { + p[i] = a->Get(i)->Uint32Value(); + } + } else if (args[0]->IsString()) { + Local s = args[0]->ToString(); + enum encoding e = ParseEncoding(args[1], UTF8); + int length = e == UTF8 ? s->Utf8Length() : s->Length(); + buffer = new Buffer(length); } else if (Buffer::HasInstance(args[0]) && args.Length() > 2) { // var slice = new Buffer(buffer, 123, 130); // args: parent, start, end @@ -143,6 +156,27 @@ Handle Buffer::New(const Arguments &args) { kExternalUnsignedByteArray, buffer->length()); args.This()->Set(length_symbol, Integer::New(buffer->length_)); + + if (args[0]->IsString()) { + if (write_sym.IsEmpty()) { + write_sym = Persistent::New(String::NewSymbol("write")); + } + + Local write_v = args.This()->Get(write_sym); + assert(write_v->IsFunction()); + Local write = Local::Cast(write_v); + + Local argv[2] = { args[0], args[1] }; + + TryCatch try_catch; + + write->Call(args.This(), 2, argv); + + if (try_catch.HasCaught()) { + FatalException(try_catch); + } + } + return args.This(); } diff --git a/test/simple/test-buffer.js b/test/simple/test-buffer.js index 17d6f08d56..89a0148119 100644 --- a/test/simple/test-buffer.js +++ b/test/simple/test-buffer.js @@ -106,3 +106,16 @@ assert.equal(7, b[3]); var c = b.slice(2 , 4); assert.equal(6, c[0]); assert.equal(7, c[1]); + + +var d = new Buffer([23, 42, 255]); +assert.equal(d.length, 3); +assert.equal(d[0], 23); +assert.equal(d[1], 42); +assert.equal(d[2], 255); + +var e = new Buffer('über'); +assert.deepEqual(e, new Buffer([195, 188, 98, 101, 114])); + +var f = new Buffer('über', 'ascii'); +assert.deepEqual(f, new Buffer([252, 98, 101, 114])); \ No newline at end of file