1 /* eslint-disable require-buffer */
4 const binding = process.binding('buffer');
5 const internalUtil = require('internal/util');
8 exports.Buffer = Buffer;
9 exports.SlowBuffer = SlowBuffer;
10 exports.INSPECT_MAX_BYTES = 50;
11 exports.kMaxLength = binding.kMaxLength;
14 Buffer.poolSize = 8 * 1024;
15 var poolSize, poolOffset, allocPool;
18 binding.setupBufferJS(Buffer.prototype, bindingObj);
19 const flags = bindingObj.flags;
20 const kNoZeroFill = 0;
23 function createPool() {
24 poolSize = Buffer.poolSize;
26 flags[kNoZeroFill] = 1;
27 allocPool = new Uint8Array(poolSize);
28 Object.setPrototypeOf(allocPool, Buffer.prototype);
34 function alignPool() {
35 // Ensure aligned slices
36 if (poolOffset & 0x7) {
43 function Buffer(arg, encoding) {
45 if (typeof arg === 'number') {
46 // If less than zero, or NaN.
47 if (arg < 0 || arg !== arg)
52 // Slightly less common case.
53 if (typeof arg === 'string') {
54 return fromString(arg, encoding);
58 return fromObject(arg);
61 Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype);
62 Object.setPrototypeOf(Buffer, Uint8Array);
65 function SlowBuffer(length) {
66 if (+length != length)
69 flags[kNoZeroFill] = 1;
70 const ui8 = new Uint8Array(+length);
71 Object.setPrototypeOf(ui8, Buffer.prototype);
75 Object.setPrototypeOf(SlowBuffer.prototype, Uint8Array.prototype);
76 Object.setPrototypeOf(SlowBuffer, Uint8Array);
79 function allocate(size) {
81 const ui8 = new Uint8Array(size);
82 Object.setPrototypeOf(ui8, Buffer.prototype);
85 if (size < (Buffer.poolSize >>> 1)) {
86 if (size > (poolSize - poolOffset))
88 var b = allocPool.slice(poolOffset, poolOffset + size);
93 // Even though this is checked above, the conditional is a safety net and
94 // sanity check to prevent any subsequent typed array allocation from not
97 flags[kNoZeroFill] = 1;
98 const ui8 = new Uint8Array(size);
99 Object.setPrototypeOf(ui8, Buffer.prototype);
105 function fromString(string, encoding) {
106 if (typeof encoding !== 'string' || encoding === '')
109 var length = byteLength(string, encoding);
110 if (length >= (Buffer.poolSize >>> 1))
111 return binding.createFromString(string, encoding);
113 if (length > (poolSize - poolOffset))
115 var actual = allocPool.write(string, poolOffset, encoding);
116 var b = allocPool.slice(poolOffset, poolOffset + actual);
117 poolOffset += actual;
123 function fromObject(obj) {
124 if (obj instanceof Buffer) {
125 var b = allocate(obj.length);
126 obj.copy(b, 0, 0, obj.length);
130 if (Array.isArray(obj)) {
131 var length = obj.length;
132 var b = allocate(length);
133 for (var i = 0; i < length; i++)
139 throw new TypeError('must start with number, buffer, array or string');
142 if (obj instanceof ArrayBuffer) {
143 return binding.createFromArrayBuffer(obj);
146 if (obj.buffer instanceof ArrayBuffer || obj.length) {
148 if (typeof obj.length !== 'number' || obj.length !== obj.length)
152 var b = allocate(length);
153 for (var i = 0; i < length; i++) {
159 if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
160 var array = obj.data;
161 var b = allocate(array.length);
162 for (var i = 0; i < array.length; i++)
163 b[i] = array[i] & 255;
167 throw new TypeError('must start with number, buffer, array or string');
173 Buffer.isBuffer = function isBuffer(b) {
174 return b instanceof Buffer;
178 Buffer.compare = function compare(a, b) {
179 if (!(a instanceof Buffer) ||
180 !(b instanceof Buffer)) {
181 throw new TypeError('Arguments must be Buffers');
188 return binding.compare(a, b);
192 Buffer.isEncoding = function(encoding) {
193 var loweredCase = false;
212 encoding = ('' + encoding).toLowerCase();
219 Buffer.concat = function(list, length) {
220 if (!Array.isArray(list))
221 throw new TypeError('list argument must be an Array of Buffers.');
223 if (list.length === 0)
224 return new Buffer(0);
226 if (length === undefined) {
228 for (var i = 0; i < list.length; i++)
229 length += list[i].length;
231 length = length >>> 0;
234 var buffer = new Buffer(length);
236 for (var i = 0; i < list.length; i++) {
238 buf.copy(buffer, pos);
246 function base64ByteLength(str, bytes) {
248 if (str.charCodeAt(bytes - 1) === 0x3D)
250 if (bytes > 1 && str.charCodeAt(bytes - 1) === 0x3D)
254 return (bytes * 3) >>> 2;
258 function byteLength(string, encoding) {
259 if (typeof string !== 'string')
260 string = '' + string;
262 var len = string.length;
266 // Use a for loop to avoid recursion
267 var loweredCase = false;
280 return binding.byteLengthUtf8(string);
292 return base64ByteLength(string, len);
295 // The C++ binding defaulted to UTF8, we should too.
297 return binding.byteLengthUtf8(string);
299 encoding = ('' + encoding).toLowerCase();
305 Buffer.byteLength = byteLength;
308 // For backwards compatibility.
309 Object.defineProperty(Buffer.prototype, 'parent', {
312 if (!(this instanceof Buffer))
314 if (this.byteLength === 0 ||
315 this.byteLength === this.buffer.byteLength) {
321 Object.defineProperty(Buffer.prototype, 'offset', {
324 if (!(this instanceof Buffer))
326 return this.byteOffset;
331 function slowToString(encoding, start, end) {
332 var loweredCase = false;
335 end = end === undefined || end === Infinity ? this.length : end >>> 0;
337 if (!encoding) encoding = 'utf8';
338 if (start < 0) start = 0;
339 if (end > this.length) end = this.length;
340 if (end <= start) return '';
345 return this.hexSlice(start, end);
349 return this.utf8Slice(start, end);
352 return this.asciiSlice(start, end);
355 return this.binarySlice(start, end);
358 return this.base64Slice(start, end);
364 return this.ucs2Slice(start, end);
368 throw new TypeError('Unknown encoding: ' + encoding);
369 encoding = (encoding + '').toLowerCase();
376 Buffer.prototype.toString = function() {
377 if (arguments.length === 0) {
378 var result = this.utf8Slice(0, this.length);
380 var result = slowToString.apply(this, arguments);
382 if (result === undefined)
383 throw new Error('toString failed');
388 Buffer.prototype.equals = function equals(b) {
389 if (!(b instanceof Buffer))
390 throw new TypeError('Argument must be a Buffer');
395 return binding.compare(this, b) === 0;
400 Buffer.prototype.inspect = function inspect() {
402 var max = exports.INSPECT_MAX_BYTES;
403 if (this.length > 0) {
404 str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');
405 if (this.length > max)
408 return '<' + this.constructor.name + ' ' + str + '>';
412 Buffer.prototype.compare = function compare(b) {
413 if (!(b instanceof Buffer))
414 throw new TypeError('Argument must be a Buffer');
419 return binding.compare(this, b);
422 function slowIndexOf(buffer, val, byteOffset, encoding) {
423 var loweredCase = false;
433 return binding.indexOfString(buffer, val, byteOffset, encoding);
438 return binding.indexOfBuffer(
439 buffer, Buffer(val, encoding), byteOffset, encoding);
443 throw new TypeError('Unknown encoding: ' + encoding);
446 encoding = ('' + encoding).toLowerCase();
452 Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
453 if (byteOffset > 0x7fffffff)
454 byteOffset = 0x7fffffff;
455 else if (byteOffset < -0x80000000)
456 byteOffset = -0x80000000;
459 if (typeof val === 'string') {
460 if (encoding === undefined) {
461 return binding.indexOfString(this, val, byteOffset, encoding);
463 return slowIndexOf(this, val, byteOffset, encoding);
464 } else if (val instanceof Buffer) {
465 return binding.indexOfBuffer(this, val, byteOffset, encoding);
466 } else if (typeof val === 'number') {
467 return binding.indexOfNumber(this, val, byteOffset);
470 throw new TypeError('val must be string, number or Buffer');
474 Buffer.prototype.fill = function fill(val, start, end) {
476 end = (end === undefined) ? this.length : end >> 0;
478 if (start < 0 || end > this.length)
479 throw new RangeError('out of range index');
483 if (typeof val !== 'string') {
485 } else if (val.length === 1) {
486 var code = val.charCodeAt(0);
491 binding.fill(this, val, start, end);
497 // XXX remove in v0.13
498 Buffer.prototype.get = internalUtil.deprecate(function get(offset) {
500 if (offset < 0 || offset >= this.length)
501 throw new RangeError('index out of range');
503 }, 'Buffer.get is deprecated. Use array indexes instead.');
506 // XXX remove in v0.13
507 Buffer.prototype.set = internalUtil.deprecate(function set(offset, v) {
509 if (offset < 0 || offset >= this.length)
510 throw new RangeError('index out of range');
511 return this[offset] = v;
512 }, 'Buffer.set is deprecated. Use array indexes instead.');
515 // TODO(trevnorris): fix these checks to follow new standard
516 // write(string, offset = 0, length = buffer.length, encoding = 'utf8')
517 var writeWarned = false;
518 const writeMsg = 'Buffer.write(string, encoding, offset, length) is ' +
519 'deprecated. Use write(string[, offset[, length]]' +
520 '[, encoding]) instead.';
521 Buffer.prototype.write = function(string, offset, length, encoding) {
522 // Buffer#write(string);
523 if (offset === undefined) {
525 length = this.length;
528 // Buffer#write(string, encoding)
529 } else if (length === undefined && typeof offset === 'string') {
531 length = this.length;
534 // Buffer#write(string, offset[, length][, encoding])
535 } else if (isFinite(offset)) {
536 offset = offset >>> 0;
537 if (isFinite(length)) {
538 length = length >>> 0;
539 if (encoding === undefined)
546 // XXX legacy write(string, encoding, offset, length) - remove in v0.13
548 writeWarned = internalUtil.printDeprecationMessage(writeMsg, writeWarned);
551 offset = length >>> 0;
555 var remaining = this.length - offset;
556 if (length === undefined || length > remaining)
559 if (string.length > 0 && (length < 0 || offset < 0))
560 throw new RangeError('attempt to write outside buffer bounds');
565 var loweredCase = false;
569 return this.hexWrite(string, offset, length);
573 return this.utf8Write(string, offset, length);
576 return this.asciiWrite(string, offset, length);
579 return this.binaryWrite(string, offset, length);
582 // Warning: maxLength not taken into account in base64Write
583 return this.base64Write(string, offset, length);
589 return this.ucs2Write(string, offset, length);
593 throw new TypeError('Unknown encoding: ' + encoding);
594 encoding = ('' + encoding).toLowerCase();
601 Buffer.prototype.toJSON = function() {
604 data: Array.prototype.slice.call(this, 0)
609 // TODO(trevnorris): currently works like Array.prototype.slice(), which
610 // doesn't follow the new standard for throwing on out of range indexes.
611 Buffer.prototype.slice = function slice(start, end) {
612 const buffer = this.subarray(start, end);
613 Object.setPrototypeOf(buffer, Buffer.prototype);
618 function checkOffset(offset, ext, length) {
619 if (offset + ext > length)
620 throw new RangeError('index out of range');
624 Buffer.prototype.readUIntLE = function(offset, byteLength, noAssert) {
625 offset = offset >>> 0;
626 byteLength = byteLength >>> 0;
628 checkOffset(offset, byteLength, this.length);
630 var val = this[offset];
633 while (++i < byteLength && (mul *= 0x100))
634 val += this[offset + i] * mul;
640 Buffer.prototype.readUIntBE = function(offset, byteLength, noAssert) {
641 offset = offset >>> 0;
642 byteLength = byteLength >>> 0;
644 checkOffset(offset, byteLength, this.length);
646 var val = this[offset + --byteLength];
648 while (byteLength > 0 && (mul *= 0x100))
649 val += this[offset + --byteLength] * mul;
655 Buffer.prototype.readUInt8 = function(offset, noAssert) {
656 offset = offset >>> 0;
658 checkOffset(offset, 1, this.length);
663 Buffer.prototype.readUInt16LE = function(offset, noAssert) {
664 offset = offset >>> 0;
666 checkOffset(offset, 2, this.length);
667 return this[offset] | (this[offset + 1] << 8);
671 Buffer.prototype.readUInt16BE = function(offset, noAssert) {
672 offset = offset >>> 0;
674 checkOffset(offset, 2, this.length);
675 return (this[offset] << 8) | this[offset + 1];
679 Buffer.prototype.readUInt32LE = function(offset, noAssert) {
680 offset = offset >>> 0;
682 checkOffset(offset, 4, this.length);
684 return ((this[offset]) |
685 (this[offset + 1] << 8) |
686 (this[offset + 2] << 16)) +
687 (this[offset + 3] * 0x1000000);
691 Buffer.prototype.readUInt32BE = function(offset, noAssert) {
692 offset = offset >>> 0;
694 checkOffset(offset, 4, this.length);
696 return (this[offset] * 0x1000000) +
697 ((this[offset + 1] << 16) |
698 (this[offset + 2] << 8) |
703 Buffer.prototype.readIntLE = function(offset, byteLength, noAssert) {
704 offset = offset >>> 0;
705 byteLength = byteLength >>> 0;
707 checkOffset(offset, byteLength, this.length);
709 var val = this[offset];
712 while (++i < byteLength && (mul *= 0x100))
713 val += this[offset + i] * mul;
717 val -= Math.pow(2, 8 * byteLength);
723 Buffer.prototype.readIntBE = function(offset, byteLength, noAssert) {
724 offset = offset >>> 0;
725 byteLength = byteLength >>> 0;
727 checkOffset(offset, byteLength, this.length);
731 var val = this[offset + --i];
732 while (i > 0 && (mul *= 0x100))
733 val += this[offset + --i] * mul;
737 val -= Math.pow(2, 8 * byteLength);
743 Buffer.prototype.readInt8 = function(offset, noAssert) {
744 offset = offset >>> 0;
746 checkOffset(offset, 1, this.length);
747 var val = this[offset];
748 return !(val & 0x80) ? val : (0xff - val + 1) * -1;
752 Buffer.prototype.readInt16LE = function(offset, noAssert) {
753 offset = offset >>> 0;
755 checkOffset(offset, 2, this.length);
756 var val = this[offset] | (this[offset + 1] << 8);
757 return (val & 0x8000) ? val | 0xFFFF0000 : val;
761 Buffer.prototype.readInt16BE = function(offset, noAssert) {
762 offset = offset >>> 0;
764 checkOffset(offset, 2, this.length);
765 var val = this[offset + 1] | (this[offset] << 8);
766 return (val & 0x8000) ? val | 0xFFFF0000 : val;
770 Buffer.prototype.readInt32LE = function(offset, noAssert) {
771 offset = offset >>> 0;
773 checkOffset(offset, 4, this.length);
775 return (this[offset]) |
776 (this[offset + 1] << 8) |
777 (this[offset + 2] << 16) |
778 (this[offset + 3] << 24);
782 Buffer.prototype.readInt32BE = function(offset, noAssert) {
783 offset = offset >>> 0;
785 checkOffset(offset, 4, this.length);
787 return (this[offset] << 24) |
788 (this[offset + 1] << 16) |
789 (this[offset + 2] << 8) |
794 Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
795 offset = offset >>> 0;
797 checkOffset(offset, 4, this.length);
798 return binding.readFloatLE(this, offset);
802 Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
803 offset = offset >>> 0;
805 checkOffset(offset, 4, this.length);
806 return binding.readFloatBE(this, offset);
810 Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
811 offset = offset >>> 0;
813 checkOffset(offset, 8, this.length);
814 return binding.readDoubleLE(this, offset);
818 Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
819 offset = offset >>> 0;
821 checkOffset(offset, 8, this.length);
822 return binding.readDoubleBE(this, offset);
826 function checkInt(buffer, value, offset, ext, max, min) {
827 if (!(buffer instanceof Buffer))
828 throw new TypeError('buffer must be a Buffer instance');
829 if (value > max || value < min)
830 throw new TypeError('value is out of bounds');
831 if (offset + ext > buffer.length)
832 throw new RangeError('index out of range');
836 Buffer.prototype.writeUIntLE = function(value, offset, byteLength, noAssert) {
838 offset = offset >>> 0;
839 byteLength = byteLength >>> 0;
841 const maxBytes = Math.pow(2, 8 * byteLength) - 1;
842 checkInt(this, value, offset, byteLength, maxBytes, 0);
847 this[offset] = value;
848 while (++i < byteLength && (mul *= 0x100))
849 this[offset + i] = (value / mul) >>> 0;
851 return offset + byteLength;
855 Buffer.prototype.writeUIntBE = function(value, offset, byteLength, noAssert) {
857 offset = offset >>> 0;
858 byteLength = byteLength >>> 0;
860 const maxBytes = Math.pow(2, 8 * byteLength) - 1;
861 checkInt(this, value, offset, byteLength, maxBytes, 0);
864 var i = byteLength - 1;
866 this[offset + i] = value;
867 while (--i >= 0 && (mul *= 0x100))
868 this[offset + i] = (value / mul) >>> 0;
870 return offset + byteLength;
874 Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
876 offset = offset >>> 0;
878 checkInt(this, value, offset, 1, 0xff, 0);
879 this[offset] = value;
884 Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
886 offset = offset >>> 0;
888 checkInt(this, value, offset, 2, 0xffff, 0);
889 this[offset] = value;
890 this[offset + 1] = (value >>> 8);
895 Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
897 offset = offset >>> 0;
899 checkInt(this, value, offset, 2, 0xffff, 0);
900 this[offset] = (value >>> 8);
901 this[offset + 1] = value;
906 Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
908 offset = offset >>> 0;
910 checkInt(this, value, offset, 4, 0xffffffff, 0);
911 this[offset + 3] = (value >>> 24);
912 this[offset + 2] = (value >>> 16);
913 this[offset + 1] = (value >>> 8);
914 this[offset] = value;
919 Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
921 offset = offset >>> 0;
923 checkInt(this, value, offset, 4, 0xffffffff, 0);
924 this[offset] = (value >>> 24);
925 this[offset + 1] = (value >>> 16);
926 this[offset + 2] = (value >>> 8);
927 this[offset + 3] = value;
932 Buffer.prototype.writeIntLE = function(value, offset, byteLength, noAssert) {
934 offset = offset >>> 0;
940 Math.pow(2, 8 * byteLength - 1) - 1,
941 -Math.pow(2, 8 * byteLength - 1));
947 this[offset] = value;
948 while (++i < byteLength && (mul *= 0x100)) {
949 if (value < 0 && sub === 0 && this[offset + i - 1] !== 0)
951 this[offset + i] = ((value / mul) >> 0) - sub;
954 return offset + byteLength;
958 Buffer.prototype.writeIntBE = function(value, offset, byteLength, noAssert) {
960 offset = offset >>> 0;
966 Math.pow(2, 8 * byteLength - 1) - 1,
967 -Math.pow(2, 8 * byteLength - 1));
970 var i = byteLength - 1;
973 this[offset + i] = value;
974 while (--i >= 0 && (mul *= 0x100)) {
975 if (value < 0 && sub === 0 && this[offset + i + 1] !== 0)
977 this[offset + i] = ((value / mul) >> 0) - sub;
980 return offset + byteLength;
984 Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
986 offset = offset >>> 0;
988 checkInt(this, value, offset, 1, 0x7f, -0x80);
989 this[offset] = value;
994 Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
996 offset = offset >>> 0;
998 checkInt(this, value, offset, 2, 0x7fff, -0x8000);
999 this[offset] = value;
1000 this[offset + 1] = (value >>> 8);
1005 Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
1007 offset = offset >>> 0;
1009 checkInt(this, value, offset, 2, 0x7fff, -0x8000);
1010 this[offset] = (value >>> 8);
1011 this[offset + 1] = value;
1016 Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
1018 offset = offset >>> 0;
1020 checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
1021 this[offset] = value;
1022 this[offset + 1] = (value >>> 8);
1023 this[offset + 2] = (value >>> 16);
1024 this[offset + 3] = (value >>> 24);
1029 Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
1031 offset = offset >>> 0;
1033 checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
1034 this[offset] = (value >>> 24);
1035 this[offset + 1] = (value >>> 16);
1036 this[offset + 2] = (value >>> 8);
1037 this[offset + 3] = value;
1042 function checkFloat(buffer, value, offset, ext) {
1043 if (!(buffer instanceof Buffer))
1044 throw new TypeError('buffer must be a Buffer instance');
1045 if (offset + ext > buffer.length)
1046 throw new RangeError('index out of range');
1050 Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) {
1052 offset = offset >>> 0;
1054 checkFloat(this, val, offset, 4);
1055 binding.writeFloatLE(this, val, offset);
1060 Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) {
1062 offset = offset >>> 0;
1064 checkFloat(this, val, offset, 4);
1065 binding.writeFloatBE(this, val, offset);
1070 Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) {
1072 offset = offset >>> 0;
1074 checkFloat(this, val, offset, 8);
1075 binding.writeDoubleLE(this, val, offset);
1080 Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
1082 offset = offset >>> 0;
1084 checkFloat(this, val, offset, 8);
1085 binding.writeDoubleBE(this, val, offset);