• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const {
4  BigInt,
5  Float32Array,
6  MathFloor,
7  Number,
8  Uint8Array,
9} = primordials;
10
11const {
12  ERR_BUFFER_OUT_OF_BOUNDS,
13  ERR_INVALID_ARG_TYPE,
14  ERR_OUT_OF_RANGE
15} = require('internal/errors').codes;
16const { validateNumber } = require('internal/validators');
17const {
18  asciiSlice,
19  base64Slice,
20  latin1Slice,
21  hexSlice,
22  ucs2Slice,
23  utf8Slice,
24  asciiWrite,
25  base64Write,
26  latin1Write,
27  hexWrite,
28  ucs2Write,
29  utf8Write
30} = internalBinding('buffer');
31const {
32  untransferable_object_private_symbol,
33  setHiddenValue,
34} = internalBinding('util');
35
36// Temporary buffers to convert numbers.
37const float32Array = new Float32Array(1);
38const uInt8Float32Array = new Uint8Array(float32Array.buffer);
39const float64Array = new Float64Array(1);
40const uInt8Float64Array = new Uint8Array(float64Array.buffer);
41
42// Check endianness.
43float32Array[0] = -1; // 0xBF800000
44// Either it is [0, 0, 128, 191] or [191, 128, 0, 0]. It is not possible to
45// check this with `os.endianness()` because that is determined at compile time.
46const bigEndian = uInt8Float32Array[3] === 0;
47
48function checkBounds(buf, offset, byteLength) {
49  validateNumber(offset, 'offset');
50  if (buf[offset] === undefined || buf[offset + byteLength] === undefined)
51    boundsError(offset, buf.length - (byteLength + 1));
52}
53
54function checkInt(value, min, max, buf, offset, byteLength) {
55  if (value > max || value < min) {
56    const n = typeof min === 'bigint' ? 'n' : '';
57    let range;
58    if (byteLength > 3) {
59      if (min === 0 || min === 0n) {
60        range = `>= 0${n} and < 2${n} ** ${(byteLength + 1) * 8}${n}`;
61      } else {
62        range = `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and < 2 ** ` +
63                `${(byteLength + 1) * 8 - 1}${n}`;
64      }
65    } else {
66      range = `>= ${min}${n} and <= ${max}${n}`;
67    }
68    throw new ERR_OUT_OF_RANGE('value', range, value);
69  }
70  checkBounds(buf, offset, byteLength);
71}
72
73function boundsError(value, length, type) {
74  if (MathFloor(value) !== value) {
75    validateNumber(value, type);
76    throw new ERR_OUT_OF_RANGE(type || 'offset', 'an integer', value);
77  }
78
79  if (length < 0)
80    throw new ERR_BUFFER_OUT_OF_BOUNDS();
81
82  throw new ERR_OUT_OF_RANGE(type || 'offset',
83                             `>= ${type ? 1 : 0} and <= ${length}`,
84                             value);
85}
86
87// Read integers.
88function readBigUInt64LE(offset = 0) {
89  validateNumber(offset, 'offset');
90  const first = this[offset];
91  const last = this[offset + 7];
92  if (first === undefined || last === undefined)
93    boundsError(offset, this.length - 8);
94
95  const lo = first +
96    this[++offset] * 2 ** 8 +
97    this[++offset] * 2 ** 16 +
98    this[++offset] * 2 ** 24;
99
100  const hi = this[++offset] +
101    this[++offset] * 2 ** 8 +
102    this[++offset] * 2 ** 16 +
103    last * 2 ** 24;
104
105  return BigInt(lo) + (BigInt(hi) << 32n);
106}
107
108function readBigUInt64BE(offset = 0) {
109  validateNumber(offset, 'offset');
110  const first = this[offset];
111  const last = this[offset + 7];
112  if (first === undefined || last === undefined)
113    boundsError(offset, this.length - 8);
114
115  const hi = first * 2 ** 24 +
116    this[++offset] * 2 ** 16 +
117    this[++offset] * 2 ** 8 +
118    this[++offset];
119
120  const lo = this[++offset] * 2 ** 24 +
121    this[++offset] * 2 ** 16 +
122    this[++offset] * 2 ** 8 +
123    last;
124
125  return (BigInt(hi) << 32n) + BigInt(lo);
126}
127
128function readBigInt64LE(offset = 0) {
129  validateNumber(offset, 'offset');
130  const first = this[offset];
131  const last = this[offset + 7];
132  if (first === undefined || last === undefined)
133    boundsError(offset, this.length - 8);
134
135  const val = this[offset + 4] +
136    this[offset + 5] * 2 ** 8 +
137    this[offset + 6] * 2 ** 16 +
138    (last << 24); // Overflow
139  return (BigInt(val) << 32n) +
140    BigInt(first +
141    this[++offset] * 2 ** 8 +
142    this[++offset] * 2 ** 16 +
143    this[++offset] * 2 ** 24);
144}
145
146function readBigInt64BE(offset = 0) {
147  validateNumber(offset, 'offset');
148  const first = this[offset];
149  const last = this[offset + 7];
150  if (first === undefined || last === undefined)
151    boundsError(offset, this.length - 8);
152
153  const val = (first << 24) + // Overflow
154    this[++offset] * 2 ** 16 +
155    this[++offset] * 2 ** 8 +
156    this[++offset];
157  return (BigInt(val) << 32n) +
158    BigInt(this[++offset] * 2 ** 24 +
159    this[++offset] * 2 ** 16 +
160    this[++offset] * 2 ** 8 +
161    last);
162}
163
164function readUIntLE(offset, byteLength) {
165  if (offset === undefined)
166    throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset);
167  if (byteLength === 6)
168    return readUInt48LE(this, offset);
169  if (byteLength === 5)
170    return readUInt40LE(this, offset);
171  if (byteLength === 3)
172    return readUInt24LE(this, offset);
173  if (byteLength === 4)
174    return this.readUInt32LE(offset);
175  if (byteLength === 2)
176    return this.readUInt16LE(offset);
177  if (byteLength === 1)
178    return this.readUInt8(offset);
179
180  boundsError(byteLength, 6, 'byteLength');
181}
182
183function readUInt48LE(buf, offset = 0) {
184  validateNumber(offset, 'offset');
185  const first = buf[offset];
186  const last = buf[offset + 5];
187  if (first === undefined || last === undefined)
188    boundsError(offset, buf.length - 6);
189
190  return first +
191    buf[++offset] * 2 ** 8 +
192    buf[++offset] * 2 ** 16 +
193    buf[++offset] * 2 ** 24 +
194    (buf[++offset] + last * 2 ** 8) * 2 ** 32;
195}
196
197function readUInt40LE(buf, offset = 0) {
198  validateNumber(offset, 'offset');
199  const first = buf[offset];
200  const last = buf[offset + 4];
201  if (first === undefined || last === undefined)
202    boundsError(offset, buf.length - 5);
203
204  return first +
205    buf[++offset] * 2 ** 8 +
206    buf[++offset] * 2 ** 16 +
207    buf[++offset] * 2 ** 24 +
208    last * 2 ** 32;
209}
210
211function readUInt32LE(offset = 0) {
212  validateNumber(offset, 'offset');
213  const first = this[offset];
214  const last = this[offset + 3];
215  if (first === undefined || last === undefined)
216    boundsError(offset, this.length - 4);
217
218  return first +
219    this[++offset] * 2 ** 8 +
220    this[++offset] * 2 ** 16 +
221    last * 2 ** 24;
222}
223
224function readUInt24LE(buf, offset = 0) {
225  validateNumber(offset, 'offset');
226  const first = buf[offset];
227  const last = buf[offset + 2];
228  if (first === undefined || last === undefined)
229    boundsError(offset, buf.length - 3);
230
231  return first + buf[++offset] * 2 ** 8 + last * 2 ** 16;
232}
233
234function readUInt16LE(offset = 0) {
235  validateNumber(offset, 'offset');
236  const first = this[offset];
237  const last = this[offset + 1];
238  if (first === undefined || last === undefined)
239    boundsError(offset, this.length - 2);
240
241  return first + last * 2 ** 8;
242}
243
244function readUInt8(offset = 0) {
245  validateNumber(offset, 'offset');
246  const val = this[offset];
247  if (val === undefined)
248    boundsError(offset, this.length - 1);
249
250  return val;
251}
252
253function readUIntBE(offset, byteLength) {
254  if (offset === undefined)
255    throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset);
256  if (byteLength === 6)
257    return readUInt48BE(this, offset);
258  if (byteLength === 5)
259    return readUInt40BE(this, offset);
260  if (byteLength === 3)
261    return readUInt24BE(this, offset);
262  if (byteLength === 4)
263    return this.readUInt32BE(offset);
264  if (byteLength === 2)
265    return this.readUInt16BE(offset);
266  if (byteLength === 1)
267    return this.readUInt8(offset);
268
269  boundsError(byteLength, 6, 'byteLength');
270}
271
272function readUInt48BE(buf, offset = 0) {
273  validateNumber(offset, 'offset');
274  const first = buf[offset];
275  const last = buf[offset + 5];
276  if (first === undefined || last === undefined)
277    boundsError(offset, buf.length - 6);
278
279  return (first * 2 ** 8 + buf[++offset]) * 2 ** 32 +
280    buf[++offset] * 2 ** 24 +
281    buf[++offset] * 2 ** 16 +
282    buf[++offset] * 2 ** 8 +
283    last;
284}
285
286function readUInt40BE(buf, offset = 0) {
287  validateNumber(offset, 'offset');
288  const first = buf[offset];
289  const last = buf[offset + 4];
290  if (first === undefined || last === undefined)
291    boundsError(offset, buf.length - 5);
292
293  return first * 2 ** 32 +
294    buf[++offset] * 2 ** 24 +
295    buf[++offset] * 2 ** 16 +
296    buf[++offset] * 2 ** 8 +
297    last;
298}
299
300function readUInt32BE(offset = 0) {
301  validateNumber(offset, 'offset');
302  const first = this[offset];
303  const last = this[offset + 3];
304  if (first === undefined || last === undefined)
305    boundsError(offset, this.length - 4);
306
307  return first * 2 ** 24 +
308    this[++offset] * 2 ** 16 +
309    this[++offset] * 2 ** 8 +
310    last;
311}
312
313function readUInt24BE(buf, offset = 0) {
314  validateNumber(offset, 'offset');
315  const first = buf[offset];
316  const last = buf[offset + 2];
317  if (first === undefined || last === undefined)
318    boundsError(offset, buf.length - 3);
319
320  return first * 2 ** 16 + buf[++offset] * 2 ** 8 + last;
321}
322
323function readUInt16BE(offset = 0) {
324  validateNumber(offset, 'offset');
325  const first = this[offset];
326  const last = this[offset + 1];
327  if (first === undefined || last === undefined)
328    boundsError(offset, this.length - 2);
329
330  return first * 2 ** 8 + last;
331}
332
333function readIntLE(offset, byteLength) {
334  if (offset === undefined)
335    throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset);
336  if (byteLength === 6)
337    return readInt48LE(this, offset);
338  if (byteLength === 5)
339    return readInt40LE(this, offset);
340  if (byteLength === 3)
341    return readInt24LE(this, offset);
342  if (byteLength === 4)
343    return this.readInt32LE(offset);
344  if (byteLength === 2)
345    return this.readInt16LE(offset);
346  if (byteLength === 1)
347    return this.readInt8(offset);
348
349  boundsError(byteLength, 6, 'byteLength');
350}
351
352function readInt48LE(buf, offset = 0) {
353  validateNumber(offset, 'offset');
354  const first = buf[offset];
355  const last = buf[offset + 5];
356  if (first === undefined || last === undefined)
357    boundsError(offset, buf.length - 6);
358
359  const val = buf[offset + 4] + last * 2 ** 8;
360  return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 +
361    first +
362    buf[++offset] * 2 ** 8 +
363    buf[++offset] * 2 ** 16 +
364    buf[++offset] * 2 ** 24;
365}
366
367function readInt40LE(buf, offset = 0) {
368  validateNumber(offset, 'offset');
369  const first = buf[offset];
370  const last = buf[offset + 4];
371  if (first === undefined || last === undefined)
372    boundsError(offset, buf.length - 5);
373
374  return (last | (last & 2 ** 7) * 0x1fffffe) * 2 ** 32 +
375    first +
376    buf[++offset] * 2 ** 8 +
377    buf[++offset] * 2 ** 16 +
378    buf[++offset] * 2 ** 24;
379}
380
381function readInt32LE(offset = 0) {
382  validateNumber(offset, 'offset');
383  const first = this[offset];
384  const last = this[offset + 3];
385  if (first === undefined || last === undefined)
386    boundsError(offset, this.length - 4);
387
388  return first +
389    this[++offset] * 2 ** 8 +
390    this[++offset] * 2 ** 16 +
391    (last << 24); // Overflow
392}
393
394function readInt24LE(buf, offset = 0) {
395  validateNumber(offset, 'offset');
396  const first = buf[offset];
397  const last = buf[offset + 2];
398  if (first === undefined || last === undefined)
399    boundsError(offset, buf.length - 3);
400
401  const val = first + buf[++offset] * 2 ** 8 + last * 2 ** 16;
402  return val | (val & 2 ** 23) * 0x1fe;
403}
404
405function readInt16LE(offset = 0) {
406  validateNumber(offset, 'offset');
407  const first = this[offset];
408  const last = this[offset + 1];
409  if (first === undefined || last === undefined)
410    boundsError(offset, this.length - 2);
411
412  const val = first + last * 2 ** 8;
413  return val | (val & 2 ** 15) * 0x1fffe;
414}
415
416function readInt8(offset = 0) {
417  validateNumber(offset, 'offset');
418  const val = this[offset];
419  if (val === undefined)
420    boundsError(offset, this.length - 1);
421
422  return val | (val & 2 ** 7) * 0x1fffffe;
423}
424
425function readIntBE(offset, byteLength) {
426  if (offset === undefined)
427    throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset);
428  if (byteLength === 6)
429    return readInt48BE(this, offset);
430  if (byteLength === 5)
431    return readInt40BE(this, offset);
432  if (byteLength === 3)
433    return readInt24BE(this, offset);
434  if (byteLength === 4)
435    return this.readInt32BE(offset);
436  if (byteLength === 2)
437    return this.readInt16BE(offset);
438  if (byteLength === 1)
439    return this.readInt8(offset);
440
441  boundsError(byteLength, 6, 'byteLength');
442}
443
444function readInt48BE(buf, offset = 0) {
445  validateNumber(offset, 'offset');
446  const first = buf[offset];
447  const last = buf[offset + 5];
448  if (first === undefined || last === undefined)
449    boundsError(offset, buf.length - 6);
450
451  const val = buf[++offset] + first * 2 ** 8;
452  return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 +
453    buf[++offset] * 2 ** 24 +
454    buf[++offset] * 2 ** 16 +
455    buf[++offset] * 2 ** 8 +
456    last;
457}
458
459function readInt40BE(buf, offset = 0) {
460  validateNumber(offset, 'offset');
461  const first = buf[offset];
462  const last = buf[offset + 4];
463  if (first === undefined || last === undefined)
464    boundsError(offset, buf.length - 5);
465
466  return (first | (first & 2 ** 7) * 0x1fffffe) * 2 ** 32 +
467    buf[++offset] * 2 ** 24 +
468    buf[++offset] * 2 ** 16 +
469    buf[++offset] * 2 ** 8 +
470    last;
471}
472
473function readInt32BE(offset = 0) {
474  validateNumber(offset, 'offset');
475  const first = this[offset];
476  const last = this[offset + 3];
477  if (first === undefined || last === undefined)
478    boundsError(offset, this.length - 4);
479
480  return (first << 24) + // Overflow
481    this[++offset] * 2 ** 16 +
482    this[++offset] * 2 ** 8 +
483    last;
484}
485
486function readInt24BE(buf, offset = 0) {
487  validateNumber(offset, 'offset');
488  const first = buf[offset];
489  const last = buf[offset + 2];
490  if (first === undefined || last === undefined)
491    boundsError(offset, buf.length - 3);
492
493  const val = first * 2 ** 16 + buf[++offset] * 2 ** 8 + last;
494  return val | (val & 2 ** 23) * 0x1fe;
495}
496
497function readInt16BE(offset = 0) {
498  validateNumber(offset, 'offset');
499  const first = this[offset];
500  const last = this[offset + 1];
501  if (first === undefined || last === undefined)
502    boundsError(offset, this.length - 2);
503
504  const val = first * 2 ** 8 + last;
505  return val | (val & 2 ** 15) * 0x1fffe;
506}
507
508// Read floats
509function readFloatBackwards(offset = 0) {
510  validateNumber(offset, 'offset');
511  const first = this[offset];
512  const last = this[offset + 3];
513  if (first === undefined || last === undefined)
514    boundsError(offset, this.length - 4);
515
516  uInt8Float32Array[3] = first;
517  uInt8Float32Array[2] = this[++offset];
518  uInt8Float32Array[1] = this[++offset];
519  uInt8Float32Array[0] = last;
520  return float32Array[0];
521}
522
523function readFloatForwards(offset = 0) {
524  validateNumber(offset, 'offset');
525  const first = this[offset];
526  const last = this[offset + 3];
527  if (first === undefined || last === undefined)
528    boundsError(offset, this.length - 4);
529
530  uInt8Float32Array[0] = first;
531  uInt8Float32Array[1] = this[++offset];
532  uInt8Float32Array[2] = this[++offset];
533  uInt8Float32Array[3] = last;
534  return float32Array[0];
535}
536
537function readDoubleBackwards(offset = 0) {
538  validateNumber(offset, 'offset');
539  const first = this[offset];
540  const last = this[offset + 7];
541  if (first === undefined || last === undefined)
542    boundsError(offset, this.length - 8);
543
544  uInt8Float64Array[7] = first;
545  uInt8Float64Array[6] = this[++offset];
546  uInt8Float64Array[5] = this[++offset];
547  uInt8Float64Array[4] = this[++offset];
548  uInt8Float64Array[3] = this[++offset];
549  uInt8Float64Array[2] = this[++offset];
550  uInt8Float64Array[1] = this[++offset];
551  uInt8Float64Array[0] = last;
552  return float64Array[0];
553}
554
555function readDoubleForwards(offset = 0) {
556  validateNumber(offset, 'offset');
557  const first = this[offset];
558  const last = this[offset + 7];
559  if (first === undefined || last === undefined)
560    boundsError(offset, this.length - 8);
561
562  uInt8Float64Array[0] = first;
563  uInt8Float64Array[1] = this[++offset];
564  uInt8Float64Array[2] = this[++offset];
565  uInt8Float64Array[3] = this[++offset];
566  uInt8Float64Array[4] = this[++offset];
567  uInt8Float64Array[5] = this[++offset];
568  uInt8Float64Array[6] = this[++offset];
569  uInt8Float64Array[7] = last;
570  return float64Array[0];
571}
572
573// Write integers.
574function writeBigU_Int64LE(buf, value, offset, min, max) {
575  checkInt(value, min, max, buf, offset, 7);
576
577  let lo = Number(value & 0xffffffffn);
578  buf[offset++] = lo;
579  lo = lo >> 8;
580  buf[offset++] = lo;
581  lo = lo >> 8;
582  buf[offset++] = lo;
583  lo = lo >> 8;
584  buf[offset++] = lo;
585  let hi = Number(value >> 32n & 0xffffffffn);
586  buf[offset++] = hi;
587  hi = hi >> 8;
588  buf[offset++] = hi;
589  hi = hi >> 8;
590  buf[offset++] = hi;
591  hi = hi >> 8;
592  buf[offset++] = hi;
593  return offset;
594}
595
596function writeBigUInt64LE(value, offset = 0) {
597  return writeBigU_Int64LE(this, value, offset, 0n, 0xffffffffffffffffn);
598}
599
600function writeBigU_Int64BE(buf, value, offset, min, max) {
601  checkInt(value, min, max, buf, offset, 7);
602
603  let lo = Number(value & 0xffffffffn);
604  buf[offset + 7] = lo;
605  lo = lo >> 8;
606  buf[offset + 6] = lo;
607  lo = lo >> 8;
608  buf[offset + 5] = lo;
609  lo = lo >> 8;
610  buf[offset + 4] = lo;
611  let hi = Number(value >> 32n & 0xffffffffn);
612  buf[offset + 3] = hi;
613  hi = hi >> 8;
614  buf[offset + 2] = hi;
615  hi = hi >> 8;
616  buf[offset + 1] = hi;
617  hi = hi >> 8;
618  buf[offset] = hi;
619  return offset + 8;
620}
621
622function writeBigUInt64BE(value, offset = 0) {
623  return writeBigU_Int64BE(this, value, offset, 0n, 0xffffffffffffffffn);
624}
625
626function writeBigInt64LE(value, offset = 0) {
627  return writeBigU_Int64LE(
628    this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn);
629}
630
631function writeBigInt64BE(value, offset = 0) {
632  return writeBigU_Int64BE(
633    this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn);
634}
635
636function writeUIntLE(value, offset, byteLength) {
637  if (byteLength === 6)
638    return writeU_Int48LE(this, value, offset, 0, 0xffffffffffff);
639  if (byteLength === 5)
640    return writeU_Int40LE(this, value, offset, 0, 0xffffffffff);
641  if (byteLength === 3)
642    return writeU_Int24LE(this, value, offset, 0, 0xffffff);
643  if (byteLength === 4)
644    return writeU_Int32LE(this, value, offset, 0, 0xffffffff);
645  if (byteLength === 2)
646    return writeU_Int16LE(this, value, offset, 0, 0xffff);
647  if (byteLength === 1)
648    return writeU_Int8(this, value, offset, 0, 0xff);
649
650  boundsError(byteLength, 6, 'byteLength');
651}
652
653function writeU_Int48LE(buf, value, offset, min, max) {
654  value = +value;
655  checkInt(value, min, max, buf, offset, 5);
656
657  const newVal = MathFloor(value * 2 ** -32);
658  buf[offset++] = value;
659  value = value >>> 8;
660  buf[offset++] = value;
661  value = value >>> 8;
662  buf[offset++] = value;
663  value = value >>> 8;
664  buf[offset++] = value;
665  buf[offset++] = newVal;
666  buf[offset++] = (newVal >>> 8);
667  return offset;
668}
669
670function writeU_Int40LE(buf, value, offset, min, max) {
671  value = +value;
672  checkInt(value, min, max, buf, offset, 4);
673
674  const newVal = value;
675  buf[offset++] = value;
676  value = value >>> 8;
677  buf[offset++] = value;
678  value = value >>> 8;
679  buf[offset++] = value;
680  value = value >>> 8;
681  buf[offset++] = value;
682  buf[offset++] = MathFloor(newVal * 2 ** -32);
683  return offset;
684}
685
686function writeU_Int32LE(buf, value, offset, min, max) {
687  value = +value;
688  checkInt(value, min, max, buf, offset, 3);
689
690  buf[offset++] = value;
691  value = value >>> 8;
692  buf[offset++] = value;
693  value = value >>> 8;
694  buf[offset++] = value;
695  value = value >>> 8;
696  buf[offset++] = value;
697  return offset;
698}
699
700function writeUInt32LE(value, offset = 0) {
701  return writeU_Int32LE(this, value, offset, 0, 0xffffffff);
702}
703
704function writeU_Int24LE(buf, value, offset, min, max) {
705  value = +value;
706  checkInt(value, min, max, buf, offset, 2);
707
708  buf[offset++] = value;
709  value = value >>> 8;
710  buf[offset++] = value;
711  value = value >>> 8;
712  buf[offset++] = value;
713  return offset;
714}
715
716function writeU_Int16LE(buf, value, offset, min, max) {
717  value = +value;
718  checkInt(value, min, max, buf, offset, 1);
719
720  buf[offset++] = value;
721  buf[offset++] = (value >>> 8);
722  return offset;
723}
724
725function writeUInt16LE(value, offset = 0) {
726  return writeU_Int16LE(this, value, offset, 0, 0xffff);
727}
728
729function writeU_Int8(buf, value, offset, min, max) {
730  value = +value;
731  // `checkInt()` can not be used here because it checks two entries.
732  validateNumber(offset, 'offset');
733  if (value > max || value < min) {
734    throw new ERR_OUT_OF_RANGE('value', `>= ${min} and <= ${max}`, value);
735  }
736  if (buf[offset] === undefined)
737    boundsError(offset, buf.length - 1);
738
739  buf[offset] = value;
740  return offset + 1;
741}
742
743function writeUInt8(value, offset = 0) {
744  return writeU_Int8(this, value, offset, 0, 0xff);
745}
746
747function writeUIntBE(value, offset, byteLength) {
748  if (byteLength === 6)
749    return writeU_Int48BE(this, value, offset, 0, 0xffffffffffff);
750  if (byteLength === 5)
751    return writeU_Int40BE(this, value, offset, 0, 0xffffffffff);
752  if (byteLength === 3)
753    return writeU_Int24BE(this, value, offset, 0, 0xffffff);
754  if (byteLength === 4)
755    return writeU_Int32BE(this, value, offset, 0, 0xffffffff);
756  if (byteLength === 2)
757    return writeU_Int16BE(this, value, offset, 0, 0xffff);
758  if (byteLength === 1)
759    return writeU_Int8(this, value, offset, 0, 0xff);
760
761  boundsError(byteLength, 6, 'byteLength');
762}
763
764function writeU_Int48BE(buf, value, offset, min, max) {
765  value = +value;
766  checkInt(value, min, max, buf, offset, 5);
767
768  const newVal = MathFloor(value * 2 ** -32);
769  buf[offset++] = (newVal >>> 8);
770  buf[offset++] = newVal;
771  buf[offset + 3] = value;
772  value = value >>> 8;
773  buf[offset + 2] = value;
774  value = value >>> 8;
775  buf[offset + 1] = value;
776  value = value >>> 8;
777  buf[offset] = value;
778  return offset + 4;
779}
780
781function writeU_Int40BE(buf, value, offset, min, max) {
782  value = +value;
783  checkInt(value, min, max, buf, offset, 4);
784
785  buf[offset++] = MathFloor(value * 2 ** -32);
786  buf[offset + 3] = value;
787  value = value >>> 8;
788  buf[offset + 2] = value;
789  value = value >>> 8;
790  buf[offset + 1] = value;
791  value = value >>> 8;
792  buf[offset] = value;
793  return offset + 4;
794}
795
796function writeU_Int32BE(buf, value, offset, min, max) {
797  value = +value;
798  checkInt(value, min, max, buf, offset, 3);
799
800  buf[offset + 3] = value;
801  value = value >>> 8;
802  buf[offset + 2] = value;
803  value = value >>> 8;
804  buf[offset + 1] = value;
805  value = value >>> 8;
806  buf[offset] = value;
807  return offset + 4;
808}
809
810function writeUInt32BE(value, offset = 0) {
811  return writeU_Int32BE(this, value, offset, 0, 0xffffffff);
812}
813
814function writeU_Int24BE(buf, value, offset, min, max) {
815  value = +value;
816  checkInt(value, min, max, buf, offset, 2);
817
818  buf[offset + 2] = value;
819  value = value >>> 8;
820  buf[offset + 1] = value;
821  value = value >>> 8;
822  buf[offset] = value;
823  return offset + 3;
824}
825
826function writeU_Int16BE(buf, value, offset, min, max) {
827  value = +value;
828  checkInt(value, min, max, buf, offset, 1);
829
830  buf[offset++] = (value >>> 8);
831  buf[offset++] = value;
832  return offset;
833}
834
835function writeUInt16BE(value, offset = 0) {
836  return writeU_Int16BE(this, value, offset, 0, 0xffff);
837}
838
839function writeIntLE(value, offset, byteLength) {
840  if (byteLength === 6)
841    return writeU_Int48LE(this, value, offset, -0x800000000000, 0x7fffffffffff);
842  if (byteLength === 5)
843    return writeU_Int40LE(this, value, offset, -0x8000000000, 0x7fffffffff);
844  if (byteLength === 3)
845    return writeU_Int24LE(this, value, offset, -0x800000, 0x7fffff);
846  if (byteLength === 4)
847    return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff);
848  if (byteLength === 2)
849    return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff);
850  if (byteLength === 1)
851    return writeU_Int8(this, value, offset, -0x80, 0x7f);
852
853  boundsError(byteLength, 6, 'byteLength');
854}
855
856function writeInt32LE(value, offset = 0) {
857  return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff);
858}
859
860function writeInt16LE(value, offset = 0) {
861  return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff);
862}
863
864function writeInt8(value, offset = 0) {
865  return writeU_Int8(this, value, offset, -0x80, 0x7f);
866}
867
868function writeIntBE(value, offset, byteLength) {
869  if (byteLength === 6)
870    return writeU_Int48BE(this, value, offset, -0x800000000000, 0x7fffffffffff);
871  if (byteLength === 5)
872    return writeU_Int40BE(this, value, offset, -0x8000000000, 0x7fffffffff);
873  if (byteLength === 3)
874    return writeU_Int24BE(this, value, offset, -0x800000, 0x7fffff);
875  if (byteLength === 4)
876    return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff);
877  if (byteLength === 2)
878    return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff);
879  if (byteLength === 1)
880    return writeU_Int8(this, value, offset, -0x80, 0x7f);
881
882  boundsError(byteLength, 6, 'byteLength');
883}
884
885function writeInt32BE(value, offset = 0) {
886  return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff);
887}
888
889function writeInt16BE(value, offset = 0) {
890  return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff);
891}
892
893// Write floats.
894function writeDoubleForwards(val, offset = 0) {
895  val = +val;
896  checkBounds(this, offset, 7);
897
898  float64Array[0] = val;
899  this[offset++] = uInt8Float64Array[0];
900  this[offset++] = uInt8Float64Array[1];
901  this[offset++] = uInt8Float64Array[2];
902  this[offset++] = uInt8Float64Array[3];
903  this[offset++] = uInt8Float64Array[4];
904  this[offset++] = uInt8Float64Array[5];
905  this[offset++] = uInt8Float64Array[6];
906  this[offset++] = uInt8Float64Array[7];
907  return offset;
908}
909
910function writeDoubleBackwards(val, offset = 0) {
911  val = +val;
912  checkBounds(this, offset, 7);
913
914  float64Array[0] = val;
915  this[offset++] = uInt8Float64Array[7];
916  this[offset++] = uInt8Float64Array[6];
917  this[offset++] = uInt8Float64Array[5];
918  this[offset++] = uInt8Float64Array[4];
919  this[offset++] = uInt8Float64Array[3];
920  this[offset++] = uInt8Float64Array[2];
921  this[offset++] = uInt8Float64Array[1];
922  this[offset++] = uInt8Float64Array[0];
923  return offset;
924}
925
926function writeFloatForwards(val, offset = 0) {
927  val = +val;
928  checkBounds(this, offset, 3);
929
930  float32Array[0] = val;
931  this[offset++] = uInt8Float32Array[0];
932  this[offset++] = uInt8Float32Array[1];
933  this[offset++] = uInt8Float32Array[2];
934  this[offset++] = uInt8Float32Array[3];
935  return offset;
936}
937
938function writeFloatBackwards(val, offset = 0) {
939  val = +val;
940  checkBounds(this, offset, 3);
941
942  float32Array[0] = val;
943  this[offset++] = uInt8Float32Array[3];
944  this[offset++] = uInt8Float32Array[2];
945  this[offset++] = uInt8Float32Array[1];
946  this[offset++] = uInt8Float32Array[0];
947  return offset;
948}
949
950class FastBuffer extends Uint8Array {}
951
952function addBufferPrototypeMethods(proto) {
953  proto.readBigUInt64LE = readBigUInt64LE,
954  proto.readBigUInt64BE = readBigUInt64BE,
955  proto.readBigUint64LE = readBigUInt64LE,
956  proto.readBigUint64BE = readBigUInt64BE,
957  proto.readBigInt64LE = readBigInt64LE,
958  proto.readBigInt64BE = readBigInt64BE,
959  proto.writeBigUInt64LE = writeBigUInt64LE,
960  proto.writeBigUInt64BE = writeBigUInt64BE,
961  proto.writeBigUint64LE = writeBigUInt64LE,
962  proto.writeBigUint64BE = writeBigUInt64BE,
963  proto.writeBigInt64LE = writeBigInt64LE,
964  proto.writeBigInt64BE = writeBigInt64BE,
965
966  proto.readUIntLE = readUIntLE;
967  proto.readUInt32LE = readUInt32LE;
968  proto.readUInt16LE = readUInt16LE;
969  proto.readUInt8 = readUInt8;
970  proto.readUIntBE = readUIntBE;
971  proto.readUInt32BE = readUInt32BE;
972  proto.readUInt16BE = readUInt16BE;
973  proto.readUintLE = readUIntLE;
974  proto.readUint32LE = readUInt32LE;
975  proto.readUint16LE = readUInt16LE;
976  proto.readUint8 = readUInt8;
977  proto.readUintBE = readUIntBE;
978  proto.readUint32BE = readUInt32BE;
979  proto.readUint16BE = readUInt16BE;
980  proto.readIntLE = readIntLE;
981  proto.readInt32LE = readInt32LE;
982  proto.readInt16LE = readInt16LE;
983  proto.readInt8 = readInt8;
984  proto.readIntBE = readIntBE;
985  proto.readInt32BE = readInt32BE;
986  proto.readInt16BE = readInt16BE;
987
988  proto.writeUIntLE = writeUIntLE;
989  proto.writeUInt32LE = writeUInt32LE;
990  proto.writeUInt16LE = writeUInt16LE;
991  proto.writeUInt8 = writeUInt8;
992  proto.writeUIntBE = writeUIntBE;
993  proto.writeUInt32BE = writeUInt32BE;
994  proto.writeUInt16BE = writeUInt16BE;
995  proto.writeUintLE = writeUIntLE;
996  proto.writeUint32LE = writeUInt32LE;
997  proto.writeUint16LE = writeUInt16LE;
998  proto.writeUint8 = writeUInt8;
999  proto.writeUintBE = writeUIntBE;
1000  proto.writeUint32BE = writeUInt32BE;
1001  proto.writeUint16BE = writeUInt16BE;
1002  proto.writeIntLE = writeIntLE;
1003  proto.writeInt32LE = writeInt32LE;
1004  proto.writeInt16LE = writeInt16LE;
1005  proto.writeInt8 = writeInt8;
1006  proto.writeIntBE = writeIntBE;
1007  proto.writeInt32BE = writeInt32BE;
1008  proto.writeInt16BE = writeInt16BE;
1009
1010  proto.readFloatLE = bigEndian ? readFloatBackwards : readFloatForwards;
1011  proto.readFloatBE = bigEndian ? readFloatForwards : readFloatBackwards;
1012  proto.readDoubleLE = bigEndian ? readDoubleBackwards : readDoubleForwards;
1013  proto.readDoubleBE = bigEndian ? readDoubleForwards : readDoubleBackwards;
1014  proto.writeFloatLE = bigEndian ? writeFloatBackwards : writeFloatForwards;
1015  proto.writeFloatBE = bigEndian ? writeFloatForwards : writeFloatBackwards;
1016  proto.writeDoubleLE = bigEndian ? writeDoubleBackwards : writeDoubleForwards;
1017  proto.writeDoubleBE = bigEndian ? writeDoubleForwards : writeDoubleBackwards;
1018
1019  proto.asciiSlice = asciiSlice;
1020  proto.base64Slice = base64Slice;
1021  proto.latin1Slice = latin1Slice;
1022  proto.hexSlice = hexSlice;
1023  proto.ucs2Slice = ucs2Slice;
1024  proto.utf8Slice = utf8Slice;
1025  proto.asciiWrite = asciiWrite;
1026  proto.base64Write = base64Write;
1027  proto.latin1Write = latin1Write;
1028  proto.hexWrite = hexWrite;
1029  proto.ucs2Write = ucs2Write;
1030  proto.utf8Write = utf8Write;
1031}
1032
1033// This would better be placed in internal/worker/io.js, but that doesn't work
1034// because Buffer needs this and that would introduce a cyclic dependency.
1035function markAsUntransferable(obj) {
1036  if ((typeof obj !== 'object' && typeof obj !== 'function') || obj === null)
1037    return;  // This object is a primitive and therefore already untransferable.
1038  setHiddenValue(obj, untransferable_object_private_symbol, true);
1039}
1040
1041module.exports = {
1042  FastBuffer,
1043  addBufferPrototypeMethods,
1044  markAsUntransferable,
1045};
1046