@gsknnft/bigint-buffer 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +3 -3
  2. package/build/Release/bigint_buffer.exp +0 -0
  3. package/build/Release/bigint_buffer.iobj +0 -0
  4. package/build/Release/bigint_buffer.ipdb +0 -0
  5. package/build/Release/bigint_buffer.lib +0 -0
  6. package/build/Release/bigint_buffer.node +0 -0
  7. package/build/Release/bigint_buffer.pdb +0 -0
  8. package/build/Release/obj/bigint_buffer/bigint_buffer.node.recipe +11 -0
  9. package/build/Release/obj/bigint_buffer/bigint_buffer.tlog/CL.command.1.tlog +0 -0
  10. package/build/Release/obj/bigint_buffer/bigint_buffer.tlog/CL.read.1.tlog +0 -0
  11. package/build/Release/obj/bigint_buffer/bigint_buffer.tlog/CL.write.1.tlog +0 -0
  12. package/build/Release/obj/bigint_buffer/bigint_buffer.tlog/Cl.items.tlog +2 -0
  13. package/build/Release/obj/bigint_buffer/bigint_buffer.tlog/bigint_buffer.lastbuildstate +2 -0
  14. package/build/Release/obj/bigint_buffer/bigint_buffer.tlog/link.command.1.tlog +0 -0
  15. package/build/Release/obj/bigint_buffer/bigint_buffer.tlog/link.read.1.tlog +0 -0
  16. package/build/Release/obj/bigint_buffer/bigint_buffer.tlog/link.secondary.1.tlog +5 -0
  17. package/build/Release/obj/bigint_buffer/bigint_buffer.tlog/link.write.1.tlog +0 -0
  18. package/build/Release/obj/bigint_buffer/src/bigint-buffer.obj +0 -0
  19. package/build/Release/obj/bigint_buffer/win_delay_load_hook.obj +0 -0
  20. package/build/bigint_buffer.vcxproj +148 -0
  21. package/build/bigint_buffer.vcxproj.filters +67 -0
  22. package/build/binding.sln +19 -0
  23. package/build/config.gypi +522 -0
  24. package/dist/types/conversion/src/ts/index.d.ts +168 -0
  25. package/dist/types/conversion/test/bigintToBase64.test.d.ts +1 -0
  26. package/dist/types/conversion/test/bigintToBuf.test.d.ts +1 -0
  27. package/dist/types/conversion/test/bigintToHex.test.d.ts +1 -0
  28. package/dist/types/conversion/test/bigintToText.test.d.ts +1 -0
  29. package/dist/types/conversion/test/bufToBigint.test.d.ts +1 -0
  30. package/dist/types/conversion/test/hexToBigint.test.d.ts +1 -0
  31. package/dist/types/conversion/test/hexToBuf.test.d.ts +1 -0
  32. package/dist/types/conversion/test/parseHex.test.d.ts +1 -0
  33. package/dist/types/conversion/test/setup.test.d.ts +1 -0
  34. package/dist/types/conversion/test/textToBuf.test.d.ts +1 -0
  35. package/package.json +42 -27
  36. package/src/bigint-buffer.c +203 -0
  37. package/src/bigint-buffer.test.ts +11 -0
  38. package/src/conversion/.github/workflows/build-and-test.yml +116 -0
  39. package/src/conversion/CODE_OF_CONDUCT.md +134 -0
  40. package/src/conversion/LICENSE +21 -0
  41. package/src/conversion/README.md +48 -0
  42. package/src/conversion/docs/README.md +34 -0
  43. package/src/conversion/docs/functions/base64ToBigint.md +27 -0
  44. package/src/conversion/docs/functions/bigintToBase64.md +43 -0
  45. package/src/conversion/docs/functions/bigintToBuf.md +35 -0
  46. package/src/conversion/docs/functions/bigintToHex.md +43 -0
  47. package/src/conversion/docs/functions/bigintToText.md +31 -0
  48. package/src/conversion/docs/functions/bufToBigint.md +25 -0
  49. package/src/conversion/docs/functions/bufToHex.md +37 -0
  50. package/src/conversion/docs/functions/bufToText.md +27 -0
  51. package/src/conversion/docs/functions/hexToBigint.md +29 -0
  52. package/src/conversion/docs/functions/hexToBuf.md +37 -0
  53. package/src/conversion/docs/functions/parseHex.md +45 -0
  54. package/src/conversion/docs/functions/textToBigint.md +27 -0
  55. package/src/conversion/docs/functions/textToBuf.md +33 -0
  56. package/src/conversion/docs/functions/toBigIntBE.md +27 -0
  57. package/src/conversion/docs/functions/toBigIntLE.md +27 -0
  58. package/src/conversion/docs/functions/toBufferBE.md +33 -0
  59. package/src/conversion/docs/functions/toBufferLE.md +33 -0
  60. package/src/conversion/docs/functions/validateBigIntBuffer.md +15 -0
  61. package/src/conversion/docs/type-aliases/TypedArray.md +11 -0
  62. package/src/conversion/docs/variables/isNative.md +11 -0
  63. package/src/conversion/example.cjs +9 -0
  64. package/src/conversion/example.esm.js +11 -0
  65. package/src/conversion/index.ts +1 -0
  66. package/src/conversion/package.json +163 -0
  67. package/src/conversion/src/docs/index.md +47 -0
  68. package/src/conversion/src/ts/index.ts +514 -0
  69. package/src/conversion/test/bigintToBase64.test.ts +37 -0
  70. package/src/conversion/test/bigintToBuf.test.ts +43 -0
  71. package/src/conversion/test/bigintToHex.test.ts +52 -0
  72. package/src/conversion/test/bigintToText.test.ts +30 -0
  73. package/src/conversion/test/bufToBigint.test.ts +20 -0
  74. package/src/conversion/test/hexToBigint.test.ts +22 -0
  75. package/src/conversion/test/hexToBuf.test.ts +39 -0
  76. package/src/conversion/test/parseHex.test.ts +35 -0
  77. package/src/conversion/test/setup.test.ts +9 -0
  78. package/src/conversion/test/textToBuf.test.ts +26 -0
  79. package/src/conversion/tsconfig.json +57 -0
  80. package/src/conversion/tsconfig.rollup.json +9 -0
  81. package/src/conversion/typedoc.json +5 -0
  82. package/src/conversion/types/bindings.d.t.s +4 -0
  83. package/src/conversion/vite.config.ts +10 -0
  84. package/src/conversion/vitest.config.ts +15 -0
  85. package/src/index.bench.ts +206 -0
  86. package/src/index.spec.ts +318 -0
  87. package/src/index.ts +215 -0
  88. package/.travis.yml +0 -51
  89. package/PR_TEMPLATE.md +0 -53
  90. package/WHY_BIGINT.md +0 -127
  91. package/benchmark.md +0 -38
  92. package/eslint.config.ts +0 -12
  93. package/karma.conf.js +0 -62
  94. package/pnpm-workspace.yaml +0 -14
  95. package/rollup.cjs.config.js +0 -13
  96. package/rollup.conversion.cjs.config.js +0 -13
  97. package/rollup.conversion.esm.config.js +0 -24
  98. package/rollup.esm.config.js +0 -24
  99. package/tsconfig.tsbuildinfo +0 -1
  100. package/vite.config.ts +0 -44
  101. package/vitest.config.ts +0 -20
