index.js
 1  var toString = Object.prototype.toString
 2  
 3  var isModern = (
 4    typeof Buffer.alloc === 'function' &&
 5    typeof Buffer.allocUnsafe === 'function' &&
 6    typeof Buffer.from === 'function'
 7  )
 8  
 9  function isArrayBuffer (input) {
10    return toString.call(input).slice(8, -1) === 'ArrayBuffer'
11  }
12  
13  function fromArrayBuffer (obj, byteOffset, length) {
14    byteOffset >>>= 0
15  
16    var maxLength = obj.byteLength - byteOffset
17  
18    if (maxLength < 0) {
19      throw new RangeError("'offset' is out of bounds")
20    }
21  
22    if (length === undefined) {
23      length = maxLength
24    } else {
25      length >>>= 0
26  
27      if (length > maxLength) {
28        throw new RangeError("'length' is out of bounds")
29      }
30    }
31  
32    return isModern
33      ? Buffer.from(obj.slice(byteOffset, byteOffset + length))
34      : new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length)))
35  }
36  
37  function fromString (string, encoding) {
38    if (typeof encoding !== 'string' || encoding === '') {
39      encoding = 'utf8'
40    }
41  
42    if (!Buffer.isEncoding(encoding)) {
43      throw new TypeError('"encoding" must be a valid string encoding')
44    }
45  
46    return isModern
47      ? Buffer.from(string, encoding)
48      : new Buffer(string, encoding)
49  }
50  
51  function bufferFrom (value, encodingOrOffset, length) {
52    if (typeof value === 'number') {
53      throw new TypeError('"value" argument must not be a number')
54    }
55  
56    if (isArrayBuffer(value)) {
57      return fromArrayBuffer(value, encodingOrOffset, length)
58    }
59  
60    if (typeof value === 'string') {
61      return fromString(value, encodingOrOffset)
62    }
63  
64    return isModern
65      ? Buffer.from(value)
66      : new Buffer(value)
67  }
68  
69  module.exports = bufferFrom