@ohos-ports/bare-buffer 3.7.1-beta.0
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.
- package/LICENSE +201 -0
- package/README.md +26 -0
- package/binding.c +1077 -0
- package/binding.gyp +32 -0
- package/binding.js +1 -0
- package/build/Release/bare_buffer.node +0 -0
- package/deps/libbase64/.clang-format +10 -0
- package/deps/libbase64/.gitattributes +1 -0
- package/deps/libbase64/.github/workflows/integrate.yml +45 -0
- package/deps/libbase64/.github/workflows/nightly.yml +28 -0
- package/deps/libbase64/.prettierrc +1 -0
- package/deps/libbase64/CMakeLists.txt +71 -0
- package/deps/libbase64/LICENSE +201 -0
- package/deps/libbase64/NOTICE +13 -0
- package/deps/libbase64/README.md +11 -0
- package/deps/libbase64/include/base64.h +323 -0
- package/deps/libbase64/package.json +25 -0
- package/deps/libbase64/src/base64.c +22 -0
- package/deps/libbase64/test/CMakeLists.txt +31 -0
- package/deps/libbase64/test/decode-invalid.c +35 -0
- package/deps/libbase64/test/decode-length.c +23 -0
- package/deps/libbase64/test/decode.c +36 -0
- package/deps/libbase64/test/encode-length.c +22 -0
- package/deps/libbase64/test/encode.c +42 -0
- package/deps/libbase64/test/fuzz/CMakeLists.txt +18 -0
- package/deps/libbase64/test/fuzz/decode/utf16le.c +53 -0
- package/deps/libbase64/test/fuzz/decode/utf8.c +47 -0
- package/deps/libbase64/test/fuzz/encode/utf16le.c +56 -0
- package/deps/libbase64/test/fuzz/encode/utf8.c +56 -0
- package/deps/libhex/.clang-format +10 -0
- package/deps/libhex/.gitattributes +1 -0
- package/deps/libhex/.github/workflows/integrate.yml +45 -0
- package/deps/libhex/.github/workflows/nightly.yml +28 -0
- package/deps/libhex/.prettierrc +1 -0
- package/deps/libhex/CMakeLists.txt +72 -0
- package/deps/libhex/LICENSE +201 -0
- package/deps/libhex/NOTICE +13 -0
- package/deps/libhex/README.md +11 -0
- package/deps/libhex/include/hex.h +163 -0
- package/deps/libhex/package.json +25 -0
- package/deps/libhex/src/hex.c +16 -0
- package/deps/libhex/test/CMakeLists.txt +31 -0
- package/deps/libhex/test/decode-invalid.c +37 -0
- package/deps/libhex/test/decode-length.c +23 -0
- package/deps/libhex/test/decode.c +25 -0
- package/deps/libhex/test/encode-length.c +22 -0
- package/deps/libhex/test/encode.c +25 -0
- package/deps/libhex/test/fuzz/CMakeLists.txt +18 -0
- package/deps/libhex/test/fuzz/decode/utf16le.c +53 -0
- package/deps/libhex/test/fuzz/decode/utf8.c +47 -0
- package/deps/libhex/test/fuzz/encode/utf16le.c +36 -0
- package/deps/libhex/test/fuzz/encode/utf8.c +36 -0
- package/deps/libutf/.clang-format +10 -0
- package/deps/libutf/.gitattributes +1 -0
- package/deps/libutf/.github/workflows/integrate.yml +45 -0
- package/deps/libutf/.github/workflows/nightly.yml +28 -0
- package/deps/libutf/.prettierrc +1 -0
- package/deps/libutf/CMakeLists.txt +105 -0
- package/deps/libutf/LICENSE +201 -0
- package/deps/libutf/NOTICE +13 -0
- package/deps/libutf/README.md +11 -0
- package/deps/libutf/include/utf/string.h +1655 -0
- package/deps/libutf/include/utf.h +132 -0
- package/deps/libutf/package.json +24 -0
- package/deps/libutf/src/ascii/validate.c +47 -0
- package/deps/libutf/src/endianness.c +19 -0
- package/deps/libutf/src/endianness.h +54 -0
- package/deps/libutf/src/latin1/convert-to-utf16.c +37 -0
- package/deps/libutf/src/latin1/convert-to-utf32.c +34 -0
- package/deps/libutf/src/latin1/convert-to-utf8.c +58 -0
- package/deps/libutf/src/latin1/length-from-utf16.c +26 -0
- package/deps/libutf/src/latin1/length-from-utf32.c +26 -0
- package/deps/libutf/src/latin1/length-from-utf8.c +34 -0
- package/deps/libutf/src/utf16/convert-to-latin1.c +41 -0
- package/deps/libutf/src/utf16/convert-to-utf32.c +56 -0
- package/deps/libutf/src/utf16/convert-to-utf8.c +80 -0
- package/deps/libutf/src/utf16/length-from-latin1.c +26 -0
- package/deps/libutf/src/utf16/length-from-utf32.c +33 -0
- package/deps/libutf/src/utf16/length-from-utf8.c +38 -0
- package/deps/libutf/src/utf16/validate.c +53 -0
- package/deps/libutf/src/utf32/convert-to-latin1.c +40 -0
- package/deps/libutf/src/utf32/convert-to-utf16.c +56 -0
- package/deps/libutf/src/utf32/convert-to-utf8.c +71 -0
- package/deps/libutf/src/utf32/length-from-latin1.c +26 -0
- package/deps/libutf/src/utf32/length-from-utf16.c +35 -0
- package/deps/libutf/src/utf32/length-from-utf8.c +35 -0
- package/deps/libutf/src/utf32/string.c +149 -0
- package/deps/libutf/src/utf32/validate.c +39 -0
- package/deps/libutf/src/utf8/convert-to-latin1.c +70 -0
- package/deps/libutf/src/utf8/convert-to-utf16.c +95 -0
- package/deps/libutf/src/utf8/convert-to-utf32.c +110 -0
- package/deps/libutf/src/utf8/length-from-latin1.c +32 -0
- package/deps/libutf/src/utf8/length-from-utf16.c +48 -0
- package/deps/libutf/src/utf8/length-from-utf32.c +35 -0
- package/deps/libutf/src/utf8/string.c +149 -0
- package/deps/libutf/src/utf8/validate.c +107 -0
- package/deps/libutf/test/CMakeLists.txt +56 -0
- package/deps/libutf/test/fuzz/CMakeLists.txt +26 -0
- package/deps/libutf/test/fuzz/corpus/.gitignore +2 -0
- package/deps/libutf/test/fuzz/crashes/.gitignore +2 -0
- package/deps/libutf/test/fuzz/latin1/convert-to-utf16.c +32 -0
- package/deps/libutf/test/fuzz/latin1/convert-to-utf32.c +32 -0
- package/deps/libutf/test/fuzz/latin1/convert-to-utf8.c +33 -0
- package/deps/libutf/test/fuzz/utf16/convert-to-latin1.c +36 -0
- package/deps/libutf/test/fuzz/utf16/convert-to-utf32.c +38 -0
- package/deps/libutf/test/fuzz/utf16/convert-to-utf8.c +38 -0
- package/deps/libutf/test/fuzz/utf32/convert-to-latin1.c +36 -0
- package/deps/libutf/test/fuzz/utf32/convert-to-utf16.c +38 -0
- package/deps/libutf/test/fuzz/utf32/convert-to-utf8.c +38 -0
- package/deps/libutf/test/fuzz/utf8/convert-to-latin1.c +33 -0
- package/deps/libutf/test/fuzz/utf8/convert-to-utf16.c +35 -0
- package/deps/libutf/test/fuzz/utf8/convert-to-utf32.c +35 -0
- package/deps/libutf/test/utf16/utf8-convert.c +45 -0
- package/deps/libutf/test/utf16/utf8-length.c +41 -0
- package/deps/libutf/test/utf16/validate-invalid.c +50 -0
- package/deps/libutf/test/utf16/validate.c +32 -0
- package/deps/libutf/test/utf32/string-append.c +74 -0
- package/deps/libutf/test/utf32/string-compare.c +108 -0
- package/deps/libutf/test/utf32/string-erase.c +79 -0
- package/deps/libutf/test/utf32/string-index.c +102 -0
- package/deps/libutf/test/utf32/string-insert.c +92 -0
- package/deps/libutf/test/utf32/string-last-index.c +71 -0
- package/deps/libutf/test/utf32/string-prepend.c +51 -0
- package/deps/libutf/test/utf32/string-replace.c +88 -0
- package/deps/libutf/test/utf32/string-reserve.c +99 -0
- package/deps/libutf/test/utf32/string-substring.c +93 -0
- package/deps/libutf/test/utf8/latin1-convert.c +23 -0
- package/deps/libutf/test/utf8/string-append.c +23 -0
- package/deps/libutf/test/utf8/string-compare.c +67 -0
- package/deps/libutf/test/utf8/string-erase.c +75 -0
- package/deps/libutf/test/utf8/string-index.c +99 -0
- package/deps/libutf/test/utf8/string-last-index.c +68 -0
- package/deps/libutf/test/utf8/string-prepend.c +23 -0
- package/deps/libutf/test/utf8/string-replace.c +74 -0
- package/deps/libutf/test/utf8/string-reserve.c +51 -0
- package/deps/libutf/test/utf8/string-substring.c +68 -0
- package/deps/libutf/test/utf8/utf16-convert.c +32 -0
- package/deps/libutf/test/utf8/utf16-length.c +29 -0
- package/deps/libutf/test/utf8/validate-invalid.c +26 -0
- package/deps/libutf/test/utf8/validate.c +21 -0
- package/global.d.ts +21 -0
- package/global.js +6 -0
- package/index.d.ts +769 -0
- package/index.js +1339 -0
- package/lib/ascii.js +36 -0
- package/lib/base64.js +25 -0
- package/lib/base64url.js +25 -0
- package/lib/checked.js +23 -0
- package/lib/constants.d.ts +7 -0
- package/lib/constants.js +3 -0
- package/lib/hex.js +20 -0
- package/lib/latin1.js +14 -0
- package/lib/utf16le.js +20 -0
- package/lib/utf8.js +18 -0
- package/package.json +64 -0
package/binding.c
ADDED
|
@@ -0,0 +1,1077 @@
|
|
|
1
|
+
#include <assert.h>
|
|
2
|
+
#include <node_api.h>
|
|
3
|
+
#include <base64.h>
|
|
4
|
+
#include <hex.h>
|
|
5
|
+
#include <utf.h>
|
|
6
|
+
#include <stdatomic.h>
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
|
|
11
|
+
#define BARE_BUFFER_STACK_STRING_MAX 1024
|
|
12
|
+
#define BARE_BUFFER_STACK_UTF16_MAX (BARE_BUFFER_STACK_STRING_MAX / sizeof(utf16_t))
|
|
13
|
+
|
|
14
|
+
#define BARE_BUFFER_OUT_OF_BOUNDS INT32_MIN
|
|
15
|
+
#define BARE_BUFFER_INVALID_BUFFER (INT32_MIN + 1)
|
|
16
|
+
#define BARE_BUFFER_INVALID_STRING (INT32_MIN + 2)
|
|
17
|
+
|
|
18
|
+
static inline bool
|
|
19
|
+
bare_buffer__is_aligned(const void *data) {
|
|
20
|
+
return ((uintptr_t) data & (sizeof(utf16_t) - 1)) == 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* Node.js default limits (N-API doesn't expose platform limits) */
|
|
24
|
+
#define BARE_BUFFER_MAX_ARRAYBUFFER_LENGTH ((size_t)0x7FFFFFFF)
|
|
25
|
+
#define BARE_BUFFER_MAX_STRING_LENGTH ((size_t)0x1FFFFFFF)
|
|
26
|
+
|
|
27
|
+
static inline size_t
|
|
28
|
+
bare_buffer__arraybuffer_limit(void) {
|
|
29
|
+
return BARE_BUFFER_MAX_ARRAYBUFFER_LENGTH;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static inline size_t
|
|
33
|
+
bare_buffer__string_limit(void) {
|
|
34
|
+
return BARE_BUFFER_MAX_STRING_LENGTH;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static inline bool
|
|
38
|
+
bare_buffer__is_buffer(napi_env env, napi_value value) {
|
|
39
|
+
bool is_arraybuffer;
|
|
40
|
+
napi_is_arraybuffer(env, value, &is_arraybuffer);
|
|
41
|
+
if (is_arraybuffer) return true;
|
|
42
|
+
|
|
43
|
+
bool is_shared;
|
|
44
|
+
node_api_is_sharedarraybuffer(env, value, &is_shared);
|
|
45
|
+
return is_shared;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static inline int
|
|
49
|
+
bare_buffer__get_info(napi_env env, napi_value buffer, void **data, size_t *len) {
|
|
50
|
+
bool is_arraybuffer;
|
|
51
|
+
napi_is_arraybuffer(env, buffer, &is_arraybuffer);
|
|
52
|
+
|
|
53
|
+
if (is_arraybuffer) {
|
|
54
|
+
napi_get_arraybuffer_info(env, buffer, data, len);
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
bool is_shared;
|
|
59
|
+
node_api_is_sharedarraybuffer(env, buffer, &is_shared);
|
|
60
|
+
|
|
61
|
+
if (is_shared) {
|
|
62
|
+
/* SharedArrayBuffer: try napi_get_arraybuffer_info (works on some Node versions) */
|
|
63
|
+
napi_get_arraybuffer_info(env, buffer, data, len);
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return -1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static inline bool
|
|
71
|
+
bare_buffer__is_string(napi_env env, napi_value value) {
|
|
72
|
+
napi_valuetype type;
|
|
73
|
+
napi_typeof(env, value, &type);
|
|
74
|
+
return type == napi_string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static inline int
|
|
78
|
+
bare_buffer__slice(napi_env env, napi_value buffer, int64_t offset, int64_t len, void **data) {
|
|
79
|
+
void *base;
|
|
80
|
+
size_t byte_len;
|
|
81
|
+
int err = bare_buffer__get_info(env, buffer, &base, &byte_len);
|
|
82
|
+
if (err < 0) return BARE_BUFFER_INVALID_BUFFER;
|
|
83
|
+
|
|
84
|
+
if (offset < 0 || len < 0 || (uint64_t) offset + (uint64_t) len > byte_len) {
|
|
85
|
+
return BARE_BUFFER_OUT_OF_BOUNDS;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static uint8_t nowhere;
|
|
89
|
+
assert(base != NULL || len == 0);
|
|
90
|
+
*data = base == NULL ? &nowhere : (uint8_t *) base + offset;
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static inline int
|
|
95
|
+
bare_buffer__alloc(size_t len, void **result) {
|
|
96
|
+
void *data = malloc(len);
|
|
97
|
+
if (data == NULL) return -1;
|
|
98
|
+
*result = data;
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* ---- String write helpers ---- */
|
|
103
|
+
|
|
104
|
+
static int64_t
|
|
105
|
+
bare_buffer__write_utf8(napi_env env, napi_value string, utf8_t *buf, int64_t len) {
|
|
106
|
+
size_t str_len;
|
|
107
|
+
napi_get_value_string_utf8(env, string, NULL, 0, &str_len);
|
|
108
|
+
|
|
109
|
+
size_t written;
|
|
110
|
+
if (str_len <= (size_t) len) {
|
|
111
|
+
napi_get_value_string_utf8(env, string, buf, str_len + 1, &written);
|
|
112
|
+
return written;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
size_t tail_at = (size_t) len - (len < 3 ? (size_t) len : 3);
|
|
116
|
+
utf8_t tail[3];
|
|
117
|
+
memcpy(tail, &buf[tail_at], (size_t) len - tail_at);
|
|
118
|
+
|
|
119
|
+
napi_get_value_string_utf8(env, string, buf, (size_t) len + 1, &written);
|
|
120
|
+
|
|
121
|
+
if (written < (size_t) len && written >= tail_at) {
|
|
122
|
+
memcpy(&buf[written], &tail[written - tail_at], (size_t) len - written);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return written;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static int64_t
|
|
129
|
+
bare_buffer__write_latin1(napi_env env, napi_value string, latin1_t *buf, int64_t len) {
|
|
130
|
+
size_t str_len;
|
|
131
|
+
napi_get_value_string_latin1(env, string, NULL, 0, &str_len);
|
|
132
|
+
|
|
133
|
+
if (str_len > (size_t) len) str_len = (size_t) len;
|
|
134
|
+
|
|
135
|
+
size_t written;
|
|
136
|
+
napi_get_value_string_latin1(env, string, buf, str_len + 1, &written);
|
|
137
|
+
return written;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static int64_t
|
|
141
|
+
bare_buffer__write_utf16le(napi_env env, napi_value string, uint8_t *bytes, int64_t len) {
|
|
142
|
+
size_t str_len;
|
|
143
|
+
napi_get_value_string_utf16(env, string, NULL, 0, &str_len);
|
|
144
|
+
|
|
145
|
+
size_t capacity = (size_t) len / sizeof(utf16_t);
|
|
146
|
+
if (str_len > capacity) str_len = capacity;
|
|
147
|
+
|
|
148
|
+
size_t written;
|
|
149
|
+
if (bare_buffer__is_aligned(bytes)) {
|
|
150
|
+
napi_get_value_string_utf16(env, string, (utf16_t *) bytes, str_len + 1, &written);
|
|
151
|
+
return written * sizeof(utf16_t);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
utf16_t stack[BARE_BUFFER_STACK_UTF16_MAX];
|
|
155
|
+
utf16_t *str = stack;
|
|
156
|
+
|
|
157
|
+
if (str_len > BARE_BUFFER_STACK_UTF16_MAX) {
|
|
158
|
+
if (bare_buffer__alloc(str_len * sizeof(utf16_t), (void **) &str) < 0) return -1;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
napi_get_value_string_utf16(env, string, str, str_len + 1, &written);
|
|
162
|
+
memcpy(bytes, str, written * sizeof(utf16_t));
|
|
163
|
+
|
|
164
|
+
if (str != stack) free(str);
|
|
165
|
+
return written * sizeof(utf16_t);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static int64_t
|
|
169
|
+
bare_buffer__write_base64(napi_env env, napi_value string, utf8_t *buf, int64_t len) {
|
|
170
|
+
size_t str_len;
|
|
171
|
+
napi_get_value_string_utf8(env, string, NULL, 0, &str_len);
|
|
172
|
+
|
|
173
|
+
char *str_buf = malloc(str_len + 1);
|
|
174
|
+
if (str_buf == NULL) return -1;
|
|
175
|
+
|
|
176
|
+
size_t written;
|
|
177
|
+
napi_get_value_string_utf8(env, string, str_buf, str_len + 1, &written);
|
|
178
|
+
|
|
179
|
+
size_t decoded = (size_t) len;
|
|
180
|
+
int err = base64_decode_utf8((const utf8_t *) str_buf, written, buf, &decoded);
|
|
181
|
+
|
|
182
|
+
free(str_buf);
|
|
183
|
+
return err == 0 ? (int64_t) decoded : -1;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
static int64_t
|
|
187
|
+
bare_buffer__write_hex(napi_env env, napi_value string, utf8_t *buf, int64_t len) {
|
|
188
|
+
size_t str_len;
|
|
189
|
+
napi_get_value_string_utf8(env, string, NULL, 0, &str_len);
|
|
190
|
+
|
|
191
|
+
char *str_buf = malloc(str_len + 1);
|
|
192
|
+
if (str_buf == NULL) return -1;
|
|
193
|
+
|
|
194
|
+
size_t written;
|
|
195
|
+
napi_get_value_string_utf8(env, string, str_buf, str_len + 1, &written);
|
|
196
|
+
|
|
197
|
+
size_t decoded = (size_t) len;
|
|
198
|
+
int err = hex_decode_utf8((const utf8_t *) str_buf, written, buf, &decoded);
|
|
199
|
+
|
|
200
|
+
free(str_buf);
|
|
201
|
+
return err == 0 ? (int64_t) decoded : -1;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* ---- Check helpers ---- */
|
|
205
|
+
|
|
206
|
+
static bool
|
|
207
|
+
bare_buffer__check_buffer(napi_env env, napi_value value) {
|
|
208
|
+
if (bare_buffer__is_buffer(env, value)) return true;
|
|
209
|
+
napi_throw_type_error(env, NULL, "Buffer must be an array buffer");
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
static bool
|
|
214
|
+
bare_buffer__check_number(napi_env env, napi_value value, const char *message) {
|
|
215
|
+
napi_valuetype type;
|
|
216
|
+
napi_typeof(env, value, &type);
|
|
217
|
+
if (type != napi_number) {
|
|
218
|
+
napi_throw_type_error(env, NULL, message);
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
static bool
|
|
225
|
+
bare_buffer__check_string(napi_env env, napi_value value, const char *message) {
|
|
226
|
+
if (bare_buffer__is_string(env, value)) return true;
|
|
227
|
+
napi_throw_type_error(env, NULL, message);
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
static napi_value
|
|
232
|
+
bare_buffer__view_out_of_bounds(napi_env env) {
|
|
233
|
+
napi_throw_range_error(env, NULL, "View is out of bounds of its backing store");
|
|
234
|
+
return NULL;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
static napi_value
|
|
238
|
+
bare_buffer__out_of_memory(napi_env env) {
|
|
239
|
+
napi_throw_error(env, NULL, "Out of memory");
|
|
240
|
+
return NULL;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
static napi_value
|
|
244
|
+
bare_buffer__invalid_string_length(napi_env env) {
|
|
245
|
+
napi_throw_range_error(env, NULL, "Invalid string length");
|
|
246
|
+
return NULL;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
static inline int64_t
|
|
250
|
+
bare_buffer__to_int64(napi_env env, napi_value value) {
|
|
251
|
+
int64_t result;
|
|
252
|
+
napi_get_value_int64(env, value, &result);
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* ---- N-API callbacks ---- */
|
|
257
|
+
|
|
258
|
+
static napi_value
|
|
259
|
+
bare_buffer_alloc(napi_env env, napi_callback_info info) {
|
|
260
|
+
size_t argc = 1;
|
|
261
|
+
napi_value argv[1];
|
|
262
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
263
|
+
|
|
264
|
+
if (!bare_buffer__check_number(env, argv[0], "Length must be a number")) return NULL;
|
|
265
|
+
|
|
266
|
+
int64_t len = bare_buffer__to_int64(env, argv[0]);
|
|
267
|
+
|
|
268
|
+
if (len < 0) {
|
|
269
|
+
napi_throw_range_error(env, NULL, "Length must not be negative");
|
|
270
|
+
return NULL;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if ((uint64_t) len > bare_buffer__arraybuffer_limit()) {
|
|
274
|
+
napi_throw_range_error(env, NULL, "Length must not exceed the maximum array buffer length");
|
|
275
|
+
return NULL;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
void *data;
|
|
279
|
+
napi_value result;
|
|
280
|
+
if (napi_create_arraybuffer(env, len, &data, &result) != napi_ok) return NULL;
|
|
281
|
+
if (len > 0) memset(data, 0, (size_t) len);
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
static napi_value
|
|
286
|
+
bare_buffer_alloc_unsafe(napi_env env, napi_callback_info info) {
|
|
287
|
+
size_t argc = 1;
|
|
288
|
+
napi_value argv[1];
|
|
289
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
290
|
+
|
|
291
|
+
if (!bare_buffer__check_number(env, argv[0], "Length must be a number")) return NULL;
|
|
292
|
+
|
|
293
|
+
int64_t len = bare_buffer__to_int64(env, argv[0]);
|
|
294
|
+
|
|
295
|
+
if (len < 0) {
|
|
296
|
+
napi_throw_range_error(env, NULL, "Length must not be negative");
|
|
297
|
+
return NULL;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if ((uint64_t) len > bare_buffer__arraybuffer_limit()) {
|
|
301
|
+
napi_throw_range_error(env, NULL, "Length must not exceed the maximum array buffer length");
|
|
302
|
+
return NULL;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
void *data;
|
|
306
|
+
napi_value result;
|
|
307
|
+
if (napi_create_arraybuffer(env, len, &data, &result) != napi_ok) return NULL;
|
|
308
|
+
return result;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
static napi_value
|
|
312
|
+
bare_buffer_byte_length_utf8(napi_env env, napi_callback_info info) {
|
|
313
|
+
size_t argc = 1;
|
|
314
|
+
napi_value argv[1];
|
|
315
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
316
|
+
|
|
317
|
+
if (!bare_buffer__check_string(env, argv[0], "String must be a string")) return NULL;
|
|
318
|
+
|
|
319
|
+
size_t str_len;
|
|
320
|
+
napi_get_value_string_utf8(env, argv[0], NULL, 0, &str_len);
|
|
321
|
+
|
|
322
|
+
napi_value result;
|
|
323
|
+
napi_create_int64(env, str_len, &result);
|
|
324
|
+
return result;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
static napi_value
|
|
328
|
+
bare_buffer_to_string_utf8(napi_env env, napi_callback_info info) {
|
|
329
|
+
size_t argc = 3;
|
|
330
|
+
napi_value argv[3];
|
|
331
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
332
|
+
|
|
333
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
334
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
335
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
336
|
+
|
|
337
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
338
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
339
|
+
|
|
340
|
+
utf8_t *buf;
|
|
341
|
+
if (bare_buffer__slice(env, argv[0], offset, len, (void **) &buf) < 0)
|
|
342
|
+
return bare_buffer__view_out_of_bounds(env);
|
|
343
|
+
|
|
344
|
+
napi_value result;
|
|
345
|
+
if (napi_create_string_utf8(env, buf, len, &result) != napi_ok) return NULL;
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
static napi_value
|
|
350
|
+
bare_buffer_validate_utf8(napi_env env, napi_callback_info info) {
|
|
351
|
+
size_t argc = 3;
|
|
352
|
+
napi_value argv[3];
|
|
353
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
354
|
+
|
|
355
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
356
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
357
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
358
|
+
|
|
359
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
360
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
361
|
+
|
|
362
|
+
utf8_t *buf;
|
|
363
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
364
|
+
int32_t valid = err == 0 ? utf8_validate(buf, len) : err;
|
|
365
|
+
|
|
366
|
+
napi_value result;
|
|
367
|
+
napi_create_int32(env, valid, &result);
|
|
368
|
+
return result;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
static napi_value
|
|
372
|
+
bare_buffer_write_utf8(napi_env env, napi_callback_info info) {
|
|
373
|
+
size_t argc = 4;
|
|
374
|
+
napi_value argv[4];
|
|
375
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
376
|
+
|
|
377
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
378
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
379
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
380
|
+
if (!bare_buffer__check_string(env, argv[3], "String must be a string")) return NULL;
|
|
381
|
+
|
|
382
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
383
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
384
|
+
|
|
385
|
+
utf8_t *buf;
|
|
386
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
387
|
+
int64_t written = err == 0 ? bare_buffer__write_utf8(env, argv[3], buf, len) : err;
|
|
388
|
+
|
|
389
|
+
napi_value result;
|
|
390
|
+
napi_create_int64(env, written, &result);
|
|
391
|
+
return result;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
static napi_value
|
|
395
|
+
bare_buffer_to_string_utf16le(napi_env env, napi_callback_info info) {
|
|
396
|
+
size_t argc = 3;
|
|
397
|
+
napi_value argv[3];
|
|
398
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
399
|
+
|
|
400
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
401
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
402
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
403
|
+
|
|
404
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
405
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
406
|
+
|
|
407
|
+
uint8_t *bytes;
|
|
408
|
+
if (bare_buffer__slice(env, argv[0], offset, len, (void **) &bytes) < 0)
|
|
409
|
+
return bare_buffer__view_out_of_bounds(env);
|
|
410
|
+
|
|
411
|
+
size_t str_len = (size_t) len / sizeof(utf16_t);
|
|
412
|
+
|
|
413
|
+
if (str_len > bare_buffer__string_limit())
|
|
414
|
+
return bare_buffer__invalid_string_length(env);
|
|
415
|
+
|
|
416
|
+
napi_value result;
|
|
417
|
+
if (bare_buffer__is_aligned(bytes)) {
|
|
418
|
+
if (napi_create_string_utf16(env, (utf16_t *) bytes, str_len, &result) != napi_ok) return NULL;
|
|
419
|
+
return result;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
utf16_t stack[BARE_BUFFER_STACK_UTF16_MAX];
|
|
423
|
+
utf16_t *str = stack;
|
|
424
|
+
|
|
425
|
+
if (str_len > BARE_BUFFER_STACK_UTF16_MAX) {
|
|
426
|
+
if (bare_buffer__alloc(str_len * sizeof(utf16_t), (void **) &str) < 0)
|
|
427
|
+
return bare_buffer__out_of_memory(env);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
memcpy(str, bytes, str_len * sizeof(utf16_t));
|
|
431
|
+
napi_status status = napi_create_string_utf16(env, str, str_len, &result);
|
|
432
|
+
if (str != stack) free(str);
|
|
433
|
+
if (status != napi_ok) return NULL;
|
|
434
|
+
return result;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
static napi_value
|
|
438
|
+
bare_buffer_write_utf16le(napi_env env, napi_callback_info info) {
|
|
439
|
+
size_t argc = 4;
|
|
440
|
+
napi_value argv[4];
|
|
441
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
442
|
+
|
|
443
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
444
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
445
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
446
|
+
if (!bare_buffer__check_string(env, argv[3], "String must be a string")) return NULL;
|
|
447
|
+
|
|
448
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
449
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
450
|
+
|
|
451
|
+
uint8_t *bytes;
|
|
452
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &bytes);
|
|
453
|
+
int64_t written = err == 0 ? bare_buffer__write_utf16le(env, argv[3], bytes, len) : err;
|
|
454
|
+
|
|
455
|
+
napi_value result;
|
|
456
|
+
napi_create_int64(env, written, &result);
|
|
457
|
+
return result;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
static napi_value
|
|
461
|
+
bare_buffer_to_string_latin1(napi_env env, napi_callback_info info) {
|
|
462
|
+
size_t argc = 3;
|
|
463
|
+
napi_value argv[3];
|
|
464
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
465
|
+
|
|
466
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
467
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
468
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
469
|
+
|
|
470
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
471
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
472
|
+
|
|
473
|
+
latin1_t *buf;
|
|
474
|
+
if (bare_buffer__slice(env, argv[0], offset, len, (void **) &buf) < 0)
|
|
475
|
+
return bare_buffer__view_out_of_bounds(env);
|
|
476
|
+
|
|
477
|
+
napi_value result;
|
|
478
|
+
if (napi_create_string_latin1(env, buf, len, &result) != napi_ok) return NULL;
|
|
479
|
+
return result;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
static napi_value
|
|
483
|
+
bare_buffer_write_latin1(napi_env env, napi_callback_info info) {
|
|
484
|
+
size_t argc = 4;
|
|
485
|
+
napi_value argv[4];
|
|
486
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
487
|
+
|
|
488
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
489
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
490
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
491
|
+
if (!bare_buffer__check_string(env, argv[3], "String must be a string")) return NULL;
|
|
492
|
+
|
|
493
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
494
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
495
|
+
|
|
496
|
+
latin1_t *buf;
|
|
497
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
498
|
+
int64_t written = err == 0 ? bare_buffer__write_latin1(env, argv[3], buf, len) : err;
|
|
499
|
+
|
|
500
|
+
napi_value result;
|
|
501
|
+
napi_create_int64(env, written, &result);
|
|
502
|
+
return result;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
static napi_value
|
|
506
|
+
bare_buffer_to_string_base64(napi_env env, napi_callback_info info) {
|
|
507
|
+
size_t argc = 3;
|
|
508
|
+
napi_value argv[3];
|
|
509
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
510
|
+
|
|
511
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
512
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
513
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
514
|
+
|
|
515
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
516
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
517
|
+
|
|
518
|
+
utf8_t *buf;
|
|
519
|
+
if (bare_buffer__slice(env, argv[0], offset, len, (void **) &buf) < 0)
|
|
520
|
+
return bare_buffer__view_out_of_bounds(env);
|
|
521
|
+
|
|
522
|
+
size_t str_len;
|
|
523
|
+
base64_encode_utf8(buf, len, NULL, &str_len);
|
|
524
|
+
|
|
525
|
+
if (str_len > bare_buffer__string_limit())
|
|
526
|
+
return bare_buffer__invalid_string_length(env);
|
|
527
|
+
|
|
528
|
+
utf8_t stack[BARE_BUFFER_STACK_STRING_MAX];
|
|
529
|
+
utf8_t *str = stack;
|
|
530
|
+
|
|
531
|
+
if (str_len > sizeof(stack)) {
|
|
532
|
+
if (bare_buffer__alloc(str_len, (void **) &str) < 0)
|
|
533
|
+
return bare_buffer__out_of_memory(env);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
base64_encode_utf8(buf, len, str, &str_len);
|
|
537
|
+
|
|
538
|
+
napi_value result;
|
|
539
|
+
napi_status status = napi_create_string_latin1(env, str, str_len, &result);
|
|
540
|
+
if (str != stack) free(str);
|
|
541
|
+
if (status != napi_ok) return NULL;
|
|
542
|
+
return result;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
static napi_value
|
|
546
|
+
bare_buffer_to_string_base64url(napi_env env, napi_callback_info info) {
|
|
547
|
+
size_t argc = 3;
|
|
548
|
+
napi_value argv[3];
|
|
549
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
550
|
+
|
|
551
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
552
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
553
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
554
|
+
|
|
555
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
556
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
557
|
+
|
|
558
|
+
utf8_t *buf;
|
|
559
|
+
if (bare_buffer__slice(env, argv[0], offset, len, (void **) &buf) < 0)
|
|
560
|
+
return bare_buffer__view_out_of_bounds(env);
|
|
561
|
+
|
|
562
|
+
size_t str_len;
|
|
563
|
+
base64url_encode_utf8(buf, len, NULL, &str_len);
|
|
564
|
+
|
|
565
|
+
if (str_len > bare_buffer__string_limit())
|
|
566
|
+
return bare_buffer__invalid_string_length(env);
|
|
567
|
+
|
|
568
|
+
utf8_t stack[BARE_BUFFER_STACK_STRING_MAX];
|
|
569
|
+
utf8_t *str = stack;
|
|
570
|
+
|
|
571
|
+
if (str_len > sizeof(stack)) {
|
|
572
|
+
if (bare_buffer__alloc(str_len, (void **) &str) < 0)
|
|
573
|
+
return bare_buffer__out_of_memory(env);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
base64url_encode_utf8(buf, len, str, &str_len);
|
|
577
|
+
|
|
578
|
+
napi_value result;
|
|
579
|
+
napi_status status = napi_create_string_latin1(env, str, str_len, &result);
|
|
580
|
+
if (str != stack) free(str);
|
|
581
|
+
if (status != napi_ok) return NULL;
|
|
582
|
+
return result;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
static napi_value
|
|
586
|
+
bare_buffer_write_base64(napi_env env, napi_callback_info info) {
|
|
587
|
+
size_t argc = 4;
|
|
588
|
+
napi_value argv[4];
|
|
589
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
590
|
+
|
|
591
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
592
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
593
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
594
|
+
if (!bare_buffer__check_string(env, argv[3], "String must be a string")) return NULL;
|
|
595
|
+
|
|
596
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
597
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
598
|
+
|
|
599
|
+
utf8_t *buf;
|
|
600
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
601
|
+
int64_t decoded = err == 0 ? bare_buffer__write_base64(env, argv[3], buf, len) : err;
|
|
602
|
+
|
|
603
|
+
napi_value result;
|
|
604
|
+
napi_create_int64(env, decoded, &result);
|
|
605
|
+
return result;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
static napi_value
|
|
609
|
+
bare_buffer_to_string_hex(napi_env env, napi_callback_info info) {
|
|
610
|
+
size_t argc = 3;
|
|
611
|
+
napi_value argv[3];
|
|
612
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
613
|
+
|
|
614
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
615
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
616
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
617
|
+
|
|
618
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
619
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
620
|
+
|
|
621
|
+
utf8_t *buf;
|
|
622
|
+
if (bare_buffer__slice(env, argv[0], offset, len, (void **) &buf) < 0)
|
|
623
|
+
return bare_buffer__view_out_of_bounds(env);
|
|
624
|
+
|
|
625
|
+
size_t str_len;
|
|
626
|
+
hex_encode_utf8(buf, len, NULL, &str_len);
|
|
627
|
+
|
|
628
|
+
if (str_len > bare_buffer__string_limit())
|
|
629
|
+
return bare_buffer__invalid_string_length(env);
|
|
630
|
+
|
|
631
|
+
utf8_t stack[BARE_BUFFER_STACK_STRING_MAX];
|
|
632
|
+
utf8_t *str = stack;
|
|
633
|
+
|
|
634
|
+
if (str_len > sizeof(stack)) {
|
|
635
|
+
if (bare_buffer__alloc(str_len, (void **) &str) < 0)
|
|
636
|
+
return bare_buffer__out_of_memory(env);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
hex_encode_utf8(buf, len, str, &str_len);
|
|
640
|
+
|
|
641
|
+
napi_value result;
|
|
642
|
+
napi_status status = napi_create_string_latin1(env, str, str_len, &result);
|
|
643
|
+
if (str != stack) free(str);
|
|
644
|
+
if (status != napi_ok) return NULL;
|
|
645
|
+
return result;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
static napi_value
|
|
649
|
+
bare_buffer_write_hex(napi_env env, napi_callback_info info) {
|
|
650
|
+
size_t argc = 4;
|
|
651
|
+
napi_value argv[4];
|
|
652
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
653
|
+
|
|
654
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
655
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
656
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
657
|
+
if (!bare_buffer__check_string(env, argv[3], "String must be a string")) return NULL;
|
|
658
|
+
|
|
659
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
660
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
661
|
+
|
|
662
|
+
utf8_t *buf;
|
|
663
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
664
|
+
int64_t decoded = err == 0 ? bare_buffer__write_hex(env, argv[3], buf, len) : err;
|
|
665
|
+
|
|
666
|
+
napi_value result;
|
|
667
|
+
napi_create_int64(env, decoded, &result);
|
|
668
|
+
return result;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
static napi_value
|
|
672
|
+
bare_buffer_validate_ascii(napi_env env, napi_callback_info info) {
|
|
673
|
+
size_t argc = 3;
|
|
674
|
+
napi_value argv[3];
|
|
675
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
676
|
+
|
|
677
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
678
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
679
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
680
|
+
|
|
681
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
682
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
683
|
+
|
|
684
|
+
ascii_t *buf;
|
|
685
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
686
|
+
int32_t valid = err == 0 ? ascii_validate(buf, len) : err;
|
|
687
|
+
|
|
688
|
+
napi_value result;
|
|
689
|
+
napi_create_int32(env, valid, &result);
|
|
690
|
+
return result;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/* ---- Swap functions ---- */
|
|
694
|
+
|
|
695
|
+
static inline void
|
|
696
|
+
bare_buffer__swap16(uint8_t *data, size_t len) {
|
|
697
|
+
for (size_t i = 0; i + 1 < len; i += 2) {
|
|
698
|
+
uint8_t a = data[i];
|
|
699
|
+
data[i] = data[i + 1];
|
|
700
|
+
data[i + 1] = a;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
static inline void
|
|
705
|
+
bare_buffer__swap32(uint8_t *data, size_t len) {
|
|
706
|
+
for (size_t i = 0; i + 3 < len; i += 4) {
|
|
707
|
+
uint8_t a = data[i];
|
|
708
|
+
uint8_t b = data[i + 1];
|
|
709
|
+
data[i] = data[i + 3];
|
|
710
|
+
data[i + 1] = data[i + 2];
|
|
711
|
+
data[i + 2] = b;
|
|
712
|
+
data[i + 3] = a;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
static inline void
|
|
717
|
+
bare_buffer__swap64(uint8_t *data, size_t len) {
|
|
718
|
+
for (size_t i = 0; i + 7 < len; i += 8) {
|
|
719
|
+
for (size_t j = 0; j < 4; j++) {
|
|
720
|
+
uint8_t a = data[i + j];
|
|
721
|
+
data[i + j] = data[i + 7 - j];
|
|
722
|
+
data[i + 7 - j] = a;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
static napi_value
|
|
728
|
+
bare_buffer_swap16(napi_env env, napi_callback_info info) {
|
|
729
|
+
size_t argc = 3;
|
|
730
|
+
napi_value argv[3];
|
|
731
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
732
|
+
|
|
733
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
734
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
735
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
736
|
+
|
|
737
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
738
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
739
|
+
|
|
740
|
+
uint8_t *buf;
|
|
741
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
742
|
+
if (err == 0) bare_buffer__swap16(buf, len);
|
|
743
|
+
|
|
744
|
+
napi_value result;
|
|
745
|
+
napi_create_int32(env, err, &result);
|
|
746
|
+
return result;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
static napi_value
|
|
750
|
+
bare_buffer_swap32(napi_env env, napi_callback_info info) {
|
|
751
|
+
size_t argc = 3;
|
|
752
|
+
napi_value argv[3];
|
|
753
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
754
|
+
|
|
755
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
756
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
757
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
758
|
+
|
|
759
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
760
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
761
|
+
|
|
762
|
+
uint8_t *buf;
|
|
763
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
764
|
+
if (err == 0) bare_buffer__swap32(buf, len);
|
|
765
|
+
|
|
766
|
+
napi_value result;
|
|
767
|
+
napi_create_int32(env, err, &result);
|
|
768
|
+
return result;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
static napi_value
|
|
772
|
+
bare_buffer_swap64(napi_env env, napi_callback_info info) {
|
|
773
|
+
size_t argc = 3;
|
|
774
|
+
napi_value argv[3];
|
|
775
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
776
|
+
|
|
777
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
778
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
779
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
780
|
+
|
|
781
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
782
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
783
|
+
|
|
784
|
+
uint8_t *buf;
|
|
785
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
786
|
+
if (err == 0) bare_buffer__swap64(buf, len);
|
|
787
|
+
|
|
788
|
+
napi_value result;
|
|
789
|
+
napi_create_int32(env, err, &result);
|
|
790
|
+
return result;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
/* ---- IndexOf / LastIndexOf ---- */
|
|
794
|
+
|
|
795
|
+
static const uint8_t *
|
|
796
|
+
bare_buffer__memrchr(const uint8_t *data, uint8_t c, size_t len) {
|
|
797
|
+
const size_t chunk_len = 512;
|
|
798
|
+
|
|
799
|
+
while (len > 0) {
|
|
800
|
+
size_t take = len < chunk_len ? len : chunk_len;
|
|
801
|
+
const uint8_t *chunk = &data[len - take];
|
|
802
|
+
size_t probe = take < 8 ? take : 8;
|
|
803
|
+
|
|
804
|
+
for (size_t i = 0; i < probe; i++) {
|
|
805
|
+
if (chunk[take - 1 - i] == c) return &chunk[take - 1 - i];
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
if (memchr(chunk, c, take - probe) != NULL) {
|
|
809
|
+
size_t lo = 0;
|
|
810
|
+
size_t hi = take - probe;
|
|
811
|
+
|
|
812
|
+
while (hi - lo > 1) {
|
|
813
|
+
size_t mid = lo + (hi - lo) / 2;
|
|
814
|
+
if (memchr(&chunk[mid], c, hi - mid) != NULL) lo = mid;
|
|
815
|
+
else hi = mid;
|
|
816
|
+
}
|
|
817
|
+
return &chunk[lo];
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
len -= take;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
return NULL;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
static int64_t
|
|
827
|
+
bare_buffer__index_of(const uint8_t *data, size_t len, const uint8_t *needle, size_t needle_len, int64_t start) {
|
|
828
|
+
if (needle_len == 0 || needle_len > len) return -1;
|
|
829
|
+
if (start < 0 || (uint64_t) start > len - needle_len) return -1;
|
|
830
|
+
|
|
831
|
+
size_t from = (size_t) start;
|
|
832
|
+
|
|
833
|
+
if (needle_len == 1) {
|
|
834
|
+
const uint8_t *at = memchr(&data[from], needle[0], len - from);
|
|
835
|
+
return at == NULL ? -1 : (int64_t) (at - data);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
size_t end = len - needle_len + 1;
|
|
839
|
+
size_t i = from;
|
|
840
|
+
size_t rejected = 0;
|
|
841
|
+
|
|
842
|
+
while (i < end) {
|
|
843
|
+
const uint8_t *at = memchr(&data[i], needle[0], end - i);
|
|
844
|
+
if (at == NULL) return -1;
|
|
845
|
+
i = (size_t) (at - data);
|
|
846
|
+
if (memcmp(&data[i + 1], &needle[1], needle_len - 1) == 0) return (int64_t) i;
|
|
847
|
+
i++;
|
|
848
|
+
if (++rejected == 32) break;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
if (i >= end) return -1;
|
|
852
|
+
|
|
853
|
+
size_t skip[256];
|
|
854
|
+
for (size_t j = 0; j < 256; j++) skip[j] = needle_len;
|
|
855
|
+
for (size_t j = 0; j < needle_len - 1; j++) skip[needle[j]] = needle_len - 1 - j;
|
|
856
|
+
|
|
857
|
+
size_t last = needle_len - 1;
|
|
858
|
+
while (i < end) {
|
|
859
|
+
if (data[i + last] == needle[last] && memcmp(&data[i], needle, last) == 0)
|
|
860
|
+
return (int64_t) i;
|
|
861
|
+
i += skip[data[i + last]];
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
return -1;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
static int64_t
|
|
868
|
+
bare_buffer__last_index_of(const uint8_t *data, size_t len, const uint8_t *needle, size_t needle_len, int64_t start) {
|
|
869
|
+
if (needle_len == 0 || needle_len > len) return -1;
|
|
870
|
+
if (start < 0) return -1;
|
|
871
|
+
|
|
872
|
+
size_t last = len - needle_len;
|
|
873
|
+
size_t from = (uint64_t) start > last ? last : (size_t) start;
|
|
874
|
+
|
|
875
|
+
if (needle_len == 1) {
|
|
876
|
+
const uint8_t *at = bare_buffer__memrchr(data, needle[0], from + 1);
|
|
877
|
+
return at == NULL ? -1 : (int64_t) (at - data);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
size_t i = from;
|
|
881
|
+
size_t rejected = 0;
|
|
882
|
+
|
|
883
|
+
while (rejected < 32) {
|
|
884
|
+
const uint8_t *at = bare_buffer__memrchr(data, needle[0], i + 1);
|
|
885
|
+
if (at == NULL) return -1;
|
|
886
|
+
i = (size_t) (at - data);
|
|
887
|
+
if (memcmp(&data[i + 1], &needle[1], needle_len - 1) == 0) return (int64_t) i;
|
|
888
|
+
if (i == 0) return -1;
|
|
889
|
+
i--;
|
|
890
|
+
rejected++;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
size_t skip[256];
|
|
894
|
+
for (size_t j = 0; j < 256; j++) skip[j] = needle_len;
|
|
895
|
+
for (size_t j = needle_len - 1; j >= 1; j--) skip[needle[j]] = j;
|
|
896
|
+
|
|
897
|
+
while (true) {
|
|
898
|
+
if (data[i] == needle[0] && memcmp(&data[i + 1], &needle[1], needle_len - 1) == 0)
|
|
899
|
+
return (int64_t) i;
|
|
900
|
+
size_t shift = skip[data[i]];
|
|
901
|
+
if (i < shift) return -1;
|
|
902
|
+
i -= shift;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
static napi_value
|
|
907
|
+
bare_buffer_index_of(napi_env env, napi_callback_info info) {
|
|
908
|
+
size_t argc = 7;
|
|
909
|
+
napi_value argv[7];
|
|
910
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
911
|
+
|
|
912
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
913
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
914
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
915
|
+
|
|
916
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
917
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
918
|
+
|
|
919
|
+
if (!bare_buffer__check_buffer(env, argv[3])) return NULL;
|
|
920
|
+
if (!bare_buffer__check_number(env, argv[4], "Offset must be a number")) return NULL;
|
|
921
|
+
if (!bare_buffer__check_number(env, argv[5], "Length must be a number")) return NULL;
|
|
922
|
+
if (!bare_buffer__check_number(env, argv[6], "Start must be a number")) return NULL;
|
|
923
|
+
|
|
924
|
+
int64_t needle_offset = bare_buffer__to_int64(env, argv[4]);
|
|
925
|
+
int64_t needle_len = bare_buffer__to_int64(env, argv[5]);
|
|
926
|
+
int64_t from = bare_buffer__to_int64(env, argv[6]);
|
|
927
|
+
|
|
928
|
+
uint8_t *buf;
|
|
929
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
930
|
+
int64_t at = err;
|
|
931
|
+
|
|
932
|
+
if (err == 0) {
|
|
933
|
+
uint8_t *needle;
|
|
934
|
+
err = bare_buffer__slice(env, argv[3], needle_offset, needle_len, (void **) &needle);
|
|
935
|
+
at = err == 0 ? bare_buffer__index_of(buf, len, needle, needle_len, from) : err;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
napi_value result;
|
|
939
|
+
napi_create_int64(env, at, &result);
|
|
940
|
+
return result;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
static napi_value
|
|
944
|
+
bare_buffer_last_index_of(napi_env env, napi_callback_info info) {
|
|
945
|
+
size_t argc = 7;
|
|
946
|
+
napi_value argv[7];
|
|
947
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
948
|
+
|
|
949
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
950
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
951
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
952
|
+
|
|
953
|
+
int64_t offset = bare_buffer__to_int64(env, argv[1]);
|
|
954
|
+
int64_t len = bare_buffer__to_int64(env, argv[2]);
|
|
955
|
+
|
|
956
|
+
if (!bare_buffer__check_buffer(env, argv[3])) return NULL;
|
|
957
|
+
if (!bare_buffer__check_number(env, argv[4], "Offset must be a number")) return NULL;
|
|
958
|
+
if (!bare_buffer__check_number(env, argv[5], "Length must be a number")) return NULL;
|
|
959
|
+
if (!bare_buffer__check_number(env, argv[6], "Start must be a number")) return NULL;
|
|
960
|
+
|
|
961
|
+
int64_t needle_offset = bare_buffer__to_int64(env, argv[4]);
|
|
962
|
+
int64_t needle_len = bare_buffer__to_int64(env, argv[5]);
|
|
963
|
+
int64_t from = bare_buffer__to_int64(env, argv[6]);
|
|
964
|
+
|
|
965
|
+
uint8_t *buf;
|
|
966
|
+
int err = bare_buffer__slice(env, argv[0], offset, len, (void **) &buf);
|
|
967
|
+
int64_t at = err;
|
|
968
|
+
|
|
969
|
+
if (err == 0) {
|
|
970
|
+
uint8_t *needle;
|
|
971
|
+
err = bare_buffer__slice(env, argv[3], needle_offset, needle_len, (void **) &needle);
|
|
972
|
+
at = err == 0 ? bare_buffer__last_index_of(buf, len, needle, needle_len, from) : err;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
napi_value result;
|
|
976
|
+
napi_create_int64(env, at, &result);
|
|
977
|
+
return result;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/* ---- Compare ---- */
|
|
981
|
+
|
|
982
|
+
static inline int
|
|
983
|
+
bare_buffer__memcmp(void *a, size_t a_len, void *b, size_t b_len) {
|
|
984
|
+
int r = memcmp(a, b, a_len < b_len ? a_len : b_len);
|
|
985
|
+
if (r == 0) {
|
|
986
|
+
if (a_len < b_len) return -1;
|
|
987
|
+
if (a_len > b_len) return 1;
|
|
988
|
+
return 0;
|
|
989
|
+
}
|
|
990
|
+
return r < 0 ? -1 : 1;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
static napi_value
|
|
994
|
+
bare_buffer_compare(napi_env env, napi_callback_info info) {
|
|
995
|
+
size_t argc = 6;
|
|
996
|
+
napi_value argv[6];
|
|
997
|
+
napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
998
|
+
|
|
999
|
+
if (!bare_buffer__check_buffer(env, argv[0])) return NULL;
|
|
1000
|
+
if (!bare_buffer__check_number(env, argv[1], "Offset must be a number")) return NULL;
|
|
1001
|
+
if (!bare_buffer__check_number(env, argv[2], "Length must be a number")) return NULL;
|
|
1002
|
+
if (!bare_buffer__check_buffer(env, argv[3])) return NULL;
|
|
1003
|
+
if (!bare_buffer__check_number(env, argv[4], "Offset must be a number")) return NULL;
|
|
1004
|
+
if (!bare_buffer__check_number(env, argv[5], "Length must be a number")) return NULL;
|
|
1005
|
+
|
|
1006
|
+
int64_t a_offset = bare_buffer__to_int64(env, argv[1]);
|
|
1007
|
+
int64_t a_len = bare_buffer__to_int64(env, argv[2]);
|
|
1008
|
+
int64_t b_offset = bare_buffer__to_int64(env, argv[4]);
|
|
1009
|
+
int64_t b_len = bare_buffer__to_int64(env, argv[5]);
|
|
1010
|
+
|
|
1011
|
+
uint8_t *a;
|
|
1012
|
+
int err = bare_buffer__slice(env, argv[0], a_offset, a_len, (void **) &a);
|
|
1013
|
+
int32_t comparison = err;
|
|
1014
|
+
|
|
1015
|
+
if (err == 0) {
|
|
1016
|
+
uint8_t *b;
|
|
1017
|
+
err = bare_buffer__slice(env, argv[3], b_offset, b_len, (void **) &b);
|
|
1018
|
+
comparison = err == 0 ? bare_buffer__memcmp(a, a_len, b, b_len) : err;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
napi_value result;
|
|
1022
|
+
napi_create_int32(env, comparison, &result);
|
|
1023
|
+
return result;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
/* ---- Module Init ---- */
|
|
1027
|
+
|
|
1028
|
+
static napi_value
|
|
1029
|
+
bare_buffer_exports(napi_env env, napi_value exports) {
|
|
1030
|
+
napi_value constants;
|
|
1031
|
+
napi_create_object(env, &constants);
|
|
1032
|
+
napi_set_named_property(env, exports, "constants", constants);
|
|
1033
|
+
|
|
1034
|
+
#define SET_INT64_CONST(name, value) do { \
|
|
1035
|
+
napi_value val; \
|
|
1036
|
+
napi_create_int64(env, value, &val); \
|
|
1037
|
+
napi_set_named_property(env, constants, name, val); \
|
|
1038
|
+
} while (0)
|
|
1039
|
+
|
|
1040
|
+
SET_INT64_CONST("MAX_LENGTH", bare_buffer__arraybuffer_limit());
|
|
1041
|
+
SET_INT64_CONST("MAX_STRING_LENGTH", bare_buffer__string_limit());
|
|
1042
|
+
#undef SET_INT64_CONST
|
|
1043
|
+
|
|
1044
|
+
#define V(name, fn) do { \
|
|
1045
|
+
napi_value val; \
|
|
1046
|
+
napi_create_function(env, name, NAPI_AUTO_LENGTH, fn, NULL, &val); \
|
|
1047
|
+
napi_set_named_property(env, exports, name, val); \
|
|
1048
|
+
} while (0)
|
|
1049
|
+
|
|
1050
|
+
V("alloc", bare_buffer_alloc);
|
|
1051
|
+
V("allocUnsafe", bare_buffer_alloc_unsafe);
|
|
1052
|
+
V("byteLengthUTF8", bare_buffer_byte_length_utf8);
|
|
1053
|
+
V("toStringUTF8", bare_buffer_to_string_utf8);
|
|
1054
|
+
V("validateUTF8", bare_buffer_validate_utf8);
|
|
1055
|
+
V("writeUTF8", bare_buffer_write_utf8);
|
|
1056
|
+
V("toStringUTF16LE", bare_buffer_to_string_utf16le);
|
|
1057
|
+
V("writeUTF16LE", bare_buffer_write_utf16le);
|
|
1058
|
+
V("toStringLatin1", bare_buffer_to_string_latin1);
|
|
1059
|
+
V("writeLatin1", bare_buffer_write_latin1);
|
|
1060
|
+
V("toStringBase64", bare_buffer_to_string_base64);
|
|
1061
|
+
V("toStringBase64URL", bare_buffer_to_string_base64url);
|
|
1062
|
+
V("writeBase64", bare_buffer_write_base64);
|
|
1063
|
+
V("toStringHex", bare_buffer_to_string_hex);
|
|
1064
|
+
V("writeHex", bare_buffer_write_hex);
|
|
1065
|
+
V("validateAscii", bare_buffer_validate_ascii);
|
|
1066
|
+
V("swap16", bare_buffer_swap16);
|
|
1067
|
+
V("swap32", bare_buffer_swap32);
|
|
1068
|
+
V("swap64", bare_buffer_swap64);
|
|
1069
|
+
V("indexOf", bare_buffer_index_of);
|
|
1070
|
+
V("lastIndexOf", bare_buffer_last_index_of);
|
|
1071
|
+
V("compare", bare_buffer_compare);
|
|
1072
|
+
#undef V
|
|
1073
|
+
|
|
1074
|
+
return exports;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
NAPI_MODULE(NODE_GYP_MODULE_NAME, bare_buffer_exports)
|