UNPKG

2.55 kBJavaScriptView Raw
1import { BigInt } from '@polkadot/x-bigint';
2import { _1n } from '../bi/consts.js';
3const U8_MAX = BigInt(256);
4const U16_MAX = BigInt(256 * 256);
5const U64_MAX = BigInt('0x10000000000000000');
6/**
7 * @name u8aToBigInt
8 * @summary Creates a BigInt from a Uint8Array object.
9 */
10export function u8aToBigInt(value, { isLe = true, isNegative = false } = {}) {
11 // slice + reverse is expensive, however SCALE is LE by default so this is the path
12 // we are most interested in (the BE is added for the sake of being comprehensive)
13 if (!isLe) {
14 value = value.slice().reverse();
15 }
16 const count = value.length;
17 if (isNegative && count && (value[count - 1] & 0x80)) {
18 switch (count) {
19 case 0:
20 return BigInt(0);
21 case 1:
22 return BigInt(((value[0] ^ 255) * -1) - 1);
23 case 2:
24 return BigInt((((value[0] + (value[1] << 8)) ^ 65535) * -1) - 1);
25 case 4:
26 return BigInt((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216)) ^ 4294967295) * -1) - 1);
27 }
28 const dvI = new DataView(value.buffer, value.byteOffset);
29 if (count === 8) {
30 return dvI.getBigInt64(0, true);
31 }
32 let result = BigInt(0);
33 const mod = count % 2;
34 for (let i = count - 2; i >= mod; i -= 2) {
35 result = (result * U16_MAX) + BigInt(dvI.getUint16(i, true) ^ 0xffff);
36 }
37 if (mod) {
38 result = (result * U8_MAX) + BigInt(value[0] ^ 0xff);
39 }
40 return (result * -_1n) - _1n;
41 }
42 switch (count) {
43 case 0:
44 return BigInt(0);
45 case 1:
46 return BigInt(value[0]);
47 case 2:
48 return BigInt(value[0] + (value[1] << 8));
49 case 4:
50 return BigInt(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216));
51 }
52 const dvI = new DataView(value.buffer, value.byteOffset);
53 switch (count) {
54 case 8:
55 return dvI.getBigUint64(0, true);
56 case 16:
57 return (dvI.getBigUint64(8, true) * U64_MAX) + dvI.getBigUint64(0, true);
58 default: {
59 let result = BigInt(0);
60 const mod = count % 2;
61 for (let i = count - 2; i >= mod; i -= 2) {
62 result = (result * U16_MAX) + BigInt(dvI.getUint16(i, true));
63 }
64 if (mod) {
65 result = (result * U8_MAX) + BigInt(value[0]);
66 }
67 return result;
68 }
69 }
70}