1 // Copyright Joyent, Inc. and other Node contributors.
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
22 var buffer = process.binding('buffer');
23 var smalloc = process.binding('smalloc');
24 var util = require('util');
25 var alloc = smalloc.alloc;
26 var truncate = smalloc.truncate;
27 var sliceOnto = smalloc.sliceOnto;
28 var kMaxLength = smalloc.kMaxLength;
31 exports.Buffer = Buffer;
32 exports.SlowBuffer = SlowBuffer;
33 exports.INSPECT_MAX_BYTES = 50;
36 Buffer.poolSize = 8 * 1024;
37 var poolSize, poolOffset, allocPool;
40 function createPool() {
41 poolSize = Buffer.poolSize;
42 allocPool = alloc({}, poolSize);
48 function Buffer(subject, encoding) {
49 if (!util.isBuffer(this))
50 return new Buffer(subject, encoding);
52 if (util.isNumber(subject)) {
53 this.length = subject > 0 ? subject >>> 0 : 0;
55 } else if (util.isString(subject)) {
56 if (!util.isString(encoding) || encoding.length === 0)
58 this.length = Buffer.byteLength(subject, encoding);
60 // Handle Arrays, Buffers, Uint8Arrays or JSON.
61 } else if (util.isObject(subject)) {
62 if (subject.type === 'Buffer' && util.isArray(subject.data))
63 subject = subject.data;
64 // Must use floor() because array length may be > kMaxLength.
65 this.length = +subject.length > 0 ? Math.floor(+subject.length) : 0;
68 throw new TypeError('must start with number, buffer, array or string');
71 if (this.length > kMaxLength) {
72 throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
73 'size: 0x' + kMaxLength.toString(16) + ' bytes');
76 this.parent = undefined;
77 if (this.length <= (Buffer.poolSize >>> 1) && this.length > 0) {
78 if (this.length > poolSize - poolOffset)
80 this.parent = sliceOnto(allocPool,
83 poolOffset + this.length);
84 poolOffset += this.length;
86 alloc(this, this.length);
89 if (util.isNumber(subject)) {
93 if (util.isString(subject)) {
94 // In the case of base64 it's possible that the size of the buffer
95 // allocated was slightly too large. In this case we need to rewrite
96 // the length to the actual length written.
97 var len = this.write(subject, encoding);
98 // Buffer was truncated after decode, realloc internal ExternalArray
99 if (len !== this.length) {
100 var prevLen = this.length;
102 truncate(this, this.length);
103 poolOffset -= (prevLen - len);
106 } else if (util.isBuffer(subject)) {
107 subject.copy(this, 0, 0, this.length);
109 } else if (util.isNumber(subject.length) || util.isArray(subject)) {
110 // Really crappy way to handle Uint8Arrays, but V8 doesn't give a simple
111 // way to access the data from the C++ API.
112 for (var i = 0; i < this.length; i++)
113 this[i] = subject[i];
118 function SlowBuffer(length) {
119 length = length >>> 0;
120 if (length > kMaxLength) {
121 throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
122 'size: 0x' + kMaxLength.toString(16) + ' bytes');
124 var b = new NativeBuffer(length);
130 // Bypass all checks for instantiating unallocated Buffer required for
131 // Objects created in C++. Significantly faster than calling the Buffer
133 function NativeBuffer(length) {
134 this.length = length >>> 0;
135 // Set this to keep the object map the same.
136 this.parent = undefined;
138 NativeBuffer.prototype = Buffer.prototype;
141 // add methods to Buffer prototype
142 buffer.setupBufferJS(NativeBuffer, internal);
147 Buffer.isBuffer = function isBuffer(b) {
148 return util.isBuffer(b);
152 Buffer.compare = function compare(a, b) {
153 if (!(a instanceof Buffer) ||
154 !(b instanceof Buffer))
155 throw new TypeError('Arguments must be Buffers');
157 return internal.compare(a, b);
161 Buffer.isEncoding = function(encoding) {
162 switch ((encoding + '').toLowerCase()) {
182 Buffer.concat = function(list, length) {
183 if (!util.isArray(list))
184 throw new TypeError('Usage: Buffer.concat(list[, length])');
186 if (util.isUndefined(length)) {
188 for (var i = 0; i < list.length; i++)
189 length += list[i].length;
191 length = length >>> 0;
194 if (list.length === 0)
195 return new Buffer(0);
196 else if (list.length === 1)
199 var buffer = new Buffer(length);
201 for (var i = 0; i < list.length; i++) {
203 buf.copy(buffer, pos);
211 Buffer.byteLength = function(str, enc) {
224 ret = str.length * 2;
227 ret = str.length >>> 1;
230 ret = internal.byteLength(str, enc);
236 // toString(encoding, start=0, end=buffer.length)
237 Buffer.prototype.toString = function(encoding, start, end) {
238 var loweredCase = false;
241 end = util.isUndefined(end) || end === Infinity ? this.length : end >>> 0;
243 if (!encoding) encoding = 'utf8';
244 if (start < 0) start = 0;
245 if (end > this.length) end = this.length;
246 if (end <= start) return '';
251 return this.hexSlice(start, end);
255 return this.utf8Slice(start, end);
258 return this.asciiSlice(start, end);
261 return this.binarySlice(start, end);
264 return this.base64Slice(start, end);
270 return this.ucs2Slice(start, end);
274 throw new TypeError('Unknown encoding: ' + encoding);
275 encoding = (encoding + '').toLowerCase();
282 Buffer.prototype.equals = function equals(b) {
283 if (!(b instanceof Buffer))
284 throw new TypeError('Argument must be a Buffer');
286 return internal.compare(this, b) === 0;
291 Buffer.prototype.inspect = function inspect() {
293 var max = exports.INSPECT_MAX_BYTES;
294 if (this.length > 0) {
295 str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');
296 if (this.length > max)
299 return '<' + this.constructor.name + ' ' + str + '>';
303 Buffer.prototype.compare = function compare(b) {
304 if (!(b instanceof Buffer))
305 throw new TypeError('Argument must be a Buffer');
307 return internal.compare(this, b);
311 Buffer.prototype.fill = function fill(val, start, end) {
313 end = (end === undefined) ? this.length : end >> 0;
315 if (start < 0 || end > this.length)
316 throw new RangeError('out of range index');
320 if (typeof val !== 'string') {
322 } else if (val.length === 1) {
323 var code = val.charCodeAt(0);
328 internal.fill(this, val, start, end);
334 // XXX remove in v0.13
335 Buffer.prototype.get = util.deprecate(function get(offset) {
337 if (offset < 0 || offset >= this.length)
338 throw new RangeError('index out of range');
340 }, '.get() is deprecated. Access using array indexes instead.');
343 // XXX remove in v0.13
344 Buffer.prototype.set = util.deprecate(function set(offset, v) {
346 if (offset < 0 || offset >= this.length)
347 throw new RangeError('index out of range');
348 return this[offset] = v;
349 }, '.set() is deprecated. Set using array indexes instead.');
352 // TODO(trevnorris): fix these checks to follow new standard
353 // write(string, offset = 0, length = buffer.length, encoding = 'utf8')
354 var writeWarned = false;
355 var writeMsg = '.write(string, encoding, offset, length) is deprecated.' +
356 ' Use write(string[, offset[, length]][, encoding]) instead.';
357 Buffer.prototype.write = function(string, offset, length, encoding) {
358 // Buffer#write(string);
359 if (util.isUndefined(offset)) {
361 length = this.length;
364 // Buffer#write(string, encoding)
365 } else if (util.isUndefined(length) && util.isString(offset)) {
367 length = this.length;
370 // Buffer#write(string, offset[, length][, encoding])
371 } else if (isFinite(offset)) {
372 offset = offset >>> 0;
373 if (isFinite(length)) {
374 length = length >>> 0;
375 if (util.isUndefined(encoding))
382 // XXX legacy write(string, encoding, offset, length) - remove in v0.13
385 if (process.throwDeprecation)
386 throw new Error(writeMsg);
387 else if (process.traceDeprecation)
388 console.trace(writeMsg);
390 console.error(writeMsg);
396 offset = length >>> 0;
400 var remaining = this.length - offset;
401 if (util.isUndefined(length) || length > remaining)
404 encoding = !!encoding ? (encoding + '').toLowerCase() : 'utf8';
406 if (string.length > 0 && (length < 0 || offset < 0))
407 throw new RangeError('attempt to write outside buffer bounds');
412 ret = this.hexWrite(string, offset, length);
417 ret = this.utf8Write(string, offset, length);
421 ret = this.asciiWrite(string, offset, length);
425 ret = this.binaryWrite(string, offset, length);
429 // Warning: maxLength not taken into account in base64Write
430 ret = this.base64Write(string, offset, length);
437 ret = this.ucs2Write(string, offset, length);
441 throw new TypeError('Unknown encoding: ' + encoding);
448 Buffer.prototype.toJSON = function() {
451 data: Array.prototype.slice.call(this, 0)
456 // TODO(trevnorris): currently works like Array.prototype.slice(), which
457 // doesn't follow the new standard for throwing on out of range indexes.
458 Buffer.prototype.slice = function(start, end) {
459 var len = this.length;
461 end = util.isUndefined(end) ? len : ~~end;
467 } else if (start > len) {
475 } else if (end > len) {
482 var buf = new NativeBuffer();
483 sliceOnto(this, buf, start, end);
484 buf.length = end - start;
486 buf.parent = util.isUndefined(this.parent) ? this : this.parent;
492 function checkOffset(offset, ext, length) {
493 if (offset + ext > length)
494 throw new RangeError('index out of range');
498 Buffer.prototype.readUIntLE = function(offset, byteLength, noAssert) {
499 offset = offset >>> 0;
500 byteLength = byteLength >>> 0;
502 checkOffset(offset, byteLength, this.length);
504 var val = this[offset];
507 while (++i < byteLength && (mul *= 0x100))
508 val += this[offset + i] * mul;
514 Buffer.prototype.readUIntBE = function(offset, byteLength, noAssert) {
515 offset = offset >>> 0;
516 byteLength = byteLength >>> 0;
518 checkOffset(offset, byteLength, this.length);
520 var val = this[offset + --byteLength];
522 while (byteLength > 0 && (mul *= 0x100))
523 val += this[offset + --byteLength] * mul;
529 Buffer.prototype.readUInt8 = function(offset, noAssert) {
530 offset = offset >>> 0;
532 checkOffset(offset, 1, this.length);
537 Buffer.prototype.readUInt16LE = function(offset, noAssert) {
538 offset = offset >>> 0;
540 checkOffset(offset, 2, this.length);
541 return this[offset] | (this[offset + 1] << 8);
545 Buffer.prototype.readUInt16BE = function(offset, noAssert) {
546 offset = offset >>> 0;
548 checkOffset(offset, 2, this.length);
549 return (this[offset] << 8) | this[offset + 1];
553 Buffer.prototype.readUInt32LE = function(offset, noAssert) {
554 offset = offset >>> 0;
556 checkOffset(offset, 4, this.length);
558 return ((this[offset]) |
559 (this[offset + 1] << 8) |
560 (this[offset + 2] << 16)) +
561 (this[offset + 3] * 0x1000000);
565 Buffer.prototype.readUInt32BE = function(offset, noAssert) {
566 offset = offset >>> 0;
568 checkOffset(offset, 4, this.length);
570 return (this[offset] * 0x1000000) +
571 ((this[offset + 1] << 16) |
572 (this[offset + 2] << 8) |
577 Buffer.prototype.readIntLE = function(offset, byteLength, noAssert) {
578 offset = offset >>> 0;
579 byteLength = byteLength >>> 0;
581 checkOffset(offset, byteLength, this.length);
583 var val = this[offset];
586 while (++i < byteLength && (mul *= 0x100))
587 val += this[offset + i] * mul;
591 val -= Math.pow(2, 8 * byteLength);
597 Buffer.prototype.readIntBE = function(offset, byteLength, noAssert) {
598 offset = offset >>> 0;
599 byteLength = byteLength >>> 0;
601 checkOffset(offset, byteLength, this.length);
605 var val = this[offset + --i];
606 while (i > 0 && (mul *= 0x100))
607 val += this[offset + --i] * mul;
611 val -= Math.pow(2, 8 * byteLength);
617 Buffer.prototype.readInt8 = function(offset, noAssert) {
618 offset = offset >>> 0;
620 checkOffset(offset, 1, this.length);
621 var val = this[offset];
622 return !(val & 0x80) ? val : (0xff - val + 1) * -1;
626 Buffer.prototype.readInt16LE = function(offset, noAssert) {
627 offset = offset >>> 0;
629 checkOffset(offset, 2, this.length);
630 var val = this[offset] | (this[offset + 1] << 8);
631 return (val & 0x8000) ? val | 0xFFFF0000 : val;
635 Buffer.prototype.readInt16BE = function(offset, noAssert) {
636 offset = offset >>> 0;
638 checkOffset(offset, 2, this.length);
639 var val = this[offset + 1] | (this[offset] << 8);
640 return (val & 0x8000) ? val | 0xFFFF0000 : val;
644 Buffer.prototype.readInt32LE = function(offset, noAssert) {
645 offset = offset >>> 0;
647 checkOffset(offset, 4, this.length);
649 return (this[offset]) |
650 (this[offset + 1] << 8) |
651 (this[offset + 2] << 16) |
652 (this[offset + 3] << 24);
656 Buffer.prototype.readInt32BE = function(offset, noAssert) {
657 offset = offset >>> 0;
659 checkOffset(offset, 4, this.length);
661 return (this[offset] << 24) |
662 (this[offset + 1] << 16) |
663 (this[offset + 2] << 8) |
668 Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
669 offset = offset >>> 0;
671 checkOffset(offset, 4, this.length);
672 return internal.readFloatLE(this, offset);
676 Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
677 offset = offset >>> 0;
679 checkOffset(offset, 4, this.length);
680 return internal.readFloatBE(this, offset);
684 Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
685 offset = offset >>> 0;
687 checkOffset(offset, 8, this.length);
688 return internal.readDoubleLE(this, offset);
692 Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
693 offset = offset >>> 0;
695 checkOffset(offset, 8, this.length);
696 return internal.readDoubleBE(this, offset);
700 function checkInt(buffer, value, offset, ext, max, min) {
701 if (!(buffer instanceof Buffer))
702 throw new TypeError('buffer must be a Buffer instance');
703 if (value > max || value < min)
704 throw new TypeError('value is out of bounds');
705 if (offset + ext > buffer.length)
706 throw new RangeError('index out of range');
710 Buffer.prototype.writeUIntLE = function(value, offset, byteLength, noAssert) {
712 offset = offset >>> 0;
713 byteLength = byteLength >>> 0;
715 checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
719 this[offset] = value;
720 while (++i < byteLength && (mul *= 0x100))
721 this[offset + i] = (value / mul) >>> 0;
723 return offset + byteLength;
727 Buffer.prototype.writeUIntBE = function(value, offset, byteLength, noAssert) {
729 offset = offset >>> 0;
730 byteLength = byteLength >>> 0;
732 checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
734 var i = byteLength - 1;
736 this[offset + i] = value;
737 while (--i >= 0 && (mul *= 0x100))
738 this[offset + i] = (value / mul) >>> 0;
740 return offset + byteLength;
744 Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
746 offset = offset >>> 0;
748 checkInt(this, value, offset, 1, 0xff, 0);
749 this[offset] = value;
754 Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
756 offset = offset >>> 0;
758 checkInt(this, value, offset, 2, 0xffff, 0);
759 this[offset] = value;
760 this[offset + 1] = (value >>> 8);
765 Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
767 offset = offset >>> 0;
769 checkInt(this, value, offset, 2, 0xffff, 0);
770 this[offset] = (value >>> 8);
771 this[offset + 1] = value;
776 Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
778 offset = offset >>> 0;
780 checkInt(this, value, offset, 4, 0xffffffff, 0);
781 this[offset + 3] = (value >>> 24);
782 this[offset + 2] = (value >>> 16);
783 this[offset + 1] = (value >>> 8);
784 this[offset] = value;
789 Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
791 offset = offset >>> 0;
793 checkInt(this, value, offset, 4, 0xffffffff, 0);
794 this[offset] = (value >>> 24);
795 this[offset + 1] = (value >>> 16);
796 this[offset + 2] = (value >>> 8);
797 this[offset + 3] = value;
802 Buffer.prototype.writeIntLE = function(value, offset, byteLength, noAssert) {
804 offset = offset >>> 0;
810 Math.pow(2, 8 * byteLength - 1) - 1,
811 -Math.pow(2, 8 * byteLength - 1));
816 var sub = value < 0 ? 1 : 0;
817 this[offset] = value;
818 while (++i < byteLength && (mul *= 0x100))
819 this[offset + i] = ((value / mul) >> 0) - sub;
821 return offset + byteLength;
825 Buffer.prototype.writeIntBE = function(value, offset, byteLength, noAssert) {
827 offset = offset >>> 0;
833 Math.pow(2, 8 * byteLength - 1) - 1,
834 -Math.pow(2, 8 * byteLength - 1));
837 var i = byteLength - 1;
839 var sub = value < 0 ? 1 : 0;
840 this[offset + i] = value;
841 while (--i >= 0 && (mul *= 0x100))
842 this[offset + i] = ((value / mul) >> 0) - sub;
844 return offset + byteLength;
848 Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
850 offset = offset >>> 0;
852 checkInt(this, value, offset, 1, 0x7f, -0x80);
853 this[offset] = value;
858 Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
860 offset = offset >>> 0;
862 checkInt(this, value, offset, 2, 0x7fff, -0x8000);
863 this[offset] = value;
864 this[offset + 1] = (value >>> 8);
869 Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
871 offset = offset >>> 0;
873 checkInt(this, value, offset, 2, 0x7fff, -0x8000);
874 this[offset] = (value >>> 8);
875 this[offset + 1] = value;
880 Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
882 offset = offset >>> 0;
884 checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
885 this[offset] = value;
886 this[offset + 1] = (value >>> 8);
887 this[offset + 2] = (value >>> 16);
888 this[offset + 3] = (value >>> 24);
893 Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
895 offset = offset >>> 0;
897 checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
898 this[offset] = (value >>> 24);
899 this[offset + 1] = (value >>> 16);
900 this[offset + 2] = (value >>> 8);
901 this[offset + 3] = value;
906 function checkFloat(buffer, value, offset, ext) {
907 if (!(buffer instanceof Buffer))
908 throw new TypeError('buffer must be a Buffer instance');
909 if (offset + ext > buffer.length)
910 throw new RangeError('index out of range');
914 Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) {
916 offset = offset >>> 0;
918 checkFloat(this, val, offset, 4);
919 internal.writeFloatLE(this, val, offset);
924 Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) {
926 offset = offset >>> 0;
928 checkFloat(this, val, offset, 4);
929 internal.writeFloatBE(this, val, offset);
934 Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) {
936 offset = offset >>> 0;
938 checkFloat(this, val, offset, 8);
939 internal.writeDoubleLE(this, val, offset);
944 Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
946 offset = offset >>> 0;
948 checkFloat(this, val, offset, 8);
949 internal.writeDoubleBE(this, val, offset);