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