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.
This commit is contained in:
Trevor Norris 2013-05-24 10:58:30 -07:00
parent f489649159
commit 4b40358841
2 changed files with 44 additions and 10 deletions

View File

@ -296,18 +296,42 @@ Handle<Value> 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<char>(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<int>((*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();
}

View File

@ -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);