Browse Source

Add an optional length argument to Buffer.write()

Fixes #243.
Fixes #1361.
v0.7.4-release
koichik 14 years ago
parent
commit
50e147bd03
  1. 10
      doc/api/buffers.markdown
  2. 98
      lib/buffer.js
  3. 47
      test/simple/test-buffer.js

10
doc/api/buffers.markdown

@ -47,12 +47,12 @@ Allocates a new buffer using an `array` of octets.
Allocates a new buffer containing the given `str`. 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 Writes `string` to the buffer at `offset` using the given encoding. `length` is
number of octets written. If `buffer` did not contain enough space to fit the number of bytes to write. Returns number of octets written. If `buffer` did
the entire string, it will write a partial amount of the string. not contain enough space to fit the entire string, it will write a partial
The method will not write partial characters. amount of the string. The method will not write partial characters.
Example: write a utf8 string into a buffer, then print it Example: write a utf8 string into a buffer, then print it

98
lib/buffer.js

@ -92,15 +92,27 @@ SlowBuffer.prototype.toString = function(encoding, start, end) {
}; };
SlowBuffer.prototype.hexWrite = function(string, offset) { SlowBuffer.prototype.hexWrite = function(string, offset, length) {
var len = string.length;
offset = +offset || 0; 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 // must be an even number of digits
if (len % 2) { var strLen = string.length;
if (strLen % 2) {
throw new Error('Invalid hex string'); 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); var byte = parseInt(string.substr(i * 2, 2), 16);
if (isNaN(byte)) throw new Error('Invalid hex string'); if (isNaN(byte)) throw new Error('Invalid hex string');
this[offset + i] = byte; this[offset + i] = byte;
@ -109,38 +121,53 @@ SlowBuffer.prototype.hexWrite = function(string, offset) {
}; };
SlowBuffer.prototype.write = function(string, offset, encoding) { SlowBuffer.prototype.write = function(string, offset, length, encoding) {
// Support both (string, offset, encoding) // Support both (string, offset, length, encoding)
// and the legacy (string, encoding, offset) // and the legacy (string, encoding, offset, length)
if (!isFinite(offset)) { if (isFinite(offset)) {
if (!isFinite(length)) {
encoding = length;
length = undefined;
}
} else { // legacy
var swap = encoding; var swap = encoding;
encoding = offset; encoding = offset;
offset = swap; offset = length;
length = swap;
} }
offset = +offset || 0; 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(); encoding = String(encoding || 'utf8').toLowerCase();
switch (encoding) { switch (encoding) {
case 'hex': case 'hex':
return this.hexWrite(string, offset); return this.hexWrite(string, offset, length);
case 'utf8': case 'utf8':
case 'utf-8': case 'utf-8':
return this.utf8Write(string, offset); return this.utf8Write(string, offset, length);
case 'ascii': case 'ascii':
return this.asciiWrite(string, offset); return this.asciiWrite(string, offset, length);
case 'binary': case 'binary':
return this.binaryWrite(string, offset); return this.binaryWrite(string, offset, length);
case 'base64': case 'base64':
return this.base64Write(string, offset); return this.base64Write(string, offset, length);
case 'ucs2': case 'ucs2':
case 'ucs-2': case 'ucs-2':
return this.ucs2Write(string, offset); return this.ucs2Write(string, offset, length);
default: default:
throw new Error('Unknown encoding'); throw new Error('Unknown encoding');
@ -271,47 +298,61 @@ Buffer.prototype.set = function set(i, v) {
}; };
// write(string, offset = 0, encoding = 'utf8') // write(string, offset = 0, length = buffer.length-offset, encoding = 'utf8')
Buffer.prototype.write = function(string, offset, encoding) { Buffer.prototype.write = function(string, offset, length, encoding) {
if (!isFinite(offset)) { // 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; var swap = encoding;
encoding = offset; encoding = offset;
offset = swap; offset = length;
length = swap;
} }
offset = +offset || 0; 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(); encoding = String(encoding || 'utf8').toLowerCase();
// Make sure we are not going to overflow
var maxLength = this.length - offset;
var ret; var ret;
switch (encoding) { switch (encoding) {
case 'hex': case 'hex':
ret = this.parent.hexWrite(string, this.offset + offset, maxLength); ret = this.parent.hexWrite(string, this.offset + offset, length);
break; break;
case 'utf8': case 'utf8':
case 'utf-8': case 'utf-8':
ret = this.parent.utf8Write(string, this.offset + offset, maxLength); ret = this.parent.utf8Write(string, this.offset + offset, length);
break; break;
case 'ascii': case 'ascii':
ret = this.parent.asciiWrite(string, this.offset + offset, maxLength); ret = this.parent.asciiWrite(string, this.offset + offset, length);
break; break;
case 'binary': case 'binary':
ret = this.parent.binaryWrite(string, this.offset + offset, maxLength); ret = this.parent.binaryWrite(string, this.offset + offset, length);
break; break;
case 'base64': case 'base64':
// Warning: maxLength not taken into account in base64Write // 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; break;
case 'ucs2': case 'ucs2':
case 'ucs-2': case 'ucs-2':
ret = this.parent.ucs2Write(string, this.offset + offset, maxLength); ret = this.parent.ucs2Write(string, this.offset + offset, length);
break; break;
default: default:
@ -1019,3 +1060,4 @@ Buffer.prototype.writeDouble = function(value, offset, endian) {
verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308);
IEEE754.writeIEEE754(buffer, value, offset, endian, 52, 8); IEEE754.writeIEEE754(buffer, value, offset, endian, 52, 8);
}; };

47
test/simple/test-buffer.js

@ -621,3 +621,50 @@ assert.equal(written, 9);
written = buf.write('あいう\0'); // 3bytes * 3 + 1byte written = buf.write('あいう\0'); // 3bytes * 3 + 1byte
assert.equal(written, 10); 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);

Loading…
Cancel
Save