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