@@ -0,0 +1,168 @@
1
+ import { Buffer } from 'buffer';
2
+ export declare let isNative: boolean;
3
+ /**
4
+ * Convert a little-endian buffer into a BigInt.
5
+ * @param buf The little-endian buffer to convert
6
+ * @returns A BigInt with the little-endian representation of buf.
7
+ */
8
+ export declare function toBigIntLE(buf: Buffer): bigint;
9
+ export declare function validateBigIntBuffer(): boolean;
10
+ /**
11
+ * Convert a big-endian buffer into a BigInt
12
+ * @param buf The big-endian buffer to convert.
13
+ * @returns A BigInt with the big-endian representation of buf.
14
+ */
15
+ export declare function toBigIntBE(buf: Buffer): bigint;
16
+ /**
17
+ * Convert a BigInt to a little-endian buffer.
18
+ * @param num The BigInt to convert.
19
+ * @param width The number of bytes that the resulting buffer should be.
20
+ * @returns A little-endian buffer representation of num.
21
+ */
22
+ export declare function toBufferLE(num: bigint, width: number): Buffer;
23
+ /**
24
+ * Convert a BigInt to a big-endian buffer.
25
+ * @param num The BigInt to convert.
26
+ * @param width The number of bytes that the resulting buffer should be.
27
+ * @returns A big-endian buffer representation of num.
28
+ */
29
+ export declare function toBufferBE(num: bigint, width: number): Buffer;
30
+ export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
31
+ /**
32
+ * Parses a hexadecimal string for correctness and returns it with or without
33
+ * '0x' prefix, and/or with the specified byte length
34
+ * @param a - the string with an hexadecimal number to be parsed
35
+ * @param prefix0x - set to true to prefix the output with '0x'
36
+ * @param byteLength - pad the output to have the desired byte length. Notice
37
+ * that the hex length is double the byte length.
38
+ *
39
+ * @returns
40
+ *
41
+ * @throws {@link RangeError} if input string does not hold an hexadecimal number
42
+ * @throws {@link RangeError} if requested byte length is less than the input byte length
43
+ */
44
+ export declare function parseHex(a: string, prefix0x?: boolean, byteLength?: number): string;
45
+ /**
46
+ * Converts an arbitrary-size non-negative bigint to an ArrayBuffer or a Buffer
47
+ * (default for Node.js)
48
+ *
49
+ * @param a
50
+ * @param returnArrayBuffer - In Node.js, it forces the output to be an
51
+ * ArrayBuffer instead of a Buffer.
52
+ *
53
+ * @returns an ArrayBuffer or a Buffer with a binary representation of the input
54
+ * bigint
55
+ *
56
+ * @throws {@link RangeError} if a < 0.
57
+ */
58
+ export declare function bigintToBuf(a: bigint, returnArrayBuffer?: boolean): ArrayBuffer | Buffer;
59
+ /**
60
+ * Converts an ArrayBuffer, TypedArray or Buffer (node.js) to a bigint
61
+ * @param buf
62
+ * @returns a bigint
63
+ */
64
+ export declare function bufToBigint(buf: ArrayBuffer | TypedArray | Buffer): bigint;
65
+ /**
66
+ * Converts a non-negative bigint to a hexadecimal string
67
+ * @param a - a non negative bigint
68
+ * @param prefix0x - set to true to prefix the output with '0x'
69
+ * @param byteLength - pad the output to have the desired byte length. Notice
70
+ * that the hex length is double the byte length.
71
+ *
72
+ * @returns hexadecimal representation of the input bigint
73
+ *
74
+ * @throws {@link RangeError} if a < 0
75
+ */
76
+ export declare function bigintToHex(a: bigint, prefix0x?: boolean, byteLength?: number): string;
77
+ /**
78
+ * Converts a hexadecimal string to a bigint
79
+ *
80
+ * @param hexStr
81
+ *
82
+ * @returns a bigint
83
+ *
84
+ * @throws {@link RangeError} if input string does not hold an hexadecimal number
85
+ */
86
+ export declare function hexToBigint(hexStr: string): bigint;
87
+ /**
88
+ * Converts a non-negative bigint representing a binary array of utf-8 encoded
89
+ * text to a string of utf-8 text
90
+ *
91
+ * @param a - A non-negative bigint representing a binary array of utf-8 encoded
92
+ * text.
93
+ *
94
+ * @returns a string text with utf-8 encoding
95
+ *
96
+ * @throws {@link RangeError} if a < 0.
97
+ */
98
+ export declare function bigintToText(a: bigint): string;
99
+ /**
100
+ * Converts a utf-8 string to a bigint (from its binary representaion)
101
+ *
102
+ * @param text - A string text with utf-8 encoding
103
+ *
104
+ * @returns a bigint representing a binary array of the input utf-8 encoded text
105
+ */
106
+ export declare function textToBigint(text: string): bigint;
107
+ /**
108
+ * Converts an ArrayBuffer, TypedArray or Buffer (in Node.js) containing utf-8
109
+ * encoded text to a string of utf-8 text
110
+ *
111
+ * @param buf - A buffer containing utf-8 encoded text
112
+ *
113
+ * @returns a string text with utf-8 encoding
114
+ */
115
+ export declare function bufToText(buf: ArrayBuffer | TypedArray | Buffer): string;
116
+ /**
117
+ * Converts a string of utf-8 encoded text to an ArrayBuffer or a Buffer
118
+ * (default in Node.js)
119
+ *
120
+ * @param str - A string of text (with utf-8 encoding)
121
+ * @param returnArrayBuffer - When invoked in Node.js, it can force the output
122
+ * to be an ArrayBuffer instead of a Buffer.
123
+ *
124
+ * @returns an ArrayBuffer or a Buffer containing the utf-8 encoded text
125
+ */
126
+ export declare function textToBuf(str: string, returnArrayBuffer?: boolean): ArrayBuffer | Buffer;
127
+ /**
128
+ * Returns the hexadecimal representation of a buffer.
129
+ *
130
+ * @param buf
131
+ * @param prefix0x - set to true to prefix the output with '0x'
132
+ * @param byteLength - pad the output to have the desired byte length. Notice
133
+ * that the hex length is double the byte length.
134
+ *
135
+ * @returns a string with a hexadecimal representation of the input buffer
136
+ */
137
+ export declare function bufToHex(buf: ArrayBuffer | TypedArray | Buffer, prefix0x?: boolean, byteLength?: number): string;
138
+ /**
139
+ * Converts a hexadecimal string to a buffer
140
+ *
141
+ * @param hexStr - A string representing a number with hexadecimal notation
142
+ * @param returnArrayBuffer - In Node.js, it forces the output to be an
143
+ * ArrayBuffer instead of a Buffer.
144
+ *
145
+ * @returns An ArrayBuffer or a Buffer
146
+ *
147
+ * @throws {@link RangeError} if input string does not hold an hexadecimal number
148
+ */
149
+ export declare function hexToBuf(hexStr: string, returnArrayBuffer?: boolean): ArrayBuffer | Buffer;
150
+ /**
151
+ * Converts an arbitrary-size non-negative bigint to a base64 string
152
+ * @param a - a non negative bigint
153
+ * @param urlsafe - if true Base64 URL encoding is used ('+' and '/' are
154
+ * replaced by '-', '_')
155
+ * @param padding - if false, padding (trailing '=') is removed
156
+ * @returns a base64 representation of the input bigint
157
+ *
158
+ * @throws {RangeError}
159
+ * Thrown if a < 0
160
+ */
161
+ export declare function bigintToBase64(a: bigint, urlsafe?: boolean, padding?: boolean): string;
162
+ /**
163
+ * Converts a base64 string to bigint.
164
+ * @param a base64 string. It accepts standard and URL-safe base64 with and
165
+ * without padding
166
+ * @returns a bigint
167
+ */
168
+ export declare function base64ToBigint(a: string): bigint;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gsknnft/bigint-buffer",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "bigint to buffer conversion with native support and built-in conversion helpers",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -17,7 +17,40 @@
17
17
  "require": "./dist/conversion/index.cjs"
