Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Add an optional length argument to Buffer.write()
Browse files Browse the repository at this point in the history
Fixes #243.
Fixes #1361.
  • Loading branch information
koichik committed Jul 23, 2011
1 parent fa829b0 commit 50e147b
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 33 deletions.
10 changes: 5 additions & 5 deletions doc/api/buffers.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ Allocates a new buffer using an `array` of octets.

Allocates a new buffer containing the given `str`.

### buffer.write(string, offset=0, encoding='utf8')
### buffer.write(string, offset=0, length=buffer.length-offset, encoding='utf8')

Writes `string` to the buffer at `offset` using the given encoding. Returns
number of octets written. If `buffer` did not contain enough space to fit
the entire string, it will write a partial amount of the string.
The method will not write partial characters.
Writes `string` to the buffer at `offset` using the given encoding. `length` is
the number of bytes to write. Returns number of octets written. If `buffer` did
not contain enough space to fit the entire string, it will write a partial
amount of the string. The method will not write partial characters.

Example: write a utf8 string into a buffer, then print it

Expand Down
98 changes: 70 additions & 28 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,27 @@ SlowBuffer.prototype.toString = function(encoding, start, end) {
};


SlowBuffer.prototype.hexWrite = function(string, offset) {
var len = string.length;
SlowBuffer.prototype.hexWrite = function(string, offset, length) {
offset = +offset || 0;
var remaining = this.length - offset;
if (!length) {
length = remaining;
} else {
length = +length;
if (length > remaining) {
length = remaining;
}
}

// must be an even number of digits
if (len % 2) {
var strLen = string.length;
if (strLen % 2) {
throw new Error('Invalid hex string');
}
for (var i = 0; i < len / 2; i++) {
if (length > strLen / 2) {
length = strLen / 2;
}
for (var i = 0; i < length; i++) {
var byte = parseInt(string.substr(i * 2, 2), 16);
if (isNaN(byte)) throw new Error('Invalid hex string');
this[offset + i] = byte;
Expand All @@ -109,38 +121,53 @@ SlowBuffer.prototype.hexWrite = function(string, offset) {
};


SlowBuffer.prototype.write = function(string, offset, encoding) {
// Support both (string, offset, encoding)
// and the legacy (string, encoding, offset)
if (!isFinite(offset)) {
SlowBuffer.prototype.write = function(string, offset, length, encoding) {
// Support both (string, offset, length, encoding)
// and the legacy (string, encoding, offset, length)
if (isFinite(offset)) {
if (!isFinite(length)) {
encoding = length;
length = undefined;
}
} else { // legacy
var swap = encoding;
encoding = offset;
offset = swap;
offset = length;
length = swap;
}

offset = +offset || 0;
var remaining = this.length - offset;
if (!length) {
length = remaining;
} else {
length = +length;
if (length > remaining) {
length = remaining;
}
}
encoding = String(encoding || 'utf8').toLowerCase();

switch (encoding) {
case 'hex':
return this.hexWrite(string, offset);
return this.hexWrite(string, offset, length);

case 'utf8':
case 'utf-8':
return this.utf8Write(string, offset);
return this.utf8Write(string, offset, length);

case 'ascii':
return this.asciiWrite(string, offset);
return this.asciiWrite(string, offset, length);

case 'binary':
return this.binaryWrite(string, offset);
return this.binaryWrite(string, offset, length);

case 'base64':
return this.base64Write(string, offset);
return this.base64Write(string, offset, length);

case 'ucs2':
case 'ucs-2':
return this.ucs2Write(string, offset);
return this.ucs2Write(string, offset, length);

default:
throw new Error('Unknown encoding');
Expand Down Expand Up @@ -271,47 +298,61 @@ Buffer.prototype.set = function set(i, v) {
};


// write(string, offset = 0, encoding = 'utf8')
Buffer.prototype.write = function(string, offset, encoding) {
if (!isFinite(offset)) {
// write(string, offset = 0, length = buffer.length-offset, encoding = 'utf8')
Buffer.prototype.write = function(string, offset, length, encoding) {
// Support both (string, offset, length, encoding)
// and the legacy (string, encoding, offset, length)
if (isFinite(offset)) {
if (!isFinite(length)) {
encoding = length;
length = undefined;
}
} else { // legacy
var swap = encoding;
encoding = offset;
offset = swap;
offset = length;
length = swap;
}

offset = +offset || 0;
var remaining = this.length - offset;
if (!length) {
length = remaining;
} else {
length = +length;
if (length > remaining) {
length = remaining;
}
}
encoding = String(encoding || 'utf8').toLowerCase();

// Make sure we are not going to overflow
var maxLength = this.length - offset;

var ret;
switch (encoding) {
case 'hex':
ret = this.parent.hexWrite(string, this.offset + offset, maxLength);
ret = this.parent.hexWrite(string, this.offset + offset, length);
break;

case 'utf8':
case 'utf-8':
ret = this.parent.utf8Write(string, this.offset + offset, maxLength);
ret = this.parent.utf8Write(string, this.offset + offset, length);
break;

case 'ascii':
ret = this.parent.asciiWrite(string, this.offset + offset, maxLength);
ret = this.parent.asciiWrite(string, this.offset + offset, length);
break;

case 'binary':
ret = this.parent.binaryWrite(string, this.offset + offset, maxLength);
ret = this.parent.binaryWrite(string, this.offset + offset, length);
break;

case 'base64':
// Warning: maxLength not taken into account in base64Write
ret = this.parent.base64Write(string, this.offset + offset, maxLength);
ret = this.parent.base64Write(string, this.offset + offset, length);
break;

case 'ucs2':
case 'ucs-2':
ret = this.parent.ucs2Write(string, this.offset + offset, maxLength);
ret = this.parent.ucs2Write(string, this.offset + offset, length);
break;

default:
Expand Down Expand Up @@ -1019,3 +1060,4 @@ Buffer.prototype.writeDouble = function(value, offset, endian) {
verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308);
IEEE754.writeIEEE754(buffer, value, offset, endian, 52, 8);
};

47 changes: 47 additions & 0 deletions test/simple/test-buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -621,3 +621,50 @@ assert.equal(written, 9);
written = buf.write('あいう\0'); // 3bytes * 3 + 1byte
assert.equal(written, 10);

// #243 Test write() with maxLength
var buf = new Buffer(4);
buf.fill(0xFF);
var written = buf.write('abcd', 1, 2, 'utf8');
console.log(buf);
assert.equal(written, 2);
assert.equal(buf[0], 0xFF);
assert.equal(buf[1], 0x61);
assert.equal(buf[2], 0x62);
assert.equal(buf[3], 0xFF);

buf.fill(0xFF);
written = buf.write('abcd', 1, 4);
console.log(buf);
assert.equal(written, 3);
assert.equal(buf[0], 0xFF);
assert.equal(buf[1], 0x61);
assert.equal(buf[2], 0x62);
assert.equal(buf[3], 0x63);

buf.fill(0xFF);
written = buf.write('abcd', 'utf8', 1, 2); // legacy style
console.log(buf);
assert.equal(written, 2);
assert.equal(buf[0], 0xFF);
assert.equal(buf[1], 0x61);
assert.equal(buf[2], 0x62);
assert.equal(buf[3], 0xFF);

buf.fill(0xFF);
written = buf.write('abcdef', 1, 2, 'hex');
console.log(buf);
assert.equal(written, 2);
assert.equal(buf[0], 0xFF);
assert.equal(buf[1], 0xAB);
assert.equal(buf[2], 0xCD);
assert.equal(buf[3], 0xFF);

buf.fill(0xFF);
written = buf.write('abcd', 0, 2, 'ucs2');
console.log(buf);
assert.equal(written, 2);
assert.equal(buf[0], 0x61);
assert.equal(buf[1], 0x00);
assert.equal(buf[2], 0xFF);
assert.equal(buf[3], 0xFF);

0 comments on commit 50e147b

Please sign in to comment.