From 4b403588416e7928fbda31043d5e7aa56b5d87b0 Mon Sep 17 00:00:00 2001 From: Trevor Norris Date: Fri, 24 May 2013 10:58:30 -0700 Subject: [PATCH] buffer: implement new fill behavior Old fill would take the char code of the first character and wrap around the int to fit in the 127 range. Now fill will duplicate whatever string is given through the entirety of the buffer. Note: There is one bug around ending on a partial fill of any character outside the ASCII range. --- src/node_buffer.cc | 44 +++++++++++++++++++++++++++++--------- test/simple/test-buffer.js | 10 +++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 2e5115a2394..d7f63b2ec2e 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -296,18 +296,42 @@ Handle Fill(const Arguments &args) { HandleScope scope(node_isolate); ARGS_THIS(args.This()) - int value; - - if (args[0]->IsString()) { - String::AsciiValue at(args[0]); - value = (*at)[0]; - } else { - value = static_cast(args[0]->Int32Value()); - } - SLICE_START_END(args[1], args[2], obj_length) - memset(obj_data + start, value, length); + if (args[0]->IsNumber()) { + int value = args[0]->Uint32Value() & 255; + memset(obj_data + start, value, length); + return args.This(); + } + + String::Utf8Value at(args[0]); + size_t at_length = at.length(); + + // optimize single ascii character case + if (at_length == 1) { + int value = static_cast((*at)[0]); + memset(obj_data + start, value, length); + return args.This(); + } + + size_t in_there = at_length; + char* ptr = obj_data + start + at_length; + + memcpy(obj_data + start, *at, MIN(at_length, length)); + + if (at_length >= length) + return args.This(); + + while (in_there < length - in_there) { + memcpy(ptr, obj_data + start, in_there); + ptr += in_there; + in_there *= 2; + } + + if (in_there < length) { + memcpy(ptr, obj_data + start, length - in_there); + in_there = length; + } return args.This(); } diff --git a/test/simple/test-buffer.js b/test/simple/test-buffer.js index 19fa4eacb0e..6975c8e4e58 100644 --- a/test/simple/test-buffer.js +++ b/test/simple/test-buffer.js @@ -120,6 +120,10 @@ for (var i = 0; i < b.length; i++) { assert.strictEqual(cntr, b[i]); } +// copy string longer than buffer length (failure will segfault) +var bb = new Buffer(10); +bb.fill('hello crazy world'); + var caught_error = null; @@ -637,6 +641,12 @@ for (var i = 0; i < 16; i++) assert.equal(0, b[i]); for (; i < 32; i++) assert.equal(1, b[i]); for (; i < b.length; i++) assert.equal(0, b[i]); +var buf = new Buffer(10); +buf.fill('abc'); +assert.equal(buf.toString(), 'abcabcabca'); +buf.fill('է'); +assert.equal(buf.toString(), 'էէէէէ'); + ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach(function(encoding) { var b = new Buffer(10); b.write('あいうえお', encoding);