summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTrevor Norris <trev.norris@gmail.com>2013-04-17 16:26:15 -0700
committerTrevor Norris <trev.norris@gmail.com>2013-06-18 15:39:13 -0700
commit3a2f273bd73bc94a6e93f342d629106a9f022f2d (patch)
tree37d9c0b71bfb29d5a1c293cd88ea4f88aaba8810 /lib
parent252cdfa43be38b99228b3caee373dccbb6e94e9c (diff)
downloadnode-3a2f273bd73bc94a6e93f342d629106a9f022f2d.tar.gz
buffer: use smalloc as backing data store
Memory allocations are now done through smalloc. The Buffer cc class has been removed completely, but for backwards compatibility have left the namespace as Buffer. The .parent attribute is only set if the Buffer is a slice of an allocation. Which is then set to the alloc object (not a Buffer). The .offset attribute is now a ReadOnly set to 0, for backwards compatibility. I'd like to remove it in the future (pre v1.0). A few alterations have been made to how arguments are either coerced or thrown. All primitives will now be coerced to their respective values, and (most) all out of range index requests will throw. The indexes that are coerced were left for backwards compatibility. For example: Buffer slice operates more like Array slice, and coerces instead of throwing out of range indexes. This may change in the future. The reason for wanting to throw for out of range indexes is because giving js access to raw memory has high potential risk. To mitigate that it's easier to make sure the developer is always quickly alerted to the fact that their code is attempting to access beyond memory bounds. Because SlowBuffer will be deprecated, and simply returns a new Buffer instance, all tests on SlowBuffer have been removed. Heapdumps will now show usage under "smalloc" instead of "Buffer". ParseArrayIndex was added to node_internals to support proper uint argument checking/coercion for external array data indexes. SlabAllocator had to be updated since handle_ no longer exists.
Diffstat (limited to 'lib')
-rw-r--r--lib/buffer.js654
1 files changed, 187 insertions, 467 deletions
diff --git a/lib/buffer.js b/lib/buffer.js
index 8d93384d4..a5abf368a 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -19,299 +19,202 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-var SlowBuffer = process.binding('buffer').SlowBuffer;
+var smalloc = process.binding('smalloc');
+var buffer = process.binding('buffer');
var assert = require('assert');
+var alloc = smalloc.alloc;
+var sliceOnto = smalloc.sliceOnto;
+var kMaxLength = smalloc.kMaxLength;
+exports.Buffer = Buffer;
+// backwards compatibility (DEPRECATE)
+exports.SlowBuffer = Buffer;
exports.INSPECT_MAX_BYTES = 50;
-// Make SlowBuffer inherit from Buffer.
-// This is an exception to the rule that __proto__ is not allowed in core.
-SlowBuffer.prototype.__proto__ = Buffer.prototype;
+// add methods to Buffer prototype
+buffer.setupBufferJS(Buffer);
+function Buffer(subject, encoding) {
+ if (!(this instanceof Buffer))
+ return new Buffer(subject, encoding);
-function clamp(index, len, defaultValue) {
- if (typeof index !== 'number') return defaultValue;
- index = ~~index; // Coerce to integer.
- if (index >= len) return len;
- if (index >= 0) return index;
- index += len;
- if (index >= 0) return index;
- return 0;
-}
+ var type = typeof subject;
+ switch (type) {
+ case 'number':
+ this.length = subject > 0 ? Math.floor(subject) : 0;
+ break;
-function toHex(n) {
- if (n < 16) return '0' + n.toString(16);
- return n.toString(16);
-}
+ case 'string':
+ this.length = Buffer.byteLength(subject, encoding = encoding || 'utf8');
+ break;
+ case 'object':
+ this.length = +subject.length > 0 ? Math.floor(+subject.length) : 0;
+ break;
-SlowBuffer.prototype.toString = function(encoding, start, end) {
- encoding = String(encoding || 'utf8').toLowerCase();
- start = +start || 0;
- if (typeof end !== 'number') end = this.length;
+ // undef first arg returns unallocated buffer, also assumes length passed.
+ // this is a stop-gap for now while look for better architecture.
+ // for internal use only.
+ case 'undefined':
+ this.length = encoding;
+ return;
- // Fastpath empty strings
- if (+end == start) {
- return '';
+ default:
+ throw new TypeError('must start with number, buffer, array or string');
}
- switch (encoding) {
- case 'hex':
- return this.hexSlice(start, end);
-
- case 'utf8':
- case 'utf-8':
- return this.utf8Slice(start, end);
+ if (this.length > kMaxLength)
+ throw new RangeError('length > kMaxLength');
- case 'ascii':
- return this.asciiSlice(start, end);
+ alloc(this, this.length);
- case 'binary':
- return this.binarySlice(start, end);
+ if (type !== 'number') {
+ if (type === 'string') {
+ // FIXME: the number of bytes hasn't changed, so why change the length?
+ this.length = this.write(subject, 0, encoding);
+ } else {
+ if (subject instanceof Buffer)
+ this.copy(subject, 0, 0, this.length);
+ else if (typeof subject.length === 'number' || Array.isArray(subject))
+ for (var i = 0; i < this.length; i++)
+ this[i] = subject[i];
+ }
+ }
+}
- case 'base64':
- return this.base64Slice(start, end);
- case 'ucs2':
- case 'ucs-2':
- case 'utf16le':
- case 'utf-16le':
- return this.ucs2Slice(start, end);
+// Static methods
- default:
- throw new TypeError('Unknown encoding: ' + encoding);
- }
+Buffer.isBuffer = function isBuffer(b) {
+ return b instanceof Buffer;
};
-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 = 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) {
+Buffer.isEncoding = function(encoding) {
+ switch ((encoding + '').toLowerCase()) {
case 'hex':
- return this.hexWrite(string, offset, length);
-
case 'utf8':
case 'utf-8':
- return this.utf8Write(string, offset, length);
-
case 'ascii':
- return this.asciiWrite(string, offset, length);
-
case 'binary':
- return this.binaryWrite(string, offset, length);
-
case 'base64':
- return this.base64Write(string, offset, length);
-
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
- return this.ucs2Write(string, offset, length);
+ case 'raw':
+ return true;
default:
- throw new TypeError('Unknown encoding: ' + encoding);
+ return false;
}
};
-// slice(start, end)
-SlowBuffer.prototype.slice = function(start, end) {
- var len = this.length;
- start = clamp(start, len, 0);
- end = clamp(end, len, len);
- return new Buffer(this, end - start, start);
-};
-
-
-var zeroBuffer = new SlowBuffer(0);
-
-// Buffer
-function Buffer(subject, encoding, offset) {
- if (!(this instanceof Buffer)) {
- return new Buffer(subject, encoding, offset);
- }
-
- var type;
-
- // Are we slicing?
- if (typeof offset === 'number') {
- if (!Buffer.isBuffer(subject)) {
- throw new TypeError('First argument must be a Buffer when slicing');
- }
+Buffer.concat = function(list, length) {
+ if (!Array.isArray(list))
+ throw new TypeError('Usage: Buffer.concat(list[, length])');
- this.length = +encoding > 0 ? Math.ceil(encoding) : 0;
- this.parent = subject.parent ? subject.parent : subject;
- this.offset = offset;
+ if (typeof length === 'undefined') {
+ length = 0;
+ for (var i = 0; i < list.length; i++)
+ length += list[i].length;
} else {
- // Find the length
- switch (type = typeof subject) {
- case 'number':
- this.length = +subject > 0 ? Math.ceil(subject) : 0;
- break;
-
- case 'string':
- this.length = Buffer.byteLength(subject, encoding);
- break;
-
- case 'object': // Assume object is array-ish
- this.length = +subject.length > 0 ? Math.ceil(subject.length) : 0;
- break;
-
- default:
- throw new TypeError('First argument needs to be a number, ' +
- 'array or string.');
- }
+ length = ~~length;
+ }
- if (this.length > Buffer.poolSize) {
- // Big buffer, just alloc one.
- this.parent = new SlowBuffer(this.length);
- this.offset = 0;
+ if (length < 0) length = 0;
- } else if (this.length > 0) {
- // Small buffer.
- if (!pool || pool.length - pool.used < this.length) allocPool();
- this.parent = pool;
- this.offset = pool.used;
- pool.used += this.length;
- if (pool.used & 7) pool.used = (pool.used + 8) & ~7;
+ if (list.length === 0)
+ return new Buffer(0);
+ else if (list.length === 1)
+ return list[0];
- } else {
- // Zero-length buffer
- this.parent = zeroBuffer;
- this.offset = 0;
- }
+ if (length < 0)
+ throw new RangeError('length is not a positive number');
- // 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];
- }
- }
+ var buffer = new Buffer(length);
+ var pos = 0;
+ for (var i = 0; i < list.length; i++) {
+ var buf = list[i];
+ buf.copy(buffer, pos);
+ pos += buf.length;
}
- SlowBuffer.makeFastBuffer(this.parent, this, this.offset, this.length);
-}
+ return buffer;
+};
-function isArrayIsh(subject) {
- return Array.isArray(subject) ||
- subject && typeof subject === 'object' &&
- typeof subject.length === 'number';
-}
-exports.SlowBuffer = SlowBuffer;
-exports.Buffer = Buffer;
+// toString(encoding, start=0, end=buffer.length)
+Buffer.prototype.toString = function(encoding, start, end) {
+ encoding = !!encoding ? (encoding + '').toLowerCase() : 'utf8';
+ start = ~~start;
+ end = typeof end === 'undefined' ? this.length : ~~end;
-Buffer.isEncoding = function(encoding) {
- switch (encoding && encoding.toLowerCase()) {
+ if (start < 0) start = 0;
+ if (end > this.length) end = this.length;
+ if (end <= start) return '';
+
+ switch (encoding) {
case 'hex':
+ return this.hexSlice(start, end);
+
case 'utf8':
case 'utf-8':
+ return this.utf8Slice(start, end);
+
case 'ascii':
+ return this.asciiSlice(start, end);
+
case 'binary':
+ return this.binarySlice(start, end);
+
case 'base64':
+ return this.base64Slice(start, end);
+
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
- case 'raw':
- return true;
+ return this.ucs2Slice(start, end);
default:
- return false;
+ throw new TypeError('Unknown encoding: ' + encoding);
}
};
-
-Buffer.poolSize = 8 * 1024;
-var pool;
-
-function allocPool() {
- pool = new SlowBuffer(Buffer.poolSize);
- pool.used = 0;
-}
-
-
-// Static methods
-Buffer.isBuffer = function isBuffer(b) {
- return b instanceof Buffer;
-};
-
-
// Inspect
Buffer.prototype.inspect = function inspect() {
- var out = [],
- len = this.length,
- name = this.constructor.name;
-
- for (var i = 0; i < len; i++) {
- out[i] = toHex(this[i]);
- if (i == exports.INSPECT_MAX_BYTES) {
- out[i + 1] = '...';
- break;
- }
- }
-
- return '<' + name + ' ' + out.join(' ') + '>';
+ var str = '';
+ if (this.length > 0)
+ str = this.hexSlice(0, this.length).match(/.{2}/g).join(' ');
+ return '<' + this.constructor.name + ' ' + str + '>';
};
+// TODO(trevnorris): DEPRECATE
Buffer.prototype.get = function get(offset) {
+ offset = ~~offset;
if (offset < 0 || offset >= this.length)
- throw new RangeError('offset is out of bounds');
- return this.parent[this.offset + offset];
+ throw new RangeError('index out of range');
+ return this[offset];
};
+// TODO(trevnorris): DEPRECATE
Buffer.prototype.set = function set(offset, v) {
+ offset = ~~offset;
if (offset < 0 || offset >= this.length)
- throw new RangeError('offset is out of bounds');
- return this.parent[this.offset + offset] = v;
+ throw new RangeError('index out of range');
+ return this[offset] = v;
};
-// write(string, offset = 0, length = buffer.length-offset, encoding = 'utf8')
+// TODO(trevnorris): fix these checks to follow new standard
+// write(string, offset = 0, length = buffer.length, encoding = 'utf8')
Buffer.prototype.write = function(string, offset, length, encoding) {
// Support both (string, offset, length, encoding)
// and the legacy (string, encoding, offset, length)
@@ -320,6 +223,7 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
encoding = length;
length = undefined;
}
+ // TODO(trevnorris): DEPRECATE
} else { // legacy
var swap = encoding;
encoding = offset;
@@ -337,7 +241,11 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
length = remaining;
}
}
- encoding = String(encoding || 'utf8').toLowerCase();
+
+ if (typeof encoding === 'undefined')
+ encoding = 'utf8';
+ else
+ encoding = (encoding + '').toLowerCase();
if (string.length > 0 && (length < 0 || offset < 0))
throw new RangeError('attempt to write beyond buffer bounds');
@@ -345,32 +253,32 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
var ret;
switch (encoding) {
case 'hex':
- ret = this.parent.hexWrite(string, this.offset + offset, length);
+ ret = this.hexWrite(string, offset, length);
break;
case 'utf8':
case 'utf-8':
- ret = this.parent.utf8Write(string, this.offset + offset, length);
+ ret = this.utf8Write(string, offset, length);
break;
case 'ascii':
- ret = this.parent.asciiWrite(string, this.offset + offset, length);
+ ret = this.asciiWrite(string, offset, length);
break;
case 'binary':
- ret = this.parent.binaryWrite(string, this.offset + offset, length);
+ ret = this.binaryWrite(string, offset, length);
break;
case 'base64':
// Warning: maxLength not taken into account in base64Write
- ret = this.parent.base64Write(string, this.offset + offset, length);
+ ret = this.base64Write(string, offset, length);
break;
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
- ret = this.parent.ucs2Write(string, this.offset + offset, length);
+ ret = this.ucs2Write(string, offset, length);
break;
default:
@@ -389,203 +297,48 @@ Buffer.prototype.toJSON = function() {
};
-// toString(encoding, start=0, end=buffer.length)
-Buffer.prototype.toString = function(encoding, start, end) {
- encoding = String(encoding || 'utf8').toLowerCase();
-
- if (typeof start !== 'number' || start < 0) {
- start = 0;
- } else if (start > this.length) {
- start = this.length;
- }
-
- if (typeof end !== 'number' || end > this.length) {
- end = this.length;
- } else if (end < 0) {
- end = 0;
- }
-
- start = start + this.offset;
- end = end + this.offset;
-
- switch (encoding) {
- case 'hex':
- return this.parent.hexSlice(start, end);
-
- case 'utf8':
- case 'utf-8':
- return this.parent.utf8Slice(start, end);
-
- case 'ascii':
- return this.parent.asciiSlice(start, end);
-
- case 'binary':
- return this.parent.binarySlice(start, end);
-
- case 'base64':
- return this.parent.base64Slice(start, end);
-
- case 'ucs2':
- case 'ucs-2':
- case 'utf16le':
- case 'utf-16le':
- return this.parent.ucs2Slice(start, end);
-
- default:
- throw new TypeError('Unknown encoding: ' + encoding);
- }
-};
-
-
-// byteLength
-Buffer.byteLength = SlowBuffer.byteLength;
-
-
-// fill(value, start=0, end=buffer.length)
-Buffer.prototype.fill = function fill(value, start, end) {
- value || (value = 0);
- start || (start = 0);
- end || (end = this.length);
-
- if (typeof value === 'string') {
- value = value.charCodeAt(0);
- }
- if (typeof value !== 'number' || isNaN(value)) {
- throw new TypeError('value is not a number');
- }
-
- if (end < start) throw new RangeError('end < start');
-
- // Fill 0 bytes; we're done
- if (end === start) return 0;
- if (this.length == 0) return 0;
-
- if (start < 0 || start >= this.length) {
- throw new RangeError('start out of bounds');
- }
-
- if (end < 0 || end > this.length) {
- throw new RangeError('end out of bounds');
- }
-
- this.parent.fill(value,
- start + this.offset,
- end + this.offset);
- return this;
-};
-
-
-Buffer.concat = function(list, length) {
- if (!Array.isArray(list)) {
- throw new TypeError('Usage: Buffer.concat(list, [length])');
- }
-
- if (list.length === 0) {
- return new Buffer(0);
- } else if (list.length === 1) {
- return list[0];
+// TODO(trevnorris): currently works like Array.prototype.slice(), which
+// doesn't follow the new standard for throwing on out of range indexes.
+Buffer.prototype.slice = function(start, end) {
+ var len = this.length;
+ start = ~~start;
+ end = typeof end === 'undefined' ? len : ~~end;
+
+ if (start < 0) {
+ start += len;
+ if (start < 0)
+ start = 0;
+ } else if (start > len) {
+ start = len;
}
- if (typeof length !== 'number') {
- length = 0;
- for (var i = 0; i < list.length; i++) {
- var buf = list[i];
- length += buf.length;
- }
+ if (end < 0) {
+ end += len;
+ if (end < 0)
+ end = 0;
+ } else if (end > len) {
+ end = len;
}
- var buffer = new Buffer(length);
- var pos = 0;
- for (var i = 0; i < list.length; i++) {
- var buf = list[i];
- buf.copy(buffer, pos);
- pos += buf.length;
- }
- return buffer;
-};
-
-
-
-
-// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
-Buffer.prototype.copy = function(target, target_start, start, end) {
- // set undefined/NaN or out of bounds values equal to their default
- if (!(target_start >= 0)) target_start = 0;
- if (!(start >= 0)) start = 0;
- if (!(end < this.length)) end = this.length;
-
- // Copy 0 bytes; we're done
- if (end === start ||
- target.length === 0 ||
- this.length === 0 ||
- start > this.length)
- return 0;
-
if (end < start)
- throw new RangeError('sourceEnd < sourceStart');
-
- if (target_start >= target.length)
- throw new RangeError('targetStart out of bounds');
-
- if (target.length - target_start < end - start)
- end = target.length - target_start + start;
-
- return this.parent.copy(target.parent || target,
- target_start + (target.offset || 0),
- start + this.offset,
- end + this.offset);
-};
-
-
-// slice(start, end)
-Buffer.prototype.slice = function(start, end) {
- var len = this.length;
- start = clamp(start, len, 0);
- end = clamp(end, len, len);
- return new Buffer(this.parent, end - start, start + this.offset);
-};
-
-
-// Legacy methods for backwards compatibility.
-
-Buffer.prototype.utf8Slice = function(start, end) {
- return this.toString('utf8', start, end);
-};
+ end = start;
-Buffer.prototype.binarySlice = function(start, end) {
- return this.toString('binary', start, end);
-};
+ var buf = new Buffer();
+ buf.parent = sliceOnto(this, buf, start, end);
+ buf.length = end - start;
-Buffer.prototype.asciiSlice = function(start, end) {
- return this.toString('ascii', start, end);
+ return buf;
};
-Buffer.prototype.utf8Write = function(string, offset) {
- return this.write(string, offset, 'utf8');
-};
-
-Buffer.prototype.binaryWrite = function(string, offset) {
- return this.write(string, offset, 'binary');
-};
-Buffer.prototype.asciiWrite = function(string, offset) {
- return this.write(string, offset, 'ascii');
-};
-
-
-/*
- * Need to make sure that buffer isn't trying to write out of bounds.
- * This check is far too slow internally for fast buffers.
- */
function checkOffset(offset, ext, length) {
- if ((offset % 1) !== 0 || offset < 0)
- throw new RangeError('offset is not uint');
- if (offset + ext > length)
- throw new RangeError('Trying to access beyond buffer length');
+ if (offset < 0 || offset + ext > length)
+ throw new RangeError('index out of range');
}
Buffer.prototype.readUInt8 = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 1, this.length);
return this[offset];
@@ -601,12 +354,12 @@ function readUInt16(buffer, offset, isBigEndian) {
val = buffer[offset];
val |= buffer[offset + 1] << 8;
}
-
return val;
}
Buffer.prototype.readUInt16LE = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 2, this.length);
return readUInt16(this, offset, false, noAssert);
@@ -614,6 +367,7 @@ Buffer.prototype.readUInt16LE = function(offset, noAssert) {
Buffer.prototype.readUInt16BE = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 2, this.length);
return readUInt16(this, offset, true, noAssert);
@@ -622,7 +376,6 @@ Buffer.prototype.readUInt16BE = function(offset, noAssert) {
function readUInt32(buffer, offset, isBigEndian, noAssert) {
var val = 0;
-
if (isBigEndian) {
val = buffer[offset + 1] << 16;
val |= buffer[offset + 2] << 8;
@@ -634,12 +387,12 @@ function readUInt32(buffer, offset, isBigEndian, noAssert) {
val |= buffer[offset];
val = val + (buffer[offset + 3] << 24 >>> 0);
}
-
return val;
}
Buffer.prototype.readUInt32LE = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 4, this.length);
return readUInt32(this, offset, false, noAssert);
@@ -647,6 +400,7 @@ Buffer.prototype.readUInt32LE = function(offset, noAssert) {
Buffer.prototype.readUInt32BE = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 4, this.length);
return readUInt32(this, offset, true, noAssert);
@@ -700,6 +454,7 @@ Buffer.prototype.readUInt32BE = function(offset, noAssert) {
*/
Buffer.prototype.readInt8 = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 1, this.length);
if (!(this[offset] & 0x80))
@@ -710,7 +465,6 @@ Buffer.prototype.readInt8 = function(offset, noAssert) {
function readInt16(buffer, offset, isBigEndian) {
var val = readUInt16(buffer, offset, isBigEndian);
-
if (!(val & 0x8000))
return val;
return (0xffff - val + 1) * -1;
@@ -718,6 +472,7 @@ function readInt16(buffer, offset, isBigEndian) {
Buffer.prototype.readInt16LE = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 2, this.length);
return readInt16(this, offset, false);
@@ -725,6 +480,7 @@ Buffer.prototype.readInt16LE = function(offset, noAssert) {
Buffer.prototype.readInt16BE = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 2, this.length);
return readInt16(this, offset, true);
@@ -733,7 +489,6 @@ Buffer.prototype.readInt16BE = function(offset, noAssert) {
function readInt32(buffer, offset, isBigEndian) {
var val = readUInt32(buffer, offset, isBigEndian);
-
if (!(val & 0x80000000))
return (val);
return (0xffffffff - val + 1) * -1;
@@ -741,6 +496,7 @@ function readInt32(buffer, offset, isBigEndian) {
Buffer.prototype.readInt32LE = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 4, this.length);
return readInt32(this, offset, false);
@@ -748,50 +504,24 @@ Buffer.prototype.readInt32LE = function(offset, noAssert) {
Buffer.prototype.readInt32BE = function(offset, noAssert) {
+ offset = ~~offset;
if (!noAssert)
checkOffset(offset, 4, this.length);
return readInt32(this, offset, true);
};
-Buffer.prototype.readFloatLE = function(offset, noAssert) {
- if (!noAssert)
- checkOffset(offset, 4, this.length);
- return this.parent.readFloatLE(this.offset + offset, !!noAssert);
-};
-
-
-Buffer.prototype.readFloatBE = function(offset, noAssert) {
- if (!noAssert)
- checkOffset(offset, 4, this.length);
- return this.parent.readFloatBE(this.offset + offset, !!noAssert);
-};
-
-
-Buffer.prototype.readDoubleLE = function(offset, noAssert) {
- if (!noAssert)
- checkOffset(offset, 8, this.length);
- return this.parent.readDoubleLE(this.offset + offset, !!noAssert);
-};
-
-
-Buffer.prototype.readDoubleBE = function(offset, noAssert) {
- if (!noAssert)
- checkOffset(offset, 8, this.length);
- return this.parent.readDoubleBE(this.offset + offset, !!noAssert);
-};
-
function checkInt(buffer, value, offset, ext, max, min) {
- if ((value % 1) !== 0 || value > max || value < min)
+ if (value > max || value < min)
throw TypeError('value is out of bounds');
- if ((offset % 1) !== 0 || offset < 0)
- throw TypeError('offset is not uint');
- if (offset + ext > buffer.length || buffer.length + offset < 0)
- throw RangeError('Trying to write outside buffer length');
+ if (offset < 0 || offset + ext > buffer.length || buffer.length + offset < 0)
+ throw RangeError('index out of range');
}
Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 1, 0xff, 0);
this[offset] = value;
@@ -810,6 +540,8 @@ function writeUInt16(buffer, value, offset, isBigEndian) {
Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 2, 0xffff, 0);
writeUInt16(this, value, offset, false);
@@ -817,6 +549,8 @@ Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 2, 0xffff, 0);
writeUInt16(this, value, offset, true);
@@ -839,6 +573,8 @@ function writeUInt32(buffer, value, offset, isBigEndian) {
Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 4, 0xffffffff, 0);
writeUInt32(this, value, offset, false);
@@ -846,6 +582,8 @@ Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 4, 0xffffffff, 0);
writeUInt32(this, value, offset, true);
@@ -890,6 +628,8 @@ Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
*/
Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 1, 0x7f, -0x80);
if (value < 0) value = 0xff + value + 1;
@@ -898,6 +638,8 @@ Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 2, 0x7fff, -0x8000);
if (value < 0) value = 0xffff + value + 1;
@@ -906,6 +648,8 @@ Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 2, 0x7fff, -0x8000);
if (value < 0) value = 0xffff + value + 1;
@@ -914,6 +658,8 @@ Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
if (value < 0) value = 0xffffffff + value + 1;
@@ -922,36 +668,10 @@ Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = ~~offset;
if (!noAssert)
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
if (value < 0) value = 0xffffffff + value + 1;
writeUInt32(this, value, offset, true);
};
-
-
-Buffer.prototype.writeFloatLE = function(value, offset, noAssert) {
- if (!noAssert)
- checkOffset(offset, 4, this.length);
- this.parent.writeFloatLE(value, this.offset + offset, !!noAssert);
-};
-
-
-Buffer.prototype.writeFloatBE = function(value, offset, noAssert) {
- if (!noAssert)
- checkOffset(offset, 4, this.length);
- this.parent.writeFloatBE(value, this.offset + offset, !!noAssert);
-};
-
-
-Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) {
- if (!noAssert)
- checkOffset(offset, 8, this.length);
- this.parent.writeDoubleLE(value, this.offset + offset, !!noAssert);
-};
-
-
-Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) {
- if (!noAssert)
- checkOffset(offset, 8, this.length);
- this.parent.writeDoubleBE(value, this.offset + offset, !!noAssert);
-};