Browse Source

buffer: check logic simplification

Checks have been simplified and optimized for most-used cases.

Calling Buffer with another Buffer as the subject will now use the
SlowBuffer Copy method instead of the for loop.

No need to call for value coercion, just place the ternary inline.
v0.9.11-release
Trevor Norris 12 years ago
committed by Ben Noordhuis
parent
commit
d69a26b965
  1. 53
      lib/buffer.js

53
lib/buffer.js

@ -30,7 +30,7 @@ SlowBuffer.prototype.__proto__ = Buffer.prototype;
function clamp(index, len, defaultValue) {
if (typeof index === 'undefined') return defaultValue;
if (typeof index !== 'number') return defaultValue;
index = ~~index; // Coerce to integer.
if (index >= len) return len;
if (index >= 0) return index;
@ -49,7 +49,7 @@ function toHex(n) {
SlowBuffer.prototype.toString = function(encoding, start, end) {
encoding = String(encoding || 'utf8').toLowerCase();
start = +start || 0;
if (typeof end == 'undefined') end = this.length;
if (typeof end !== 'number') end = this.length;
// Fastpath empty strings
if (+end == start) {
@ -150,15 +150,6 @@ SlowBuffer.prototype.slice = function(start, end) {
};
function coerce(length) {
// Coerce length to a number (possibly NaN), round up
// in case it's fractional (e.g. 123.456). Since NaN
// comparisons are always false, use to return zero.
length = Math.ceil(+length);
return length > 0 ? length : 0;
}
var zeroBuffer = new SlowBuffer(0);
// Buffer
@ -175,22 +166,22 @@ function Buffer(subject, encoding, offset) {
throw new TypeError('First argument must be a Buffer when slicing');
}
this.length = coerce(encoding);
this.length = +encoding > 0 ? Math.ceil(encoding) : 0;
this.parent = subject.parent ? subject.parent : subject;
this.offset = offset;
} else {
// Find the length
switch (type = typeof subject) {
case 'number':
this.length = coerce(subject);
this.length = +subject > 0 ? Math.ceil(subject) : 0;
break;
case 'string':
this.length = Buffer.byteLength(subject, encoding);
break;
case 'object': // Assume object is an array
this.length = coerce(subject.length);
case 'object': // Assume object is array-ish
this.length = +subject.length > 0 ? Math.ceil(subject.length) : 0;
break;
default:
@ -217,14 +208,24 @@ function Buffer(subject, encoding, offset) {
this.offset = 0;
}
// Treat array-ish objects as a byte array.
if (isArrayIsh(subject)) {
for (var i = 0; i < this.length; i++) {
this.parent[i + this.offset] = subject[i];
// optimize by branching logic for new allocations
if (typeof subject !== 'number') {
if (type === 'string') {
// We are a string
this.length = this.write(subject, 0, encoding);
// if subject is buffer then use built-in copy method
} else if (Buffer.isBuffer(subject)) {
if (subject.parent)
subject.parent.copy(this.parent,
this.offset,
subject.offset,
this.length + subject.offset);
else
subject.copy(this.parent, this.offset, 0, this.length);
} else if (isArrayIsh(subject)) {
for (var i = 0; i < this.length; i++)
this.parent[i + this.offset] = subject[i];
}
} else if (type == 'string') {
// We are a string
this.length = this.write(subject, 0, encoding);
}
}
@ -232,7 +233,7 @@ function Buffer(subject, encoding, offset) {
}
function isArrayIsh(subject) {
return Array.isArray(subject) || Buffer.isBuffer(subject) ||
return Array.isArray(subject) ||
subject && typeof subject === 'object' &&
typeof subject.length === 'number';
}
@ -388,13 +389,13 @@ Buffer.prototype.toJSON = function() {
Buffer.prototype.toString = function(encoding, start, end) {
encoding = String(encoding || 'utf8').toLowerCase();
if (typeof start == 'undefined' || start < 0) {
if (typeof start !== 'number' || start < 0) {
start = 0;
} else if (start > this.length) {
start = this.length;
}
if (typeof end == 'undefined' || end > this.length) {
if (typeof end !== 'number' || end > this.length) {
end = this.length;
} else if (end < 0) {
end = 0;
@ -445,7 +446,7 @@ Buffer.prototype.fill = function fill(value, start, end) {
if (typeof value === 'string') {
value = value.charCodeAt(0);
}
if (!(typeof value === 'number') || isNaN(value)) {
if (typeof value !== 'number' || isNaN(value)) {
throw new TypeError('value is not a number');
}

Loading…
Cancel
Save