18
18
  }
19
19
  },
20
+ "files": [
21
+ "dist/",
22
+ "helper/",
23
+ "src/",
24
+ "binding.gyp",
25
+ "build/",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
20
29
  "workspaces": [],
30
+ "scripts": {
31
+ "test": "vitest run",
32
+ "test:watch": "vitest watch",
33
+ "coverage": "vitest cover ./test/index.js",
34
+ "lint": "gts check",
35
+ "install": "node-gyp rebuild",
36
+ "prepublishOnly": "rm -rf build/Makefile; rm build/gyp-*; rm build/*.mk; rm build/*.Makefile; rm *.tgz",
37
+ "clean:js": "npm clean && rm -rf build/* dist/*",
38
+ "test:browser": "vite test --browser",
39
+ "test:node": "mocha build/src/**/*.spec.js --timeout 40000",
40
+ "declare": "tsc -p . --declaration --emitDeclarationOnly --outDir dist/types",
41
+ "benchmark": "node -r ts-node/register src/index.bench.ts",
42
+ "typedoc": "typedoc --out docs $(pwd)/src $(pwd)/helper --target es6 --mode file --tsconfig ./tsconfig.json --excludePrivate --excludeProtected --excludeNotExported --exclude '**/*+(spec|bench).ts'",
43
+ "rebuild:native": "node-gyp rebuild",
44
+ "build": "vite build && npm run declare && tsc -p . && cpy \"index.d.ts\" ../dist --cwd dist/types && cpy \"conversion/index.d.ts\" ../dist/conversion --cwd dist/types",
45
+ "compile": "vite build && npm run declare && tsc -p . && cpy \"index.d.ts\" ../dist/types --cwd dist/types && cpy \"conversion/index.d.ts\" ../dist/conversion --cwd dist/types",
46
+ "check": "eslint src/**/*.ts src/conversion/**/*.ts src/index.spec.ts src/conversion/test/**/*.ts",
47
+ "test:vitest": "vitest",
48
+ "test:all": "pnpm run test && pnpm run benchmark",
49
+ "clean": "gts clean",
50
+ "fix": "gts fix",
51
+ "pretest": "npm run compile",
52
+ "posttest": "npm run check"
53
+ },
21
54
  "repository": {
22
55
  "type": "git",
23
56
  "url": "https://github.com/gsknnft/bigint-buffer.git"
@@ -33,11 +66,15 @@
33
66
  "napi"
34
67
  ],
35
68
  "license": "Apache-2.0",
69
+ "pnpm": {
70
+ "overrides": {
71
+ "tmp": "0.2.5"
72
+ }
73
+ },
36
74
  "optionalDependencies": {
37
75
  "bindings": "^1.5.0"
38
76
  },
39
77
  "devDependencies": {
40
- "jiti": "^2.6.1",
41
78
  "@rollup/plugin-commonjs": "^29.0.0",
42
79
  "@rollup/plugin-esm-shim": "0.1.8",
43
80
  "@rollup/plugin-json": "^6.1.0",
@@ -59,6 +96,7 @@
59
96
  "eslint": "^9.39.1",
60
97
  "globals": "^16.5.0",
61
98
  "gts": "^6.0.2",
99
+ "jiti": "^2.6.1",
62
100
  "karma": "^6.4.4",
63
101
  "karma-chrome-launcher": "^3.2.0",
64
102
  "karma-env-preprocessor": "^0.1.1",
@@ -88,28 +126,5 @@
88
126
  "contributors": [
89
127
  "Gordon Skinner <gsknnft@gmail.com> (https://github.com/gsknnft)",
90
128
  "Michael Wei <mwei@vmware.com> (https://github.com/no2chem)"
91
- ],
92
- "scripts": {
93
- "test": "vitest run",
94
- "test:watch": "vitest watch",
95
- "coverage": "vitest cover ./test/index.js",
96
- "lint": "gts check",
97
- "install": "node-gyp rebuild",
98
- "clean:js": "npm clean && rm -rf build/* dist/*",
99
- "test:browser": "vite test --browser",
100
- "test:node": "mocha build/src/**/*.spec.js --timeout 40000",
101
- "declare": "tsc -p . --declaration --emitDeclarationOnly --outDir dist/types",
102
- "benchmark": "node -r ts-node/register src/index.bench.ts",
103
- "typedoc": "typedoc --out docs $(pwd)/src $(pwd)/helper --target es6 --mode file --tsconfig ./tsconfig.json --excludePrivate --excludeProtected --excludeNotExported --exclude '**/*+(spec|bench).ts'",
104
- "rebuild:native": "node-gyp rebuild",
105
- "build": "vite build && npm run declare && tsc -p . && cpy \"index.d.ts\" ../dist --cwd dist/types && cpy \"conversion/index.d.ts\" ../dist/conversion --cwd dist/types",
106
- "compile": "vite build && npm run declare && tsc -p . && cpy \"index.d.ts\" ../dist/types --cwd dist/types && cpy \"conversion/index.d.ts\" ../dist/conversion --cwd dist/types",
107
- "check": "eslint src/**/*.ts src/conversion/**/*.ts src/index.spec.ts src/conversion/test/**/*.ts",
108
- "test:vitest": "vitest",
109
- "test:all": "pnpm run test && pnpm run benchmark",
110
- "clean": "gts clean",
111
- "fix": "gts fix",
112
- "pretest": "npm run compile",
113
- "posttest": "npm run check"
114
- }
115
- }
129
+ ]
130
+ }
@@ -0,0 +1,203 @@
1
+
2
+ #define NAPI_EXPERIMENTAL
3
+ #include <node_api.h>
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <assert.h>
8
+ #include <limits.h>
9
+
10
+ #define BIT_MASK(n) (~( ((~0ull) << ((n)-1)) << 1 ))
11
+
12
+ // The maximum size we'll store on the stack. If we need a larger temporary
13
+ // buffer malloc will be called.
14
+ #define BUFFER_STACK_SIZE 32
15
+
16
+ #if defined(_WIN16) || defined(_WIN32) || defined(_WIN64)
17
+ #define bswap64(x) _byteswap_uint64(x)
18
+ #else
19
+ #define bswap64(x) __builtin_bswap64(x)
20
+ #endif
21
+
22
+ /**
23
+ * Converts a Buffer to bigint.
24
+ * node param 0: buffer
25
+ * node param 1: big_endian (optional boolean)
26
+ *
27
+ * returns bigint
28
+ */
29
+ napi_value toBigInt (napi_env env, napi_callback_info info) {
30
+ napi_value argv[2];
31
+ napi_status status;
32
+ size_t argc = 2;
33
+
34
+ status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
35
+ assert(status == napi_ok);
36
+
37
+ if (argc < 1) {
38
+ napi_throw_error(env, "EINVAL", "Too few arguments");
39
+ return NULL;
40
+ }
41
+
42
+ bool big_endian;
43
+ status = napi_get_value_bool(env, argv[1], &big_endian);
44
+ if (status == napi_boolean_expected) { big_endian = false; }
45
+
46
+ uint8_t* buffer;
47
+ size_t len;
48
+ status = napi_get_buffer_info(env, argv[0], (void**) &buffer, &len);
49
+ assert(status == napi_ok);
50
+
51
+ // If len is not divisible by 8 bytes, we'll need to copy
52
+ bool not_64_aligned = (len & 7) != 0;
53
+ size_t overflow_len = not_64_aligned ? 8 - (len & 0x7) : 0;
54
+ // Buffer is managed by VM, so copy it out (TODO: perhaps we can increase refcount?)
55
+ size_t aligned_len = len + overflow_len;
56
+ size_t len_in_words = not_64_aligned ? (len >> 3) + 1 : (len >> 3);
57
+ bool fits_in_stack = aligned_len <= BUFFER_STACK_SIZE;
58
+
59
+ uint8_t copy[BUFFER_STACK_SIZE];
60
+ uint8_t* bufTemp = fits_in_stack ? copy : malloc(aligned_len);
61
+ if (overflow_len > 0) {
62
+ memset(bufTemp + len, 0, overflow_len);
63
+ }
64
+ memcpy(bufTemp, buffer, len);
65
+ uint64_t* as_64_aligned = (uint64_t*) bufTemp;
66
+ size_t overflow_in_bits = overflow_len << 3; // == overflow_len * 8
67
+
68
+ napi_value out;
69
+ // swap
70
+ if (big_endian) {
71
+ if (len_in_words == 1) {
72
+ as_64_aligned[0] = not_64_aligned ? bswap64(as_64_aligned[0]) >> overflow_in_bits : bswap64(as_64_aligned[0]);
73
+ } else {
74
+ uint64_t temp;
75
+ size_t last_word = len_in_words - 1;
76
+ size_t end_ptr = last_word;
77
+ int32_t offset;
78
+ for (offset = 0; offset < (int32_t)(len_in_words / 2); offset++) {
79
+ temp = as_64_aligned[offset];
80
+ as_64_aligned[offset] = as_64_aligned[end_ptr];
81
+ as_64_aligned[end_ptr] = temp;
82
+ end_ptr--;
83
+ }
84
+ uint64_t prev_overflow = 0;
85
+ for (offset = last_word; offset >= 0; offset--) {
86
+ uint64_t as_little_endian = bswap64(as_64_aligned[offset]);
87
+ uint64_t overflow = as_little_endian & BIT_MASK(overflow_in_bits);
88
+ as_64_aligned[offset] = not_64_aligned ? (as_little_endian >> overflow_in_bits) | prev_overflow : as_little_endian;
89
+ prev_overflow = overflow << (64 - overflow_in_bits);
90
+ }
91
+ }
92
+ }
93
+
94
+ status = napi_create_bigint_words(env, 0, len_in_words, as_64_aligned , &out);
95
+ assert(status == napi_ok);
96
+
97
+ if (!fits_in_stack) {
98
+ free(bufTemp);
99
+ }
100
+
101
+ return out;
102
+ }
103
+
104
+ /**
105
+ * Converts a BigInt to a Buffer
106
+ * node param 0: BigInt
107
+ * node param 1: buffer
108
+ * node param 2: big_endian (optional boolean)
109
+ *
110
+ * returns bigint
111
+ */
112
+ napi_value fromBigInt (napi_env env, napi_callback_info info) {
113
+ napi_value argv[3];
114
+ napi_status status;
115
+ size_t argc = 3;
116
+
117
+ status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
118
+ assert(status == napi_ok);
119
+
120
+ if (argc < 1) {
121
+ napi_throw_error(env, "EINVAL", "Too few arguments");
122
+ return NULL;
123
+ }
124
+
125
+ size_t byte_width;
126
+ bool big_endian;
127
+ status = napi_get_value_bool(env, argv[2], &big_endian);
128
+ if (status == napi_boolean_expected) { big_endian = false; }
129
+
130
+ size_t word_count;
131
+ status = napi_get_value_bigint_words(env, argv[0], NULL, &word_count, NULL);
132
+ assert(status == napi_ok);
133
+
134
+ uint8_t* raw_buffer;
135
+ status = napi_get_buffer_info(env, argv[1], (void**) &raw_buffer, &byte_width);
136
+ assert(status == napi_ok);
137
+
138
+ if (word_count == 0) {
139
+ memset(raw_buffer, 0, byte_width);
140
+ return argv[1];
141
+ }
142
+
143
+ int sign_bit = 0;
144
+
145
+ bool not_64_aligned = (byte_width & 7) != 0;
146
+ size_t overflow_len = not_64_aligned ? 8 - (byte_width & 0x7) : 0;
147
+ size_t word_width = (byte_width >> 3) + (not_64_aligned ? 1 : 0);
148
+ size_t original_word_width = word_width;
149
+ if (word_count > word_width) {
150
+ word_count = word_width;
151
+ }
152
+ size_t word_width_bytes = (word_count << 3);
153
+ bool fits_in_stack = word_width_bytes <= BUFFER_STACK_SIZE;
154
+
155
+ uint64_t* conv_buffer = (uint64_t*) raw_buffer;
156
+ uint64_t stack_buffer[BUFFER_STACK_SIZE];
157
+ if (not_64_aligned) {
158
+ conv_buffer = fits_in_stack ? stack_buffer : malloc(byte_width + overflow_len);
159
+ }
160
+
161
+ memset(conv_buffer, 0, byte_width + overflow_len);
162
+ status = napi_get_value_bigint_words(env, argv[0], &sign_bit, &word_count, conv_buffer);
163
+ assert(status == napi_ok);
164
+
165
+ if (big_endian) {
166
+ uint64_t temp;
167
+ size_t conv_words = original_word_width;
168
+ size_t last_word = conv_words - 1;
169
+ size_t end_ptr = last_word;
170
+ int32_t offset;
171
+ for (offset = 0; offset < (int32_t)(conv_words / 2); offset++) {
172
+ temp = bswap64(conv_buffer[offset]);
173
+ conv_buffer[offset] = bswap64(conv_buffer[end_ptr]);
174
+ conv_buffer[end_ptr] = temp;
175
+ end_ptr--;
176
+ }
177
+ if (conv_words & 1) {
178
+ conv_buffer[conv_words / 2] = bswap64(conv_buffer[conv_words / 2]);;
179
+ }
180
+ }
181
+ if (not_64_aligned) {
182
+ memcpy(raw_buffer, big_endian ? (uint64_t*)(((uint8_t*)conv_buffer) + (8-(byte_width & 7))) : conv_buffer, byte_width);
183
+ if (!fits_in_stack) {
184
+ free(conv_buffer);
185
+ }
186
+ }
187
+ return argv[1];
188
+ }
189
+
190
+ napi_value init_all (napi_env env, napi_value exports) {
191
+ napi_value bigint_fn;
192
+ napi_value frombigint_fn;
193
+
194
+ napi_create_function(env, NULL, 0, toBigInt, NULL, &bigint_fn);
195
+ napi_create_function(env, NULL, 0, fromBigInt, NULL, &frombigint_fn);
196
+
197
+ napi_set_named_property(env, exports, "toBigInt", bigint_fn);
198
+ napi_set_named_property(env, exports, "fromBigInt", frombigint_fn);
199
+
200
+ return exports;
201
+ }
202
+
203
+ NAPI_MODULE(NODE_GYP_MODULE_NAME, init_all);
@@ -0,0 +1,11 @@
1
+ import {describe, expect, it} from 'vitest';
2
+
3
+ describe('bigint-buffer', () => {
4
+ it('should convert bigint to buffer and back', () => {
5
+ // Example test, replace with real logic
6
+ const big = BigInt('12345678901234567890');
7
+ const buf = Buffer.from(big.toString(16), 'hex');
8
+ const result = BigInt('0x' + buf.toString('hex'));
9
+ expect(result).toBe(big);
10
+ });
11
+ });
@@ -0,0 +1,116 @@
1
+ # name: build, test (node and browser), coverage, publish to NPM
2
+
3
+ # on:
4
+ # push:
5
+ # tags:
6
+ # - "v*.*.*"
7
+ # workflow_dispatch:
8
+
9
+ # jobs:
10
+ # build:
11
+ # name: build
12
+ # runs-on: ubuntu-latest
13
+ # steps:
14
+ # - name: Git checkout
15
+ # uses: actions/checkout@v3
16
+
17
+ # - name: Use Node.js 24
18
+ # uses: actions/setup-node@v3
19
+ # with:
20
+ # node-version: 24.x
21
+ # registry-url: "https://registry.npmjs.org"
22
+
23
+ # - name: install
24
+ # run: pnpm ci
25
+
26
+ # - name: build
27
+ # run: pnpm run build
28
+
29
+ # nodetests:
30
+ # name: tests in Node.js
31
+ # needs: [build]
32
+ # runs-on: ${{ matrix.os }}
33
+ # strategy:
34
+ # matrix:
35
+ # os: [ubuntu-latest, windows-latest, macos-latest]
36
+ # node-version: [18.x, 20.x, 21.x]
37
+ # # When set to true, GitHub cancels all in-progress jobs if any matrix job fails.
38
+ # fail-fast: false
39
+ # # The maximum number of jobs that can run simultaneously. Set to 1 if you can't run tests in parallel
40
+ # # max-parallel: 1
41
+ # steps:
42
+ # - name: Git checkout
43
+ # uses: actions/checkout@v3
44
+
45
+ # - name: Use Node.js ${{ matrix.node-version }}
46
+ # uses: actions/setup-node@v3
47
+ # with:
48
+ # node-version: ${{ matrix.node-version }}
49
+ # registry-url: "https://registry.npmjs.org"
50
+
51
+ # - name: install
52
+ # run: pnpm i
53
+
54
+ # - name: node esm tests
55
+ # run: pnpm run test:node-esm
56
+ # # env:
57
+ # # VARIABLE1: ${{ secrets.VARIABLE1 }}
58
+ # # VARIABLE2: ${{ secrets.VARIABLE2 }}
59
+
60
+ # - name: node cjs tests
61
+ # run: pnpm run test:node-cjs
62
+ # # env:
63
+ # # VARIABLE1: ${{ secrets.VARIABLE1 }}
64
+ # # VARIABLE2: ${{ secrets.VARIABLE2 }}
65
+
66
+ # browsertests:
67
+ # needs: [build]
68
+ # name: tests in browser
69
+ # runs-on: ubuntu-latest
70
+ # steps:
71
+ # - name: Git checkout
72
+ # uses: actions/checkout@v3
73
+
74
+ # - name: Use Node.js 20
75
+ # uses: actions/setup-node@v3
76
+ # with:
77
+ # node-version: 20.x
78
+ # registry-url: "https://registry.npmjs.org"
79
+
80
+ # - name: install
81
+ # run: npm ci
82
+
83
+ # - name: browser tests
84
+ # run: npm run test:browser-headless
85
+ # # env:
86
+ # # VARIABLE1: ${{ secrets.VARIABLE1 }}
87
+ # # VARIABLE2: ${{ secrets.VARIABLE2 }}
88
+
89
+ # publish:
90
+ # needs: [nodetests, browsertests]
91
+ # runs-on: ubuntu-latest
92
+ # steps:
93
+ # - name: Git checkout
94
+ # uses: actions/checkout@v3
95
+
96
+ # - name: Install Node.js
97
+ # uses: actions/setup-node@v3
98
+ # with:
99
+ # node-version: "20.x"
100
+ # registry-url: "https://registry.npmjs.org"
101
+
102
+ # - name: install
103
+ # run: npm ci
104
+
105
+ # - name: coverage
106
+ # run: npm run coverage
107
+
108
+ # - name: send report to coveralls.io
109
+ # uses: coverallsapp/github-action@master
110
+ # with:
111
+ # github-token: ${{ secrets.GITHUB_TOKEN }}
112
+
113
+ # - name: NPM publish
114
+ # run: npm publish --access public
115
+ # env:
116
+ # NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}