* By augmenting the instances, we can avoid modifying the `Uint8Array`
* prototype.
*/
-function Buffer (subject, encoding) {
- var self = this
- if (!(self instanceof Buffer)) return new Buffer(subject, encoding)
-
- var type = typeof subject
- var length
-
- if (type === 'number') {
- length = +subject
- } else if (type === 'string') {
- length = Buffer.byteLength(subject, encoding)
- } else if (type === 'object' && subject !== null) {
- // assume object is array-like
- if (subject.type === 'Buffer' && isArray(subject.data)) subject = subject.data
- length = +subject.length
- } else {
+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') {
+ return fromNumber(this, arg)
+ }
+
+ // Slightly less common case.
+ if (typeof arg === 'string') {
+ return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
+ }
+
+ // Unusual.
+ return fromObject(this, arg)
+}
+
+function fromNumber (that, length) {
+ that = allocate(that, length < 0 ? 0 : checked(length) | 0)
+ if (!Buffer.TYPED_ARRAY_SUPPORT) {
+ for (var i = 0; i < length; i++) {
+ that[i] = 0
+ }
+ }
+ return that
+}
+
+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
+ that = allocate(that, length)
+
+ that.write(string, encoding) | 0
+ return that
+}
+
+function fromObject (that, object) {
+ if (Buffer.isBuffer(object)) return fromBuffer(that, object)
+
+ if (isArray(object)) return fromArray(that, object)
+
+ if (object == null) {
throw new TypeError('must start with number, buffer, array or string')
}
- if (length > kMaxLength) {
- throw new RangeError('Attempt to allocate Buffer larger than maximum size: 0x' +
- kMaxLength.toString(16) + ' bytes')
+ 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
+ that = allocate(that, length)
+ buffer.copy(that, 0, 0, length)
+ return that
+}
+
+function fromArray (that, array) {
+ var length = checked(array.length) | 0
+ that = allocate(that, length)
+ for (var i = 0; i < length; i += 1) {
+ that[i] = array[i] & 255
}
+ return that
+}
- if (length < 0) length = 0
- else length >>>= 0 // coerce to uint32
+// Duplicate of fromArray() to keep fromArray() monomorphic.
+function fromTypedArray (that, array) {
+ var length = checked(array.length) | 0
+ that = 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
+ }
+ return that
+}
- if (Buffer.TYPED_ARRAY_SUPPORT) {
- // Preferred: Return an augmented `Uint8Array` instance for best performance
- self = Buffer._augment(new Uint8Array(length)) // eslint-disable-line consistent-this
- } else {
- // Fallback: Return THIS instance of Buffer (created by `new`)
- self.length = length
- self._isBuffer = true
+function fromArrayLike (that, array) {
+ var length = checked(array.length) | 0
+ that = allocate(that, length)
+ for (var i = 0; i < length; i += 1) {
+ that[i] = array[i] & 255
}
+ return that
+}
- var i
- if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') {
- // Speed optimization -- use set if we're copying from a typed array
- self._set(subject)
- } else if (isArrayish(subject)) {
- // Treat array-ish objects as a byte array
- if (Buffer.isBuffer(subject)) {
- for (i = 0; i < length; i++) {
- self[i] = subject.readUInt8(i)
- }
- } else {
- for (i = 0; i < length; i++) {
- self[i] = ((subject[i] % 256) + 256) % 256
- }
- }
- } else if (type === 'string') {
- self.write(subject, 0, encoding)
- } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT) {
- for (i = 0; i < length; i++) {
- self[i] = 0
- }
+// 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' && isArray(object.data)) {
+ array = object.data
+ length = checked(array.length) | 0
+ }
+ that = allocate(that, length)
+
+ for (var i = 0; i < length; i += 1) {
+ that[i] = array[i] & 255
+ }
+ return that
+}
+
+function allocate (that, length) {
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ // Return an augmented `Uint8Array` instance, for best performance
+ that = Buffer._augment(new Uint8Array(length))
+ } else {
+ // Fallback: Return an object instance of the Buffer class
+ that.length = length
+ that._isBuffer = true
}
var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
- if (fromPool) self.parent = rootParent
+ if (fromPool) that.parent = rootParent
+
+ return that
+}
- return self
+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 (subject, encoding) {
return buf
}
-Buffer.byteLength = function byteLength (string, encoding) {
+function byteLength (string, encoding) {
if (typeof string !== 'string') string = String(string)
if (string.length === 0) return 0
return string.length
}
}
+Buffer.byteLength = byteLength
// pre-set for values that may exist in the future
Buffer.prototype.length = undefined
return str.replace(/^\s+|\s+$/g, '')
}
-function isArrayish (subject) {
- return isArray(subject) || Buffer.isBuffer(subject) ||
- subject && typeof subject === 'object' &&
- typeof subject.length === 'number'
-}
-
function toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)