5427a5a5a66e29bd6fef7bf8236b56fef5c93f07
[platform/upstream/nodejs.git] / lib / buffer.js
1 'use strict';
2
3 const binding = process.binding('buffer');
4 const smalloc = process.binding('smalloc');
5 const util = require('util');
6 const alloc = smalloc.alloc;
7 const truncate = smalloc.truncate;
8 const sliceOnto = smalloc.sliceOnto;
9 const kMaxLength = smalloc.kMaxLength;
10
11 exports.Buffer = Buffer;
12 exports.SlowBuffer = SlowBuffer;
13 exports.INSPECT_MAX_BYTES = 50;
14
15
16 Buffer.poolSize = 8 * 1024;
17 var poolSize, poolOffset, allocPool;
18
19
20 function createPool() {
21   poolSize = Buffer.poolSize;
22   allocPool = alloc({}, poolSize);
23   poolOffset = 0;
24 }
25 createPool();
26
27 function Buffer(arg) {
28   if (!(this instanceof Buffer)) {
29     // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
30     if (arguments.length > 1)
31       return new Buffer(arg, arguments[1]);
32
33     return new Buffer(arg);
34   }
35
36   this.length = 0;
37   this.parent = undefined;
38
39   // Common case.
40   if (typeof(arg) === 'number') {
41     fromNumber(this, arg);
42     return;
43   }
44
45   // Slightly less common case.
46   if (typeof(arg) === 'string') {
47     fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8');
48     return;
49   }
50
51   // Unusual.
52   fromObject(this, arg);
53 }
54
55 function fromNumber(that, length) {
56   allocate(that, length < 0 ? 0 : checked(length) | 0);
57 }
58
59 function fromString(that, string, encoding) {
60   if (typeof(encoding) !== 'string' || encoding === '')
61     encoding = 'utf8';
62
63   // Assumption: byteLength() return value is always < kMaxLength.
64   var length = byteLength(string, encoding) | 0;
65   allocate(that, length);
66
67   var actual = that.write(string, encoding) | 0;
68   if (actual !== length) {
69     // Fix up for truncated base64 input.  Don't bother returning
70     // the unused two or three bytes to the pool.
71     that.length = actual;
72     truncate(that, actual);
73   }
74 }
75
76 function fromObject(that, object) {
77   if (object instanceof Buffer)
78     return fromBuffer(that, object);
79
80   if (Array.isArray(object))
81     return fromArray(that, object);
82
83   if (object == null)
84     throw new TypeError('must start with number, buffer, array or string');
85
86   if (object.buffer instanceof ArrayBuffer)
87     return fromTypedArray(that, object);
88
89   if (object.length)
90     return fromArrayLike(that, object);
91
92   return fromJsonObject(that, object);
93 }
94
95 function fromBuffer(that, buffer) {
96   var length = checked(buffer.length) | 0;
97   allocate(that, length);
98   buffer.copy(that, 0, 0, length);
99 }
100
101 function fromArray(that, array) {
102   var length = checked(array.length) | 0;
103   allocate(that, length);
104   for (var i = 0; i < length; i += 1)
105     that[i] = array[i] & 255;
106 }
107
108 // Duplicate of fromArray() to keep fromArray() monomorphic.
109 function fromTypedArray(that, array) {
110   var length = checked(array.length) | 0;
111   allocate(that, length);
112   // Truncating the elements is probably not what people expect from typed
113   // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
114   // of the old Buffer constructor.
115   for (var i = 0; i < length; i += 1)
116     that[i] = array[i] & 255;
117 }
118
119 function fromArrayLike(that, array) {
120   var length = checked(array.length) | 0;
121   allocate(that, length);
122   for (var i = 0; i < length; i += 1)
123     that[i] = array[i] & 255;
124 }
125
126 // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
127 // Returns a zero-length buffer for inputs that don't conform to the spec.
128 function fromJsonObject(that, object) {
129   var array;
130   var length = 0;
131
132   if (object.type === 'Buffer' && Array.isArray(object.data)) {
133     array = object.data;
134     length = checked(array.length) | 0;
135   }
136   allocate(that, length);
137
138   for (var i = 0; i < length; i += 1)
139     that[i] = array[i] & 255;
140 }
141
142 function allocate(that, length) {
143   var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1;
144   that.parent = fromPool ? palloc(that, length) : alloc(that, length);
145   that.length = length;
146 }
147
148 function palloc(that, length) {
149   if (length > poolSize - poolOffset)
150     createPool();
151
152   var start = poolOffset;
153   var end = start + length;
154   var buf = sliceOnto(allocPool, that, start, end);
155   poolOffset = end;
156
157   return buf;
158 }
159
160 function checked(length) {
161   // Note: cannot use `length < kMaxLength` here because that fails when
162   // length is NaN (which is otherwise coerced to zero.)
163   if (length >= kMaxLength) {
164     throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
165                          'size: 0x' + kMaxLength.toString(16) + ' bytes');
166   }
167   return length >>> 0;
168 }
169
170 function SlowBuffer(length) {
171   length = length >>> 0;
172   if (length > kMaxLength) {
173     throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
174                          'size: 0x' + kMaxLength.toString(16) + ' bytes');
175   }
176   var b = new NativeBuffer(length);
177   alloc(b, length);
178   return b;
179 }
180
181
182 // Bypass all checks for instantiating unallocated Buffer required for
183 // Objects created in C++. Significantly faster than calling the Buffer
184 // function.
185 function NativeBuffer(length) {
186   this.length = length >>> 0;
187   // Set this to keep the object map the same.
188   this.parent = undefined;
189 }
190 NativeBuffer.prototype = Buffer.prototype;
191
192
193 // add methods to Buffer prototype
194 binding.setupBufferJS(NativeBuffer);
195
196
197 // Static methods
198
199 Buffer.isBuffer = function isBuffer(b) {
200   return b instanceof Buffer;
201 };
202
203
204 Buffer.compare = function compare(a, b) {
205   if (!(a instanceof Buffer) ||
206       !(b instanceof Buffer))
207     throw new TypeError('Arguments must be Buffers');
208
209   if (a === b)
210     return 0;
211
212   return binding.compare(a, b);
213 };
214
215
216 Buffer.isEncoding = function(encoding) {
217   switch ((encoding + '').toLowerCase()) {
218     case 'hex':
219     case 'utf8':
220     case 'utf-8':
221     case 'ascii':
222     case 'binary':
223     case 'base64':
224     case 'ucs2':
225     case 'ucs-2':
226     case 'utf16le':
227     case 'utf-16le':
228     case 'raw':
229       return true;
230
231     default:
232       return false;
233   }
234 };
235
236
237 Buffer.concat = function(list, length) {
238   if (!Array.isArray(list))
239     throw new TypeError('list argument must be an Array of Buffers.');
240
241   if (length === undefined) {
242     length = 0;
243     for (var i = 0; i < list.length; i++)
244       length += list[i].length;
245   } else {
246     length = length >>> 0;
247   }
248
249   if (list.length === 0)
250     return new Buffer(0);
251   else if (list.length === 1)
252     return list[0];
253
254   var buffer = new Buffer(length);
255   var pos = 0;
256   for (var i = 0; i < list.length; i++) {
257     var buf = list[i];
258     buf.copy(buffer, pos);
259     pos += buf.length;
260   }
261
262   return buffer;
263 };
264
265
266 function byteLength(string, encoding) {
267   if (typeof(string) !== 'string')
268     string = String(string);
269
270   switch (encoding) {
271     case 'ascii':
272     case 'binary':
273     case 'raw':
274       return string.length;
275
276     case 'ucs2':
277     case 'ucs-2':
278     case 'utf16le':
279     case 'utf-16le':
280       return string.length * 2;
281
282     case 'hex':
283       return string.length >>> 1;
284   }
285
286   return binding.byteLength(string, encoding);
287 }
288
289 Buffer.byteLength = byteLength;
290
291 // toString(encoding, start=0, end=buffer.length)
292 Buffer.prototype.toString = function(encoding, start, end) {
293   var loweredCase = false;
294
295   start = start >>> 0;
296   end = end === undefined || end === Infinity ? this.length : end >>> 0;
297
298   if (!encoding) encoding = 'utf8';
299   if (start < 0) start = 0;
300   if (end > this.length) end = this.length;
301   if (end <= start) return '';
302
303   while (true) {
304     switch (encoding) {
305       case 'hex':
306         return this.hexSlice(start, end);
307
308       case 'utf8':
309       case 'utf-8':
310         return this.utf8Slice(start, end);
311
312       case 'ascii':
313         return this.asciiSlice(start, end);
314
315       case 'binary':
316         return this.binarySlice(start, end);
317
318       case 'base64':
319         return this.base64Slice(start, end);
320
321       case 'ucs2':
322       case 'ucs-2':
323       case 'utf16le':
324       case 'utf-16le':
325         return this.ucs2Slice(start, end);
326
327       default:
328         if (loweredCase)
329           throw new TypeError('Unknown encoding: ' + encoding);
330         encoding = (encoding + '').toLowerCase();
331         loweredCase = true;
332     }
333   }
334 };
335
336
337 Buffer.prototype.equals = function equals(b) {
338   if (!(b instanceof Buffer))
339     throw new TypeError('Argument must be a Buffer');
340
341   if (this === b)
342     return true;
343
344   return binding.compare(this, b) === 0;
345 };
346
347
348 // Inspect
349 Buffer.prototype.inspect = function inspect() {
350   var str = '';
351   var max = exports.INSPECT_MAX_BYTES;
352   if (this.length > 0) {
353     str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');
354     if (this.length > max)
355       str += ' ... ';
356   }
357   return '<' + this.constructor.name + ' ' + str + '>';
358 };
359
360
361 Buffer.prototype.compare = function compare(b) {
362   if (!(b instanceof Buffer))
363     throw new TypeError('Argument must be a Buffer');
364
365   if (this === b)
366     return 0;
367
368   return binding.compare(this, b);
369 };
370
371
372 Buffer.prototype.indexOf = function indexOf(val, byteOffset) {
373   if (byteOffset > 0x7fffffff)
374     byteOffset = 0x7fffffff;
375   else if (byteOffset < -0x80000000)
376     byteOffset = -0x80000000;
377   byteOffset >>= 0;
378
379   if (typeof val === 'string')
380     return binding.indexOfString(this, val, byteOffset);
381   if (val instanceof Buffer)
382     return binding.indexOfBuffer(this, val, byteOffset);
383   if (typeof val === 'number')
384     return binding.indexOfNumber(this, val, byteOffset);
385
386   throw new TypeError('val must be string, number or Buffer');
387 };
388
389
390 Buffer.prototype.fill = function fill(val, start, end) {
391   start = start >> 0;
392   end = (end === undefined) ? this.length : end >> 0;
393
394   if (start < 0 || end > this.length)
395     throw new RangeError('out of range index');
396   if (end <= start)
397     return this;
398
399   if (typeof val !== 'string') {
400     val = val >>> 0;
401   } else if (val.length === 1) {
402     var code = val.charCodeAt(0);
403     if (code < 256)
404       val = code;
405   }
406
407   binding.fill(this, val, start, end);
408
409   return this;
410 };
411
412
413 // XXX remove in v0.13
414 Buffer.prototype.get = util.deprecate(function get(offset) {
415   offset = ~~offset;
416   if (offset < 0 || offset >= this.length)
417     throw new RangeError('index out of range');
418   return this[offset];
419 }, '.get() is deprecated. Access using array indexes instead.');
420
421
422 // XXX remove in v0.13
423 Buffer.prototype.set = util.deprecate(function set(offset, v) {
424   offset = ~~offset;
425   if (offset < 0 || offset >= this.length)
426     throw new RangeError('index out of range');
427   return this[offset] = v;
428 }, '.set() is deprecated. Set using array indexes instead.');
429
430
431 // TODO(trevnorris): fix these checks to follow new standard
432 // write(string, offset = 0, length = buffer.length, encoding = 'utf8')
433 var writeWarned = false;
434 const writeMsg = '.write(string, encoding, offset, length) is deprecated.' +
435                  ' Use write(string[, offset[, length]][, encoding]) instead.';
436 Buffer.prototype.write = function(string, offset, length, encoding) {
437   // Buffer#write(string);
438   if (offset === undefined) {
439     encoding = 'utf8';
440     length = this.length;
441     offset = 0;
442
443   // Buffer#write(string, encoding)
444   } else if (length === undefined && typeof offset === 'string') {
445     encoding = offset;
446     length = this.length;
447     offset = 0;
448
449   // Buffer#write(string, offset[, length][, encoding])
450   } else if (isFinite(offset)) {
451     offset = offset >>> 0;
452     if (isFinite(length)) {
453       length = length >>> 0;
454       if (encoding === undefined)
455         encoding = 'utf8';
456     } else {
457       encoding = length;
458       length = undefined;
459     }
460
461   // XXX legacy write(string, encoding, offset, length) - remove in v0.13
462   } else {
463     if (!writeWarned) {
464       if (process.throwDeprecation)
465         throw new Error(writeMsg);
466       else if (process.traceDeprecation)
467         console.trace(writeMsg);
468       else
469         console.error(writeMsg);
470       writeWarned = true;
471     }
472
473     var swap = encoding;
474     encoding = offset;
475     offset = length >>> 0;
476     length = swap;
477   }
478
479   var remaining = this.length - offset;
480   if (length === undefined || length > remaining)
481     length = remaining;
482
483   if (string.length > 0 && (length < 0 || offset < 0))
484     throw new RangeError('attempt to write outside buffer bounds');
485
486   if (!encoding)
487     encoding = 'utf8';
488
489   var loweredCase = false;
490   for (;;) {
491     switch (encoding) {
492       case 'hex':
493         return this.hexWrite(string, offset, length);
494
495       case 'utf8':
496       case 'utf-8':
497         return this.utf8Write(string, offset, length);
498
499       case 'ascii':
500         return this.asciiWrite(string, offset, length);
501
502       case 'binary':
503         return this.binaryWrite(string, offset, length);
504
505       case 'base64':
506         // Warning: maxLength not taken into account in base64Write
507         return this.base64Write(string, offset, length);
508
509       case 'ucs2':
510       case 'ucs-2':
511       case 'utf16le':
512       case 'utf-16le':
513         return this.ucs2Write(string, offset, length);
514
515       default:
516         if (loweredCase)
517           throw new TypeError('Unknown encoding: ' + encoding);
518         encoding = ('' + encoding).toLowerCase();
519         loweredCase = true;
520     }
521   }
522 };
523
524
525 Buffer.prototype.toJSON = function() {
526   return {
527     type: 'Buffer',
528     data: Array.prototype.slice.call(this, 0)
529   };
530 };
531
532
533 // TODO(trevnorris): currently works like Array.prototype.slice(), which
534 // doesn't follow the new standard for throwing on out of range indexes.
535 Buffer.prototype.slice = function(start, end) {
536   var len = this.length;
537   start = ~~start;
538   end = end === undefined ? len : ~~end;
539
540   if (start < 0) {
541     start += len;
542     if (start < 0)
543       start = 0;
544   } else if (start > len) {
545     start = len;
546   }
547
548   if (end < 0) {
549     end += len;
550     if (end < 0)
551       end = 0;
552   } else if (end > len) {
553     end = len;
554   }
555
556   if (end < start)
557     end = start;
558
559   var buf = new NativeBuffer();
560   sliceOnto(this, buf, start, end);
561   buf.length = end - start;
562   if (buf.length > 0)
563     buf.parent = this.parent === undefined ? this : this.parent;
564
565   return buf;
566 };
567
568
569 function checkOffset(offset, ext, length) {
570   if (offset + ext > length)
571     throw new RangeError('index out of range');
572 }
573
574
575 Buffer.prototype.readUIntLE = function(offset, byteLength, noAssert) {
576   offset = offset >>> 0;
577   byteLength = byteLength >>> 0;
578   if (!noAssert)
579     checkOffset(offset, byteLength, this.length);
580
581   var val = this[offset];
582   var mul = 1;
583   var i = 0;
584   while (++i < byteLength && (mul *= 0x100))
585     val += this[offset + i] * mul;
586
587   return val;
588 };
589
590
591 Buffer.prototype.readUIntBE = function(offset, byteLength, noAssert) {
592   offset = offset >>> 0;
593   byteLength = byteLength >>> 0;
594   if (!noAssert)
595     checkOffset(offset, byteLength, this.length);
596
597   var val = this[offset + --byteLength];
598   var mul = 1;
599   while (byteLength > 0 && (mul *= 0x100))
600     val += this[offset + --byteLength] * mul;
601
602   return val;
603 };
604
605
606 Buffer.prototype.readUInt8 = function(offset, noAssert) {
607   offset = offset >>> 0;
608   if (!noAssert)
609     checkOffset(offset, 1, this.length);
610   return this[offset];
611 };
612
613
614 Buffer.prototype.readUInt16LE = function(offset, noAssert) {
615   offset = offset >>> 0;
616   if (!noAssert)
617     checkOffset(offset, 2, this.length);
618   return this[offset] | (this[offset + 1] << 8);
619 };
620
621
622 Buffer.prototype.readUInt16BE = function(offset, noAssert) {
623   offset = offset >>> 0;
624   if (!noAssert)
625     checkOffset(offset, 2, this.length);
626   return (this[offset] << 8) | this[offset + 1];
627 };
628
629
630 Buffer.prototype.readUInt32LE = function(offset, noAssert) {
631   offset = offset >>> 0;
632   if (!noAssert)
633     checkOffset(offset, 4, this.length);
634
635   return ((this[offset]) |
636       (this[offset + 1] << 8) |
637       (this[offset + 2] << 16)) +
638       (this[offset + 3] * 0x1000000);
639 };
640
641
642 Buffer.prototype.readUInt32BE = function(offset, noAssert) {
643   offset = offset >>> 0;
644   if (!noAssert)
645     checkOffset(offset, 4, this.length);
646
647   return (this[offset] * 0x1000000) +
648       ((this[offset + 1] << 16) |
649       (this[offset + 2] << 8) |
650       this[offset + 3]);
651 };
652
653
654 Buffer.prototype.readIntLE = function(offset, byteLength, noAssert) {
655   offset = offset >>> 0;
656   byteLength = byteLength >>> 0;
657   if (!noAssert)
658     checkOffset(offset, byteLength, this.length);
659
660   var val = this[offset];
661   var mul = 1;
662   var i = 0;
663   while (++i < byteLength && (mul *= 0x100))
664     val += this[offset + i] * mul;
665   mul *= 0x80;
666
667   if (val >= mul)
668     val -= Math.pow(2, 8 * byteLength);
669
670   return val;
671 };
672
673
674 Buffer.prototype.readIntBE = function(offset, byteLength, noAssert) {
675   offset = offset >>> 0;
676   byteLength = byteLength >>> 0;
677   if (!noAssert)
678     checkOffset(offset, byteLength, this.length);
679
680   var i = byteLength;
681   var mul = 1;
682   var val = this[offset + --i];
683   while (i > 0 && (mul *= 0x100))
684     val += this[offset + --i] * mul;
685   mul *= 0x80;
686
687   if (val >= mul)
688     val -= Math.pow(2, 8 * byteLength);
689
690   return val;
691 };
692
693
694 Buffer.prototype.readInt8 = function(offset, noAssert) {
695   offset = offset >>> 0;
696   if (!noAssert)
697     checkOffset(offset, 1, this.length);
698   var val = this[offset];
699   return !(val & 0x80) ? val : (0xff - val + 1) * -1;
700 };
701
702
703 Buffer.prototype.readInt16LE = function(offset, noAssert) {
704   offset = offset >>> 0;
705   if (!noAssert)
706     checkOffset(offset, 2, this.length);
707   var val = this[offset] | (this[offset + 1] << 8);
708   return (val & 0x8000) ? val | 0xFFFF0000 : val;
709 };
710
711
712 Buffer.prototype.readInt16BE = function(offset, noAssert) {
713   offset = offset >>> 0;
714   if (!noAssert)
715     checkOffset(offset, 2, this.length);
716   var val = this[offset + 1] | (this[offset] << 8);
717   return (val & 0x8000) ? val | 0xFFFF0000 : val;
718 };
719
720
721 Buffer.prototype.readInt32LE = function(offset, noAssert) {
722   offset = offset >>> 0;
723   if (!noAssert)
724     checkOffset(offset, 4, this.length);
725
726   return (this[offset]) |
727       (this[offset + 1] << 8) |
728       (this[offset + 2] << 16) |
729       (this[offset + 3] << 24);
730 };
731
732
733 Buffer.prototype.readInt32BE = function(offset, noAssert) {
734   offset = offset >>> 0;
735   if (!noAssert)
736     checkOffset(offset, 4, this.length);
737
738   return (this[offset] << 24) |
739       (this[offset + 1] << 16) |
740       (this[offset + 2] << 8) |
741       (this[offset + 3]);
742 };
743
744
745 Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
746   offset = offset >>> 0;
747   if (!noAssert)
748     checkOffset(offset, 4, this.length);
749   return binding.readFloatLE(this, offset);
750 };
751
752
753 Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
754   offset = offset >>> 0;
755   if (!noAssert)
756     checkOffset(offset, 4, this.length);
757   return binding.readFloatBE(this, offset);
758 };
759
760
761 Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
762   offset = offset >>> 0;
763   if (!noAssert)
764     checkOffset(offset, 8, this.length);
765   return binding.readDoubleLE(this, offset);
766 };
767
768
769 Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
770   offset = offset >>> 0;
771   if (!noAssert)
772     checkOffset(offset, 8, this.length);
773   return binding.readDoubleBE(this, offset);
774 };
775
776
777 function checkInt(buffer, value, offset, ext, max, min) {
778   if (!(buffer instanceof Buffer))
779     throw new TypeError('buffer must be a Buffer instance');
780   if (value > max || value < min)
781     throw new TypeError('value is out of bounds');
782   if (offset + ext > buffer.length)
783     throw new RangeError('index out of range');
784 }
785
786
787 Buffer.prototype.writeUIntLE = function(value, offset, byteLength, noAssert) {
788   value = +value;
789   offset = offset >>> 0;
790   byteLength = byteLength >>> 0;
791   if (!noAssert)
792     checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
793
794   var mul = 1;
795   var i = 0;
796   this[offset] = value;
797   while (++i < byteLength && (mul *= 0x100))
798     this[offset + i] = (value / mul) >>> 0;
799
800   return offset + byteLength;
801 };
802
803
804 Buffer.prototype.writeUIntBE = function(value, offset, byteLength, noAssert) {
805   value = +value;
806   offset = offset >>> 0;
807   byteLength = byteLength >>> 0;
808   if (!noAssert)
809     checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0);
810
811   var i = byteLength - 1;
812   var mul = 1;
813   this[offset + i] = value;
814   while (--i >= 0 && (mul *= 0x100))
815     this[offset + i] = (value / mul) >>> 0;
816
817   return offset + byteLength;
818 };
819
820
821 Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
822   value = +value;
823   offset = offset >>> 0;
824   if (!noAssert)
825     checkInt(this, value, offset, 1, 0xff, 0);
826   this[offset] = value;
827   return offset + 1;
828 };
829
830
831 Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
832   value = +value;
833   offset = offset >>> 0;
834   if (!noAssert)
835     checkInt(this, value, offset, 2, 0xffff, 0);
836   this[offset] = value;
837   this[offset + 1] = (value >>> 8);
838   return offset + 2;
839 };
840
841
842 Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
843   value = +value;
844   offset = offset >>> 0;
845   if (!noAssert)
846     checkInt(this, value, offset, 2, 0xffff, 0);
847   this[offset] = (value >>> 8);
848   this[offset + 1] = value;
849   return offset + 2;
850 };
851
852
853 Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
854   value = +value;
855   offset = offset >>> 0;
856   if (!noAssert)
857     checkInt(this, value, offset, 4, 0xffffffff, 0);
858   this[offset + 3] = (value >>> 24);
859   this[offset + 2] = (value >>> 16);
860   this[offset + 1] = (value >>> 8);
861   this[offset] = value;
862   return offset + 4;
863 };
864
865
866 Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
867   value = +value;
868   offset = offset >>> 0;
869   if (!noAssert)
870     checkInt(this, value, offset, 4, 0xffffffff, 0);
871   this[offset] = (value >>> 24);
872   this[offset + 1] = (value >>> 16);
873   this[offset + 2] = (value >>> 8);
874   this[offset + 3] = value;
875   return offset + 4;
876 };
877
878
879 Buffer.prototype.writeIntLE = function(value, offset, byteLength, noAssert) {
880   value = +value;
881   offset = offset >>> 0;
882   if (!noAssert) {
883     checkInt(this,
884              value,
885              offset,
886              byteLength,
887              Math.pow(2, 8 * byteLength - 1) - 1,
888              -Math.pow(2, 8 * byteLength - 1));
889   }
890
891   var i = 0;
892   var mul = 1;
893   var sub = value < 0 ? 1 : 0;
894   this[offset] = value;
895   while (++i < byteLength && (mul *= 0x100))
896     this[offset + i] = ((value / mul) >> 0) - sub;
897
898   return offset + byteLength;
899 };
900
901
902 Buffer.prototype.writeIntBE = function(value, offset, byteLength, noAssert) {
903   value = +value;
904   offset = offset >>> 0;
905   if (!noAssert) {
906     checkInt(this,
907              value,
908              offset,
909              byteLength,
910              Math.pow(2, 8 * byteLength - 1) - 1,
911              -Math.pow(2, 8 * byteLength - 1));
912   }
913
914   var i = byteLength - 1;
915   var mul = 1;
916   var sub = value < 0 ? 1 : 0;
917   this[offset + i] = value;
918   while (--i >= 0 && (mul *= 0x100))
919     this[offset + i] = ((value / mul) >> 0) - sub;
920
921   return offset + byteLength;
922 };
923
924
925 Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
926   value = +value;
927   offset = offset >>> 0;
928   if (!noAssert)
929     checkInt(this, value, offset, 1, 0x7f, -0x80);
930   this[offset] = value;
931   return offset + 1;
932 };
933
934
935 Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
936   value = +value;
937   offset = offset >>> 0;
938   if (!noAssert)
939     checkInt(this, value, offset, 2, 0x7fff, -0x8000);
940   this[offset] = value;
941   this[offset + 1] = (value >>> 8);
942   return offset + 2;
943 };
944
945
946 Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
947   value = +value;
948   offset = offset >>> 0;
949   if (!noAssert)
950     checkInt(this, value, offset, 2, 0x7fff, -0x8000);
951   this[offset] = (value >>> 8);
952   this[offset + 1] = value;
953   return offset + 2;
954 };
955
956
957 Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
958   value = +value;
959   offset = offset >>> 0;
960   if (!noAssert)
961     checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
962   this[offset] = value;
963   this[offset + 1] = (value >>> 8);
964   this[offset + 2] = (value >>> 16);
965   this[offset + 3] = (value >>> 24);
966   return offset + 4;
967 };
968
969
970 Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
971   value = +value;
972   offset = offset >>> 0;
973   if (!noAssert)
974     checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
975   this[offset] = (value >>> 24);
976   this[offset + 1] = (value >>> 16);
977   this[offset + 2] = (value >>> 8);
978   this[offset + 3] = value;
979   return offset + 4;
980 };
981
982
983 function checkFloat(buffer, value, offset, ext) {
984   if (!(buffer instanceof Buffer))
985     throw new TypeError('buffer must be a Buffer instance');
986   if (offset + ext > buffer.length)
987     throw new RangeError('index out of range');
988 }
989
990
991 Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) {
992   val = +val;
993   offset = offset >>> 0;
994   if (!noAssert)
995     checkFloat(this, val, offset, 4);
996   binding.writeFloatLE(this, val, offset);
997   return offset + 4;
998 };
999
1000
1001 Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) {
1002   val = +val;
1003   offset = offset >>> 0;
1004   if (!noAssert)
1005     checkFloat(this, val, offset, 4);
1006   binding.writeFloatBE(this, val, offset);
1007   return offset + 4;
1008 };
1009
1010
1011 Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) {
1012   val = +val;
1013   offset = offset >>> 0;
1014   if (!noAssert)
1015     checkFloat(this, val, offset, 8);
1016   binding.writeDoubleLE(this, val, offset);
1017   return offset + 8;
1018 };
1019
1020
1021 Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
1022   val = +val;
1023   offset = offset >>> 0;
1024   if (!noAssert)
1025     checkFloat(this, val, offset, 8);
1026   binding.writeDoubleBE(this, val, offset);
1027   return offset + 8;
1028 };
1029
1030 // ES6 iterator
1031
1032 var ITERATOR_KIND_KEYS = 1;
1033 var ITERATOR_KIND_ENTRIES = 3;
1034
1035 function BufferIteratorResult(value, done) {
1036   this.value = value;
1037   this.done = done;
1038 }
1039
1040 var resultCache = new Array(256);
1041
1042 for (var i = 0; i < 256; i++)
1043   resultCache[i] = Object.freeze(new BufferIteratorResult(i, false));
1044
1045 var finalResult = Object.freeze(new BufferIteratorResult(undefined, true));
1046
1047 function BufferIterator(buffer, kind) {
1048   this._buffer = buffer;
1049   this._kind = kind;
1050   this._index = 0;
1051 }
1052
1053 BufferIterator.prototype.next = function() {
1054   var buffer = this._buffer;
1055   var kind = this._kind;
1056   var index = this._index;
1057
1058   if (index >= buffer.length)
1059     return finalResult;
1060
1061   this._index++;
1062
1063   if (kind === ITERATOR_KIND_ENTRIES)
1064     return new BufferIteratorResult([index, buffer[index]], false);
1065
1066   return new BufferIteratorResult(index, false);
1067 };
1068
1069 function BufferValueIterator(buffer) {
1070   BufferIterator.call(this, buffer, null);
1071 }
1072
1073 BufferValueIterator.prototype.next = function() {
1074   var buffer = this._buffer;
1075   var index = this._index;
1076
1077   if (index >= buffer.length)
1078     return finalResult;
1079
1080   this._index++;
1081
1082   return resultCache[buffer[index]];
1083 };
1084
1085
1086 BufferIterator.prototype[Symbol.iterator] = function() {
1087   return this;
1088 };
1089
1090 BufferValueIterator.prototype[Symbol.iterator] =
1091     BufferIterator.prototype[Symbol.iterator];
1092
1093 Buffer.prototype.keys = function() {
1094   return new BufferIterator(this, ITERATOR_KIND_KEYS);
1095 };
1096
1097 Buffer.prototype.entries = function() {
1098   return new BufferIterator(this, ITERATOR_KIND_ENTRIES);
1099 };
1100
1101 Buffer.prototype.values = function() {
1102   return new BufferValueIterator(this);
1103 };
1104
1105 Buffer.prototype[Symbol.iterator] = Buffer.prototype.values;