Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/buffer.js1149
-rw-r--r--lib/internal/buffer_new.js1020
-rw-r--r--lib/internal/buffer_old.js1140
-rw-r--r--node.gyp3
-rw-r--r--src/env.h1
-rw-r--r--src/node.cc25
-rw-r--r--src/node_buffer.cc395
-rw-r--r--src/node_buffer.h6
-rw-r--r--src/node_internals.h2
-rw-r--r--src/util-inl.h8
-rw-r--r--src/util.h2
-rw-r--r--test/parallel/test-buffer-slice.js12
-rw-r--r--test/parallel/test-buffer.js10
13 files changed, 2521 insertions, 1252 deletions
diff --git a/lib/buffer.js b/lib/buffer.js
index 568a1f4b34e..641b5422760 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -1,1149 +1,8 @@
/* eslint-disable require-buffer */
'use strict';
-const binding = process.binding('buffer');
-const smalloc = process.binding('smalloc');
-const internalUtil = require('internal/util');
-const alloc = smalloc.alloc;
-const truncate = smalloc.truncate;
-const sliceOnto = smalloc.sliceOnto;
-const kMaxLength = smalloc.kMaxLength;
-
-exports.Buffer = Buffer;
-exports.SlowBuffer = SlowBuffer;
-exports.INSPECT_MAX_BYTES = 50;
-
-
-Buffer.poolSize = 8 * 1024;
-var poolSize, poolOffset, allocPool;
-
-
-function createPool() {
- poolSize = Buffer.poolSize;
- allocPool = alloc({}, poolSize);
- poolOffset = 0;
-}
-createPool();
-
-function Buffer(arg) {
- if (!(this instanceof Buffer)) {
- // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
- if (arguments.length > 1)
- return new Buffer(arg, arguments[1]);
-
- return new Buffer(arg);
- }
-
- this.length = 0;
- this.parent = undefined;
-
- // Common case.
- if (typeof(arg) === 'number') {
- fromNumber(this, arg);
- return;
- }
-
- // Slightly less common case.
- if (typeof(arg) === 'string') {
- fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8');
- return;
- }
-
- // Unusual.
- fromObject(this, arg);
-}
-
-function fromNumber(that, length) {
- allocate(that, length < 0 ? 0 : checked(length) | 0);
-}
-
-function fromString(that, string, encoding) {
- if (typeof(encoding) !== 'string' || encoding === '')
- encoding = 'utf8';
-
- // Assumption: byteLength() return value is always < kMaxLength.
- var length = byteLength(string, encoding) | 0;
- allocate(that, length);
-
- var actual = that.write(string, encoding) | 0;
- if (actual !== length) {
- // Fix up for truncated base64 input. Don't bother returning
- // the unused two or three bytes to the pool.
- that.length = actual;
- truncate(that, actual);
- }
-}
-
-function fromObject(that, object) {
- if (object instanceof Buffer)
- return fromBuffer(that, object);
-
- if (Array.isArray(object))
- return fromArray(that, object);
-
- if (object == null)
- throw new TypeError('must start with number, buffer, array or string');
-
- if (object.buffer instanceof ArrayBuffer)
- return fromTypedArray(that, object);
-
- if (object.length)
- return fromArrayLike(that, object);
-
- return fromJsonObject(that, object);
-}
-
-function fromBuffer(that, buffer) {
- var length = checked(buffer.length) | 0;
- allocate(that, length);
- buffer.copy(that, 0, 0, length);
-}
-
-function fromArray(that, array) {
- var length = checked(array.length) | 0;
- allocate(that, length);
- for (var i = 0; i < length; i += 1)
- that[i] = array[i] & 255;
-}
-
-// Duplicate of fromArray() to keep fromArray() monomorphic.
-function fromTypedArray(that, array) {
- var length = checked(array.length) | 0;
- allocate(that, length);
- // Truncating the elements is probably not what people expect from typed
- // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
- // of the old Buffer constructor.
- for (var i = 0; i < length; i += 1)
- that[i] = array[i] & 255;
-}
-
-function fromArrayLike(that, array) {
- var length = checked(array.length) | 0;
- allocate(that, length);
- for (var i = 0; i < length; i += 1)
- that[i] = array[i] & 255;
-}
-
-// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
-// Returns a zero-length buffer for inputs that don't conform to the spec.
-function fromJsonObject(that, object) {
- var array;
- var length = 0;
-
- if (object.type === 'Buffer' && Array.isArray(object.data)) {
- array = object.data;
- length = checked(array.length) | 0;
- }
- allocate(that, length);
-
- for (var i = 0; i < length; i += 1)
- that[i] = array[i] & 255;
-}
-
-function allocate(that, length) {
- var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1;
- if (fromPool)
- that.parent = palloc(that, length);
- else
- alloc(that, length);
- that.length = length;
-}
-
-function palloc(that, length) {
- if (length > poolSize - poolOffset)
- createPool();
-
- var start = poolOffset;
- var end = start + length;
- var buf = sliceOnto(allocPool, that, start, end);
- poolOffset = end;
-
- // Ensure aligned slices
- if (poolOffset & 0x7) {
- poolOffset |= 0x7;
- poolOffset++;
- }
-
- return buf;
-}
-
-function checked(length) {
- // Note: cannot use `length < kMaxLength` here because that fails when
- // length is NaN (which is otherwise coerced to zero.)
- if (length >= kMaxLength) {
- throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
- 'size: 0x' + kMaxLength.toString(16) + ' bytes');
- }
- return length >>> 0;
-}
-
-function SlowBuffer(length) {
- length = length >>> 0;
- if (length > kMaxLength) {
- throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
- 'size: 0x' + kMaxLength.toString(16) + ' bytes');
- }
- var b = new NativeBuffer(length);
- alloc(b, length);
- return b;
-}
-
-
-// Bypass all checks for instantiating unallocated Buffer required for
-// Objects created in C++. Significantly faster than calling the Buffer
-// function.
-function NativeBuffer(length) {
- this.length = length >>> 0;
- // Set this to keep the object map the same.
- this.parent = undefined;
-}
-NativeBuffer.prototype = Buffer.prototype;
-
-
-// add methods to Buffer prototype
-binding.setupBufferJS(NativeBuffer);
-
-
-// Static methods
-
-Buffer.isBuffer = function isBuffer(b) {
- return b instanceof Buffer;
-};
-
-
-Buffer.compare = function compare(a, b) {
- if (!(a instanceof Buffer) ||
- !(b instanceof Buffer))
- throw new TypeError('Arguments must be Buffers');
-
- if (a === b)
- return 0;
-
- return binding.compare(a, b);
-};
-
-
-Buffer.isEncoding = function(encoding) {
- switch ((encoding + '').toLowerCase()) {
- case 'hex':
- case 'utf8':
- case 'utf-8':
- case 'ascii':
- case 'binary':
- case 'base64':
- case 'ucs2':
- case 'ucs-2':
- case 'utf16le':
- case 'utf-16le':
- case 'raw':
- return true;
-
- default:
- return false;
- }
-};
-
-
-Buffer.concat = function(list, length) {
- if (!Array.isArray(list))
- throw new TypeError('list argument must be an Array of Buffers.');
-
- if (list.length === 0)
- return new Buffer(0);
- else if (list.length === 1)
- return list[0];
-
- if (length === undefined) {
- length = 0;
- for (var i = 0; i < list.length; i++)
- length += list[i].length;
- } else {
- length = length >>> 0;
- }
-
- 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;
-};
-
-
-function base64ByteLength(str, bytes) {
- // Handle padding
- if (str.charCodeAt(bytes - 1) === 0x3D)
- bytes--;
- if (bytes > 1 && str.charCodeAt(bytes - 1) === 0x3D)
- bytes--;
-
- // Base64 ratio: 3/4
- return (bytes * 3) >>> 2;
-}
-
-
-function byteLength(string, encoding) {
- if (typeof string !== 'string')
- string = '' + string;
-
- var len = string.length;
- if (len === 0)
- return 0;
-
- // Use a for loop to avoid recursion
- var loweredCase = false;
- for (;;) {
- switch (encoding) {
- case 'ascii':
- case 'binary':
- // Deprecated
- case 'raw':
- case 'raws':
- return len;
-
- case 'utf8':
- case 'utf-8':
- return binding.byteLengthUtf8(string);
-
- case 'ucs2':
- case 'ucs-2':
- case 'utf16le':
- case 'utf-16le':
- return len * 2;
-
- case 'hex':
- return len >>> 1;
-
- case 'base64':
- return base64ByteLength(string, len);
-
- default:
- // The C++ binding defaulted to UTF8, we should too.
- if (loweredCase)
- return binding.byteLengthUtf8(string);
-
- encoding = ('' + encoding).toLowerCase();
- loweredCase = true;
- }
- }
-}
-
-Buffer.byteLength = byteLength;
-
-function slowToString(encoding, start, end) {
- var loweredCase = false;
-
- start = start >>> 0;
- end = end === undefined || end === Infinity ? this.length : end >>> 0;
-
- if (!encoding) encoding = 'utf8';
- if (start < 0) start = 0;
- if (end > this.length) end = this.length;
- if (end <= start) return '';
-
- while (true) {
- 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':
- return this.ucs2Slice(start, end);
-
- default:
- if (loweredCase)
- throw new TypeError('Unknown encoding: ' + encoding);
- encoding = (encoding + '').toLowerCase();
- loweredCase = true;
- }
- }
-}
-
-
-Buffer.prototype.toString = function() {
- const length = this.length | 0;
- if (arguments.length === 0)
- return this.utf8Slice(0, length);
- return slowToString.apply(this, arguments);
-};
-
-
-Buffer.prototype.equals = function equals(b) {
- if (!(b instanceof Buffer))
- throw new TypeError('Argument must be a Buffer');
-
- if (this === b)
- return true;
-
- return binding.compare(this, b) === 0;
-};
-
-
-// Inspect
-Buffer.prototype.inspect = function inspect() {
- var str = '';
- var max = exports.INSPECT_MAX_BYTES;
- if (this.length > 0) {
- str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');
- if (this.length > max)
- str += ' ... ';
- }
- return '<' + this.constructor.name + ' ' + str + '>';
-};
-
-
-Buffer.prototype.compare = function compare(b) {
- if (!(b instanceof Buffer))
- throw new TypeError('Argument must be a Buffer');
-
- if (this === b)
- return 0;
-
- return binding.compare(this, b);
-};
-
-
-Buffer.prototype.indexOf = function indexOf(val, byteOffset) {
- if (byteOffset > 0x7fffffff)
- byteOffset = 0x7fffffff;
- else if (byteOffset < -0x80000000)
- byteOffset = -0x80000000;
- byteOffset >>= 0;
-
- if (typeof val === 'string')
- return binding.indexOfString(this, val, byteOffset);
- if (val instanceof Buffer)
- return binding.indexOfBuffer(this, val, byteOffset);
- if (typeof val === 'number')
- return binding.indexOfNumber(this, val, byteOffset);
-
- throw new TypeError('val must be string, number or Buffer');
-};
-
-
-Buffer.prototype.fill = function fill(val, start, end) {
- start = start >> 0;
- end = (end === undefined) ? this.length : end >> 0;
-
- if (start < 0 || end > this.length)
- throw new RangeError('out of range index');
- if (end <= start)
- return this;
-
- if (typeof val !== 'string') {
- val = val >>> 0;
- } else if (val.length === 1) {
- var code = val.charCodeAt(0);
- if (code < 256)
- val = code;
- }
-
- binding.fill(this, val, start, end);
-
- return this;
-};
-
-
-// XXX remove in v0.13
-Buffer.prototype.get = internalUtil.deprecate(function get(offset) {
- offset = ~~offset;
- if (offset < 0 || offset >= this.length)
- throw new RangeError('index out of range');
- return this[offset];
-}, 'Buffer.get is deprecated. Use array indexes instead.');
-
-
-// XXX remove in v0.13
-Buffer.prototype.set = internalUtil.deprecate(function set(offset, v) {
- offset = ~~offset;
- if (offset < 0 || offset >= this.length)
- throw new RangeError('index out of range');
- return this[offset] = v;
-}, 'Buffer.set is deprecated. Use array indexes instead.');
-
-
-// TODO(trevnorris): fix these checks to follow new standard
-// write(string, offset = 0, length = buffer.length, encoding = 'utf8')
-var writeWarned = false;
-const writeMsg = 'Buffer.write(string, encoding, offset, length) is ' +
- 'deprecated. Use write(string[, offset[, length]]' +
- '[, encoding]) instead.';
-Buffer.prototype.write = function(string, offset, length, encoding) {
- // Buffer#write(string);
- if (offset === undefined) {
- encoding = 'utf8';
- length = this.length;
- offset = 0;
-
- // Buffer#write(string, encoding)
- } else if (length === undefined && typeof offset === 'string') {
- encoding = offset;
- length = this.length;
- offset = 0;
-
- // Buffer#write(string, offset[, length][, encoding])
- } else if (isFinite(offset)) {
- offset = offset >>> 0;
- if (isFinite(length)) {
- length = length >>> 0;
- if (encoding === undefined)
- encoding = 'utf8';
- } else {
- encoding = length;
- length = undefined;
- }
-
- // XXX legacy write(string, encoding, offset, length) - remove in v0.13
- } else {
- writeWarned = internalUtil.printDeprecationMessage(writeMsg, writeWarned);
- var swap = encoding;
- encoding = offset;
- offset = length >>> 0;
- length = swap;
- }
-
- var remaining = this.length - offset;
- if (length === undefined || length > remaining)
- length = remaining;
-
- if (string.length > 0 && (length < 0 || offset < 0))
- throw new RangeError('attempt to write outside buffer bounds');
-
- if (!encoding)
- encoding = 'utf8';
-
- var loweredCase = false;
- for (;;) {
- switch (encoding) {
- 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':
- // Warning: maxLength not taken into account in base64Write
- return this.base64Write(string, offset, length);
-
- case 'ucs2':
- case 'ucs-2':
- case 'utf16le':
- case 'utf-16le':
- return this.ucs2Write(string, offset, length);
-
- default:
- if (loweredCase)
- throw new TypeError('Unknown encoding: ' + encoding);
- encoding = ('' + encoding).toLowerCase();
- loweredCase = true;
- }
- }
-};
-
-
-Buffer.prototype.toJSON = function() {
- return {
- type: 'Buffer',
- data: Array.prototype.slice.call(this, 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 = end === undefined ? len : ~~end;
-
- if (start < 0) {
- start += len;
- if (start < 0)
- start = 0;
- } else if (start > len) {
- start = len;
- }
-
- if (end < 0) {
- end += len;
- if (end < 0)
- end = 0;
- } else if (end > len) {
- end = len;
- }
-
- if (end < start)
- end = start;
-
- var buf = new NativeBuffer();
- sliceOnto(this, buf, start, end);
- buf.length = end - start;
- if (buf.length > 0)
- buf.parent = this.parent === undefined ? this : this.parent;
-
- return buf;
-};
-
-
-function checkOffset(offset, ext, length) {
- if (offset + ext > length)
- throw new RangeError('index out of range');
-}
-
-
-Buffer.prototype.readUIntLE = function(offset, byteLength, noAssert) {
- offset = offset >>> 0;
- byteLength = byteLength >>> 0;
- if (!noAssert)
- checkOffset(offset, byteLength, this.length);
-
- var val = this[offset];
- var mul = 1;
- var i = 0;
- while (++i < byteLength && (mul *= 0x100))
- val += this[offset + i] * mul;
-
- return val;
-};
-
-
-Buffer.prototype.readUIntBE = function(offset, byteLength, noAssert) {
- offset = offset >>> 0;
- byteLength = byteLength >>> 0;
- if (!noAssert)
- checkOffset(offset, byteLength, this.length);
-
- var val = this[offset + --byteLength];
- var mul = 1;
- while (byteLength > 0 && (mul *= 0x100))
- val += this[offset + --byteLength] * mul;
-
- return val;
-};
-
-
-Buffer.prototype.readUInt8 = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 1, this.length);
- return this[offset];
-};
-
-
-Buffer.prototype.readUInt16LE = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 2, this.length);
- return this[offset] | (this[offset + 1] << 8);
-};
-
-
-Buffer.prototype.readUInt16BE = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 2, this.length);
- return (this[offset] << 8) | this[offset + 1];
-};
-
-
-Buffer.prototype.readUInt32LE = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 4, this.length);
-
- return ((this[offset]) |
- (this[offset + 1] << 8) |
- (this[offset + 2] << 16)) +
- (this[offset + 3] * 0x1000000);
-};
-
-
-Buffer.prototype.readUInt32BE = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 4, this.length);
-
- return (this[offset] * 0x1000000) +
- ((this[offset + 1] << 16) |
- (this[offset + 2] << 8) |
- this[offset + 3]);
-};
-
-
-Buffer.prototype.readIntLE = function(offset, byteLength, noAssert) {
- offset = offset >>> 0;
- byteLength = byteLength >>> 0;
- if (!noAssert)
- checkOffset(offset, byteLength, this.length);
-
- var val = this[offset];
- var mul = 1;
- var i = 0;
- while (++i < byteLength && (mul *= 0x100))
- val += this[offset + i] * mul;
- mul *= 0x80;
-
- if (val >= mul)
- val -= Math.pow(2, 8 * byteLength);
-
- return val;
-};
-
-
-Buffer.prototype.readIntBE = function(offset, byteLength, noAssert) {
- offset = offset >>> 0;
- byteLength = byteLength >>> 0;
- if (!noAssert)
- checkOffset(offset, byteLength, this.length);
-
- var i = byteLength;
- var mul = 1;
- var val = this[offset + --i];
- while (i > 0 && (mul *= 0x100))
- val += this[offset + --i] * mul;
- mul *= 0x80;
-
- if (val >= mul)
- val -= Math.pow(2, 8 * byteLength);
-
- return val;
-};
-
-
-Buffer.prototype.readInt8 = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 1, this.length);
- var val = this[offset];
- return !(val & 0x80) ? val : (0xff - val + 1) * -1;
-};
-
-
-Buffer.prototype.readInt16LE = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 2, this.length);
- var val = this[offset] | (this[offset + 1] << 8);
- return (val & 0x8000) ? val | 0xFFFF0000 : val;
-};
-
-
-Buffer.prototype.readInt16BE = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 2, this.length);
- var val = this[offset + 1] | (this[offset] << 8);
- return (val & 0x8000) ? val | 0xFFFF0000 : val;
-};
-
-
-Buffer.prototype.readInt32LE = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 4, this.length);
-
- return (this[offset]) |
- (this[offset + 1] << 8) |
- (this[offset + 2] << 16) |
- (this[offset + 3] << 24);
-};
-
-
-Buffer.prototype.readInt32BE = function(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 4, this.length);
-
- return (this[offset] << 24) |
- (this[offset + 1] << 16) |
- (this[offset + 2] << 8) |
- (this[offset + 3]);
-};
-
-
-Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 4, this.length);
- return binding.readFloatLE(this, offset);
-};
-
-
-Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 4, this.length);
- return binding.readFloatBE(this, offset);
-};
-
-
-Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 8, this.length);
- return binding.readDoubleLE(this, offset);
-};
-
-
-Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
- offset = offset >>> 0;
- if (!noAssert)
- checkOffset(offset, 8, this.length);
- return binding.readDoubleBE(this, offset);
-};
-
-
-function checkInt(buffer, value, offset, ext, max, min) {
- if (!(buffer instanceof Buffer))
- throw new TypeError('buffer must be a Buffer instance');
- if (value > max || value < min)
- throw new TypeError('value is out of bounds');
- if (offset + ext > buffer.length)
- throw new RangeError('index out of range');
-}
-
-
-Buffer.prototype.writeUIntLE = function(value, offset, byteLength, noAssert) {
- value = +value;
- offset = offset >>> 0;
- byteLength = byteLength >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
-
- var mul = 1;
- var i = 0;
- this[offset] = value;
- while (++i < byteLength && (mul *= 0x100))
- this[offset + i] = (value / mul) >>> 0;
-
- return offset + byteLength;
-};
-
-
-Buffer.prototype.writeUIntBE = function(value, offset, byteLength, noAssert) {
- value = +value;
- offset = offset >>> 0;
- byteLength = byteLength >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
-
- var i = byteLength - 1;
- var mul = 1;
- this[offset + i] = value;
- while (--i >= 0 && (mul *= 0x100))
- this[offset + i] = (value / mul) >>> 0;
-
- return offset + byteLength;
-};
-
-
-Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 1, 0xff, 0);
- this[offset] = value;
- return offset + 1;
-};
-
-
-Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 2, 0xffff, 0);
- this[offset] = value;
- this[offset + 1] = (value >>> 8);
- return offset + 2;
-};
-
-
-Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 2, 0xffff, 0);
- this[offset] = (value >>> 8);
- this[offset + 1] = value;
- return offset + 2;
-};
-
-
-Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 4, 0xffffffff, 0);
- this[offset + 3] = (value >>> 24);
- this[offset + 2] = (value >>> 16);
- this[offset + 1] = (value >>> 8);
- this[offset] = value;
- return offset + 4;
-};
-
-
-Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 4, 0xffffffff, 0);
- this[offset] = (value >>> 24);
- this[offset + 1] = (value >>> 16);
- this[offset + 2] = (value >>> 8);
- this[offset + 3] = value;
- return offset + 4;
-};
-
-
-Buffer.prototype.writeIntLE = function(value, offset, byteLength, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert) {
- checkInt(this,
- value,
- offset,
- byteLength,
- Math.pow(2, 8 * byteLength - 1) - 1,
- -Math.pow(2, 8 * byteLength - 1));
- }
-
- var i = 0;
- var mul = 1;
- var sub = value < 0 ? 1 : 0;
- this[offset] = value;
- while (++i < byteLength && (mul *= 0x100))
- this[offset + i] = ((value / mul) >> 0) - sub;
-
- return offset + byteLength;
-};
-
-
-Buffer.prototype.writeIntBE = function(value, offset, byteLength, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert) {
- checkInt(this,
- value,
- offset,
- byteLength,
- Math.pow(2, 8 * byteLength - 1) - 1,
- -Math.pow(2, 8 * byteLength - 1));
- }
-
- var i = byteLength - 1;
- var mul = 1;
- var sub = value < 0 ? 1 : 0;
- this[offset + i] = value;
- while (--i >= 0 && (mul *= 0x100))
- this[offset + i] = ((value / mul) >> 0) - sub;
-
- return offset + byteLength;
-};
-
-
-Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 1, 0x7f, -0x80);
- this[offset] = value;
- return offset + 1;
-};
-
-
-Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 2, 0x7fff, -0x8000);
- this[offset] = value;
- this[offset + 1] = (value >>> 8);
- return offset + 2;
-};
-
-
-Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 2, 0x7fff, -0x8000);
- this[offset] = (value >>> 8);
- this[offset + 1] = value;
- return offset + 2;
-};
-
-
-Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
- this[offset] = value;
- this[offset + 1] = (value >>> 8);
- this[offset + 2] = (value >>> 16);
- this[offset + 3] = (value >>> 24);
- return offset + 4;
-};
-
-
-Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
- value = +value;
- offset = offset >>> 0;
- if (!noAssert)
- checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
- this[offset] = (value >>> 24);
- this[offset + 1] = (value >>> 16);
- this[offset + 2] = (value >>> 8);
- this[offset + 3] = value;
- return offset + 4;
-};
-
-
-function checkFloat(buffer, value, offset, ext) {
- if (!(buffer instanceof Buffer))
- throw new TypeError('buffer must be a Buffer instance');
- if (offset + ext > buffer.length)
- throw new RangeError('index out of range');
+if (process.useOldBuffer) {
+ module.exports = require('internal/buffer_old');
+} else {
+ module.exports = require('internal/buffer_new');
}
-
-
-Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) {
- val = +val;
- offset = offset >>> 0;
- if (!noAssert)
- checkFloat(this, val, offset, 4);
- binding.writeFloatLE(this, val, offset);
- return offset + 4;
-};
-
-
-Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) {
- val = +val;
- offset = offset >>> 0;
- if (!noAssert)
- checkFloat(this, val, offset, 4);
- binding.writeFloatBE(this, val, offset);
- return offset + 4;
-};
-
-
-Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) {
- val = +val;
- offset = offset >>> 0;
- if (!noAssert)
- checkFloat(this, val, offset, 8);
- binding.writeDoubleLE(this, val, offset);
- return offset + 8;
-};
-
-
-Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
- val = +val;
- offset = offset >>> 0;
- if (!noAssert)
- checkFloat(this, val, offset, 8);
- binding.writeDoubleBE(this, val, offset);
- return offset + 8;
-};
-
-// ES6 iterator
-
-var ITERATOR_KIND_KEYS = 1;
-var ITERATOR_KIND_ENTRIES = 3;
-
-function BufferIteratorResult(value, done) {
- this.value = value;
- this.done = done;
-}
-
-var resultCache = new Array(256);
-
-for (var i = 0; i < 256; i++)
- resultCache[i] = Object.freeze(new BufferIteratorResult(i, false));
-
-var finalResult = Object.freeze(new BufferIteratorResult(undefined, true));
-
-function BufferIterator(buffer, kind) {
- this._buffer = buffer;
- this._kind = kind;
- this._index = 0;
-}
-
-BufferIterator.prototype.next = function() {
- var buffer = this._buffer;
- var kind = this._kind;
- var index = this._index;
-
- if (index >= buffer.length)
- return finalResult;
-
- this._index++;
-
- if (kind === ITERATOR_KIND_ENTRIES)
- return new BufferIteratorResult([index, buffer[index]], false);
-
- return new BufferIteratorResult(index, false);
-};
-
-function BufferValueIterator(buffer) {
- BufferIterator.call(this, buffer, null);
-}
-
-BufferValueIterator.prototype.next = function() {
- var buffer = this._buffer;
- var index = this._index;
-
- if (index >= buffer.length)
- return finalResult;
-
- this._index++;
-
- return resultCache[buffer[index]];
-};
-
-
-BufferIterator.prototype[Symbol.iterator] = function() {
- return this;
-};
-
-BufferValueIterator.prototype[Symbol.iterator] =
- BufferIterator.prototype[Symbol.iterator];
-
-Buffer.prototype.keys = function() {
- return new BufferIterator(this, ITERATOR_KIND_KEYS);
-};
-
-Buffer.prototype.entries = function() {
- return new BufferIterator(this, ITERATOR_KIND_ENTRIES);
-};
-
-Buffer.prototype.values = function() {
- return new BufferValueIterator(this);
-};
-
-Buffer.prototype[Symbol.iterator] = Buffer.prototype.values;
diff --git a/lib/internal/buffer_new.js b/lib/internal/buffer_new.js
new file mode 100644
index 00000000000..c082ed8bd57
--- /dev/null
+++ b/lib/internal/buffer_new.js
@@ -0,0 +1,1020 @@
+'use strict';
+
+const binding = process.binding('buffer');
+const internalUtil = require('internal/util');
+
+exports.Buffer = Buffer;
+exports.SlowBuffer = SlowBuffer;
+exports.INSPECT_MAX_BYTES = 50;
+
+
+Buffer.poolSize = 8 * 1024;
+var poolSize, poolOffset, allocPool;
+
+
+function createPool() {
+ poolSize = Buffer.poolSize;
+ allocPool = binding.create(poolSize);
+ poolOffset = 0;
+}
+
+
+function Buffer(arg) {
+ // Common case.
+ if (typeof arg === 'number') {
+ // If less than zero, or NaN.
+ if (arg < 0 || arg !== arg)
+ arg = 0;
+ return allocate(arg);
+ }
+
+ // Slightly less common case.
+ if (typeof arg === 'string') {
+ return fromString(arg, arguments[1]);
+ }
+
+ // Unusual.
+ return fromObject(arg);
+};
+
+Buffer.prototype.__proto__ = Uint8Array.prototype;
+Buffer.__proto__ = Uint8Array;
+
+
+binding.setupBufferJS(Buffer.prototype);
+// Buffer prototype must be past before creating our first pool.
+createPool();
+
+
+function SlowBuffer(length) {
+ if (length < 0)
+ length = 0;
+ return binding.create(length);
+};
+
+SlowBuffer.prototype.__proto__ = Buffer.prototype;
+SlowBuffer.__proto__ = Buffer;
+
+
+function allocate(size) {
+ if (size === 0)
+ return binding.create(0);
+ if (size < (Buffer.poolSize >>> 1)) {
+ if (size > (poolSize - poolOffset))
+ createPool();
+ var b = binding.slice(allocPool, poolOffset, poolOffset + size);
+ poolOffset += size;
+ return b;
+ } else {
+ return binding.create(size);
+ }
+}
+
+
+function fromString(string, encoding) {
+ if (typeof encoding !== 'string' || encoding === '')
+ encoding = 'utf8';
+
+ var length = byteLength(string, encoding);
+ if (length >= (Buffer.poolSize >>> 1))
+ return binding.createFromString(string, encoding);
+
+ if (length > (poolSize - poolOffset))
+ createPool();
+ var actual = allocPool.write(string, poolOffset, encoding);
+ var b = binding.slice(allocPool, poolOffset, poolOffset + actual);
+ poolOffset += actual;
+ return b;
+}
+
+
+function fromObject(obj) {
+ if (obj instanceof Buffer) {
+ var b = allocate(obj.length);
+ obj.copy(b, 0, 0, obj.length);
+ return b;
+ }
+
+ if (Array.isArray(obj)) {
+ var length = obj.length;
+ var b = allocate(length);
+ for (var i = 0; i < length; i++)
+ b[i] = obj[i] & 255;
+ return b;
+ }
+
+ // TODO(trevnorris): This will fail for an actual ArrayBuffer.
+ if (obj.buffer instanceof ArrayBuffer || obj.length) {
+ var length;
+ if (typeof obj.length !== 'number' || obj.length !== obj.length)
+ length = 0;
+ else
+ length = obj.length;
+ var b = allocate(length);
+ for (var i = 0; i < length; i++) {
+ b[i] = obj[i] & 255;
+ }
+ return b;
+ }
+
+ if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
+ var array = obj.data;
+ var b = allocate(array.length);
+ for (var i = 0; i < array.length; i++)
+ b[i] = array[i] & 255;
+ return b;
+ }
+
+ throw new TypeError('must start with number, buffer, array or string');
+}
+
+
+// Static methods
+
+Buffer.isBuffer = function isBuffer(b) {
+ return b instanceof Buffer;
+};
+
+
+Buffer.compare = function compare(a, b) {
+ if (!(a instanceof Buffer) ||
+ !(b instanceof Buffer)) {
+ throw new TypeError('Arguments must be Buffers');
+ }
+
+ if (a === b) {
+ return 0;
+ }
+
+ return binding.compare(a, b);
+};
+
+
+Buffer.isEncoding = function(encoding) {
+ var loweredCase = false;
+ for (;;) {
+ switch (encoding) {
+ case 'hex':
+ case 'utf8':
+ case 'utf-8':
+ case 'ascii':
+ case 'binary':
+ case 'base64':
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ case 'raw':
+ return true;
+
+ default:
+ if (loweredCase)
+ return false;
+ encoding = ('' + encoding).toLowerCase();
+ loweredCase = true;
+ }
+ }
+};
+
+
+Buffer.concat = function(list, length) {
+ if (!Array.isArray(list))
+ throw new TypeError('list argument must be an Array of Buffers.');
+
+ if (list.length === 0)
+ return new Buffer(0);
+ else if (list.length === 1)
+ return list[0];
+
+ if (length === undefined) {
+ length = 0;
+ for (var i = 0; i < list.length; i++)
+ length += list[i].length;
+ } else {
+ length = length >>> 0;
+ }
+
+ 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;
+};
+
+
+function base64ByteLength(str, bytes) {
+ // Handle padding
+ if (str.charCodeAt(bytes - 1) === 0x3D)
+ bytes--;
+ if (bytes > 1 && str.charCodeAt(bytes - 1) === 0x3D)
+ bytes--;
+
+ // Base64 ratio: 3/4
+ return (bytes * 3) >>> 2;
+}
+
+
+function byteLength(string, encoding) {
+ if (typeof string !== 'string')
+ string = '' + string;
+
+ var len = string.length;
+ if (len === 0)
+ return 0;
+
+ // Use a for loop to avoid recursion
+ var loweredCase = false;
+ for (;;) {
+ switch (encoding) {
+ case 'ascii':
+ case 'binary':
+ // Deprecated
+ case 'raw':
+ case 'raws':
+ return len;
+
+ case 'utf8':
+ case 'utf-8':
+ return binding.byteLengthUtf8(string);
+
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return len * 2;
+
+ case 'hex':
+ return len >>> 1;
+
+ case 'base64':
+ return base64ByteLength(string, len);
+
+ default:
+ // The C++ binding defaulted to UTF8, we should too.
+ if (loweredCase)
+ return binding.byteLengthUtf8(string);
+
+ encoding = ('' + encoding).toLowerCase();
+ loweredCase = true;
+ }
+ }
+}
+
+Buffer.byteLength = byteLength;
+
+
+// For backwards compatibility.
+Object.defineProperty(Buffer.prototype, 'parent', {
+ enumerable: true,
+ get: function() {
+ if (this.byteLength === 0 ||
+ this.byteLength === this.buffer.byteLength) {
+ return undefined;
+ }
+ return this.buffer;
+ }
+});
+Object.defineProperty(Buffer.prototype, 'offset', {
+ enumerable: true,
+ get: function() {
+ return this.byteOffset;
+ }
+});
+
+
+// toString(encoding, start=0, end=buffer.length)
+Buffer.prototype.toString = function(encoding, start, end) {
+ var loweredCase = false;
+
+ start = start >>> 0;
+ end = end === undefined || end === Infinity ? this.length : end >>> 0;
+
+ if (!encoding) encoding = 'utf8';
+ if (start < 0) start = 0;
+ if (end > this.length) end = this.length;
+ if (end <= start) return '';
+
+ while (true) {
+ 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':
+ return this.ucs2Slice(start, end);
+
+ default:
+ if (loweredCase)
+ throw new TypeError('Unknown encoding: ' + encoding);
+ encoding = (encoding + '').toLowerCase();
+ loweredCase = true;
+ }
+ }
+};
+
+
+Buffer.prototype.equals = function equals(b) {
+ if (!(b instanceof Buffer))
+ throw new TypeError('Argument must be a Buffer');
+
+ if (this === b)
+ return true;
+
+ return binding.compare(this, b) === 0;
+};
+
+
+// Inspect
+Buffer.prototype.inspect = function inspect() {
+ var str = '';
+ var max = exports.INSPECT_MAX_BYTES;
+ if (this.length > 0) {
+ str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');
+ if (this.length > max)
+ str += ' ... ';
+ }
+ return '<' + this.constructor.name + ' ' + str + '>';
+};
+
+
+Buffer.prototype.compare = function compare(b) {
+ if (!(b instanceof Buffer))
+ throw new TypeError('Argument must be a Buffer');
+
+ if (this === b)
+ return 0;
+
+ return binding.compare(this, b);
+};
+
+
+Buffer.prototype.indexOf = function indexOf(val, byteOffset) {
+ if (byteOffset > 0x7fffffff)
+ byteOffset = 0x7fffffff;
+ else if (byteOffset < -0x80000000)
+ byteOffset = -0x80000000;
+ byteOffset >>= 0;
+
+ if (typeof val === 'string')
+ return binding.indexOfString(this, val, byteOffset);
+ if (val instanceof Buffer)
+ return binding.indexOfBuffer(this, val, byteOffset);
+ if (typeof val === 'number')
+ return binding.indexOfNumber(this, val, byteOffset);
+
+ throw new TypeError('val must be string, number or Buffer');
+};
+
+
+Buffer.prototype.fill = function fill(val, start, end) {
+ start = start >> 0;
+ end = (end === undefined) ? this.length : end >> 0;
+
+ if (start < 0 || end > this.length)
+ throw new RangeError('out of range index');
+ if (end <= start)
+ return this;
+
+ if (typeof val !== 'string') {
+ val = val >>> 0;
+ } else if (val.length === 1) {
+ var code = val.charCodeAt(0);
+ if (code < 256)
+ val = code;
+ }
+
+ binding.fill(this, val, start, end);
+
+ return this;
+};
+
+
+// XXX remove in v0.13
+Buffer.prototype.get = internalUtil.deprecate(function get(offset) {
+ offset = ~~offset;
+ if (offset < 0 || offset >= this.length)
+ throw new RangeError('index out of range');
+ return this[offset];
+}, '.get() is deprecated. Access using array indexes instead.');
+
+
+// XXX remove in v0.13
+Buffer.prototype.set = internalUtil.deprecate(function set(offset, v) {
+ offset = ~~offset;
+ if (offset < 0 || offset >= this.length)
+ throw new RangeError('index out of range');
+ return this[offset] = v;
+}, '.set() is deprecated. Set using array indexes instead.');
+
+
+// TODO(trevnorris): fix these checks to follow new standard
+// write(string, offset = 0, length = buffer.length, encoding = 'utf8')
+var writeWarned = false;
+const writeMsg = '.write(string, encoding, offset, length) is deprecated.' +
+ ' Use write(string[, offset[, length]][, encoding]) instead.';
+Buffer.prototype.write = function(string, offset, length, encoding) {
+ // Buffer#write(string);
+ if (offset === undefined) {
+ encoding = 'utf8';
+ length = this.length;
+ offset = 0;
+
+ // Buffer#write(string, encoding)
+ } else if (length === undefined && typeof offset === 'string') {
+ encoding = offset;
+ length = this.length;
+ offset = 0;
+
+ // Buffer#write(string, offset[, length][, encoding])
+ } else if (isFinite(offset)) {
+ offset = offset >>> 0;
+ if (isFinite(length)) {
+ length = length >>> 0;
+ if (encoding === undefined)
+ encoding = 'utf8';
+ } else {
+ encoding = length;
+ length = undefined;
+ }
+
+ // XXX legacy write(string, encoding, offset, length) - remove in v0.13
+ } else {
+ if (!writeWarned) {
+ if (process.throwDeprecation)
+ throw new Error(writeMsg);
+ else if (process.traceDeprecation)
+ console.trace(writeMsg);
+ else
+ console.error(writeMsg);
+ writeWarned = true;
+ }
+
+ var swap = encoding;
+ encoding = offset;
+ offset = length >>> 0;
+ length = swap;
+ }
+
+ var remaining = this.length - offset;
+ if (length === undefined || length > remaining)
+ length = remaining;
+
+ if (string.length > 0 && (length < 0 || offset < 0))
+ throw new RangeError('attempt to write outside buffer bounds');
+
+ if (!encoding)
+ encoding = 'utf8';
+
+ var loweredCase = false;
+ for (;;) {
+ switch (encoding) {
+ 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':
+ // Warning: maxLength not taken into account in base64Write
+ return this.base64Write(string, offset, length);
+
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return this.ucs2Write(string, offset, length);
+
+ default:
+ if (loweredCase)
+ throw new TypeError('Unknown encoding: ' + encoding);
+ encoding = ('' + encoding).toLowerCase();
+ loweredCase = true;
+ }
+ }
+};
+
+
+Buffer.prototype.toJSON = function() {
+ return {
+ type: 'Buffer',
+ data: Array.prototype.slice.call(this, 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 slice(start, end) {
+ var len = this.length;
+ start = ~~start;
+ end = end === undefined ? len : ~~end;
+
+ if (start < 0) {
+ start += len;
+ if (start < 0)
+ start = 0;
+ } else if (start > len) {
+ start = len;
+ }
+
+ if (end < 0) {
+ end += len;
+ if (end < 0)
+ end = 0;
+ } else if (end > len) {
+ end = len;
+ }
+
+ if (end < start)
+ end = start;
+
+ return binding.slice(this, start, end);
+};
+
+
+function checkOffset(offset, ext, length) {
+ if (offset + ext > length)
+ throw new RangeError('index out of range');
+}
+
+
+Buffer.prototype.readUIntLE = function(offset, byteLength, noAssert) {
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkOffset(offset, byteLength, this.length);
+
+ var val = this[offset];
+ var mul = 1;
+ var i = 0;
+ while (++i < byteLength && (mul *= 0x100))
+ val += this[offset + i] * mul;
+
+ return val;
+};
+
+
+Buffer.prototype.readUIntBE = function(offset, byteLength, noAssert) {
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkOffset(offset, byteLength, this.length);
+
+ var val = this[offset + --byteLength];
+ var mul = 1;
+ while (byteLength > 0 && (mul *= 0x100))
+ val += this[offset + --byteLength] * mul;
+
+ return val;
+};
+
+
+Buffer.prototype.readUInt8 = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 1, this.length);
+ return this[offset];
+};
+
+
+Buffer.prototype.readUInt16LE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ return this[offset] | (this[offset + 1] << 8);
+};
+
+
+Buffer.prototype.readUInt16BE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ return (this[offset] << 8) | this[offset + 1];
+};
+
+
+Buffer.prototype.readUInt32LE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+
+ return ((this[offset]) |
+ (this[offset + 1] << 8) |
+ (this[offset + 2] << 16)) +
+ (this[offset + 3] * 0x1000000);
+};
+
+
+Buffer.prototype.readUInt32BE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+
+ return (this[offset] * 0x1000000) +
+ ((this[offset + 1] << 16) |
+ (this[offset + 2] << 8) |
+ this[offset + 3]);
+};
+
+
+Buffer.prototype.readIntLE = function(offset, byteLength, noAssert) {
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkOffset(offset, byteLength, this.length);
+
+ var val = this[offset];
+ var mul = 1;
+ var i = 0;
+ while (++i < byteLength && (mul *= 0x100))
+ val += this[offset + i] * mul;
+ mul *= 0x80;
+
+ if (val >= mul)
+ val -= Math.pow(2, 8 * byteLength);
+
+ return val;
+};
+
+
+Buffer.prototype.readIntBE = function(offset, byteLength, noAssert) {
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkOffset(offset, byteLength, this.length);
+
+ var i = byteLength;
+ var mul = 1;
+ var val = this[offset + --i];
+ while (i > 0 && (mul *= 0x100))
+ val += this[offset + --i] * mul;
+ mul *= 0x80;
+
+ if (val >= mul)
+ val -= Math.pow(2, 8 * byteLength);
+
+ return val;
+};
+
+
+Buffer.prototype.readInt8 = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 1, this.length);
+ var val = this[offset];
+ return !(val & 0x80) ? val : (0xff - val + 1) * -1;
+};
+
+
+Buffer.prototype.readInt16LE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ var val = this[offset] | (this[offset + 1] << 8);
+ return (val & 0x8000) ? val | 0xFFFF0000 : val;
+};
+
+
+Buffer.prototype.readInt16BE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ var val = this[offset + 1] | (this[offset] << 8);
+ return (val & 0x8000) ? val | 0xFFFF0000 : val;
+};
+
+
+Buffer.prototype.readInt32LE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+
+ return (this[offset]) |
+ (this[offset + 1] << 8) |
+ (this[offset + 2] << 16) |
+ (this[offset + 3] << 24);
+};
+
+
+Buffer.prototype.readInt32BE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+
+ return (this[offset] << 24) |
+ (this[offset + 1] << 16) |
+ (this[offset + 2] << 8) |
+ (this[offset + 3]);
+};
+
+
+Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+ return binding.readFloatLE(this, offset);
+};
+
+
+Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+ return binding.readFloatBE(this, offset);
+};
+
+
+Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 8, this.length);
+ return binding.readDoubleLE(this, offset);
+};
+
+
+Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 8, this.length);
+ return binding.readDoubleBE(this, offset);
+};
+
+
+function checkInt(buffer, value, offset, ext, max, min) {
+ if (!(buffer instanceof Buffer))
+ throw new TypeError('buffer must be a Buffer instance');
+ if (value > max || value < min)
+ throw new TypeError('value is out of bounds');
+ if (offset + ext > buffer.length)
+ throw new RangeError('index out of range');
+}
+
+
+Buffer.prototype.writeUIntLE = function(value, offset, byteLength, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
+
+ var mul = 1;
+ var i = 0;
+ this[offset] = value;
+ while (++i < byteLength && (mul *= 0x100))
+ this[offset + i] = (value / mul) >>> 0;
+
+ return offset + byteLength;
+};
+
+
+Buffer.prototype.writeUIntBE = function(value, offset, byteLength, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
+
+ var i = byteLength - 1;
+ var mul = 1;
+ this[offset + i] = value;
+ while (--i >= 0 && (mul *= 0x100))
+ this[offset + i] = (value / mul) >>> 0;
+
+ return offset + byteLength;
+};
+
+
+Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 1, 0xff, 0);
+ this[offset] = value;
+ return offset + 1;
+};
+
+
+Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0xffff, 0);
+ this[offset] = value;
+ this[offset + 1] = (value >>> 8);
+ return offset + 2;
+};
+
+
+Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0xffff, 0);
+ this[offset] = (value >>> 8);
+ this[offset + 1] = value;
+ return offset + 2;
+};
+
+
+Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0xffffffff, 0);
+ this[offset + 3] = (value >>> 24);
+ this[offset + 2] = (value >>> 16);
+ this[offset + 1] = (value >>> 8);
+ this[offset] = value;
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0xffffffff, 0);
+ this[offset] = (value >>> 24);
+ this[offset + 1] = (value >>> 16);
+ this[offset + 2] = (value >>> 8);
+ this[offset + 3] = value;
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeIntLE = function(value, offset, byteLength, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert) {
+ checkInt(this,
+ value,
+ offset,
+ byteLength,
+ Math.pow(2, 8 * byteLength - 1) - 1,
+ -Math.pow(2, 8 * byteLength - 1));
+ }
+
+ var i = 0;
+ var mul = 1;
+ var sub = value < 0 ? 1 : 0;
+ this[offset] = value;
+ while (++i < byteLength && (mul *= 0x100))
+ this[offset + i] = ((value / mul) >> 0) - sub;
+
+ return offset + byteLength;
+};
+
+
+Buffer.prototype.writeIntBE = function(value, offset, byteLength, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert) {
+ checkInt(this,
+ value,
+ offset,
+ byteLength,
+ Math.pow(2, 8 * byteLength - 1) - 1,
+ -Math.pow(2, 8 * byteLength - 1));
+ }
+
+ var i = byteLength - 1;
+ var mul = 1;
+ var sub = value < 0 ? 1 : 0;
+ this[offset + i] = value;
+ while (--i >= 0 && (mul *= 0x100))
+ this[offset + i] = ((value / mul) >> 0) - sub;
+
+ return offset + byteLength;
+};
+
+
+Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 1, 0x7f, -0x80);
+ this[offset] = value;
+ return offset + 1;
+};
+
+
+Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0x7fff, -0x8000);
+ this[offset] = value;
+ this[offset + 1] = (value >>> 8);
+ return offset + 2;
+};
+
+
+Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0x7fff, -0x8000);
+ this[offset] = (value >>> 8);
+ this[offset + 1] = value;
+ return offset + 2;
+};
+
+
+Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
+ this[offset] = value;
+ this[offset + 1] = (value >>> 8);
+ this[offset + 2] = (value >>> 16);
+ this[offset + 3] = (value >>> 24);
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
+ this[offset] = (value >>> 24);
+ this[offset + 1] = (value >>> 16);
+ this[offset + 2] = (value >>> 8);
+ this[offset + 3] = value;
+ return offset + 4;
+};
+
+
+function checkFloat(buffer, value, offset, ext) {
+ if (!(buffer instanceof Buffer))
+ throw new TypeError('buffer must be a Buffer instance');
+ if (offset + ext > buffer.length)
+ throw new RangeError('index out of range');
+}
+
+
+Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) {
+ val = +val;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkFloat(this, val, offset, 4);
+ binding.writeFloatLE(this, val, offset);
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) {
+ val = +val;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkFloat(this, val, offset, 4);
+ binding.writeFloatBE(this, val, offset);
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) {
+ val = +val;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkFloat(this, val, offset, 8);
+ binding.writeDoubleLE(this, val, offset);
+ return offset + 8;
+};
+
+
+Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
+ val = +val;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkFloat(this, val, offset, 8);
+ binding.writeDoubleBE(this, val, offset);
+ return offset + 8;
+};
diff --git a/lib/internal/buffer_old.js b/lib/internal/buffer_old.js
new file mode 100644
index 00000000000..d892fd67a23
--- /dev/null
+++ b/lib/internal/buffer_old.js
@@ -0,0 +1,1140 @@
+'use strict';
+
+const binding = process.binding('buffer');
+const smalloc = process.binding('smalloc');
+const internalUtil = require('internal/util');
+const alloc = smalloc.alloc;
+const truncate = smalloc.truncate;
+const sliceOnto = smalloc.sliceOnto;
+const kMaxLength = smalloc.kMaxLength;
+
+exports.Buffer = Buffer;
+exports.SlowBuffer = SlowBuffer;
+exports.INSPECT_MAX_BYTES = 50;
+
+
+Buffer.poolSize = 8 * 1024;
+var poolSize, poolOffset, allocPool;
+
+
+function createPool() {
+ poolSize = Buffer.poolSize;
+ allocPool = alloc({}, poolSize);
+ poolOffset = 0;
+}
+createPool();
+
+function Buffer(arg) {
+ if (!(this instanceof Buffer)) {
+ // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
+ if (arguments.length > 1)
+ return new Buffer(arg, arguments[1]);
+
+ return new Buffer(arg);
+ }
+
+ this.length = 0;
+ this.parent = undefined;
+
+ // Common case.
+ if (typeof(arg) === 'number') {
+ fromNumber(this, arg);
+ return;
+ }
+
+ // Slightly less common case.
+ if (typeof(arg) === 'string') {
+ fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8');
+ return;
+ }
+
+ // Unusual.
+ fromObject(this, arg);
+}
+
+function fromNumber(that, length) {
+ allocate(that, length < 0 ? 0 : checked(length) | 0);
+}
+
+function fromString(that, string, encoding) {
+ if (typeof(encoding) !== 'string' || encoding === '')
+ encoding = 'utf8';
+
+ // Assumption: byteLength() return value is always < kMaxLength.
+ var length = byteLength(string, encoding) | 0;
+ allocate(that, length);
+
+ var actual = that.write(string, encoding) | 0;
+ if (actual !== length) {
+ // Fix up for truncated base64 input. Don't bother returning
+ // the unused two or three bytes to the pool.
+ that.length = actual;
+ truncate(that, actual);
+ }
+}
+
+function fromObject(that, object) {
+ if (object instanceof Buffer)
+ return fromBuffer(that, object);
+
+ if (Array.isArray(object))
+ return fromArray(that, object);
+
+ if (object == null)
+ throw new TypeError('must start with number, buffer, array or string');
+
+ if (object.buffer instanceof ArrayBuffer)
+ return fromTypedArray(that, object);
+
+ if (object.length)
+ return fromArrayLike(that, object);
+
+ return fromJsonObject(that, object);
+}
+
+function fromBuffer(that, buffer) {
+ var length = checked(buffer.length) | 0;
+ allocate(that, length);
+ buffer.copy(that, 0, 0, length);
+}
+
+function fromArray(that, array) {
+ var length = checked(array.length) | 0;
+ allocate(that, length);
+ for (var i = 0; i < length; i += 1)
+ that[i] = array[i] & 255;
+}
+
+// Duplicate of fromArray() to keep fromArray() monomorphic.
+function fromTypedArray(that, array) {
+ var length = checked(array.length) | 0;
+ allocate(that, length);
+ // Truncating the elements is probably not what people expect from typed
+ // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
+ // of the old Buffer constructor.
+ for (var i = 0; i < length; i += 1)
+ that[i] = array[i] & 255;
+}
+
+function fromArrayLike(that, array) {
+ var length = checked(array.length) | 0;
+ allocate(that, length);
+ for (var i = 0; i < length; i += 1)
+ that[i] = array[i] & 255;
+}
+
+// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
+// Returns a zero-length buffer for inputs that don't conform to the spec.
+function fromJsonObject(that, object) {
+ var array;
+ var length = 0;
+
+ if (object.type === 'Buffer' && Array.isArray(object.data)) {
+ array = object.data;
+ length = checked(array.length) | 0;
+ }
+ allocate(that, length);
+
+ for (var i = 0; i < length; i += 1)
+ that[i] = array[i] & 255;
+}
+
+function allocate(that, length) {
+ var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1;
+ if (fromPool)
+ that.parent = palloc(that, length);
+ else
+ alloc(that, length);
+ that.length = length;
+}
+
+function palloc(that, length) {
+ if (length > poolSize - poolOffset)
+ createPool();
+
+ var start = poolOffset;
+ var end = start + length;
+ var buf = sliceOnto(allocPool, that, start, end);
+ poolOffset = end;
+
+ // Ensure aligned slices
+ if (poolOffset & 0x7) {
+ poolOffset |= 0x7;
+ poolOffset++;
+ }
+
+ return buf;
+}
+
+function checked(length) {
+ // Note: cannot use `length < kMaxLength` here because that fails when
+ // length is NaN (which is otherwise coerced to zero.)
+ if (length >= kMaxLength) {
+ throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+ 'size: 0x' + kMaxLength.toString(16) + ' bytes');
+ }
+ return length >>> 0;
+}
+
+function SlowBuffer(length) {
+ length = length >>> 0;
+ if (length > kMaxLength) {
+ throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+ 'size: 0x' + kMaxLength.toString(16) + ' bytes');
+ }
+ var b = new NativeBuffer(length);
+ alloc(b, length);
+ return b;
+}
+
+
+// Bypass all checks for instantiating unallocated Buffer required for
+// Objects created in C++. Significantly faster than calling the Buffer
+// function.
+function NativeBuffer(length) {
+ this.length = length >>> 0;
+ // Set this to keep the object map the same.
+ this.parent = undefined;
+}
+NativeBuffer.prototype = Buffer.prototype;
+
+
+// add methods to Buffer prototype
+binding.setupBufferJS(NativeBuffer);
+
+
+// Static methods
+
+Buffer.isBuffer = function isBuffer(b) {
+ return b instanceof Buffer;
+};
+
+
+Buffer.compare = function compare(a, b) {
+ if (!(a instanceof Buffer) ||
+ !(b instanceof Buffer))
+ throw new TypeError('Arguments must be Buffers');
+
+ if (a === b)
+ return 0;
+
+ return binding.compare(a, b);
+};
+
+
+Buffer.isEncoding = function(encoding) {
+ switch ((encoding + '').toLowerCase()) {
+ case 'hex':
+ case 'utf8':
+ case 'utf-8':
+ case 'ascii':
+ case 'binary':
+ case 'base64':
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ case 'raw':
+ return true;
+
+ default:
+ return false;
+ }
+};
+
+
+Buffer.concat = function(list, length) {
+ if (!Array.isArray(list))
+ throw new TypeError('list argument must be an Array of Buffers.');
+
+ if (list.length === 0)
+ return new Buffer(0);
+ else if (list.length === 1)
+ return list[0];
+
+ if (length === undefined) {
+ length = 0;
+ for (var i = 0; i < list.length; i++)
+ length += list[i].length;
+ } else {
+ length = length >>> 0;
+ }
+
+ 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;
+};
+
+
+function base64ByteLength(str, bytes) {
+ // Handle padding
+ if (str.charCodeAt(bytes - 1) === 0x3D)
+ bytes--;
+ if (bytes > 1 && str.charCodeAt(bytes - 1) === 0x3D)
+ bytes--;
+
+ // Base64 ratio: 3/4
+ return (bytes * 3) >>> 2;
+}
+
+
+function byteLength(string, encoding) {
+ if (typeof string !== 'string')
+ string = '' + string;
+
+ var len = string.length;
+ if (len === 0)
+ return 0;
+
+ // Use a for loop to avoid recursion
+ var loweredCase = false;
+ for (;;) {
+ switch (encoding) {
+ case 'ascii':
+ case 'binary':
+ // Deprecated
+ case 'raw':
+ case 'raws':
+ return len;
+
+ case 'utf8':
+ case 'utf-8':
+ return binding.byteLengthUtf8(string);
+
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return len * 2;
+
+ case 'hex':
+ return len >>> 1;
+
+ case 'base64':
+ return base64ByteLength(string, len);
+
+ default:
+ // The C++ binding defaulted to UTF8, we should too.
+ if (loweredCase)
+ return binding.byteLengthUtf8(string);
+
+ encoding = ('' + encoding).toLowerCase();
+ loweredCase = true;
+ }
+ }
+}
+
+Buffer.byteLength = byteLength;
+
+// toString(encoding, start=0, end=buffer.length)
+Buffer.prototype.toString = function(encoding, start, end) {
+ var loweredCase = false;
+
+ start = start >>> 0;
+ end = end === undefined || end === Infinity ? this.length : end >>> 0;
+
+ if (!encoding) encoding = 'utf8';
+ if (start < 0) start = 0;
+ if (end > this.length) end = this.length;
+ if (end <= start) return '';
+
+ while (true) {
+ 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':
+ return this.ucs2Slice(start, end);
+
+ default:
+ if (loweredCase)
+ throw new TypeError('Unknown encoding: ' + encoding);
+ encoding = (encoding + '').toLowerCase();
+ loweredCase = true;
+ }
+ }
+};
+
+
+Buffer.prototype.equals = function equals(b) {
+ if (!(b instanceof Buffer))
+ throw new TypeError('Argument must be a Buffer');
+
+ if (this === b)
+ return true;
+
+ return binding.compare(this, b) === 0;
+};
+
+
+// Inspect
+Buffer.prototype.inspect = function inspect() {
+ var str = '';
+ var max = exports.INSPECT_MAX_BYTES;
+ if (this.length > 0) {
+ str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');
+ if (this.length > max)
+ str += ' ... ';
+ }
+ return '<' + this.constructor.name + ' ' + str + '>';
+};
+
+
+Buffer.prototype.compare = function compare(b) {
+ if (!(b instanceof Buffer))
+ throw new TypeError('Argument must be a Buffer');
+
+ if (this === b)
+ return 0;
+
+ return binding.compare(this, b);
+};
+
+
+Buffer.prototype.indexOf = function indexOf(val, byteOffset) {
+ if (byteOffset > 0x7fffffff)
+ byteOffset = 0x7fffffff;
+ else if (byteOffset < -0x80000000)
+ byteOffset = -0x80000000;
+ byteOffset >>= 0;
+
+ if (typeof val === 'string')
+ return binding.indexOfString(this, val, byteOffset);
+ if (val instanceof Buffer)
+ return binding.indexOfBuffer(this, val, byteOffset);
+ if (typeof val === 'number')
+ return binding.indexOfNumber(this, val, byteOffset);
+
+ throw new TypeError('val must be string, number or Buffer');
+};
+
+
+Buffer.prototype.fill = function fill(val, start, end) {
+ start = start >> 0;
+ end = (end === undefined) ? this.length : end >> 0;
+
+ if (start < 0 || end > this.length)
+ throw new RangeError('out of range index');
+ if (end <= start)
+ return this;
+
+ if (typeof val !== 'string') {
+ val = val >>> 0;
+ } else if (val.length === 1) {
+ var code = val.charCodeAt(0);
+ if (code < 256)
+ val = code;
+ }
+
+ binding.fill(this, val, start, end);
+
+ return this;
+};
+
+
+// XXX remove in v0.13
+Buffer.prototype.get = internalUtil.deprecate(function get(offset) {
+ offset = ~~offset;
+ if (offset < 0 || offset >= this.length)
+ throw new RangeError('index out of range');
+ return this[offset];
+}, '.get() is deprecated. Access using array indexes instead.');
+
+
+// XXX remove in v0.13
+Buffer.prototype.set = internalUtil.deprecate(function set(offset, v) {
+ offset = ~~offset;
+ if (offset < 0 || offset >= this.length)
+ throw new RangeError('index out of range');
+ return this[offset] = v;
+}, '.set() is deprecated. Set using array indexes instead.');
+
+
+// TODO(trevnorris): fix these checks to follow new standard
+// write(string, offset = 0, length = buffer.length, encoding = 'utf8')
+var writeWarned = false;
+const writeMsg = '.write(string, encoding, offset, length) is deprecated.' +
+ ' Use write(string[, offset[, length]][, encoding]) instead.';
+Buffer.prototype.write = function(string, offset, length, encoding) {
+ // Buffer#write(string);
+ if (offset === undefined) {
+ encoding = 'utf8';
+ length = this.length;
+ offset = 0;
+
+ // Buffer#write(string, encoding)
+ } else if (length === undefined && typeof offset === 'string') {
+ encoding = offset;
+ length = this.length;
+ offset = 0;
+
+ // Buffer#write(string, offset[, length][, encoding])
+ } else if (isFinite(offset)) {
+ offset = offset >>> 0;
+ if (isFinite(length)) {
+ length = length >>> 0;
+ if (encoding === undefined)
+ encoding = 'utf8';
+ } else {
+ encoding = length;
+ length = undefined;
+ }
+
+ // XXX legacy write(string, encoding, offset, length) - remove in v0.13
+ } else {
+ writeWarned = internalUtil.printDeprecationMessage(writeMsg, writeWarned);
+ var swap = encoding;
+ encoding = offset;
+ offset = length >>> 0;
+ length = swap;
+ }
+
+ var remaining = this.length - offset;
+ if (length === undefined || length > remaining)
+ length = remaining;
+
+ if (string.length > 0 && (length < 0 || offset < 0))
+ throw new RangeError('attempt to write outside buffer bounds');
+
+ if (!encoding)
+ encoding = 'utf8';
+
+ var loweredCase = false;
+ for (;;) {
+ switch (encoding) {
+ 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':
+ // Warning: maxLength not taken into account in base64Write
+ return this.base64Write(string, offset, length);
+
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return this.ucs2Write(string, offset, length);
+
+ default:
+ if (loweredCase)
+ throw new TypeError('Unknown encoding: ' + encoding);
+ encoding = ('' + encoding).toLowerCase();
+ loweredCase = true;
+ }
+ }
+};
+
+
+Buffer.prototype.toJSON = function() {
+ return {
+ type: 'Buffer',
+ data: Array.prototype.slice.call(this, 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 = end === undefined ? len : ~~end;
+
+ if (start < 0) {
+ start += len;
+ if (start < 0)
+ start = 0;
+ } else if (start > len) {
+ start = len;
+ }
+
+ if (end < 0) {
+ end += len;
+ if (end < 0)
+ end = 0;
+ } else if (end > len) {
+ end = len;
+ }
+
+ if (end < start)
+ end = start;
+
+ var buf = new NativeBuffer();
+ sliceOnto(this, buf, start, end);
+ buf.length = end - start;
+ if (buf.length > 0)
+ buf.parent = this.parent === undefined ? this : this.parent;
+
+ return buf;
+};
+
+
+function checkOffset(offset, ext, length) {
+ if (offset + ext > length)
+ throw new RangeError('index out of range');
+}
+
+
+Buffer.prototype.readUIntLE = function(offset, byteLength, noAssert) {
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkOffset(offset, byteLength, this.length);
+
+ var val = this[offset];
+ var mul = 1;
+ var i = 0;
+ while (++i < byteLength && (mul *= 0x100))
+ val += this[offset + i] * mul;
+
+ return val;
+};
+
+
+Buffer.prototype.readUIntBE = function(offset, byteLength, noAssert) {
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkOffset(offset, byteLength, this.length);
+
+ var val = this[offset + --byteLength];
+ var mul = 1;
+ while (byteLength > 0 && (mul *= 0x100))
+ val += this[offset + --byteLength] * mul;
+
+ return val;
+};
+
+
+Buffer.prototype.readUInt8 = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 1, this.length);
+ return this[offset];
+};
+
+
+Buffer.prototype.readUInt16LE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ return this[offset] | (this[offset + 1] << 8);
+};
+
+
+Buffer.prototype.readUInt16BE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ return (this[offset] << 8) | this[offset + 1];
+};
+
+
+Buffer.prototype.readUInt32LE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+
+ return ((this[offset]) |
+ (this[offset + 1] << 8) |
+ (this[offset + 2] << 16)) +
+ (this[offset + 3] * 0x1000000);
+};
+
+
+Buffer.prototype.readUInt32BE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+
+ return (this[offset] * 0x1000000) +
+ ((this[offset + 1] << 16) |
+ (this[offset + 2] << 8) |
+ this[offset + 3]);
+};
+
+
+Buffer.prototype.readIntLE = function(offset, byteLength, noAssert) {
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkOffset(offset, byteLength, this.length);
+
+ var val = this[offset];
+ var mul = 1;
+ var i = 0;
+ while (++i < byteLength && (mul *= 0x100))
+ val += this[offset + i] * mul;
+ mul *= 0x80;
+
+ if (val >= mul)
+ val -= Math.pow(2, 8 * byteLength);
+
+ return val;
+};
+
+
+Buffer.prototype.readIntBE = function(offset, byteLength, noAssert) {
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkOffset(offset, byteLength, this.length);
+
+ var i = byteLength;
+ var mul = 1;
+ var val = this[offset + --i];
+ while (i > 0 && (mul *= 0x100))
+ val += this[offset + --i] * mul;
+ mul *= 0x80;
+
+ if (val >= mul)
+ val -= Math.pow(2, 8 * byteLength);
+
+ return val;
+};
+
+
+Buffer.prototype.readInt8 = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 1, this.length);
+ var val = this[offset];
+ return !(val & 0x80) ? val : (0xff - val + 1) * -1;
+};
+
+
+Buffer.prototype.readInt16LE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ var val = this[offset] | (this[offset + 1] << 8);
+ return (val & 0x8000) ? val | 0xFFFF0000 : val;
+};
+
+
+Buffer.prototype.readInt16BE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 2, this.length);
+ var val = this[offset + 1] | (this[offset] << 8);
+ return (val & 0x8000) ? val | 0xFFFF0000 : val;
+};
+
+
+Buffer.prototype.readInt32LE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+
+ return (this[offset]) |
+ (this[offset + 1] << 8) |
+ (this[offset + 2] << 16) |
+ (this[offset + 3] << 24);
+};
+
+
+Buffer.prototype.readInt32BE = function(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+
+ return (this[offset] << 24) |
+ (this[offset + 1] << 16) |
+ (this[offset + 2] << 8) |
+ (this[offset + 3]);
+};
+
+
+Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+ return binding.readFloatLE(this, offset);
+};
+
+
+Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 4, this.length);
+ return binding.readFloatBE(this, offset);
+};
+
+
+Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 8, this.length);
+ return binding.readDoubleLE(this, offset);
+};
+
+
+Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkOffset(offset, 8, this.length);
+ return binding.readDoubleBE(this, offset);
+};
+
+
+function checkInt(buffer, value, offset, ext, max, min) {
+ if (!(buffer instanceof Buffer))
+ throw new TypeError('buffer must be a Buffer instance');
+ if (value > max || value < min)
+ throw new TypeError('value is out of bounds');
+ if (offset + ext > buffer.length)
+ throw new RangeError('index out of range');
+}
+
+
+Buffer.prototype.writeUIntLE = function(value, offset, byteLength, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
+
+ var mul = 1;
+ var i = 0;
+ this[offset] = value;
+ while (++i < byteLength && (mul *= 0x100))
+ this[offset + i] = (value / mul) >>> 0;
+
+ return offset + byteLength;
+};
+
+
+Buffer.prototype.writeUIntBE = function(value, offset, byteLength, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ byteLength = byteLength >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
+
+ var i = byteLength - 1;
+ var mul = 1;
+ this[offset + i] = value;
+ while (--i >= 0 && (mul *= 0x100))
+ this[offset + i] = (value / mul) >>> 0;
+
+ return offset + byteLength;
+};
+
+
+Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 1, 0xff, 0);
+ this[offset] = value;
+ return offset + 1;
+};
+
+
+Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0xffff, 0);
+ this[offset] = value;
+ this[offset + 1] = (value >>> 8);
+ return offset + 2;
+};
+
+
+Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0xffff, 0);
+ this[offset] = (value >>> 8);
+ this[offset + 1] = value;
+ return offset + 2;
+};
+
+
+Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0xffffffff, 0);
+ this[offset + 3] = (value >>> 24);
+ this[offset + 2] = (value >>> 16);
+ this[offset + 1] = (value >>> 8);
+ this[offset] = value;
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0xffffffff, 0);
+ this[offset] = (value >>> 24);
+ this[offset + 1] = (value >>> 16);
+ this[offset + 2] = (value >>> 8);
+ this[offset + 3] = value;
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeIntLE = function(value, offset, byteLength, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert) {
+ checkInt(this,
+ value,
+ offset,
+ byteLength,
+ Math.pow(2, 8 * byteLength - 1) - 1,
+ -Math.pow(2, 8 * byteLength - 1));
+ }
+
+ var i = 0;
+ var mul = 1;
+ var sub = value < 0 ? 1 : 0;
+ this[offset] = value;
+ while (++i < byteLength && (mul *= 0x100))
+ this[offset + i] = ((value / mul) >> 0) - sub;
+
+ return offset + byteLength;
+};
+
+
+Buffer.prototype.writeIntBE = function(value, offset, byteLength, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert) {
+ checkInt(this,
+ value,
+ offset,
+ byteLength,
+ Math.pow(2, 8 * byteLength - 1) - 1,
+ -Math.pow(2, 8 * byteLength - 1));
+ }
+
+ var i = byteLength - 1;
+ var mul = 1;
+ var sub = value < 0 ? 1 : 0;
+ this[offset + i] = value;
+ while (--i >= 0 && (mul *= 0x100))
+ this[offset + i] = ((value / mul) >> 0) - sub;
+
+ return offset + byteLength;
+};
+
+
+Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 1, 0x7f, -0x80);
+ this[offset] = value;
+ return offset + 1;
+};
+
+
+Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0x7fff, -0x8000);
+ this[offset] = value;
+ this[offset + 1] = (value >>> 8);
+ return offset + 2;
+};
+
+
+Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 2, 0x7fff, -0x8000);
+ this[offset] = (value >>> 8);
+ this[offset + 1] = value;
+ return offset + 2;
+};
+
+
+Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
+ this[offset] = value;
+ this[offset + 1] = (value >>> 8);
+ this[offset + 2] = (value >>> 16);
+ this[offset + 3] = (value >>> 24);
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
+ value = +value;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
+ this[offset] = (value >>> 24);
+ this[offset + 1] = (value >>> 16);
+ this[offset + 2] = (value >>> 8);
+ this[offset + 3] = value;
+ return offset + 4;
+};
+
+
+function checkFloat(buffer, value, offset, ext) {
+ if (!(buffer instanceof Buffer))
+ throw new TypeError('buffer must be a Buffer instance');
+ if (offset + ext > buffer.length)
+ throw new RangeError('index out of range');
+}
+
+
+Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) {
+ val = +val;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkFloat(this, val, offset, 4);
+ binding.writeFloatLE(this, val, offset);
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) {
+ val = +val;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkFloat(this, val, offset, 4);
+ binding.writeFloatBE(this, val, offset);
+ return offset + 4;
+};
+
+
+Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) {
+ val = +val;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkFloat(this, val, offset, 8);
+ binding.writeDoubleLE(this, val, offset);
+ return offset + 8;
+};
+
+
+Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
+ val = +val;
+ offset = offset >>> 0;
+ if (!noAssert)
+ checkFloat(this, val, offset, 8);
+ binding.writeDoubleBE(this, val, offset);
+ return offset + 8;
+};
+
+// ES6 iterator
+
+var ITERATOR_KIND_KEYS = 1;
+var ITERATOR_KIND_ENTRIES = 3;
+
+function BufferIteratorResult(value, done) {
+ this.value = value;
+ this.done = done;
+}
+
+var resultCache = new Array(256);
+
+for (var i = 0; i < 256; i++)
+ resultCache[i] = Object.freeze(new BufferIteratorResult(i, false));
+
+var finalResult = Object.freeze(new BufferIteratorResult(undefined, true));
+
+function BufferIterator(buffer, kind) {
+ this._buffer = buffer;
+ this._kind = kind;
+ this._index = 0;
+}
+
+BufferIterator.prototype.next = function() {
+ var buffer = this._buffer;
+ var kind = this._kind;
+ var index = this._index;
+
+ if (index >= buffer.length)
+ return finalResult;
+
+ this._index++;
+
+ if (kind === ITERATOR_KIND_ENTRIES)
+ return new BufferIteratorResult([index, buffer[index]], false);
+
+ return new BufferIteratorResult(index, false);
+};
+
+function BufferValueIterator(buffer) {
+ BufferIterator.call(this, buffer, null);
+}
+
+BufferValueIterator.prototype.next = function() {
+ var buffer = this._buffer;
+ var index = this._index;
+
+ if (index >= buffer.length)
+ return finalResult;
+
+ this._index++;
+
+ return resultCache[buffer[index]];
+};
+
+
+BufferIterator.prototype[Symbol.iterator] = function() {
+ return this;
+};
+
+BufferValueIterator.prototype[Symbol.iterator] =
+ BufferIterator.prototype[Symbol.iterator];
+
+Buffer.prototype.keys = function() {
+ return new BufferIterator(this, ITERATOR_KIND_KEYS);
+};
+
+Buffer.prototype.entries = function() {
+ return new BufferIterator(this, ITERATOR_KIND_ENTRIES);
+};
+
+Buffer.prototype.values = function() {
+ return new BufferValueIterator(this);
+};
+
+Buffer.prototype[Symbol.iterator] = Buffer.prototype.values;
diff --git a/node.gyp b/node.gyp
index dfa08ce6468..197f439f8d8 100644
--- a/node.gyp
+++ b/node.gyp
@@ -69,8 +69,9 @@
'lib/v8.js',
'lib/vm.js',
'lib/zlib.js',
-
'lib/internal/child_process.js',
+ 'lib/internal/buffer_old.js',
+ 'lib/internal/buffer_new.js',
'lib/internal/freelist.js',
'lib/internal/smalloc.js',
'lib/internal/socket_list.js',
diff --git a/src/env.h b/src/env.h
index 72895219a93..84beabcdbfa 100644
--- a/src/env.h
+++ b/src/env.h
@@ -231,6 +231,7 @@ namespace node {
V(async_hooks_post_function, v8::Function) \
V(binding_cache_object, v8::Object) \
V(buffer_constructor_function, v8::Function) \
+ V(buffer_prototype_object, v8::Object) \
V(context, v8::Context) \
V(domain_array, v8::Array) \
V(fs_stats_constructor_function, v8::Function) \
diff --git a/src/node.cc b/src/node.cc
index 631a595c6a2..4d699e8f288 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -5,6 +5,7 @@
#include "node_http_parser.h"
#include "node_javascript.h"
#include "node_version.h"
+#include "node_internals.h"
#if defined HAVE_PERFCTR
#include "node_counters.h"
@@ -147,6 +148,8 @@ static uv_async_t dispatch_debug_messages_async;
static Isolate* node_isolate = nullptr;
static v8::Platform* default_platform;
+bool using_old_buffer = false;
+
class ArrayBufferAllocator : public ArrayBuffer::Allocator {
public:
// Impose an upper limit to avoid out of memory errors that bring down
@@ -166,23 +169,17 @@ ArrayBufferAllocator ArrayBufferAllocator::the_singleton;
void* ArrayBufferAllocator::Allocate(size_t length) {
- if (length > kMaxLength)
- return nullptr;
- char* data = new char[length];
- memset(data, 0, length);
- return data;
+ return calloc(length, 1);
}
void* ArrayBufferAllocator::AllocateUninitialized(size_t length) {
- if (length > kMaxLength)
- return nullptr;
- return new char[length];
+ return malloc(length);
}
void ArrayBufferAllocator::Free(void* data, size_t length) {
- delete[] static_cast<char*>(data);
+ free(data);
}
@@ -2836,6 +2833,11 @@ void SetupProcessObject(Environment* env,
READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
}
+ // --use-old_buffer
+ if (using_old_buffer) {
+ READONLY_PROPERTY(process, "useOldBuffer", True(env->isolate()));
+ }
+
size_t exec_path_len = 2 * PATH_MAX;
char* exec_path = new char[exec_path_len];
Local<String> exec_path_value;
@@ -3067,6 +3069,7 @@ static void PrintHelp() {
" --track-heap-objects track heap object allocations for heap "
"snapshots\n"
" --v8-options print v8 command line options\n"
+ " --use-old-buffer Revert to old Buffer implementation\n"
#if defined(NODE_HAVE_I18N_SUPPORT)
" --icu-data-dir=dir set ICU data load path to dir\n"
" (overrides NODE_ICU_DATA)\n"
@@ -3204,6 +3207,10 @@ static void ParseArgs(int* argc,
#endif
} else if (strcmp(arg, "--expose-internals") == 0 ||
strcmp(arg, "--expose_internals") == 0) {
+ } else if (strcmp(arg, "--use-old-buffer") == 0 ||
+ strcmp(arg, "--use_old_buffer") == 0) {
+ using_old_buffer = true;
+
// consumed in js
} else {
// V8 option. Pass through as-is.
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index 3f429817e13..d3398075d06 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -5,6 +5,8 @@
#include "env-inl.h"
#include "smalloc.h"
#include "string_bytes.h"
+#include "util.h"
+#include "util-inl.h"
#include "v8-profiler.h"
#include "v8.h"
@@ -28,6 +30,16 @@
size_t name##_length; \
char* name##_data;
+#define SPREAD_ARG(val, name) \
+ CHECK((val)->IsUint8Array()); \
+ Local<Uint8Array> name = (val).As<Uint8Array>(); \
+ ArrayBuffer::Contents name##_c = name->Buffer()->GetContents(); \
+ size_t name##_offset = name->ByteOffset(); \
+ name##_length = name->ByteLength(); \
+ name##_data = static_cast<char*>(name##_c.Data()) + name##_offset; \
+ if (name##_length > 0) \
+ CHECK_NE(name##_data, nullptr);
+
#define ARGS_THIS(argT, name) \
Local<Object> name = argT; \
name##_length = name->GetIndexedPropertiesExternalArrayDataLength(); \
@@ -48,6 +60,8 @@
namespace node {
namespace Buffer {
+using v8::ArrayBuffer;
+using v8::ArrayBufferCreationMode;
using v8::Context;
using v8::EscapableHandleScope;
using v8::Function;
@@ -61,6 +75,7 @@ using v8::Number;
using v8::Object;
using v8::String;
using v8::Uint32;
+using v8::Uint8Array;
using v8::Value;
@@ -70,10 +85,19 @@ bool HasInstance(Handle<Value> val) {
bool HasInstance(Handle<Object> obj) {
- if (!obj->HasIndexedPropertiesInExternalArrayData())
+ if (using_old_buffer) {
+ if (!obj->HasIndexedPropertiesInExternalArrayData())
+ return false;
+ v8::ExternalArrayType type =
+ obj->GetIndexedPropertiesExternalArrayDataType();
+ return type == v8::kExternalUint8Array;
+ }
+
+ if (!obj->IsUint8Array())
return false;
- v8::ExternalArrayType type = obj->GetIndexedPropertiesExternalArrayDataType();
- return type == v8::kExternalUint8Array;
+ Local<Uint8Array> array = obj.As<Uint8Array>();
+ Environment* env = Environment::GetCurrent(array->GetIsolate());
+ return array->GetPrototype()->StrictEquals(env->buffer_prototype_object());
}
@@ -86,8 +110,15 @@ char* Data(Handle<Value> val) {
char* Data(Handle<Object> obj) {
- CHECK(obj->HasIndexedPropertiesInExternalArrayData());
- return static_cast<char*>(obj->GetIndexedPropertiesExternalArrayData());
+ if (using_old_buffer) {
+ CHECK(obj->HasIndexedPropertiesInExternalArrayData());
+ return static_cast<char*>(obj->GetIndexedPropertiesExternalArrayData());
+ }
+
+ CHECK(obj->IsUint8Array());
+ Local<Uint8Array> ui = obj.As<Uint8Array>();
+ ArrayBuffer::Contents ab_c = ui->Buffer()->GetContents();
+ return static_cast<char*>(ab_c.Data()) + ui->ByteOffset();
}
@@ -98,8 +129,14 @@ size_t Length(Handle<Value> val) {
size_t Length(Handle<Object> obj) {
- CHECK(obj->HasIndexedPropertiesInExternalArrayData());
- return obj->GetIndexedPropertiesExternalArrayDataLength();
+ if (using_old_buffer) {
+ CHECK(obj->HasIndexedPropertiesInExternalArrayData());
+ return obj->GetIndexedPropertiesExternalArrayDataLength();
+ }
+
+ CHECK(obj->IsUint8Array());
+ Local<Uint8Array> ui = obj.As<Uint8Array>();
+ return ui->ByteLength();
}
@@ -107,11 +144,20 @@ Local<Object> New(Isolate* isolate, Handle<String> string, enum encoding enc) {
EscapableHandleScope scope(isolate);
size_t length = StringBytes::Size(isolate, string, enc);
+ char* data = static_cast<char*>(malloc(length));
- Local<Object> buf = New(isolate, length);
- char* data = Buffer::Data(buf);
- StringBytes::Write(isolate, data, length, string, enc);
+ if (data == nullptr)
+ return Local<Object>();
+ size_t actual = StringBytes::Write(isolate, data, length, string, enc);
+ CHECK(actual <= length);
+
+ if (actual < length) {
+ data = static_cast<char*>(realloc(data, actual));
+ CHECK_NE(data, nullptr);
+ }
+
+ Local<Object> buf = Use(isolate, data, actual);
return scope.Escape(buf);
}
@@ -123,19 +169,44 @@ Local<Object> New(Isolate* isolate, size_t length) {
}
-// TODO(trevnorris): these have a flaw by needing to call the Buffer inst then
-// Alloc. continue to look for a better architecture.
Local<Object> New(Environment* env, size_t length) {
EscapableHandleScope scope(env->isolate());
- CHECK_LE(length, kMaxLength);
+ if (using_old_buffer) {
+ CHECK_LE(length, kMaxLength);
- Local<Value> arg = Uint32::NewFromUnsigned(env->isolate(), length);
- Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
+ Local<Value> arg = Uint32::NewFromUnsigned(env->isolate(), length);
+ Local<Object> obj =
+ env->buffer_constructor_function()->NewInstance(1, &arg);
- smalloc::Alloc(env, obj, length);
+ smalloc::Alloc(env, obj, length);
- return scope.Escape(obj);
+ return scope.Escape(obj);
+ }
+
+ // V8 currently only allows a maximum Typed Array index of max Smi.
+ if (!IsValidSmi(length)) {
+ return Local<Object>();
+ }
+
+ void* data;
+ if (length > 0) {
+ data = malloc(length);
+ // NOTE: API change. Must check .IsEmpty() on the return object to see if
+ // the data was able to be allocated.
+ if (data == nullptr)
+ return Local<Object>();
+ } else {
+ data = nullptr;
+ }
+ Local<ArrayBuffer> ab =
+ ArrayBuffer::New(env->isolate(),
+ data,
+ length,
+ ArrayBufferCreationMode::kInternalized);
+ Local<Uint8Array> ui = Uint8Array::New(ab, 0, length);
+ ui->SetPrototype(env->buffer_prototype_object());
+ return scope.Escape(ui);
}
@@ -147,33 +218,59 @@ Local<Object> New(Isolate* isolate, const char* data, size_t length) {
}
-// TODO(trevnorris): for backwards compatibility this is left to copy the data,
-// but for consistency w/ the other should use data. And a copy version renamed
-// to something else.
+// Make a copy of "data". Why this isn't called "Copy", we'll never know.
Local<Object> New(Environment* env, const char* data, size_t length) {
EscapableHandleScope scope(env->isolate());
- CHECK_LE(length, kMaxLength);
+ if (using_old_buffer) {
+ CHECK_LE(length, kMaxLength);
+
+ Local<Value> arg = Uint32::NewFromUnsigned(env->isolate(), length);
+ Local<Object> obj =
+ env->buffer_constructor_function()->NewInstance(1, &arg);
+
+ char* new_data;
+ if (length > 0) {
+ new_data = static_cast<char*>(malloc(length));
+ if (new_data == nullptr)
+ FatalError("node::Buffer::New(const char*, size_t)", "Out Of Memory");
+ memcpy(new_data, data, length);
+ } else {
+ new_data = nullptr;
+ }
- Local<Value> arg = Uint32::NewFromUnsigned(env->isolate(), length);
- Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
+ smalloc::Alloc(env, obj, new_data, length);
- // TODO(trevnorris): done like this to handle HasInstance since only checks
- // if external array data has been set, but would like to use a better
- // approach if v8 provided one.
- char* new_data;
+ return scope.Escape(obj);
+ }
+
+ // V8 currently only allows a maximum Typed Array index of max Smi.
+ if (!IsValidSmi(length)) {
+ return Local<Object>();
+ }
+
+ void* new_data;
if (length > 0) {
- new_data = static_cast<char*>(malloc(length));
+ CHECK_NE(data, nullptr);
+ new_data = malloc(length);
+ // NOTE: API change. Must check .IsEmpty() on the return object to see if
+ // the data was able to be allocated.
if (new_data == nullptr)
- FatalError("node::Buffer::New(const char*, size_t)", "Out Of Memory");
+ return Local<Object>();
memcpy(new_data, data, length);
} else {
new_data = nullptr;
}
- smalloc::Alloc(env, obj, new_data, length);
+ Local<ArrayBuffer> ab =
+ ArrayBuffer::New(env->isolate(),
+ new_data,
+ length,
+ ArrayBufferCreationMode::kInternalized);
+ Local<Uint8Array> ui = Uint8Array::New(ab, 0, length);
+ ui->SetPrototype(env->buffer_prototype_object());
- return scope.Escape(obj);
+ return scope.Escape(ui);
}
@@ -196,6 +293,7 @@ Local<Object> New(Environment* env,
void* hint) {
EscapableHandleScope scope(env->isolate());
+ // TODO(trevnorris): IMPLEMENT
CHECK_LE(length, kMaxLength);
Local<Value> arg = Uint32::NewFromUnsigned(env->isolate(), length);
@@ -207,7 +305,7 @@ Local<Object> New(Environment* env,
}
-Local<Object> Use(Isolate* isolate, char* data, uint32_t length) {
+Local<Object> Use(Isolate* isolate, char* data, size_t length) {
Environment* env = Environment::GetCurrent(isolate);
EscapableHandleScope handle_scope(env->isolate());
Local<Object> obj = Buffer::Use(env, data, length);
@@ -215,17 +313,98 @@ Local<Object> Use(Isolate* isolate, char* data, uint32_t length) {
}
-Local<Object> Use(Environment* env, char* data, uint32_t length) {
+Local<Object> Use(Environment* env, char* data, size_t length) {
EscapableHandleScope scope(env->isolate());
- CHECK_LE(length, kMaxLength);
+ if (using_old_buffer) {
+ CHECK_LE(length, kMaxLength);
- Local<Value> arg = Uint32::NewFromUnsigned(env->isolate(), length);
- Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
+ Local<Value> arg = Uint32::NewFromUnsigned(env->isolate(), length);
+ Local<Object> obj =
+ env->buffer_constructor_function()->NewInstance(1, &arg);
- smalloc::Alloc(env, obj, data, length);
+ smalloc::Alloc(env, obj, data, length);
- return scope.Escape(obj);
+ return scope.Escape(obj);
+ }
+
+ if (length > 0) {
+ CHECK_NE(data, nullptr);
+ CHECK(IsValidSmi(length));
+ }
+
+ Local<ArrayBuffer> ab =
+ ArrayBuffer::New(env->isolate(),
+ data,
+ length,
+ ArrayBufferCreationMode::kInternalized);
+ Local<Uint8Array> ui = Uint8Array::New(ab, 0, length);
+ ui->SetPrototype(env->buffer_prototype_object());
+ return scope.Escape(ui);
+}
+
+
+void Create(const FunctionCallbackInfo<Value>& args) {
+ Isolate* isolate = args.GetIsolate();
+ Environment* env = Environment::GetCurrent(args);
+
+ CHECK(args[0]->IsNumber());
+
+ int64_t length = args[0]->IntegerValue();
+
+ if (!IsValidSmi(length)) {
+ return env->ThrowRangeError("invalid Buffer length");
+ }
+
+ void* data;
+ if (length > 0) {
+ data = malloc(length);
+ if (data == nullptr)
+ return env->ThrowRangeError("invalid Buffer length");
+ } else {
+ data = nullptr;
+ }
+
+ Local<ArrayBuffer> ab =
+ ArrayBuffer::New(isolate,
+ data,
+ length,
+ ArrayBufferCreationMode::kInternalized);
+ Local<Uint8Array> ui = Uint8Array::New(ab, 0, length);
+ ui->SetPrototype(env->buffer_prototype_object());
+ args.GetReturnValue().Set(ui);
+}
+
+
+void CreateFromString(const FunctionCallbackInfo<Value>& args) {
+ CHECK(args[0]->IsString());
+ CHECK(args[1]->IsString());
+
+ enum encoding enc = ParseEncoding(args.GetIsolate(),
+ args[1].As<String>(),
+ UTF8);
+ Local<Object> buf = New(args.GetIsolate(), args[0].As<String>(), enc);
+ args.GetReturnValue().Set(buf);
+}
+
+
+void Slice(const FunctionCallbackInfo<Value>& args) {
+ CHECK(args[0]->IsUint8Array());
+ CHECK(args[1]->IsNumber());
+ CHECK(args[2]->IsNumber());
+ Environment* env = Environment::GetCurrent(args);
+ Local<Uint8Array> ab_ui = args[0].As<Uint8Array>();
+ Local<ArrayBuffer> ab = ab_ui->Buffer();
+ ArrayBuffer::Contents ab_c = ab->GetContents();
+ size_t offset = ab_ui->ByteOffset();
+ size_t start = args[1]->NumberValue() + offset;
+ size_t end = args[2]->NumberValue() + offset;
+ CHECK_GE(end, start);
+ size_t size = end - start;
+ CHECK_GE(ab_c.ByteLength(), start + size);
+ Local<Uint8Array> ui = Uint8Array::New(ab, start, size);
+ ui->SetPrototype(env->buffer_prototype_object());
+ args.GetReturnValue().Set(ui);
}
@@ -237,7 +416,12 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
ARGS_THIS_DEC(ts_obj);
- ARGS_THIS(args.This(), ts_obj);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args.This(), ts_obj);
+ } else {
+ SPREAD_ARG(args.This(), ts_obj);
+ }
if (ts_obj_length == 0)
return args.GetReturnValue().SetEmptyString();
@@ -252,10 +436,16 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
template <>
void StringSlice<UCS2>(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- ARGS_THIS_DEC(ts_obj);
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
- ARGS_THIS(args.This(), ts_obj);
+
+ ARGS_THIS_DEC(ts_obj);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args.This(), ts_obj);
+ } else {
+ SPREAD_ARG(args.This(), ts_obj);
+ }
if (ts_obj_length == 0)
return args.GetReturnValue().SetEmptyString();
@@ -329,11 +519,22 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
- Local<Object> target_obj = args[0].As<Object>();
- size_t target_length = target->GetIndexedPropertiesExternalArrayDataLength();
- char* target_data = static_cast<char*>(
- target->GetIndexedPropertiesExternalArrayData());
+ Local<Object> target_obj = args[0]->ToObject(env->isolate());
+
+ ARGS_THIS_DEC(ts_obj);
+ ARGS_THIS_DEC(target);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args.This(), ts_obj);
+ target_length = target_obj->GetIndexedPropertiesExternalArrayDataLength();
+ target_data = static_cast<char*>(
+ target_obj->GetIndexedPropertiesExternalArrayData());
+ } else {
+ SPREAD_ARG(args.This(), ts_obj);
+ SPREAD_ARG(target_obj, target);
+ }
+
size_t target_start;
size_t source_start;
size_t source_end;
@@ -364,7 +565,12 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
void Fill(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
ARGS_THIS_DEC(ts_obj);
- ARGS_THIS(args[0].As<Object>(), ts_obj);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args[0].As<Object>(), ts_obj);
+ } else {
+ SPREAD_ARG(args[0], ts_obj);
+ }
size_t start = args[2]->Uint32Value();
size_t end = args[3]->Uint32Value();
@@ -409,7 +615,12 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
ARGS_THIS_DEC(ts_obj);
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
- ARGS_THIS(args.This(), ts_obj);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args.This(), ts_obj);
+ } else {
+ SPREAD_ARG(args.This(), ts_obj);
+ }
if (!args[0]->IsString())
return env->ThrowTypeError("Argument must be a string");
@@ -487,7 +698,12 @@ template <typename T, enum Endianness endianness>
void ReadFloatGeneric(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
ARGS_THIS_DEC(ts_obj);
- ARGS_THIS(args[0].As<Object>(), ts_obj);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args[0].As<Object>(), ts_obj);
+ } else {
+ SPREAD_ARG(args[0], ts_obj);
+ }
uint32_t offset = args[1]->Uint32Value();
CHECK_LE(offset + sizeof(T), ts_obj_length);
@@ -530,7 +746,12 @@ void ReadDoubleBE(const FunctionCallbackInfo<Value>& args) {
template <typename T, enum Endianness endianness>
uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
ARGS_THIS_DEC(ts_obj);
- ARGS_THIS(args[0].As<Object>(), ts_obj);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args[0].As<Object>(), ts_obj);
+ } else {
+ SPREAD_ARG(args[0], ts_obj);
+ }
T val = args[1]->NumberValue();
uint32_t offset = args[2]->Uint32Value();
@@ -588,26 +809,27 @@ void Compare(const FunctionCallbackInfo<Value> &args) {
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
THROW_AND_RETURN_UNLESS_BUFFER(env, args[1]);
- Local<Object> obj_a = args[0].As<Object>();
- char* obj_a_data =
- static_cast<char*>(obj_a->GetIndexedPropertiesExternalArrayData());
- size_t obj_a_len = obj_a->GetIndexedPropertiesExternalArrayDataLength();
+ ARGS_THIS_DEC(obj_a);
+ ARGS_THIS_DEC(obj_b);
- Local<Object> obj_b = args[1].As<Object>();
- char* obj_b_data =
- static_cast<char*>(obj_b->GetIndexedPropertiesExternalArrayData());
- size_t obj_b_len = obj_b->GetIndexedPropertiesExternalArrayDataLength();
+ if (using_old_buffer) {
+ ARGS_THIS(args[0].As<Object>(), obj_a);
+ ARGS_THIS(args[1].As<Object>(), obj_b);
+ } else {
+ SPREAD_ARG(args[0], obj_a);
+ SPREAD_ARG(args[1], obj_b);
+ }
- size_t cmp_length = MIN(obj_a_len, obj_b_len);
+ size_t cmp_length = MIN(obj_a_length, obj_b_length);
int32_t val = memcmp(obj_a_data, obj_b_data, cmp_length);
// Normalize val to be an integer in the range of [1, -1] since
// implementations of memcmp() can vary by platform.
if (val == 0) {
- if (obj_a_len > obj_b_len)
+ if (obj_a_length > obj_b_length)
val = 1;
- else if (obj_a_len < obj_b_len)
+ else if (obj_a_length < obj_b_length)
val = -1;
} else {
if (val > 0)
@@ -642,7 +864,12 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
ARGS_THIS_DEC(ts_obj);
- ARGS_THIS(args[0].As<Object>(), ts_obj);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args[0].As<Object>(), ts_obj);
+ } else {
+ SPREAD_ARG(args[0], ts_obj);
+ }
node::Utf8Value str(args.GetIsolate(), args[1]);
int32_t offset_i32 = args[2]->Int32Value();
@@ -675,7 +902,12 @@ void IndexOfBuffer(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
ARGS_THIS_DEC(ts_obj);
- ARGS_THIS(args[0].As<Object>(), ts_obj);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args[0].As<Object>(), ts_obj);
+ } else {
+ SPREAD_ARG(args[0], ts_obj);
+ }
Local<Object> buf = args[1].As<Object>();
int32_t offset_i32 = args[2]->Int32Value();
@@ -714,7 +946,12 @@ void IndexOfNumber(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
ARGS_THIS_DEC(ts_obj);
- ARGS_THIS(args[0].As<Object>(), ts_obj);
+
+ if (using_old_buffer) {
+ ARGS_THIS(args[0].As<Object>(), ts_obj);
+ } else {
+ SPREAD_ARG(args[0], ts_obj);
+ }
uint32_t needle = args[1]->Uint32Value();
int32_t offset_i32 = args[2]->Int32Value();
@@ -743,15 +980,20 @@ void IndexOfNumber(const FunctionCallbackInfo<Value>& args) {
void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- CHECK(args[0]->IsFunction());
-
- Local<Function> bv = args[0].As<Function>();
- env->set_buffer_constructor_function(bv);
- Local<Value> proto_v = bv->Get(env->prototype_string());
-
- CHECK(proto_v->IsObject());
+ Local<Object> proto;
- Local<Object> proto = proto_v.As<Object>();
+ if (using_old_buffer) {
+ CHECK(args[0]->IsFunction());
+ Local<Function> bv = args[0].As<Function>();
+ env->set_buffer_constructor_function(bv);
+ Local<Value> proto_v = bv->Get(env->prototype_string());
+ CHECK(proto_v->IsObject());
+ proto = proto_v.As<Object>();
+ } else {
+ CHECK(args[0]->IsObject());
+ proto = args[0].As<Object>();
+ env->set_buffer_prototype_object(proto);
+ }
env->SetMethod(proto, "asciiSlice", AsciiSlice);
env->SetMethod(proto, "base64Slice", Base64Slice);
@@ -770,9 +1012,11 @@ void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
env->SetMethod(proto, "copy", Copy);
// for backwards compatibility
- proto->ForceSet(env->offset_string(),
- Uint32::New(env->isolate(), 0),
- v8::ReadOnly);
+ if (using_old_buffer) {
+ proto->ForceSet(env->offset_string(),
+ Uint32::New(env->isolate(), 0),
+ v8::ReadOnly);
+ }
}
@@ -782,7 +1026,10 @@ void Initialize(Handle<Object> target,
Environment* env = Environment::GetCurrent(context);
env->SetMethod(target, "setupBufferJS", SetupBufferJS);
+ env->SetMethod(target, "create", Create);
+ env->SetMethod(target, "createFromString", CreateFromString);
+ env->SetMethod(target, "slice", Slice);
env->SetMethod(target, "byteLengthUtf8", ByteLengthUtf8);
env->SetMethod(target, "compare", Compare);
env->SetMethod(target, "fill", Fill);
diff --git a/src/node_buffer.h b/src/node_buffer.h
index 2e649970c47..4b1b2cd8591 100644
--- a/src/node_buffer.h
+++ b/src/node_buffer.h
@@ -63,9 +63,9 @@ NODE_DEPRECATED("Use New(isolate, ...)",
// TODO(trevnorris): should be New() for consistency
NODE_EXTERN v8::Local<v8::Object> Use(v8::Isolate* isolate,
char* data,
- uint32_t len);
+ size_t len);
NODE_DEPRECATED("Use Use(isolate, ...)",
- inline v8::Local<v8::Object> Use(char* data, uint32_t len) {
+ inline v8::Local<v8::Object> Use(char* data, size_t len) {
return Use(v8::Isolate::GetCurrent(), data, len);
})
@@ -95,7 +95,7 @@ v8::Local<v8::Object> New(Environment* env,
size_t length,
smalloc::FreeCallback callback,
void* hint);
-v8::Local<v8::Object> Use(Environment* env, char* data, uint32_t length);
+v8::Local<v8::Object> Use(Environment* env, char* data, size_t length);
#endif // defined(NODE_WANT_INTERNALS)
} // namespace Buffer
diff --git a/src/node_internals.h b/src/node_internals.h
index c99b2feeb0b..e5f7458f78d 100644
--- a/src/node_internals.h
+++ b/src/node_internals.h
@@ -17,6 +17,8 @@ namespace node {
// Forward declaration
class Environment;
+extern bool using_old_buffer;
+
// If persistent.IsWeak() == false, then do not call persistent.Reset()
// while the returned Local<T> is still in scope, it will destroy the
// reference to the object.
diff --git a/src/util-inl.h b/src/util-inl.h
index 75bdb4784aa..308c9b2787d 100644
--- a/src/util-inl.h
+++ b/src/util-inl.h
@@ -198,6 +198,14 @@ TypeName* Unwrap(v8::Local<v8::Object> object) {
return static_cast<TypeName*>(pointer);
}
+inline bool IsValidSmi(int64_t value) {
+ if (sizeof(int32_t) == sizeof(intptr_t)) {
+ return value >= -0x40000000LL && value <= 0x3fffffffLL;
+ } else {
+ return value >= -0x80000000LL && value <= 0x7fffffffLL;
+ }
+}
+
} // namespace node
#endif // SRC_UTIL_INL_H_
diff --git a/src/util.h b/src/util.h
index ea17a155745..3ca79c0ac15 100644
--- a/src/util.h
+++ b/src/util.h
@@ -195,6 +195,8 @@ class Utf8Value {
char str_st_[1024];
};
+inline bool IsValidSmi(int64_t value);
+
} // namespace node
#endif // SRC_UTIL_H_
diff --git a/test/parallel/test-buffer-slice.js b/test/parallel/test-buffer-slice.js
deleted file mode 100644
index 53434eab8e3..00000000000
--- a/test/parallel/test-buffer-slice.js
+++ /dev/null
@@ -1,12 +0,0 @@
-'use strict';
-var common = require('../common');
-var assert = require('assert');
-
-var Buffer = require('buffer').Buffer;
-
-var buff = new Buffer(Buffer.poolSize + 1);
-var slicedBuffer = buff.slice();
-assert.equal(slicedBuffer.parent,
- buff,
- 'slicedBufffer should have its parent set to the original ' +
- ' buffer');
diff --git a/test/parallel/test-buffer.js b/test/parallel/test-buffer.js
index 27a211bc2da..443da055600 100644
--- a/test/parallel/test-buffer.js
+++ b/test/parallel/test-buffer.js
@@ -329,8 +329,6 @@ assert.equal(b.parent, d.parent);
var b = new SlowBuffer(5);
var c = b.slice(0, 4);
var d = c.slice(0, 2);
-assert.equal(b, c.parent);
-assert.equal(b, d.parent);
// Bug regression test
@@ -1075,10 +1073,6 @@ assert.equal(buf.readInt8(0), -1);
// try to slice a zero length Buffer
// see https://github.com/joyent/node/issues/5881
SlowBuffer(0).slice(0, 1);
- // make sure a zero length slice doesn't set the .parent attribute
- assert.equal(Buffer(5).slice(0, 0).parent, undefined);
- // and make sure a proper slice does have a parent
- assert.ok(typeof Buffer(5).slice(0, 5).parent === 'object');
})();
// Regression test for #5482: should throw but not assert in C++ land.
@@ -1105,11 +1099,11 @@ assert.throws(function() {
assert.throws(function() {
- new Buffer(smalloc.kMaxLength + 1);
+ new Buffer((-1 >>> 0) + 1);
}, RangeError);
assert.throws(function() {
- new SlowBuffer(smalloc.kMaxLength + 1);
+ new SlowBuffer((-1 >>> 0) + 1);
}, RangeError);
if (common.hasCrypto) {