From bc42d0474bb9ea310b8e6a44c986ee6560cdb510 Mon Sep 17 00:00:00 2001 From: koichik Date: Fri, 22 Jul 2011 15:28:48 +0900 Subject: [PATCH] Add an optional length argument to Buffer.write() Fixes #243. Fixes #1361. --- doc/api/buffers.markdown | 10 ++-- lib/buffer.js | 118 +++++++++++++++++++++++---------------- 2 files changed, 74 insertions(+), 54 deletions(-) diff --git a/doc/api/buffers.markdown b/doc/api/buffers.markdown index ae24855fb60d..2183e006ddb1 100644 --- a/doc/api/buffers.markdown +++ b/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`. -### 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 diff --git a/lib/buffer.js b/lib/buffer.js index fe367ec3804c..19f7b6dd15f6 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -92,17 +92,27 @@ SlowBuffer.prototype.toString = function(encoding, start, end) { }; -SlowBuffer.prototype.hexWrite = function(string, offset, maxLength) { - var len = string.length; +SlowBuffer.prototype.hexWrite = function(string, offset, length) { offset = +offset || 0; - maxLength = Math.min(+maxLength || Number.MAX_VALUE, this.length - offset); + 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'); } - maxLength = Math.min(maxLength, len / 2); - for (var i = 0; i < maxLength; 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; @@ -111,48 +121,53 @@ SlowBuffer.prototype.hexWrite = function(string, offset, maxLength) { }; -SlowBuffer.prototype.write = function(string) { - // Support both (string, offset, maxLength, encoding) - // and the legacy (string, encoding, offset, maxLength) - var offset, maxLength, encoding; - if (isFinite(arguments[1])) { - offset = arguments[1]; - if (isFinite(arguments[2])) { - maxLength = arguments[2]; - encoding = arguments[3]; - } else { - encoding = arguments[2]; +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 - encoding = arguments[1]; - offset = arguments[2]; - maxLength = arguments[3]; + var swap = encoding; + encoding = offset; + offset = length; + length = swap; } offset = +offset || 0; - maxLength = Math.min(+maxLength || Number.MAX_VALUE, this.length - offset); + 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, maxLength); + return this.hexWrite(string, offset, length); case 'utf8': case 'utf-8': - return this.utf8Write(string, offset, maxLength); + return this.utf8Write(string, offset, length); case 'ascii': - return this.asciiWrite(string, offset, maxLength); + return this.asciiWrite(string, offset, length); case 'binary': - return this.binaryWrite(string, offset, maxLength); + return this.binaryWrite(string, offset, length); case 'base64': - return this.base64Write(string, offset, maxLength); + return this.base64Write(string, offset, length); case 'ucs2': case 'ucs-2': - return this.ucs2Write(string, offset, maxLength); + return this.ucs2Write(string, offset, length); default: throw new Error('Unknown encoding'); @@ -283,56 +298,61 @@ Buffer.prototype.set = function set(i, v) { }; -// write(string, offset = 0, maxLength = this.length-offset, encoding = 'utf8') -Buffer.prototype.write = function(string) { - // Support both (string, offset, maxLength, encoding) - // and the legacy (string, encoding, offset, maxLength) - var offset, maxLength, encoding; - if (isFinite(arguments[1])) { - offset = arguments[1]; - if (isFinite(arguments[2])) { - maxLength = arguments[2]; - encoding = arguments[3]; - } else { - encoding = arguments[2]; +// 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 - encoding = arguments[1]; - offset = arguments[2]; - maxLength = arguments[3]; + var swap = encoding; + encoding = offset; + offset = length; + length = swap; } offset = +offset || 0; - maxLength = Math.min(+maxLength || Number.MAX_VALUE, this.length - offset); + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } encoding = String(encoding || 'utf8').toLowerCase(); 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: