xbintsc 0.2.9 → 0.3.3
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/README.md +17 -2
- package/README.zh-CN.md +16 -2
- package/bin/xbintsc.js +49 -10
- package/dist/src/ast/expressions.d.ts +2 -0
- package/dist/src/binder/binder.d.ts +24 -98
- package/dist/src/binder/binder.js +13 -559
- package/dist/src/binder/binder.js.map +1 -1
- package/dist/src/binder/declarations.d.ts +16 -0
- package/dist/src/binder/declarations.js +168 -0
- package/dist/src/binder/declarations.js.map +1 -0
- package/dist/src/binder/helpers.d.ts +11 -0
- package/dist/src/binder/helpers.js +46 -0
- package/dist/src/binder/helpers.js.map +1 -0
- package/dist/src/binder/references.d.ts +21 -0
- package/dist/src/binder/references.js +349 -0
- package/dist/src/binder/references.js.map +1 -0
- package/dist/src/binder/types.d.ts +114 -0
- package/dist/src/binder/types.js +27 -0
- package/dist/src/binder/types.js.map +1 -0
- package/dist/src/cli/main.d.ts +1 -0
- package/dist/src/cli/main.js +40 -0
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/calls/access.d.ts +13 -0
- package/dist/src/codegen/generator/calls/access.js +115 -0
- package/dist/src/codegen/generator/calls/access.js.map +1 -0
- package/dist/src/codegen/generator/calls/closures.d.ts +11 -0
- package/dist/src/codegen/generator/calls/closures.js +50 -0
- package/dist/src/codegen/generator/calls/closures.js.map +1 -0
- package/dist/src/codegen/generator/calls/invocation.d.ts +18 -0
- package/dist/src/codegen/generator/calls/invocation.js +242 -0
- package/dist/src/codegen/generator/calls/invocation.js.map +1 -0
- package/dist/src/codegen/generator/calls/literals.d.ts +10 -0
- package/dist/src/codegen/generator/calls/literals.js +69 -0
- package/dist/src/codegen/generator/calls/literals.js.map +1 -0
- package/dist/src/codegen/generator/calls/super.d.ts +10 -0
- package/dist/src/codegen/generator/calls/super.js +47 -0
- package/dist/src/codegen/generator/calls/super.js.map +1 -0
- package/dist/src/codegen/generator/calls.d.ts +15 -24
- package/dist/src/codegen/generator/calls.js +15 -482
- package/dist/src/codegen/generator/calls.js.map +1 -1
- package/dist/src/codegen/generator/context.d.ts +1 -1
- package/dist/src/codegen/generator/context.js +2 -2
- package/dist/src/codegen/generator/context.js.map +1 -1
- package/dist/src/codegen/generator/expressions/assignment.d.ts +13 -0
- package/dist/src/codegen/generator/expressions/assignment.js +203 -0
- package/dist/src/codegen/generator/expressions/assignment.js.map +1 -0
- package/dist/src/codegen/generator/expressions/operators.d.ts +14 -0
- package/dist/src/codegen/generator/expressions/operators.js +163 -0
- package/dist/src/codegen/generator/expressions/operators.js.map +1 -0
- package/dist/src/codegen/generator/expressions/primary.d.ts +17 -0
- package/dist/src/codegen/generator/expressions/primary.js +260 -0
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -0
- package/dist/src/codegen/generator/expressions.d.ts +11 -21
- package/dist/src/codegen/generator/expressions.js +11 -494
- package/dist/src/codegen/generator/expressions.js.map +1 -1
- package/dist/src/codegen/generator/module.js +16 -4
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/state.js +8 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/control-flow.d.ts +14 -0
- package/dist/src/codegen/generator/statements/control-flow.js +199 -0
- package/dist/src/codegen/generator/statements/control-flow.js.map +1 -0
- package/dist/src/codegen/generator/statements/dispatch.d.ts +12 -0
- package/dist/src/codegen/generator/statements/dispatch.js +100 -0
- package/dist/src/codegen/generator/statements/dispatch.js.map +1 -0
- package/dist/src/codegen/generator/statements/loops.d.ts +13 -0
- package/dist/src/codegen/generator/statements/loops.js +152 -0
- package/dist/src/codegen/generator/statements/loops.js.map +1 -0
- package/dist/src/codegen/generator/statements/variables.d.ts +13 -0
- package/dist/src/codegen/generator/statements/variables.js +146 -0
- package/dist/src/codegen/generator/statements/variables.js.map +1 -0
- package/dist/src/codegen/generator/statements.d.ts +13 -21
- package/dist/src/codegen/generator/statements.js +13 -568
- package/dist/src/codegen/generator/statements.js.map +1 -1
- package/dist/src/codegen/generator/tables.js +7 -0
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/codegen/values.d.ts +17 -17
- package/dist/src/codegen/values.js +21 -57
- package/dist/src/codegen/values.js.map +1 -1
- package/dist/src/diagnostics/diagnostic.d.ts +1 -0
- package/dist/src/diagnostics/diagnostic.js +1 -0
- package/dist/src/diagnostics/diagnostic.js.map +1 -1
- package/dist/src/diagnostics/source.d.ts +1 -1
- package/dist/src/diagnostics/source.js +7 -12
- package/dist/src/diagnostics/source.js.map +1 -1
- package/dist/src/driver/compiler.d.ts +4 -0
- package/dist/src/driver/compiler.js +51 -16
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/index.d.ts +5 -2
- package/dist/src/driver/index.js +5 -2
- package/dist/src/driver/index.js.map +1 -1
- package/dist/src/driver/paths.d.ts +20 -0
- package/dist/src/driver/paths.js +49 -0
- package/dist/src/driver/paths.js.map +1 -1
- package/dist/src/driver/runtime-lib.d.ts +18 -0
- package/dist/src/driver/runtime-lib.js +31 -0
- package/dist/src/driver/runtime-lib.js.map +1 -0
- package/dist/src/driver/toolchain-download.d.ts +50 -0
- package/dist/src/driver/toolchain-download.js +76 -0
- package/dist/src/driver/toolchain-download.js.map +1 -0
- package/dist/src/driver/toolchain-provider.d.ts +33 -0
- package/dist/src/driver/toolchain-provider.js +71 -0
- package/dist/src/driver/toolchain-provider.js.map +1 -0
- package/dist/src/driver/toolchain.d.ts +9 -4
- package/dist/src/driver/toolchain.js +6 -10
- package/dist/src/driver/toolchain.js.map +1 -1
- package/dist/src/extensions/node/child_process/index.d.ts +4 -2
- package/dist/src/extensions/node/child_process/index.js +4 -2
- package/dist/src/extensions/node/child_process/index.js.map +1 -1
- package/dist/src/extensions/node/events/index.d.ts +10 -0
- package/dist/src/extensions/node/events/index.js +22 -0
- package/dist/src/extensions/node/events/index.js.map +1 -0
- package/dist/src/extensions/node/index.js +6 -0
- package/dist/src/extensions/node/index.js.map +1 -1
- package/dist/src/extensions/node/querystring/index.d.ts +10 -0
- package/dist/src/extensions/node/querystring/index.js +25 -0
- package/dist/src/extensions/node/querystring/index.js.map +1 -0
- package/dist/src/extensions/node/util/index.d.ts +11 -0
- package/dist/src/extensions/node/util/index.js +41 -0
- package/dist/src/extensions/node/util/index.js.map +1 -0
- package/dist/src/extensions/registry.d.ts +6 -0
- package/dist/src/extensions/registry.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lexer/scanner/identifiers.d.ts +9 -0
- package/dist/src/lexer/scanner/identifiers.js +33 -0
- package/dist/src/lexer/scanner/identifiers.js.map +1 -0
- package/dist/src/lexer/scanner/numbers.d.ts +10 -0
- package/dist/src/lexer/scanner/numbers.js +89 -0
- package/dist/src/lexer/scanner/numbers.js.map +1 -0
- package/dist/src/lexer/scanner/punctuation.d.ts +9 -0
- package/dist/src/lexer/scanner/punctuation.js +151 -0
- package/dist/src/lexer/scanner/punctuation.js.map +1 -0
- package/dist/src/lexer/scanner/regex.d.ts +11 -0
- package/dist/src/lexer/scanner/regex.js +69 -0
- package/dist/src/lexer/scanner/regex.js.map +1 -0
- package/dist/src/lexer/scanner/strings.d.ts +13 -0
- package/dist/src/lexer/scanner/strings.js +118 -0
- package/dist/src/lexer/scanner/strings.js.map +1 -0
- package/dist/src/lexer/scanner.d.ts +20 -27
- package/dist/src/lexer/scanner.js +11 -415
- package/dist/src/lexer/scanner.js.map +1 -1
- package/dist/src/parser/declarations/classes.d.ts +14 -0
- package/dist/src/parser/declarations/classes.js +191 -0
- package/dist/src/parser/declarations/classes.js.map +1 -0
- package/dist/src/parser/declarations/functions.d.ts +17 -0
- package/dist/src/parser/declarations/functions.js +241 -0
- package/dist/src/parser/declarations/functions.js.map +1 -0
- package/dist/src/parser/declarations/type-members.d.ts +16 -0
- package/dist/src/parser/declarations/type-members.js +156 -0
- package/dist/src/parser/declarations/type-members.js.map +1 -0
- package/dist/src/parser/declarations.d.ts +13 -24
- package/dist/src/parser/declarations.js +13 -571
- package/dist/src/parser/declarations.js.map +1 -1
- package/dist/src/parser/helpers.js +13 -4
- package/dist/src/parser/helpers.js.map +1 -1
- package/dist/src/parser/literals.js +10 -1
- package/dist/src/parser/literals.js.map +1 -1
- package/dist/tests/codegen/llvm.test.js +24 -0
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/driver/compiler.test.js +3 -0
- package/dist/tests/driver/compiler.test.js.map +1 -1
- package/dist/tests/driver/paths.test.d.ts +1 -0
- package/dist/tests/driver/paths.test.js +26 -0
- package/dist/tests/driver/paths.test.js.map +1 -0
- package/dist/tests/driver/toolchain-download.test.d.ts +1 -0
- package/dist/tests/driver/toolchain-download.test.js +38 -0
- package/dist/tests/driver/toolchain-download.test.js.map +1 -0
- package/dist/tests/driver/toolchain-provider.test.d.ts +1 -0
- package/dist/tests/driver/toolchain-provider.test.js +37 -0
- package/dist/tests/driver/toolchain-provider.test.js.map +1 -0
- package/dist/tests/e2e/compile-node.test.d.ts +7 -0
- package/dist/tests/e2e/compile-node.test.js +123 -0
- package/dist/tests/e2e/compile-node.test.js.map +1 -0
- package/dist/tests/e2e/compile.test.d.ts +4 -1
- package/dist/tests/e2e/compile.test.js +78 -130
- package/dist/tests/e2e/compile.test.js.map +1 -1
- package/dist/tests/e2e/harness.d.ts +36 -0
- package/dist/tests/e2e/harness.js +64 -0
- package/dist/tests/e2e/harness.js.map +1 -0
- package/dist/tests/e2e/node-modules.test.js +60 -0
- package/dist/tests/e2e/node-modules.test.js.map +1 -1
- package/dist/tests/extensions/registry.test.js +4 -0
- package/dist/tests/extensions/registry.test.js.map +1 -1
- package/package.json +5 -3
- package/runtime/ext_node/buffer/buffer.c +12 -552
- package/runtime/ext_node/buffer/parts/byte-access.inc +35 -0
- package/runtime/ext_node/buffer/parts/construction.inc +60 -0
- package/runtime/ext_node/buffer/parts/integer-io.inc +119 -0
- package/runtime/ext_node/buffer/parts/methods.inc +135 -0
- package/runtime/ext_node/buffer/parts/prototype.inc +54 -0
- package/runtime/ext_node/buffer/parts/search.inc +86 -0
- package/runtime/ext_node/buffer/parts/static-api.inc +58 -0
- package/runtime/ext_node/child_process/child_process.c +37 -3
- package/runtime/ext_node/events/events.c +285 -0
- package/runtime/ext_node/http/http.c +11 -736
- package/runtime/ext_node/http/parts/client.inc +290 -0
- package/runtime/ext_node/http/parts/helpers.inc +45 -0
- package/runtime/ext_node/http/parts/prototypes.inc +57 -0
- package/runtime/ext_node/http/parts/response.inc +149 -0
- package/runtime/ext_node/http/parts/server.inc +133 -0
- package/runtime/ext_node/http/parts/string-builder.inc +58 -0
- package/runtime/ext_node/net/net.c +12 -504
- package/runtime/ext_node/net/parts/construction.inc +22 -0
- package/runtime/ext_node/net/parts/platform.inc +60 -0
- package/runtime/ext_node/net/parts/prototypes.inc +35 -0
- package/runtime/ext_node/net/parts/read-loop.inc +58 -0
- package/runtime/ext_node/net/parts/server.inc +131 -0
- package/runtime/ext_node/net/parts/socket-methods.inc +100 -0
- package/runtime/ext_node/net/parts/static-api.inc +93 -0
- package/runtime/ext_node/querystring/querystring.c +251 -0
- package/runtime/ext_node/util/util.c +456 -0
- package/runtime/rt.h +8 -2
- package/runtime/rt_internal.h +34 -0
- package/runtime/xt_bigint/arithmetic.inc +135 -0
- package/runtime/xt_bigint/bits.inc +98 -0
- package/runtime/xt_bigint/bitwise.inc +103 -0
- package/runtime/xt_bigint/compare.inc +30 -0
- package/runtime/xt_bigint/conversions.inc +51 -0
- package/runtime/xt_bigint/division.inc +85 -0
- package/runtime/xt_bigint/format.inc +145 -0
- package/runtime/xt_bigint/helpers.inc +92 -0
- package/runtime/xt_bigint/magnitude.inc +88 -0
- package/runtime/xt_bigint/public.inc +59 -0
- package/runtime/xt_bigint/small-arithmetic.inc +58 -0
- package/runtime/xt_bigint.c +42 -0
- package/runtime/xt_builtins.c +1 -0
- package/runtime/xt_io.c +7 -0
- package/runtime/xt_stdlib/arrays.inc +161 -0
- package/runtime/xt_stdlib/dispatch.inc +116 -0
- package/runtime/xt_stdlib/helpers.inc +23 -0
- package/runtime/xt_stdlib/math.inc +72 -0
- package/runtime/xt_stdlib/strings.inc +178 -0
- package/runtime/xt_stdlib.c +10 -549
- package/runtime/xt_stdlib2/array-statics.inc +37 -0
- package/runtime/xt_stdlib2/arrays.inc +189 -0
- package/runtime/xt_stdlib2/container.inc +23 -0
- package/runtime/xt_stdlib2/date.inc +72 -0
- package/runtime/xt_stdlib2/error.inc +22 -0
- package/runtime/xt_stdlib2/helpers.inc +43 -0
- package/runtime/xt_stdlib2/json.inc +213 -0
- package/runtime/xt_stdlib2/map.inc +95 -0
- package/runtime/xt_stdlib2/number-string-statics.inc +73 -0
- package/runtime/xt_stdlib2/numbers.inc +38 -0
- package/runtime/xt_stdlib2/objects.inc +41 -0
- package/runtime/xt_stdlib2/regexp-match.inc +204 -0
- package/runtime/xt_stdlib2/regexp.inc +20 -0
- package/runtime/xt_stdlib2/set.inc +105 -0
- package/runtime/xt_stdlib2/strings.inc +94 -0
- package/runtime/xt_stdlib2.c +19 -1278
- package/runtime/xt_values.c +155 -12
- package/scripts/build-runtime.ts +109 -0
- package/scripts/fetch-toolchain.ts +101 -0
- package/scripts/package-release.ts +192 -0
- package/src/ast/expressions.ts +2 -0
- package/src/binder/binder.ts +40 -725
- package/src/binder/declarations.ts +203 -0
- package/src/binder/helpers.ts +47 -0
- package/src/binder/references.ts +410 -0
- package/src/binder/types.ts +134 -0
- package/src/cli/main.ts +43 -0
- package/src/codegen/generator/calls/access.ts +139 -0
- package/src/codegen/generator/calls/closures.ts +60 -0
- package/src/codegen/generator/calls/invocation.ts +282 -0
- package/src/codegen/generator/calls/literals.ts +77 -0
- package/src/codegen/generator/calls/super.ts +61 -0
- package/src/codegen/generator/calls.ts +30 -552
- package/src/codegen/generator/context.ts +2 -2
- package/src/codegen/generator/expressions/assignment.ts +226 -0
- package/src/codegen/generator/expressions/operators.ts +182 -0
- package/src/codegen/generator/expressions/primary.ts +304 -0
- package/src/codegen/generator/expressions.ts +22 -553
- package/src/codegen/generator/module.ts +14 -4
- package/src/codegen/generator/state.ts +8 -0
- package/src/codegen/generator/statements/control-flow.ts +225 -0
- package/src/codegen/generator/statements/dispatch.ts +122 -0
- package/src/codegen/generator/statements/loops.ts +173 -0
- package/src/codegen/generator/statements/variables.ts +152 -0
- package/src/codegen/generator/statements.ts +26 -612
- package/src/codegen/generator/tables.ts +7 -0
- package/src/codegen/values.ts +22 -57
- package/src/diagnostics/diagnostic.ts +1 -0
- package/src/diagnostics/source.ts +7 -12
- package/src/driver/compiler.ts +61 -18
- package/src/driver/index.ts +17 -2
- package/src/driver/paths.ts +54 -0
- package/src/driver/runtime-lib.ts +32 -0
- package/src/driver/toolchain-download.ts +108 -0
- package/src/driver/toolchain-provider.ts +91 -0
- package/src/driver/toolchain.ts +29 -11
- package/src/extensions/node/child_process/index.ts +4 -2
- package/src/extensions/node/events/index.ts +27 -0
- package/src/extensions/node/index.ts +6 -0
- package/src/extensions/node/querystring/index.ts +29 -0
- package/src/extensions/node/util/index.ts +48 -0
- package/src/extensions/registry.ts +6 -0
- package/src/index.ts +1 -0
- package/src/lexer/scanner/identifiers.ts +37 -0
- package/src/lexer/scanner/numbers.ts +84 -0
- package/src/lexer/scanner/punctuation.ts +132 -0
- package/src/lexer/scanner/regex.ts +79 -0
- package/src/lexer/scanner/strings.ts +128 -0
- package/src/lexer/scanner.ts +35 -401
- package/src/parser/declarations/classes.ts +215 -0
- package/src/parser/declarations/functions.ts +254 -0
- package/src/parser/declarations/type-members.ts +181 -0
- package/src/parser/declarations.ts +32 -609
- package/src/parser/helpers.ts +13 -6
- package/src/parser/literals.ts +10 -1
- package/scripts/build-runtime.mjs +0 -55
|
@@ -14,556 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
static xt_value xt_buffer_proto(void);
|
|
16
16
|
|
|
17
|
-
/*
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
static uint32_t xt_buffer_length(xt_value buffer) {
|
|
25
|
-
double length = xt_to_number(xt_object_get_cstr(buffer, "length"));
|
|
26
|
-
if (length < 0) return 0;
|
|
27
|
-
return (uint32_t)length;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
static unsigned char xt_buffer_byte(xt_value buffer, uint32_t index) {
|
|
31
|
-
char key[24];
|
|
32
|
-
xt_value value = xt_object_get_cstr(buffer, xt_buffer_key(index, key, sizeof(key)));
|
|
33
|
-
return (unsigned char)((int32_t)xt_to_number(value) & 0xff);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
static void xt_buffer_put(xt_value buffer, uint32_t index, unsigned char byte) {
|
|
37
|
-
char key[24];
|
|
38
|
-
xt_object_set(buffer, xt_string_from_cstr(xt_buffer_key(index, key, sizeof(key))), xt_number((double)byte));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
static xt_value xt_buffer_new(uint32_t length, const unsigned char *data) {
|
|
42
|
-
xt_value buffer = xt_object_new_with_proto(xt_buffer_proto());
|
|
43
|
-
for (uint32_t i = 0; i < length; i++) xt_buffer_put(buffer, i, data ? data[i] : 0);
|
|
44
|
-
xt_node_set(buffer, "length", xt_number((double)length));
|
|
45
|
-
return buffer;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
static int xt_buffer_is(xt_value value) {
|
|
49
|
-
if (!XT_IS_OBJECT(value)) return 0;
|
|
50
|
-
return xt_truthy(xt_seq(xt_object_get_prototype(value), xt_buffer_proto()));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/* -- construction --------------------------------------------------------- */
|
|
54
|
-
|
|
55
|
-
static xt_value xt_buffer_from_bytes(const unsigned char *data, size_t length) {
|
|
56
|
-
return xt_buffer_new((uint32_t)length, data);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
static xt_value xt_buffer_from(xt_value value, const char *encoding) {
|
|
60
|
-
if (xt_buffer_is(value)) {
|
|
61
|
-
uint32_t length = xt_buffer_length(value);
|
|
62
|
-
unsigned char *copy = (unsigned char *)malloc(length ? length : 1);
|
|
63
|
-
for (uint32_t i = 0; i < length; i++) copy[i] = xt_buffer_byte(value, i);
|
|
64
|
-
xt_value result = xt_buffer_new(length, copy);
|
|
65
|
-
free(copy);
|
|
66
|
-
return result;
|
|
67
|
-
}
|
|
68
|
-
if (XT_IS_ARRAY(value)) {
|
|
69
|
-
uint32_t length = (uint32_t)xt_to_number(xt_array_length(value));
|
|
70
|
-
xt_value result = xt_buffer_new(length, NULL);
|
|
71
|
-
for (uint32_t i = 0; i < length; i++) {
|
|
72
|
-
xt_value item = xt_array_get(value, xt_number((double)i));
|
|
73
|
-
xt_buffer_put(result, i, (unsigned char)((int32_t)xt_to_number(item) & 0xff));
|
|
74
|
-
}
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
77
|
-
xt_value text = xt_to_string(value);
|
|
78
|
-
xt_string *string = xt_as_string(text);
|
|
79
|
-
size_t decoded = 0;
|
|
80
|
-
unsigned char *bytes = xt_node_decode(string->data, string->length, encoding, &decoded);
|
|
81
|
-
if (!bytes) return xt_buffer_new(0, NULL);
|
|
82
|
-
xt_value result = xt_buffer_from_bytes(bytes, decoded);
|
|
83
|
-
free(bytes);
|
|
84
|
-
return result;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
static xt_value xt_buffer_from_args(int32_t argc, xt_value *argv) {
|
|
88
|
-
if (argc < 1) return xt_buffer_new(0, NULL);
|
|
89
|
-
const char *encoding = argc > 1 ? xt_node_encoding(argv[1]) : NULL;
|
|
90
|
-
return xt_buffer_from(argv[0], encoding);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
static xt_value xt_buffer_alloc(uint32_t size, xt_value fill, const char *encoding) {
|
|
94
|
-
xt_value buffer = xt_buffer_new(size, NULL);
|
|
95
|
-
if (XT_IS_UNDEFINED(fill)) return buffer;
|
|
96
|
-
if (XT_IS_NUMBER(fill)) {
|
|
97
|
-
unsigned char byte = (unsigned char)((int32_t)xt_to_number(fill) & 0xff);
|
|
98
|
-
for (uint32_t i = 0; i < size; i++) xt_buffer_put(buffer, i, byte);
|
|
99
|
-
return buffer;
|
|
100
|
-
}
|
|
101
|
-
xt_value text = xt_to_string(fill);
|
|
102
|
-
xt_string *string = xt_as_string(text);
|
|
103
|
-
size_t decoded = 0;
|
|
104
|
-
unsigned char *bytes = xt_node_decode(string->data, string->length, encoding, &decoded);
|
|
105
|
-
if (!bytes || decoded == 0) {
|
|
106
|
-
free(bytes);
|
|
107
|
-
return buffer;
|
|
108
|
-
}
|
|
109
|
-
for (uint32_t i = 0; i < size; i++) xt_buffer_put(buffer, i, bytes[i % decoded]);
|
|
110
|
-
free(bytes);
|
|
111
|
-
return buffer;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/* -- static API ----------------------------------------------------------- */
|
|
115
|
-
|
|
116
|
-
xt_value xt_buffer_ctor(int32_t argc, xt_value *argv) {
|
|
117
|
-
if (argc == 0) return xt_buffer_new(0, NULL);
|
|
118
|
-
if (XT_IS_NUMBER(argv[0])) {
|
|
119
|
-
return xt_buffer_alloc((uint32_t)xt_to_number(argv[0]), XT_UNDEFINED, NULL);
|
|
120
|
-
}
|
|
121
|
-
return xt_buffer_from_args(argc, argv);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
xt_value xt_buffer_static(xt_value name, int32_t argc, xt_value *argv) {
|
|
125
|
-
const char *fn = xt_string_data(name);
|
|
126
|
-
if (!fn) return xt_undefined();
|
|
127
|
-
if (strcmp(fn, "from") == 0 || strcmp(fn, "of") == 0) return xt_buffer_from_args(argc, argv);
|
|
128
|
-
if (strcmp(fn, "alloc") == 0 || strcmp(fn, "allocUnsafe") == 0 || strcmp(fn, "allocUnsafeSlow") == 0) {
|
|
129
|
-
uint32_t size = argc > 0 ? (uint32_t)xt_to_number(argv[0]) : 0;
|
|
130
|
-
const char *encoding = argc > 2 ? xt_node_encoding(argv[2]) : NULL;
|
|
131
|
-
return xt_buffer_alloc(size, argc > 1 ? argv[1] : XT_UNDEFINED, encoding);
|
|
132
|
-
}
|
|
133
|
-
if (strcmp(fn, "isBuffer") == 0) return xt_bool(xt_buffer_is(xt_arg_at(argc, argv, 0)));
|
|
134
|
-
if (strcmp(fn, "byteLength") == 0) {
|
|
135
|
-
xt_value value = xt_arg_at(argc, argv, 0);
|
|
136
|
-
if (xt_buffer_is(value)) return xt_number((double)xt_buffer_length(value));
|
|
137
|
-
const char *encoding = argc > 1 ? xt_node_encoding(argv[1]) : NULL;
|
|
138
|
-
xt_value text = xt_to_string(value);
|
|
139
|
-
xt_string *string = xt_as_string(text);
|
|
140
|
-
if (encoding && strcmp(encoding, "hex") == 0) return xt_number((double)(string->length / 2));
|
|
141
|
-
if (encoding && strcmp(encoding, "base64") == 0) return xt_number((double)(string->length / 4 * 3));
|
|
142
|
-
return xt_number((double)string->length);
|
|
143
|
-
}
|
|
144
|
-
if (strcmp(fn, "concat") == 0) {
|
|
145
|
-
xt_value list = xt_arg_at(argc, argv, 0);
|
|
146
|
-
uint32_t total = 0;
|
|
147
|
-
uint32_t count = XT_IS_ARRAY(list) ? (uint32_t)xt_to_number(xt_array_length(list)) : 0;
|
|
148
|
-
for (uint32_t i = 0; i < count; i++) total += xt_buffer_length(xt_array_get(list, xt_number((double)i)));
|
|
149
|
-
if (argc > 1 && XT_IS_NUMBER(argv[1])) total = (uint32_t)xt_to_number(argv[1]);
|
|
150
|
-
xt_value result = xt_buffer_new(total, NULL);
|
|
151
|
-
uint32_t offset = 0;
|
|
152
|
-
for (uint32_t i = 0; i < count && offset < total; i++) {
|
|
153
|
-
xt_value item = xt_array_get(list, xt_number((double)i));
|
|
154
|
-
uint32_t length = xt_buffer_length(item);
|
|
155
|
-
for (uint32_t j = 0; j < length && offset < total; j++) xt_buffer_put(result, offset++, xt_buffer_byte(item, j));
|
|
156
|
-
}
|
|
157
|
-
return result;
|
|
158
|
-
}
|
|
159
|
-
if (strcmp(fn, "compare") == 0) {
|
|
160
|
-
xt_value a = xt_arg_at(argc, argv, 0);
|
|
161
|
-
xt_value b = xt_arg_at(argc, argv, 1);
|
|
162
|
-
uint32_t la = xt_buffer_length(a), lb = xt_buffer_length(b);
|
|
163
|
-
uint32_t n = la < lb ? la : lb;
|
|
164
|
-
for (uint32_t i = 0; i < n; i++) {
|
|
165
|
-
unsigned char x = xt_buffer_byte(a, i), y = xt_buffer_byte(b, i);
|
|
166
|
-
if (x != y) return xt_number(x < y ? -1 : 1);
|
|
167
|
-
}
|
|
168
|
-
return xt_number(la < lb ? -1 : la > lb ? 1 : 0);
|
|
169
|
-
}
|
|
170
|
-
return xt_undefined();
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/* -- instance methods ----------------------------------------------------- */
|
|
174
|
-
|
|
175
|
-
static xt_value xt_buffer_method_to_string(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
176
|
-
(void)env;
|
|
177
|
-
const char *encoding = argc > 0 ? xt_node_encoding(argv[0]) : NULL;
|
|
178
|
-
uint32_t length = xt_buffer_length(thisValue);
|
|
179
|
-
uint32_t start = argc > 1 ? (uint32_t)xt_to_number(argv[1]) : 0;
|
|
180
|
-
uint32_t end = argc > 2 ? (uint32_t)xt_to_number(argv[2]) : length;
|
|
181
|
-
if (end > length) end = length;
|
|
182
|
-
if (start > end) start = end;
|
|
183
|
-
unsigned char *bytes = (unsigned char *)malloc(end - start + 1);
|
|
184
|
-
for (uint32_t i = start; i < end; i++) bytes[i - start] = xt_buffer_byte(thisValue, i);
|
|
185
|
-
xt_value result = xt_node_encode(bytes, end - start, encoding);
|
|
186
|
-
free(bytes);
|
|
187
|
-
return result;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
static xt_value xt_buffer_method_to_json(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
191
|
-
(void)env;
|
|
192
|
-
(void)argc;
|
|
193
|
-
(void)argv;
|
|
194
|
-
xt_value object = xt_object_new();
|
|
195
|
-
xt_value type = xt_string_from_cstr("Buffer");
|
|
196
|
-
xt_object_set(object, xt_string_from_cstr("type"), type);
|
|
197
|
-
xt_value data = xt_array_new(0, NULL);
|
|
198
|
-
uint32_t length = xt_buffer_length(thisValue);
|
|
199
|
-
for (uint32_t i = 0; i < length; i++) xt_array_push(data, xt_number((double)xt_buffer_byte(thisValue, i)));
|
|
200
|
-
xt_object_set(object, xt_string_from_cstr("data"), data);
|
|
201
|
-
return object;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
static xt_value xt_buffer_method_slice(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
205
|
-
(void)env;
|
|
206
|
-
uint32_t length = xt_buffer_length(thisValue);
|
|
207
|
-
int32_t start = argc > 0 ? (int32_t)xt_to_number(argv[0]) : 0;
|
|
208
|
-
int32_t end = argc > 1 ? (int32_t)xt_to_number(argv[1]) : (int32_t)length;
|
|
209
|
-
if (start < 0) start += (int32_t)length;
|
|
210
|
-
if (end < 0) end += (int32_t)length;
|
|
211
|
-
if (start < 0) start = 0;
|
|
212
|
-
if (end > (int32_t)length) end = (int32_t)length;
|
|
213
|
-
if (end < start) end = start;
|
|
214
|
-
unsigned char *bytes = (unsigned char *)malloc((size_t)(end - start) + 1);
|
|
215
|
-
for (int32_t i = start; i < end; i++) bytes[i - start] = xt_buffer_byte(thisValue, (uint32_t)i);
|
|
216
|
-
xt_value result = xt_buffer_from_bytes(bytes, (size_t)(end - start));
|
|
217
|
-
free(bytes);
|
|
218
|
-
return result;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
static xt_value xt_buffer_method_equals(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
222
|
-
(void)env;
|
|
223
|
-
xt_value other = xt_arg_at(argc, argv, 0);
|
|
224
|
-
if (!xt_buffer_is(other)) return xt_bool(0);
|
|
225
|
-
uint32_t length = xt_buffer_length(thisValue);
|
|
226
|
-
if (length != xt_buffer_length(other)) return xt_bool(0);
|
|
227
|
-
for (uint32_t i = 0; i < length; i++) {
|
|
228
|
-
if (xt_buffer_byte(thisValue, i) != xt_buffer_byte(other, i)) return xt_bool(0);
|
|
229
|
-
}
|
|
230
|
-
return xt_bool(1);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
static xt_value xt_buffer_method_compare(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
234
|
-
(void)env;
|
|
235
|
-
xt_value other = xt_arg_at(argc, argv, 0);
|
|
236
|
-
uint32_t la = xt_buffer_length(thisValue), lb = xt_buffer_length(other);
|
|
237
|
-
uint32_t n = la < lb ? la : lb;
|
|
238
|
-
for (uint32_t i = 0; i < n; i++) {
|
|
239
|
-
unsigned char x = xt_buffer_byte(thisValue, i), y = xt_buffer_byte(other, i);
|
|
240
|
-
if (x != y) return xt_number(x < y ? -1 : 1);
|
|
241
|
-
}
|
|
242
|
-
return xt_number(la < lb ? -1 : la > lb ? 1 : 0);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
static xt_value xt_buffer_method_copy(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
246
|
-
(void)env;
|
|
247
|
-
xt_value target = xt_arg_at(argc, argv, 0);
|
|
248
|
-
if (!xt_buffer_is(target)) return xt_number(0);
|
|
249
|
-
uint32_t targetStart = argc > 1 ? (uint32_t)xt_to_number(argv[1]) : 0;
|
|
250
|
-
uint32_t sourceStart = argc > 2 ? (uint32_t)xt_to_number(argv[2]) : 0;
|
|
251
|
-
uint32_t sourceEnd = argc > 3 ? (uint32_t)xt_to_number(argv[3]) : xt_buffer_length(thisValue);
|
|
252
|
-
uint32_t targetLength = xt_buffer_length(target);
|
|
253
|
-
uint32_t written = 0;
|
|
254
|
-
for (uint32_t i = sourceStart; i < sourceEnd && targetStart + written < targetLength; i++) {
|
|
255
|
-
xt_buffer_put(target, targetStart + written, xt_buffer_byte(thisValue, i));
|
|
256
|
-
written++;
|
|
257
|
-
}
|
|
258
|
-
return xt_number((double)written);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
static xt_value xt_buffer_method_write(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
262
|
-
(void)env;
|
|
263
|
-
xt_value text = xt_to_string(xt_arg_at(argc, argv, 0));
|
|
264
|
-
xt_string *string = xt_as_string(text);
|
|
265
|
-
uint32_t offset = argc > 1 ? (uint32_t)xt_to_number(argv[1]) : 0;
|
|
266
|
-
const char *encoding = argc > 3 ? xt_node_encoding(argv[3]) : NULL;
|
|
267
|
-
size_t decoded = 0;
|
|
268
|
-
unsigned char *bytes = xt_node_decode(string->data, string->length, encoding, &decoded);
|
|
269
|
-
uint32_t available = xt_buffer_length(thisValue);
|
|
270
|
-
uint32_t written = 0;
|
|
271
|
-
for (size_t i = 0; i < decoded && offset + written < available; i++) {
|
|
272
|
-
xt_buffer_put(thisValue, offset + written, bytes[i]);
|
|
273
|
-
written++;
|
|
274
|
-
}
|
|
275
|
-
free(bytes);
|
|
276
|
-
return xt_number((double)written);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
static xt_value xt_buffer_method_fill(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
280
|
-
(void)env;
|
|
281
|
-
uint32_t length = xt_buffer_length(thisValue);
|
|
282
|
-
uint32_t start = argc > 1 ? (uint32_t)xt_to_number(argv[1]) : 0;
|
|
283
|
-
uint32_t end = argc > 2 ? (uint32_t)xt_to_number(argv[2]) : length;
|
|
284
|
-
if (end > length) end = length;
|
|
285
|
-
unsigned char byte = 0;
|
|
286
|
-
if (XT_IS_STRING(xt_arg_at(argc, argv, 0))) {
|
|
287
|
-
const char *text = xt_string_data(xt_arg_at(argc, argv, 0));
|
|
288
|
-
if (text && text[0]) byte = (unsigned char)text[0];
|
|
289
|
-
} else if (argc > 0) {
|
|
290
|
-
byte = (unsigned char)((int32_t)xt_to_number(argv[0]) & 0xff);
|
|
291
|
-
}
|
|
292
|
-
for (uint32_t i = start; i < end; i++) xt_buffer_put(thisValue, i, byte);
|
|
293
|
-
return thisValue;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
static xt_value xt_buffer_method_reverse(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
297
|
-
(void)env;
|
|
298
|
-
(void)argc;
|
|
299
|
-
(void)argv;
|
|
300
|
-
uint32_t length = xt_buffer_length(thisValue);
|
|
301
|
-
for (uint32_t i = 0; i < length / 2; i++) {
|
|
302
|
-
unsigned char a = xt_buffer_byte(thisValue, i);
|
|
303
|
-
xt_buffer_put(thisValue, i, xt_buffer_byte(thisValue, length - 1 - i));
|
|
304
|
-
xt_buffer_put(thisValue, length - 1 - i, a);
|
|
305
|
-
}
|
|
306
|
-
return thisValue;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/* -- search --------------------------------------------------------------- */
|
|
310
|
-
|
|
311
|
-
static const unsigned char *xt_buffer_search_needle(xt_value value, const char *encoding, size_t *length,
|
|
312
|
-
unsigned char *single) {
|
|
313
|
-
if (XT_IS_NUMBER(value)) {
|
|
314
|
-
*single = (unsigned char)((int32_t)xt_to_number(value) & 0xff);
|
|
315
|
-
*length = 1;
|
|
316
|
-
return single;
|
|
317
|
-
}
|
|
318
|
-
if (xt_buffer_is(value)) {
|
|
319
|
-
uint32_t n = xt_buffer_length(value);
|
|
320
|
-
unsigned char *bytes = (unsigned char *)malloc(n ? n : 1);
|
|
321
|
-
for (uint32_t i = 0; i < n; i++) bytes[i] = xt_buffer_byte(value, i);
|
|
322
|
-
*length = n;
|
|
323
|
-
return bytes;
|
|
324
|
-
}
|
|
325
|
-
xt_value text = xt_to_string(value);
|
|
326
|
-
xt_string *string = xt_as_string(text);
|
|
327
|
-
size_t decoded = 0;
|
|
328
|
-
unsigned char *bytes = xt_node_decode(string->data, string->length, encoding, &decoded);
|
|
329
|
-
*length = decoded;
|
|
330
|
-
return bytes;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
static xt_value xt_buffer_method_index_of(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv,
|
|
334
|
-
int reverse) {
|
|
335
|
-
(void)env;
|
|
336
|
-
const char *encoding = argc > 2 ? xt_node_encoding(argv[2]) : NULL;
|
|
337
|
-
size_t needleLength = 0;
|
|
338
|
-
unsigned char single = 0;
|
|
339
|
-
const unsigned char *needle = xt_buffer_search_needle(xt_arg_at(argc, argv, 0), encoding, &needleLength, &single);
|
|
340
|
-
uint32_t length = xt_buffer_length(thisValue);
|
|
341
|
-
int32_t start = argc > 1 ? (int32_t)xt_to_number(argv[1]) : (reverse ? (int32_t)length - 1 : 0);
|
|
342
|
-
if (start < 0) start += (int32_t)length;
|
|
343
|
-
if (start < 0) start = 0;
|
|
344
|
-
if (needleLength == 0 || needleLength > length) {
|
|
345
|
-
if (!xt_buffer_is(xt_arg_at(argc, argv, 0))) free((void *)needle);
|
|
346
|
-
return xt_number(-1);
|
|
347
|
-
}
|
|
348
|
-
int found = -1;
|
|
349
|
-
if (reverse) {
|
|
350
|
-
if (start > (int32_t)length - 1) start = (int32_t)length - 1;
|
|
351
|
-
for (int32_t i = start; i >= 0; i--) {
|
|
352
|
-
int match = 1;
|
|
353
|
-
for (size_t j = 0; j < needleLength; j++) {
|
|
354
|
-
if ((uint32_t)(i + (int32_t)j) >= length || xt_buffer_byte(thisValue, (uint32_t)(i + (int32_t)j)) != needle[j]) {
|
|
355
|
-
match = 0;
|
|
356
|
-
break;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
if (match) {
|
|
360
|
-
found = i;
|
|
361
|
-
break;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
} else {
|
|
365
|
-
for (uint32_t i = (uint32_t)start; i + needleLength <= length; i++) {
|
|
366
|
-
int match = 1;
|
|
367
|
-
for (size_t j = 0; j < needleLength; j++) {
|
|
368
|
-
if (xt_buffer_byte(thisValue, i + (uint32_t)j) != needle[j]) {
|
|
369
|
-
match = 0;
|
|
370
|
-
break;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
if (match) {
|
|
374
|
-
found = (int)i;
|
|
375
|
-
break;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
if (!xt_buffer_is(xt_arg_at(argc, argv, 0))) free((void *)needle);
|
|
380
|
-
return xt_number((double)found);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
static xt_value xt_buffer_method_index_of_fwd(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
384
|
-
return xt_buffer_method_index_of(thisValue, env, argc, argv, 0);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
static xt_value xt_buffer_method_index_of_rev(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
388
|
-
return xt_buffer_method_index_of(thisValue, env, argc, argv, 1);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
static xt_value xt_buffer_method_includes(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
392
|
-
xt_value result = xt_buffer_method_index_of(thisValue, env, argc, argv, 0);
|
|
393
|
-
return xt_bool(xt_to_number(result) >= 0);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/* -- integer readers / writers -------------------------------------------- */
|
|
397
|
-
|
|
398
|
-
static uint64_t xt_buffer_read_le(xt_value buffer, uint32_t offset, int bytes) {
|
|
399
|
-
uint64_t value = 0;
|
|
400
|
-
for (int i = 0; i < bytes; i++) value |= ((uint64_t)xt_buffer_byte(buffer, offset + (uint32_t)i)) << (8 * i);
|
|
401
|
-
return value;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
static uint64_t xt_buffer_read_be(xt_value buffer, uint32_t offset, int bytes) {
|
|
405
|
-
uint64_t value = 0;
|
|
406
|
-
for (int i = 0; i < bytes; i++) value = (value << 8) | xt_buffer_byte(buffer, offset + (uint32_t)i);
|
|
407
|
-
return value;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
static void xt_buffer_write_le(xt_value buffer, uint32_t offset, int bytes, uint64_t value) {
|
|
411
|
-
for (int i = 0; i < bytes; i++) xt_buffer_put(buffer, offset + (uint32_t)i, (unsigned char)((value >> (8 * i)) & 0xff));
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
static void xt_buffer_write_be(xt_value buffer, uint32_t offset, int bytes, uint64_t value) {
|
|
415
|
-
for (int i = 0; i < bytes; i++) xt_buffer_put(buffer, offset + (uint32_t)i, (unsigned char)((value >> (8 * (bytes - 1 - i))) & 0xff));
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
static xt_value xt_buffer_read_method(xt_value thisValue, int32_t argc, xt_value *argv, int bytes, int little, int signedValue) {
|
|
419
|
-
uint32_t offset = argc > 0 ? (uint32_t)xt_to_number(argv[0]) : 0;
|
|
420
|
-
uint64_t raw = little ? xt_buffer_read_le(thisValue, offset, bytes) : xt_buffer_read_be(thisValue, offset, bytes);
|
|
421
|
-
double result;
|
|
422
|
-
if (signedValue) {
|
|
423
|
-
int64_t signedRaw = (int64_t)raw;
|
|
424
|
-
int bits = bytes * 8;
|
|
425
|
-
if (bits < 64 && (raw & (1ULL << (bits - 1)))) signedRaw = (int64_t)(raw | (~0ULL << bits));
|
|
426
|
-
result = (double)signedRaw;
|
|
427
|
-
} else {
|
|
428
|
-
result = (double)raw;
|
|
429
|
-
}
|
|
430
|
-
return xt_number(result);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
static xt_value xt_buffer_write_method(xt_value thisValue, int32_t argc, xt_value *argv, int bytes, int little) {
|
|
434
|
-
uint32_t offset = argc > 1 ? (uint32_t)xt_to_number(argv[1]) : 0;
|
|
435
|
-
uint64_t value = (uint64_t)(int64_t)xt_to_number(xt_arg_at(argc, argv, 0));
|
|
436
|
-
if (little) xt_buffer_write_le(thisValue, offset, bytes, value);
|
|
437
|
-
else xt_buffer_write_be(thisValue, offset, bytes, value);
|
|
438
|
-
return xt_number((double)(offset + (uint32_t)bytes));
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
#define XT_BUFFER_DEFINE_IO(name, bytes, little, signedValue) \
|
|
442
|
-
static xt_value xt_buffer_read_##name(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) { \
|
|
443
|
-
(void)env; \
|
|
444
|
-
return xt_buffer_read_method(thisValue, argc, argv, bytes, little, signedValue); \
|
|
445
|
-
} \
|
|
446
|
-
static xt_value xt_buffer_write_##name(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) { \
|
|
447
|
-
(void)env; \
|
|
448
|
-
return xt_buffer_write_method(thisValue, argc, argv, bytes, little); \
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
#define XT_BUFFER_DEFINE_SIGNED_IO(name, bytes, little) \
|
|
452
|
-
XT_BUFFER_DEFINE_IO(name, bytes, little, 0) \
|
|
453
|
-
static xt_value xt_buffer_read_##name##s(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) { \
|
|
454
|
-
(void)env; \
|
|
455
|
-
return xt_buffer_read_method(thisValue, argc, argv, bytes, little, 1); \
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
XT_BUFFER_DEFINE_SIGNED_IO(u8, 1, 1)
|
|
459
|
-
XT_BUFFER_DEFINE_SIGNED_IO(u16, 2, 1)
|
|
460
|
-
static xt_value xt_buffer_read_u16be(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
461
|
-
(void)env;
|
|
462
|
-
return xt_buffer_read_method(thisValue, argc, argv, 2, 0, 0);
|
|
463
|
-
}
|
|
464
|
-
static xt_value xt_buffer_write_u16be(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
465
|
-
(void)env;
|
|
466
|
-
return xt_buffer_write_method(thisValue, argc, argv, 2, 0);
|
|
467
|
-
}
|
|
468
|
-
static xt_value xt_buffer_read_u16bes(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
469
|
-
(void)env;
|
|
470
|
-
return xt_buffer_read_method(thisValue, argc, argv, 2, 0, 1);
|
|
471
|
-
}
|
|
472
|
-
XT_BUFFER_DEFINE_SIGNED_IO(u32, 4, 1)
|
|
473
|
-
static xt_value xt_buffer_read_u32be(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
474
|
-
(void)env;
|
|
475
|
-
return xt_buffer_read_method(thisValue, argc, argv, 4, 0, 0);
|
|
476
|
-
}
|
|
477
|
-
static xt_value xt_buffer_write_u32be(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
478
|
-
(void)env;
|
|
479
|
-
return xt_buffer_write_method(thisValue, argc, argv, 4, 0);
|
|
480
|
-
}
|
|
481
|
-
static xt_value xt_buffer_read_u32bes(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
482
|
-
(void)env;
|
|
483
|
-
return xt_buffer_read_method(thisValue, argc, argv, 4, 0, 1);
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
static xt_value xt_buffer_read_float(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv, int little, int doublePrecision) {
|
|
487
|
-
(void)env;
|
|
488
|
-
(void)thisValue;
|
|
489
|
-
(void)argc;
|
|
490
|
-
(void)argv;
|
|
491
|
-
(void)little;
|
|
492
|
-
(void)doublePrecision;
|
|
493
|
-
return xt_number(0);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
static xt_value xt_buffer_method_keys(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
497
|
-
(void)env;
|
|
498
|
-
(void)argc;
|
|
499
|
-
(void)argv;
|
|
500
|
-
xt_value result = xt_array_new(0, NULL);
|
|
501
|
-
uint32_t length = xt_buffer_length(thisValue);
|
|
502
|
-
for (uint32_t i = 0; i < length; i++) xt_array_push(result, xt_number((double)i));
|
|
503
|
-
return result;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
static xt_value xt_buffer_method_values(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
507
|
-
(void)env;
|
|
508
|
-
(void)argc;
|
|
509
|
-
(void)argv;
|
|
510
|
-
xt_value result = xt_array_new(0, NULL);
|
|
511
|
-
uint32_t length = xt_buffer_length(thisValue);
|
|
512
|
-
for (uint32_t i = 0; i < length; i++) xt_array_push(result, xt_number((double)xt_buffer_byte(thisValue, i)));
|
|
513
|
-
return result;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
/* -- prototype ------------------------------------------------------------ */
|
|
517
|
-
|
|
518
|
-
static xt_value xt_buffer_proto(void) {
|
|
519
|
-
static xt_value proto = 0;
|
|
520
|
-
if (proto) return proto;
|
|
521
|
-
proto = xt_object_new();
|
|
522
|
-
xt_node_define_method(proto, "toString", (void *)xt_buffer_method_to_string);
|
|
523
|
-
xt_node_define_method(proto, "toJSON", (void *)xt_buffer_method_to_json);
|
|
524
|
-
xt_node_define_method(proto, "slice", (void *)xt_buffer_method_slice);
|
|
525
|
-
xt_node_define_method(proto, "subarray", (void *)xt_buffer_method_slice);
|
|
526
|
-
xt_node_define_method(proto, "equals", (void *)xt_buffer_method_equals);
|
|
527
|
-
xt_node_define_method(proto, "compare", (void *)xt_buffer_method_compare);
|
|
528
|
-
xt_node_define_method(proto, "copy", (void *)xt_buffer_method_copy);
|
|
529
|
-
xt_node_define_method(proto, "write", (void *)xt_buffer_method_write);
|
|
530
|
-
xt_node_define_method(proto, "fill", (void *)xt_buffer_method_fill);
|
|
531
|
-
xt_node_define_method(proto, "reverse", (void *)xt_buffer_method_reverse);
|
|
532
|
-
xt_node_define_method(proto, "indexOf", (void *)xt_buffer_method_index_of_fwd);
|
|
533
|
-
xt_node_define_method(proto, "lastIndexOf", (void *)xt_buffer_method_index_of_rev);
|
|
534
|
-
xt_node_define_method(proto, "includes", (void *)xt_buffer_method_includes);
|
|
535
|
-
xt_node_define_method(proto, "keys", (void *)xt_buffer_method_keys);
|
|
536
|
-
xt_node_define_method(proto, "values", (void *)xt_buffer_method_values);
|
|
537
|
-
xt_node_define_method(proto, "readUInt8", (void *)xt_buffer_read_u8);
|
|
538
|
-
xt_node_define_method(proto, "readInt8", (void *)xt_buffer_read_u8s);
|
|
539
|
-
xt_node_define_method(proto, "writeUInt8", (void *)xt_buffer_write_u8);
|
|
540
|
-
xt_node_define_method(proto, "writeInt8", (void *)xt_buffer_write_u8);
|
|
541
|
-
xt_node_define_method(proto, "readUInt16LE", (void *)xt_buffer_read_u16);
|
|
542
|
-
xt_node_define_method(proto, "readUInt16BE", (void *)xt_buffer_read_u16be);
|
|
543
|
-
xt_node_define_method(proto, "readInt16LE", (void *)xt_buffer_read_u16s);
|
|
544
|
-
xt_node_define_method(proto, "readInt16BE", (void *)xt_buffer_read_u16bes);
|
|
545
|
-
xt_node_define_method(proto, "writeUInt16LE", (void *)xt_buffer_write_u16);
|
|
546
|
-
xt_node_define_method(proto, "writeUInt16BE", (void *)xt_buffer_write_u16be);
|
|
547
|
-
xt_node_define_method(proto, "readUInt32LE", (void *)xt_buffer_read_u32);
|
|
548
|
-
xt_node_define_method(proto, "readUInt32BE", (void *)xt_buffer_read_u32be);
|
|
549
|
-
xt_node_define_method(proto, "readInt32LE", (void *)xt_buffer_read_u32s);
|
|
550
|
-
xt_node_define_method(proto, "readInt32BE", (void *)xt_buffer_read_u32bes);
|
|
551
|
-
xt_node_define_method(proto, "writeUInt32LE", (void *)xt_buffer_write_u32);
|
|
552
|
-
xt_node_define_method(proto, "writeUInt32BE", (void *)xt_buffer_write_u32be);
|
|
553
|
-
(void)xt_buffer_read_float;
|
|
554
|
-
return proto;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
/* Enforce prototype creation on first use so `Buffer.from` marks the object. */
|
|
558
|
-
void xt_buffer_ensure_proto(void) { (void)xt_buffer_proto(); }
|
|
559
|
-
|
|
560
|
-
/* Cross-module helpers used by the net/http/dgram modules. */
|
|
561
|
-
int xt_node_is_buffer(xt_value value) { return xt_buffer_is(value); }
|
|
17
|
+
/*
|
|
18
|
+
* The implementation is grouped by functional area under `buffer/parts/` and
|
|
19
|
+
* `#include`d here as a single translation unit so the helpers stay `static`
|
|
20
|
+
* while each file stays focused on one area.
|
|
21
|
+
*/
|
|
562
22
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
23
|
+
#include "parts/byte-access.inc"
|
|
24
|
+
#include "parts/construction.inc"
|
|
25
|
+
#include "parts/static-api.inc"
|
|
26
|
+
#include "parts/methods.inc"
|
|
27
|
+
#include "parts/search.inc"
|
|
28
|
+
#include "parts/integer-io.inc"
|
|
29
|
+
#include "parts/prototype.inc"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* -- byte access ---------------------------------------------------------- */
|
|
2
|
+
|
|
3
|
+
static char *xt_buffer_key(uint32_t index, char *buffer, size_t size) {
|
|
4
|
+
snprintf(buffer, size, "%u", index);
|
|
5
|
+
return buffer;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
static uint32_t xt_buffer_length(xt_value buffer) {
|
|
9
|
+
double length = xt_to_number(xt_object_get_cstr(buffer, "length"));
|
|
10
|
+
if (length < 0) return 0;
|
|
11
|
+
return (uint32_t)length;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static unsigned char xt_buffer_byte(xt_value buffer, uint32_t index) {
|
|
15
|
+
char key[24];
|
|
16
|
+
xt_value value = xt_object_get_cstr(buffer, xt_buffer_key(index, key, sizeof(key)));
|
|
17
|
+
return (unsigned char)((int32_t)xt_to_number(value) & 0xff);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static void xt_buffer_put(xt_value buffer, uint32_t index, unsigned char byte) {
|
|
21
|
+
char key[24];
|
|
22
|
+
xt_object_set(buffer, xt_string_from_cstr(xt_buffer_key(index, key, sizeof(key))), xt_number((double)byte));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static xt_value xt_buffer_new(uint32_t length, const unsigned char *data) {
|
|
26
|
+
xt_value buffer = xt_object_new_with_proto(xt_buffer_proto());
|
|
27
|
+
for (uint32_t i = 0; i < length; i++) xt_buffer_put(buffer, i, data ? data[i] : 0);
|
|
28
|
+
xt_node_set(buffer, "length", xt_number((double)length));
|
|
29
|
+
return buffer;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static int xt_buffer_is(xt_value value) {
|
|
33
|
+
if (!XT_IS_OBJECT(value)) return 0;
|
|
34
|
+
return xt_truthy(xt_seq(xt_object_get_prototype(value), xt_buffer_proto()));
|
|
35
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* -- construction --------------------------------------------------------- */
|
|
2
|
+
|
|
3
|
+
static xt_value xt_buffer_from_bytes(const unsigned char *data, size_t length) {
|
|
4
|
+
return xt_buffer_new((uint32_t)length, data);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
static xt_value xt_buffer_from(xt_value value, const char *encoding) {
|
|
8
|
+
if (xt_buffer_is(value)) {
|
|
9
|
+
uint32_t length = xt_buffer_length(value);
|
|
10
|
+
unsigned char *copy = (unsigned char *)malloc(length ? length : 1);
|
|
11
|
+
for (uint32_t i = 0; i < length; i++) copy[i] = xt_buffer_byte(value, i);
|
|
12
|
+
xt_value result = xt_buffer_new(length, copy);
|
|
13
|
+
free(copy);
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
if (XT_IS_ARRAY(value)) {
|
|
17
|
+
uint32_t length = (uint32_t)xt_to_number(xt_array_length(value));
|
|
18
|
+
xt_value result = xt_buffer_new(length, NULL);
|
|
19
|
+
for (uint32_t i = 0; i < length; i++) {
|
|
20
|
+
xt_value item = xt_array_get(value, xt_number((double)i));
|
|
21
|
+
xt_buffer_put(result, i, (unsigned char)((int32_t)xt_to_number(item) & 0xff));
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
xt_value text = xt_to_string(value);
|
|
26
|
+
xt_string *string = xt_as_string(text);
|
|
27
|
+
size_t decoded = 0;
|
|
28
|
+
unsigned char *bytes = xt_node_decode(string->data, string->length, encoding, &decoded);
|
|
29
|
+
if (!bytes) return xt_buffer_new(0, NULL);
|
|
30
|
+
xt_value result = xt_buffer_from_bytes(bytes, decoded);
|
|
31
|
+
free(bytes);
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static xt_value xt_buffer_from_args(int32_t argc, xt_value *argv) {
|
|
36
|
+
if (argc < 1) return xt_buffer_new(0, NULL);
|
|
37
|
+
const char *encoding = argc > 1 ? xt_node_encoding(argv[1]) : NULL;
|
|
38
|
+
return xt_buffer_from(argv[0], encoding);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static xt_value xt_buffer_alloc(uint32_t size, xt_value fill, const char *encoding) {
|
|
42
|
+
xt_value buffer = xt_buffer_new(size, NULL);
|
|
43
|
+
if (XT_IS_UNDEFINED(fill)) return buffer;
|
|
44
|
+
if (XT_IS_NUMBER(fill)) {
|
|
45
|
+
unsigned char byte = (unsigned char)((int32_t)xt_to_number(fill) & 0xff);
|
|
46
|
+
for (uint32_t i = 0; i < size; i++) xt_buffer_put(buffer, i, byte);
|
|
47
|
+
return buffer;
|
|
48
|
+
}
|
|
49
|
+
xt_value text = xt_to_string(fill);
|
|
50
|
+
xt_string *string = xt_as_string(text);
|
|
51
|
+
size_t decoded = 0;
|
|
52
|
+
unsigned char *bytes = xt_node_decode(string->data, string->length, encoding, &decoded);
|
|
53
|
+
if (!bytes || decoded == 0) {
|
|
54
|
+
free(bytes);
|
|
55
|
+
return buffer;
|
|
56
|
+
}
|
|
57
|
+
for (uint32_t i = 0; i < size; i++) xt_buffer_put(buffer, i, bytes[i % decoded]);
|
|
58
|
+
free(bytes);
|
|
59
|
+
return buffer;
|
|
60
|
+
}
|