@scriptc/runtime 0.0.0 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/package.json +16 -6
- package/src/scr_array.c +488 -0
- package/src/scr_assert.c +1393 -0
- package/src/scr_async.c +2593 -0
- package/src/scr_async_dyn.c +607 -0
- package/src/scr_bytes.c +1425 -0
- package/src/scr_bytes_io.c +161 -0
- package/src/scr_child.c +3587 -0
- package/src/scr_closure.c +214 -0
- package/src/scr_console.c +143 -0
- package/src/scr_cycle.c +218 -0
- package/src/scr_dc.c +805 -0
- package/src/scr_dgram.c +1007 -0
- package/src/scr_dyn_handle.c +154 -0
- package/src/scr_dyn_invoke.c +644 -0
- package/src/scr_error.c +332 -0
- package/src/scr_events.c +714 -0
- package/src/scr_events_emitter.c +699 -0
- package/src/scr_exception.c +242 -0
- package/src/scr_fetch.c +1130 -0
- package/src/scr_fetch_curl.c +654 -0
- package/src/scr_http.c +3482 -0
- package/src/scr_http2.c +3030 -0
- package/src/scr_inspect.c +803 -0
- package/src/scr_inspect_island.c +51 -0
- package/src/scr_island.c +9363 -0
- package/src/scr_json.c +2151 -0
- package/src/scr_lib.c +3612 -0
- package/src/scr_loop_epoll.c +241 -0
- package/src/scr_loop_kqueue.c +121 -0
- package/src/scr_loop_wsapoll.c +208 -0
- package/src/scr_map.c +591 -0
- package/src/scr_net.c +3017 -0
- package/src/scr_net_island.c +458 -0
- package/src/scr_number.c +115 -0
- package/src/scr_object.c +25 -0
- package/src/scr_path.c +1266 -0
- package/src/scr_platform.h +119 -0
- package/src/scr_readline.c +287 -0
- package/src/scr_regex.c +1080 -0
- package/src/scr_runtime.h +5046 -0
- package/src/scr_stream.c +2877 -0
- package/src/scr_string.c +1264 -0
- package/src/scr_symbol.c +132 -0
- package/src/scr_test.c +662 -0
- package/src/scr_tls.c +1520 -0
- package/src/scr_union.c +105 -0
- package/src/scr_url.c +911 -0
- package/src/scr_url_internal.h +29 -0
- package/src/scr_url_params.c +561 -0
- package/src/scr_watch.c +568 -0
- package/src/scr_web.c +1778 -0
- package/src/scr_win.c +76 -0
- package/src/scr_zlib.c +197 -0
- package/src/scr_zlib_island.c +15 -0
- package/vendor/README.md +52 -0
- package/vendor/curl/COPYRIGHT +534 -0
- package/vendor/curl/include/curl/curl.h +3214 -0
- package/vendor/curl/include/curl/curlver.h +79 -0
- package/vendor/curl/include/curl/easy.h +125 -0
- package/vendor/curl/include/curl/header.h +74 -0
- package/vendor/curl/include/curl/mprintf.h +52 -0
- package/vendor/curl/include/curl/multi.h +460 -0
- package/vendor/curl/include/curl/options.h +70 -0
- package/vendor/curl/include/curl/stdcheaders.h +35 -0
- package/vendor/curl/include/curl/system.h +508 -0
- package/vendor/curl/include/curl/typecheck-gcc.h +716 -0
- package/vendor/curl/include/curl/urlapi.h +149 -0
- package/vendor/curl/include/curl/websockets.h +84 -0
- package/vendor/mbedtls/LICENSE +553 -0
- package/vendor/mbedtls/include/CMakeLists.txt +22 -0
- package/vendor/mbedtls/include/mbedtls/aes.h +631 -0
- package/vendor/mbedtls/include/mbedtls/aria.h +343 -0
- package/vendor/mbedtls/include/mbedtls/asn1.h +642 -0
- package/vendor/mbedtls/include/mbedtls/asn1write.h +390 -0
- package/vendor/mbedtls/include/mbedtls/base64.h +82 -0
- package/vendor/mbedtls/include/mbedtls/bignum.h +1088 -0
- package/vendor/mbedtls/include/mbedtls/block_cipher.h +76 -0
- package/vendor/mbedtls/include/mbedtls/build_info.h +194 -0
- package/vendor/mbedtls/include/mbedtls/camellia.h +305 -0
- package/vendor/mbedtls/include/mbedtls/ccm.h +526 -0
- package/vendor/mbedtls/include/mbedtls/chacha20.h +209 -0
- package/vendor/mbedtls/include/mbedtls/chachapoly.h +351 -0
- package/vendor/mbedtls/include/mbedtls/check_config.h +1149 -0
- package/vendor/mbedtls/include/mbedtls/cipher.h +1250 -0
- package/vendor/mbedtls/include/mbedtls/cmac.h +246 -0
- package/vendor/mbedtls/include/mbedtls/compat-2.x.h +46 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +578 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h +873 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h +359 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h +145 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h +91 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_x509.h +35 -0
- package/vendor/mbedtls/include/mbedtls/config_psa.h +61 -0
- package/vendor/mbedtls/include/mbedtls/constant_time.h +36 -0
- package/vendor/mbedtls/include/mbedtls/ctr_drbg.h +596 -0
- package/vendor/mbedtls/include/mbedtls/debug.h +156 -0
- package/vendor/mbedtls/include/mbedtls/des.h +385 -0
- package/vendor/mbedtls/include/mbedtls/dhm.h +972 -0
- package/vendor/mbedtls/include/mbedtls/ecdh.h +455 -0
- package/vendor/mbedtls/include/mbedtls/ecdsa.h +674 -0
- package/vendor/mbedtls/include/mbedtls/ecjpake.h +298 -0
- package/vendor/mbedtls/include/mbedtls/ecp.h +1517 -0
- package/vendor/mbedtls/include/mbedtls/entropy.h +274 -0
- package/vendor/mbedtls/include/mbedtls/error.h +201 -0
- package/vendor/mbedtls/include/mbedtls/gcm.h +387 -0
- package/vendor/mbedtls/include/mbedtls/hkdf.h +124 -0
- package/vendor/mbedtls/include/mbedtls/hmac_drbg.h +434 -0
- package/vendor/mbedtls/include/mbedtls/lms.h +440 -0
- package/vendor/mbedtls/include/mbedtls/mbedtls_config.h +4446 -0
- package/vendor/mbedtls/include/mbedtls/md.h +526 -0
- package/vendor/mbedtls/include/mbedtls/md5.h +190 -0
- package/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h +142 -0
- package/vendor/mbedtls/include/mbedtls/net_sockets.h +299 -0
- package/vendor/mbedtls/include/mbedtls/nist_kw.h +166 -0
- package/vendor/mbedtls/include/mbedtls/oid.h +727 -0
- package/vendor/mbedtls/include/mbedtls/pem.h +160 -0
- package/vendor/mbedtls/include/mbedtls/pk.h +1303 -0
- package/vendor/mbedtls/include/mbedtls/pkcs12.h +186 -0
- package/vendor/mbedtls/include/mbedtls/pkcs5.h +198 -0
- package/vendor/mbedtls/include/mbedtls/pkcs7.h +252 -0
- package/vendor/mbedtls/include/mbedtls/platform.h +516 -0
- package/vendor/mbedtls/include/mbedtls/platform_time.h +79 -0
- package/vendor/mbedtls/include/mbedtls/platform_util.h +247 -0
- package/vendor/mbedtls/include/mbedtls/poly1305.h +168 -0
- package/vendor/mbedtls/include/mbedtls/private_access.h +20 -0
- package/vendor/mbedtls/include/mbedtls/psa_util.h +207 -0
- package/vendor/mbedtls/include/mbedtls/ripemd160.h +136 -0
- package/vendor/mbedtls/include/mbedtls/rsa.h +1170 -0
- package/vendor/mbedtls/include/mbedtls/sha1.h +219 -0
- package/vendor/mbedtls/include/mbedtls/sha256.h +200 -0
- package/vendor/mbedtls/include/mbedtls/sha3.h +172 -0
- package/vendor/mbedtls/include/mbedtls/sha512.h +208 -0
- package/vendor/mbedtls/include/mbedtls/ssl.h +5887 -0
- package/vendor/mbedtls/include/mbedtls/ssl_cache.h +187 -0
- package/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h +482 -0
- package/vendor/mbedtls/include/mbedtls/ssl_cookie.h +106 -0
- package/vendor/mbedtls/include/mbedtls/ssl_ticket.h +199 -0
- package/vendor/mbedtls/include/mbedtls/threading.h +167 -0
- package/vendor/mbedtls/include/mbedtls/timing.h +94 -0
- package/vendor/mbedtls/include/mbedtls/version.h +78 -0
- package/vendor/mbedtls/include/mbedtls/x509.h +500 -0
- package/vendor/mbedtls/include/mbedtls/x509_crl.h +184 -0
- package/vendor/mbedtls/include/mbedtls/x509_crt.h +1208 -0
- package/vendor/mbedtls/include/mbedtls/x509_csr.h +382 -0
- package/vendor/mbedtls/include/psa/build_info.h +20 -0
- package/vendor/mbedtls/include/psa/crypto.h +4998 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h +31 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h +51 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h +101 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h +49 -0
- package/vendor/mbedtls/include/psa/crypto_builtin_composites.h +214 -0
- package/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h +118 -0
- package/vendor/mbedtls/include/psa/crypto_builtin_primitives.h +114 -0
- package/vendor/mbedtls/include/psa/crypto_compat.h +230 -0
- package/vendor/mbedtls/include/psa/crypto_config.h +145 -0
- package/vendor/mbedtls/include/psa/crypto_driver_common.h +44 -0
- package/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h +151 -0
- package/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h +52 -0
- package/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h +105 -0
- package/vendor/mbedtls/include/psa/crypto_extra.h +2145 -0
- package/vendor/mbedtls/include/psa/crypto_legacy.h +88 -0
- package/vendor/mbedtls/include/psa/crypto_platform.h +102 -0
- package/vendor/mbedtls/include/psa/crypto_se_driver.h +1383 -0
- package/vendor/mbedtls/include/psa/crypto_sizes.h +1319 -0
- package/vendor/mbedtls/include/psa/crypto_struct.h +527 -0
- package/vendor/mbedtls/include/psa/crypto_types.h +508 -0
- package/vendor/mbedtls/include/psa/crypto_values.h +2782 -0
- package/vendor/mbedtls/library/aes.c +2294 -0
- package/vendor/mbedtls/library/aesce.c +624 -0
- package/vendor/mbedtls/library/aesce.h +136 -0
- package/vendor/mbedtls/library/aesni.c +846 -0
- package/vendor/mbedtls/library/aesni.h +162 -0
- package/vendor/mbedtls/library/alignment.h +704 -0
- package/vendor/mbedtls/library/aria.c +969 -0
- package/vendor/mbedtls/library/asn1parse.c +468 -0
- package/vendor/mbedtls/library/asn1write.c +440 -0
- package/vendor/mbedtls/library/base64.c +322 -0
- package/vendor/mbedtls/library/base64_internal.h +45 -0
- package/vendor/mbedtls/library/bignum.c +2583 -0
- package/vendor/mbedtls/library/bignum_core.c +1240 -0
- package/vendor/mbedtls/library/bignum_core.h +872 -0
- package/vendor/mbedtls/library/bignum_core_invasive.h +38 -0
- package/vendor/mbedtls/library/bignum_internal.h +122 -0
- package/vendor/mbedtls/library/bignum_mod.c +394 -0
- package/vendor/mbedtls/library/bignum_mod.h +452 -0
- package/vendor/mbedtls/library/bignum_mod_raw.c +276 -0
- package/vendor/mbedtls/library/bignum_mod_raw.h +416 -0
- package/vendor/mbedtls/library/bignum_mod_raw_invasive.h +34 -0
- package/vendor/mbedtls/library/block_cipher.c +207 -0
- package/vendor/mbedtls/library/block_cipher_internal.h +99 -0
- package/vendor/mbedtls/library/bn_mul.h +1094 -0
- package/vendor/mbedtls/library/camellia.c +1058 -0
- package/vendor/mbedtls/library/ccm.c +777 -0
- package/vendor/mbedtls/library/chacha20.c +563 -0
- package/vendor/mbedtls/library/chacha20_internal.h +23 -0
- package/vendor/mbedtls/library/chachapoly.c +487 -0
- package/vendor/mbedtls/library/check_crypto_config.h +136 -0
- package/vendor/mbedtls/library/cipher.c +1712 -0
- package/vendor/mbedtls/library/cipher_invasive.h +28 -0
- package/vendor/mbedtls/library/cipher_wrap.c +2482 -0
- package/vendor/mbedtls/library/cipher_wrap.h +178 -0
- package/vendor/mbedtls/library/cmac.c +1067 -0
- package/vendor/mbedtls/library/common.h +487 -0
- package/vendor/mbedtls/library/constant_time.c +247 -0
- package/vendor/mbedtls/library/constant_time_impl.h +541 -0
- package/vendor/mbedtls/library/constant_time_internal.h +579 -0
- package/vendor/mbedtls/library/ctr.h +35 -0
- package/vendor/mbedtls/library/ctr_drbg.c +1016 -0
- package/vendor/mbedtls/library/debug.c +475 -0
- package/vendor/mbedtls/library/debug_internal.h +185 -0
- package/vendor/mbedtls/library/des.c +1042 -0
- package/vendor/mbedtls/library/dhm.c +700 -0
- package/vendor/mbedtls/library/ecdh.c +696 -0
- package/vendor/mbedtls/library/ecdsa.c +858 -0
- package/vendor/mbedtls/library/ecjpake.c +1216 -0
- package/vendor/mbedtls/library/ecp.c +3674 -0
- package/vendor/mbedtls/library/ecp_curves.c +6125 -0
- package/vendor/mbedtls/library/ecp_curves_new.c +9 -0
- package/vendor/mbedtls/library/ecp_internal_alt.h +287 -0
- package/vendor/mbedtls/library/ecp_invasive.h +305 -0
- package/vendor/mbedtls/library/entropy.c +680 -0
- package/vendor/mbedtls/library/entropy_poll.c +233 -0
- package/vendor/mbedtls/library/entropy_poll.h +64 -0
- package/vendor/mbedtls/library/error.c +878 -0
- package/vendor/mbedtls/library/gcm.c +1330 -0
- package/vendor/mbedtls/library/hkdf.c +161 -0
- package/vendor/mbedtls/library/hmac_drbg.c +633 -0
- package/vendor/mbedtls/library/lmots.c +789 -0
- package/vendor/mbedtls/library/lmots.h +288 -0
- package/vendor/mbedtls/library/lms.c +778 -0
- package/vendor/mbedtls/library/md.c +1108 -0
- package/vendor/mbedtls/library/md5.c +426 -0
- package/vendor/mbedtls/library/md_psa.h +26 -0
- package/vendor/mbedtls/library/md_wrap.h +46 -0
- package/vendor/mbedtls/library/memory_buffer_alloc.c +751 -0
- package/vendor/mbedtls/library/mps_common.h +181 -0
- package/vendor/mbedtls/library/mps_error.h +89 -0
- package/vendor/mbedtls/library/mps_reader.c +538 -0
- package/vendor/mbedtls/library/mps_reader.h +366 -0
- package/vendor/mbedtls/library/mps_trace.c +112 -0
- package/vendor/mbedtls/library/mps_trace.h +154 -0
- package/vendor/mbedtls/library/net_sockets.c +694 -0
- package/vendor/mbedtls/library/nist_kw.c +729 -0
- package/vendor/mbedtls/library/oid.c +1166 -0
- package/vendor/mbedtls/library/padlock.c +157 -0
- package/vendor/mbedtls/library/padlock.h +111 -0
- package/vendor/mbedtls/library/pem.c +554 -0
- package/vendor/mbedtls/library/pk.c +1602 -0
- package/vendor/mbedtls/library/pk_ecc.c +261 -0
- package/vendor/mbedtls/library/pk_internal.h +241 -0
- package/vendor/mbedtls/library/pk_wrap.c +1618 -0
- package/vendor/mbedtls/library/pk_wrap.h +138 -0
- package/vendor/mbedtls/library/pkcs12.c +437 -0
- package/vendor/mbedtls/library/pkcs5.c +500 -0
- package/vendor/mbedtls/library/pkcs7.c +787 -0
- package/vendor/mbedtls/library/pkparse.c +1392 -0
- package/vendor/mbedtls/library/pkwrite.c +631 -0
- package/vendor/mbedtls/library/pkwrite.h +121 -0
- package/vendor/mbedtls/library/platform.c +402 -0
- package/vendor/mbedtls/library/platform_util.c +258 -0
- package/vendor/mbedtls/library/poly1305.c +492 -0
- package/vendor/mbedtls/library/psa_crypto.c +9532 -0
- package/vendor/mbedtls/library/psa_crypto_aead.c +646 -0
- package/vendor/mbedtls/library/psa_crypto_aead.h +499 -0
- package/vendor/mbedtls/library/psa_crypto_cipher.c +747 -0
- package/vendor/mbedtls/library/psa_crypto_cipher.h +316 -0
- package/vendor/mbedtls/library/psa_crypto_client.c +22 -0
- package/vendor/mbedtls/library/psa_crypto_core.h +983 -0
- package/vendor/mbedtls/library/psa_crypto_core_common.h +52 -0
- package/vendor/mbedtls/library/psa_crypto_driver_wrappers.h +2896 -0
- package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c +256 -0
- package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h +31 -0
- package/vendor/mbedtls/library/psa_crypto_ecp.c +594 -0
- package/vendor/mbedtls/library/psa_crypto_ecp.h +267 -0
- package/vendor/mbedtls/library/psa_crypto_ffdh.c +361 -0
- package/vendor/mbedtls/library/psa_crypto_ffdh.h +131 -0
- package/vendor/mbedtls/library/psa_crypto_hash.c +470 -0
- package/vendor/mbedtls/library/psa_crypto_hash.h +211 -0
- package/vendor/mbedtls/library/psa_crypto_invasive.h +92 -0
- package/vendor/mbedtls/library/psa_crypto_its.h +131 -0
- package/vendor/mbedtls/library/psa_crypto_mac.c +505 -0
- package/vendor/mbedtls/library/psa_crypto_mac.h +264 -0
- package/vendor/mbedtls/library/psa_crypto_pake.c +571 -0
- package/vendor/mbedtls/library/psa_crypto_pake.h +159 -0
- package/vendor/mbedtls/library/psa_crypto_random.c +181 -0
- package/vendor/mbedtls/library/psa_crypto_random.h +72 -0
- package/vendor/mbedtls/library/psa_crypto_random_impl.h +200 -0
- package/vendor/mbedtls/library/psa_crypto_rsa.c +714 -0
- package/vendor/mbedtls/library/psa_crypto_rsa.h +321 -0
- package/vendor/mbedtls/library/psa_crypto_se.c +373 -0
- package/vendor/mbedtls/library/psa_crypto_se.h +192 -0
- package/vendor/mbedtls/library/psa_crypto_slot_management.c +1137 -0
- package/vendor/mbedtls/library/psa_crypto_slot_management.h +344 -0
- package/vendor/mbedtls/library/psa_crypto_storage.c +481 -0
- package/vendor/mbedtls/library/psa_crypto_storage.h +392 -0
- package/vendor/mbedtls/library/psa_its_file.c +254 -0
- package/vendor/mbedtls/library/psa_util.c +614 -0
- package/vendor/mbedtls/library/psa_util_internal.h +100 -0
- package/vendor/mbedtls/library/ripemd160.c +490 -0
- package/vendor/mbedtls/library/rsa.c +3121 -0
- package/vendor/mbedtls/library/rsa_alt_helpers.c +455 -0
- package/vendor/mbedtls/library/rsa_alt_helpers.h +209 -0
- package/vendor/mbedtls/library/rsa_internal.h +188 -0
- package/vendor/mbedtls/library/sha1.c +480 -0
- package/vendor/mbedtls/library/sha256.c +983 -0
- package/vendor/mbedtls/library/sha3.c +721 -0
- package/vendor/mbedtls/library/sha512.c +1115 -0
- package/vendor/mbedtls/library/ssl_cache.c +410 -0
- package/vendor/mbedtls/library/ssl_ciphersuites.c +2050 -0
- package/vendor/mbedtls/library/ssl_ciphersuites_internal.h +154 -0
- package/vendor/mbedtls/library/ssl_client.c +1023 -0
- package/vendor/mbedtls/library/ssl_client.h +22 -0
- package/vendor/mbedtls/library/ssl_cookie.c +384 -0
- package/vendor/mbedtls/library/ssl_debug_helpers.h +85 -0
- package/vendor/mbedtls/library/ssl_debug_helpers_generated.c +251 -0
- package/vendor/mbedtls/library/ssl_misc.h +3198 -0
- package/vendor/mbedtls/library/ssl_msg.c +6619 -0
- package/vendor/mbedtls/library/ssl_ticket.c +556 -0
- package/vendor/mbedtls/library/ssl_tls.c +10234 -0
- package/vendor/mbedtls/library/ssl_tls12_client.c +3688 -0
- package/vendor/mbedtls/library/ssl_tls12_server.c +4311 -0
- package/vendor/mbedtls/library/ssl_tls13_client.c +3208 -0
- package/vendor/mbedtls/library/ssl_tls13_generic.c +1793 -0
- package/vendor/mbedtls/library/ssl_tls13_invasive.h +23 -0
- package/vendor/mbedtls/library/ssl_tls13_keys.c +1918 -0
- package/vendor/mbedtls/library/ssl_tls13_keys.h +668 -0
- package/vendor/mbedtls/library/ssl_tls13_server.c +3624 -0
- package/vendor/mbedtls/library/threading.c +193 -0
- package/vendor/mbedtls/library/threading_internal.h +28 -0
- package/vendor/mbedtls/library/timing.c +152 -0
- package/vendor/mbedtls/library/version.c +32 -0
- package/vendor/mbedtls/library/version_features.c +856 -0
- package/vendor/mbedtls/library/x509.c +1776 -0
- package/vendor/mbedtls/library/x509_create.c +570 -0
- package/vendor/mbedtls/library/x509_crl.c +708 -0
- package/vendor/mbedtls/library/x509_crt.c +3311 -0
- package/vendor/mbedtls/library/x509_csr.c +648 -0
- package/vendor/mbedtls/library/x509_internal.h +101 -0
- package/vendor/mbedtls/library/x509write.c +174 -0
- package/vendor/mbedtls/library/x509write_crt.c +688 -0
- package/vendor/mbedtls/library/x509write_csr.c +336 -0
- package/vendor/quickjs-ng/CMakeLists.txt +566 -0
- package/vendor/quickjs-ng/LICENSE +24 -0
- package/vendor/quickjs-ng/README.md +24 -0
- package/vendor/quickjs-ng/api-test.c +1195 -0
- package/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
- package/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
- package/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
- package/vendor/quickjs-ng/cutils.h +1998 -0
- package/vendor/quickjs-ng/dtoa.c +1619 -0
- package/vendor/quickjs-ng/dtoa.h +87 -0
- package/vendor/quickjs-ng/gen/function_source.c +81 -0
- package/vendor/quickjs-ng/gen/hello.c +53 -0
- package/vendor/quickjs-ng/gen/hello_module.c +106 -0
- package/vendor/quickjs-ng/gen/repl.c +3036 -0
- package/vendor/quickjs-ng/gen/standalone.c +323 -0
- package/vendor/quickjs-ng/gen/test_fib.c +81 -0
- package/vendor/quickjs-ng/libregexp-opcode.h +73 -0
- package/vendor/quickjs-ng/libregexp.c +3474 -0
- package/vendor/quickjs-ng/libregexp.h +101 -0
- package/vendor/quickjs-ng/libunicode-table.h +5173 -0
- package/vendor/quickjs-ng/libunicode.c +2069 -0
- package/vendor/quickjs-ng/libunicode.h +172 -0
- package/vendor/quickjs-ng/list.h +107 -0
- package/vendor/quickjs-ng/lre-test.c +52 -0
- package/vendor/quickjs-ng/qjs.c +762 -0
- package/vendor/quickjs-ng/qjsc.c +673 -0
- package/vendor/quickjs-ng/quickjs-atom.h +280 -0
- package/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
- package/vendor/quickjs-ng/quickjs-libc.c +5037 -0
- package/vendor/quickjs-ng/quickjs-libc.h +87 -0
- package/vendor/quickjs-ng/quickjs-opcode.h +377 -0
- package/vendor/quickjs-ng/quickjs.c +64041 -0
- package/vendor/quickjs-ng/quickjs.h +1447 -0
- package/vendor/quickjs-ng/run-test262.c +2374 -0
- package/vendor/quickjs-ng/unicode_gen.c +3121 -0
- package/vendor/quickjs-ng/unicode_gen_def.h +310 -0
- package/vendor/ryu/LICENSE-Boost +23 -0
- package/vendor/ryu/common.h +114 -0
- package/vendor/ryu/d2s.c +509 -0
- package/vendor/ryu/d2s_full_table.h +367 -0
- package/vendor/ryu/d2s_intrinsics.h +357 -0
- package/vendor/ryu/d2s_small_table.h +186 -0
- package/vendor/ryu/digit_table.h +35 -0
- package/vendor/ryu/ryu.h +46 -0
- package/vendor/zlib/LICENSE +22 -0
- package/vendor/zlib/adler32.c +164 -0
- package/vendor/zlib/compress.c +75 -0
- package/vendor/zlib/crc32.c +1049 -0
- package/vendor/zlib/crc32.h +9446 -0
- package/vendor/zlib/deflate.c +2139 -0
- package/vendor/zlib/deflate.h +377 -0
- package/vendor/zlib/gzclose.c +23 -0
- package/vendor/zlib/gzguts.h +214 -0
- package/vendor/zlib/gzlib.c +582 -0
- package/vendor/zlib/gzread.c +602 -0
- package/vendor/zlib/gzwrite.c +631 -0
- package/vendor/zlib/infback.c +628 -0
- package/vendor/zlib/inffast.c +320 -0
- package/vendor/zlib/inffast.h +11 -0
- package/vendor/zlib/inffixed.h +94 -0
- package/vendor/zlib/inflate.c +1526 -0
- package/vendor/zlib/inflate.h +126 -0
- package/vendor/zlib/inftrees.c +299 -0
- package/vendor/zlib/inftrees.h +62 -0
- package/vendor/zlib/trees.c +1117 -0
- package/vendor/zlib/trees.h +128 -0
- package/vendor/zlib/uncompr.c +85 -0
- package/vendor/zlib/zconf.h +543 -0
- package/vendor/zlib/zlib.h +1938 -0
- package/vendor/zlib/zutil.c +299 -0
- package/vendor/zlib/zutil.h +254 -0
- package/README.md +0 -3
- package/index.js +0 -2
package/src/scr_bytes.c
ADDED
|
@@ -0,0 +1,1425 @@
|
|
|
1
|
+
/* Typed arrays / Buffer: ONE runtime representation (ScrBytes — see the
|
|
2
|
+
* header contract). Element buffers own their storage outright: no views,
|
|
3
|
+
* no byteOffset, slice/subarray both copy. Coercions are JS-exact
|
|
4
|
+
* (ToUint8/ToUint32 modular truncation, double→float rounding); the
|
|
5
|
+
* encoding conversions (utf8 with WHATWG replacement, hex, base64) match
|
|
6
|
+
* Node byte-for-byte — the differential corpus holds them to it. */
|
|
7
|
+
#include "scr_runtime.h"
|
|
8
|
+
|
|
9
|
+
#include <math.h>
|
|
10
|
+
#include <stdio.h>
|
|
11
|
+
#include <stdlib.h>
|
|
12
|
+
#include <string.h>
|
|
13
|
+
|
|
14
|
+
#ifdef SCR_RC_AUDIT
|
|
15
|
+
static long scr_live_bytes = 0;
|
|
16
|
+
long scr_bytes_live_count(void) { return scr_live_bytes; }
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
static void scr_bytes_oom(void) {
|
|
20
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
21
|
+
abort();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
size_t scr_bytes_elem_size(ScrBytesElem elem) {
|
|
25
|
+
return elem == SCR_BYTES_U8 ? 1 : 4;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* ── lifecycle ─────────────────────────────────────────────────────────── */
|
|
29
|
+
|
|
30
|
+
static ScrBytes *scr_bytes_alloc(ScrBytesElem elem, size_t len) {
|
|
31
|
+
ScrBytes *b = malloc(sizeof(ScrBytes));
|
|
32
|
+
if (!b) scr_bytes_oom();
|
|
33
|
+
b->rc = 1;
|
|
34
|
+
b->len = len;
|
|
35
|
+
b->elem = elem;
|
|
36
|
+
b->data = calloc(len ? len : 1, scr_bytes_elem_size(elem));
|
|
37
|
+
if (!b->data) scr_bytes_oom();
|
|
38
|
+
b->backing = NULL;
|
|
39
|
+
#ifdef SCR_RC_AUDIT
|
|
40
|
+
scr_live_bytes++;
|
|
41
|
+
#endif
|
|
42
|
+
return b;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
ScrBytes *scr_bytes_new(ScrBytesElem elem, double n) {
|
|
46
|
+
/* ToIndex: NaN → 0, truncate toward zero; a negative or > 2^53-1 result
|
|
47
|
+
* throws Node's RangeError ("Invalid typed array length: -1"). A
|
|
48
|
+
* fractional 3.5 is length 3 — ToIndex never compares back. */
|
|
49
|
+
double t = (n != n) ? 0 : trunc(n);
|
|
50
|
+
if (!(t >= 0) || t > 9007199254740991.0 || t > (double)(SIZE_MAX / 8)) {
|
|
51
|
+
char num[32];
|
|
52
|
+
size_t numlen = scr_f64_to_str(t, num);
|
|
53
|
+
char msg[80];
|
|
54
|
+
int mlen = snprintf(msg, sizeof msg, "Invalid typed array length: %.*s",
|
|
55
|
+
(int)numlen, num);
|
|
56
|
+
scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
|
|
57
|
+
return NULL;
|
|
58
|
+
}
|
|
59
|
+
return scr_bytes_alloc(elem, (size_t)t);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
ScrBytes *scr_bytes_copy(const ScrBytes *src) {
|
|
63
|
+
ScrBytes *b = scr_bytes_alloc(src->elem, src->len);
|
|
64
|
+
memcpy(b->data, src->data, src->len * scr_bytes_elem_size(src->elem));
|
|
65
|
+
return b;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void scr_bytes_release(ScrBytes *b) {
|
|
69
|
+
if (!b || b->rc == SIZE_MAX) return; /* NULL: an uninitialized `let` local */
|
|
70
|
+
if (--b->rc == 0) {
|
|
71
|
+
if (b->backing) {
|
|
72
|
+
scr_bytes_release(b->backing); /* a view: data points into the owner */
|
|
73
|
+
} else {
|
|
74
|
+
free(b->data);
|
|
75
|
+
}
|
|
76
|
+
#ifdef SCR_RC_AUDIT
|
|
77
|
+
scr_live_bytes--;
|
|
78
|
+
#endif
|
|
79
|
+
free(b);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
void *scr_bytes_retain_v(void *b) { return scr_bytes_retain((ScrBytes *)b); }
|
|
84
|
+
void scr_bytes_release_v(void *b) { scr_bytes_release((ScrBytes *)b); }
|
|
85
|
+
|
|
86
|
+
double scr_bytes_len(const ScrBytes *b) { return (double)b->len; }
|
|
87
|
+
|
|
88
|
+
double scr_bytes_byte_len(const ScrBytes *b) {
|
|
89
|
+
return (double)(b->len * scr_bytes_elem_size(b->elem));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* ── element access ────────────────────────────────────────────────────
|
|
93
|
+
* JS reads undefined and IGNORES writes out of bounds on typed arrays;
|
|
94
|
+
* both are unrepresentable here, so any invalid index traps — the array
|
|
95
|
+
* runtime's exact discipline (SEMANTICS.md). */
|
|
96
|
+
|
|
97
|
+
static size_t scr_bytes_check_index(const ScrBytes *b, double i) {
|
|
98
|
+
if (!(i >= 0) || i != trunc(i) || i >= (double)b->len) {
|
|
99
|
+
char buf[32];
|
|
100
|
+
scr_f64_to_str(i, buf);
|
|
101
|
+
fprintf(stderr,
|
|
102
|
+
"scriptc: RangeError: typed array index %s out of bounds (length %zu)\n",
|
|
103
|
+
buf, b->len);
|
|
104
|
+
abort();
|
|
105
|
+
}
|
|
106
|
+
return (size_t)i;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* ToUint32: NaN/±Infinity → 0, truncate toward zero, wrap mod 2^32.
|
|
110
|
+
* ToUint8 is its low byte (2^8 divides 2^32, so the residues agree). */
|
|
111
|
+
static uint32_t scr_bytes_to_u32(double v) {
|
|
112
|
+
if (v != v || isinf(v)) return 0;
|
|
113
|
+
double t = trunc(v);
|
|
114
|
+
t = fmod(t, 4294967296.0);
|
|
115
|
+
if (t < 0) t += 4294967296.0;
|
|
116
|
+
return (uint32_t)t;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
double scr_bytes_get(const ScrBytes *b, double i) {
|
|
120
|
+
size_t idx = scr_bytes_check_index(b, i);
|
|
121
|
+
switch (b->elem) {
|
|
122
|
+
case SCR_BYTES_U8:
|
|
123
|
+
return (double)b->data[idx];
|
|
124
|
+
case SCR_BYTES_U32: {
|
|
125
|
+
uint32_t v;
|
|
126
|
+
memcpy(&v, b->data + idx * 4, 4);
|
|
127
|
+
return (double)v;
|
|
128
|
+
}
|
|
129
|
+
case SCR_BYTES_F32: {
|
|
130
|
+
float v;
|
|
131
|
+
memcpy(&v, b->data + idx * 4, 4);
|
|
132
|
+
return (double)v;
|
|
133
|
+
}
|
|
134
|
+
case SCR_BYTES_I32: {
|
|
135
|
+
int32_t v;
|
|
136
|
+
memcpy(&v, b->data + idx * 4, 4);
|
|
137
|
+
return (double)v;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return 0; /* unreachable */
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
void scr_bytes_set(ScrBytes *b, double i, double v) {
|
|
144
|
+
size_t idx = scr_bytes_check_index(b, i);
|
|
145
|
+
switch (b->elem) {
|
|
146
|
+
case SCR_BYTES_U8:
|
|
147
|
+
b->data[idx] = (uint8_t)scr_bytes_to_u32(v);
|
|
148
|
+
break;
|
|
149
|
+
case SCR_BYTES_U32: {
|
|
150
|
+
uint32_t u = scr_bytes_to_u32(v);
|
|
151
|
+
memcpy(b->data + idx * 4, &u, 4);
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
case SCR_BYTES_F32: {
|
|
155
|
+
float f = (float)v; /* round-to-nearest-even, exactly Float32Array */
|
|
156
|
+
memcpy(b->data + idx * 4, &f, 4);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case SCR_BYTES_I32: {
|
|
160
|
+
/* ToInt32 is ToUint32 reinterpreted signed (same 2^32 residue). */
|
|
161
|
+
uint32_t u = scr_bytes_to_u32(v);
|
|
162
|
+
int32_t s;
|
|
163
|
+
memcpy(&s, &u, 4);
|
|
164
|
+
memcpy(b->data + idx * 4, &s, 4);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* ── slice / subarray (both COPY) ──────────────────────────────────────── */
|
|
171
|
+
|
|
172
|
+
/* Relative index: ToIntegerOrInfinity, negatives from the end, clamped. */
|
|
173
|
+
static size_t scr_bytes_rel_index(double i, size_t len) {
|
|
174
|
+
if (i != i) return 0;
|
|
175
|
+
double t = trunc(i);
|
|
176
|
+
if (t < 0) t += (double)len;
|
|
177
|
+
if (t < 0) return 0;
|
|
178
|
+
if (t > (double)len) return len;
|
|
179
|
+
return (size_t)t;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
ScrBytes *scr_bytes_slice(const ScrBytes *b, double start, double end) {
|
|
183
|
+
size_t s = scr_bytes_rel_index(start, b->len);
|
|
184
|
+
size_t e = scr_bytes_rel_index(end, b->len);
|
|
185
|
+
size_t count = e > s ? e - s : 0;
|
|
186
|
+
size_t esize = scr_bytes_elem_size(b->elem);
|
|
187
|
+
ScrBytes *out = scr_bytes_alloc(b->elem, count);
|
|
188
|
+
memcpy(out->data, b->data + s * esize, count * esize);
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
void scr_bytes_set_from(ScrBytes *dst, const ScrBytes *src, double offset) {
|
|
193
|
+
double t = (offset != offset) ? 0 : trunc(offset);
|
|
194
|
+
if (!(t >= 0) || (double)src->len + t > (double)dst->len) {
|
|
195
|
+
static const char msg[] = "offset is out of bounds";
|
|
196
|
+
scr_throw_error_msg(SCR_ERR_RANGE, msg, sizeof msg - 1);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
size_t esize = scr_bytes_elem_size(dst->elem);
|
|
200
|
+
memmove(dst->data + (size_t)t * esize, src->data, src->len * esize);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* ── DataView (the ONE view kind — see the header contract) ────────────── */
|
|
204
|
+
|
|
205
|
+
double scr_bytes_byte_offset(const ScrBytes *b) {
|
|
206
|
+
return b->backing ? (double)(size_t)(b->data - b->backing->data) : 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
ScrBytes *scr_dataview_new(ScrBytes *src, double byte_off, bool has_len, double byte_len) {
|
|
210
|
+
/* `x.buffer` names the ONE buffer behind x — for a view src that is its
|
|
211
|
+
* owner's storage, so indices stay buffer-relative exactly like JS. */
|
|
212
|
+
ScrBytes *owner = src->backing ? src->backing : src;
|
|
213
|
+
double buf_bytes = (double)(owner->len * scr_bytes_elem_size(owner->elem));
|
|
214
|
+
/* ToIndex on the offset; every bad value takes Node's ONE message
|
|
215
|
+
* (negative, > 2^53-1, Infinity, and past-the-end alike). */
|
|
216
|
+
double off = (byte_off != byte_off) ? 0 : trunc(byte_off);
|
|
217
|
+
if (!(off >= 0) || off > 9007199254740991.0 || off > buf_bytes) {
|
|
218
|
+
char num[32];
|
|
219
|
+
size_t numlen = scr_f64_to_str(off, num);
|
|
220
|
+
char msg[96];
|
|
221
|
+
int mlen = snprintf(msg, sizeof msg, "Start offset %.*s is outside the bounds of the buffer",
|
|
222
|
+
(int)numlen, num);
|
|
223
|
+
scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
|
|
224
|
+
return NULL;
|
|
225
|
+
}
|
|
226
|
+
double len;
|
|
227
|
+
if (has_len) {
|
|
228
|
+
len = (byte_len != byte_len) ? 0 : trunc(byte_len);
|
|
229
|
+
if (!(len >= 0) || len > 9007199254740991.0 || off + len > buf_bytes) {
|
|
230
|
+
char num[32];
|
|
231
|
+
size_t numlen = scr_f64_to_str(len, num);
|
|
232
|
+
char msg[64];
|
|
233
|
+
int mlen = snprintf(msg, sizeof msg, "Invalid DataView length %.*s", (int)numlen, num);
|
|
234
|
+
scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
|
|
235
|
+
return NULL;
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
238
|
+
len = buf_bytes - off;
|
|
239
|
+
}
|
|
240
|
+
ScrBytes *v = malloc(sizeof(ScrBytes));
|
|
241
|
+
if (!v) scr_bytes_oom();
|
|
242
|
+
v->rc = 1;
|
|
243
|
+
v->len = (size_t)len; /* elem u8 — len IS the byte length */
|
|
244
|
+
v->elem = SCR_BYTES_U8;
|
|
245
|
+
v->data = owner->data + (size_t)off;
|
|
246
|
+
v->backing = scr_bytes_retain(owner);
|
|
247
|
+
#ifdef SCR_RC_AUDIT
|
|
248
|
+
scr_live_bytes++;
|
|
249
|
+
#endif
|
|
250
|
+
return v;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
static size_t scr_dataview_get_size(ScrDataViewGet kind) {
|
|
254
|
+
switch (kind) {
|
|
255
|
+
case SCR_DV_U8:
|
|
256
|
+
case SCR_DV_I8:
|
|
257
|
+
return 1;
|
|
258
|
+
case SCR_DV_U16:
|
|
259
|
+
case SCR_DV_I16:
|
|
260
|
+
return 2;
|
|
261
|
+
case SCR_DV_U32:
|
|
262
|
+
case SCR_DV_I32:
|
|
263
|
+
case SCR_DV_F32:
|
|
264
|
+
return 4;
|
|
265
|
+
default:
|
|
266
|
+
return 8;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
double scr_dataview_get(const ScrBytes *b, double byte_off, ScrDataViewGet kind, bool le) {
|
|
271
|
+
size_t width = scr_dataview_get_size(kind);
|
|
272
|
+
/* ToIndex, then the view-relative bounds check — Node's ONE constant
|
|
273
|
+
* message for every failure mode (negative, NaN is fine, too large). */
|
|
274
|
+
double off = (byte_off != byte_off) ? 0 : trunc(byte_off);
|
|
275
|
+
if (!(off >= 0) || off > 9007199254740991.0 || off + (double)width > (double)b->len) {
|
|
276
|
+
static const char msg[] = "Offset is outside the bounds of the DataView";
|
|
277
|
+
scr_throw_error_msg(SCR_ERR_RANGE, msg, sizeof msg - 1);
|
|
278
|
+
return 0;
|
|
279
|
+
}
|
|
280
|
+
const uint8_t *p = b->data + (size_t)off;
|
|
281
|
+
/* Assemble host-independently; le false is the JS big-endian default. */
|
|
282
|
+
uint64_t u = 0;
|
|
283
|
+
for (size_t i = 0; i < width; i++) {
|
|
284
|
+
u |= (uint64_t)p[le ? i : width - 1 - i] << (8 * i);
|
|
285
|
+
}
|
|
286
|
+
switch (kind) {
|
|
287
|
+
case SCR_DV_U8:
|
|
288
|
+
case SCR_DV_U16:
|
|
289
|
+
case SCR_DV_U32:
|
|
290
|
+
return (double)u;
|
|
291
|
+
case SCR_DV_I8:
|
|
292
|
+
return (double)(int8_t)u;
|
|
293
|
+
case SCR_DV_I16:
|
|
294
|
+
return (double)(int16_t)u;
|
|
295
|
+
case SCR_DV_I32:
|
|
296
|
+
return (double)(int32_t)u;
|
|
297
|
+
case SCR_DV_F32: {
|
|
298
|
+
uint32_t bits = (uint32_t)u;
|
|
299
|
+
float f;
|
|
300
|
+
memcpy(&f, &bits, 4);
|
|
301
|
+
return (double)f;
|
|
302
|
+
}
|
|
303
|
+
case SCR_DV_F64: {
|
|
304
|
+
double d;
|
|
305
|
+
memcpy(&d, &u, 8);
|
|
306
|
+
return d;
|
|
307
|
+
}
|
|
308
|
+
case SCR_DV_BIGU64:
|
|
309
|
+
/* Number(view.getBigUint64(...)): u64 → double rounds to nearest
|
|
310
|
+
* even — the same conversion Number(bigint) performs. */
|
|
311
|
+
return (double)u;
|
|
312
|
+
case SCR_DV_BIGI64:
|
|
313
|
+
return (double)(int64_t)u;
|
|
314
|
+
}
|
|
315
|
+
return 0; /* unreachable */
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* ── encodings (u8 only — the compiler routes only u8 receivers here) ──── */
|
|
319
|
+
|
|
320
|
+
static const char scr_hex_digits[] = "0123456789abcdef";
|
|
321
|
+
|
|
322
|
+
/* WHATWG UTF-8 decode with U+FFFD replacement per maximal invalid subpart
|
|
323
|
+
* — what Buffer.prototype.toString("utf8") does. Output re-encodes as
|
|
324
|
+
* (now valid) UTF-8: worst case 3 bytes per input byte. */
|
|
325
|
+
static ScrStr *scr_bytes_decode_utf8(const uint8_t *in, size_t n) {
|
|
326
|
+
char *out = malloc(n * 3 + 1);
|
|
327
|
+
if (!out) scr_bytes_oom();
|
|
328
|
+
size_t o = 0;
|
|
329
|
+
uint32_t cp = 0;
|
|
330
|
+
int needed = 0;
|
|
331
|
+
uint8_t lower = 0x80, upper = 0xbf;
|
|
332
|
+
for (size_t i = 0; i <= n; i++) {
|
|
333
|
+
if (i == n) {
|
|
334
|
+
if (needed > 0) { /* EOF inside a sequence: one replacement */
|
|
335
|
+
memcpy(out + o, "\xef\xbf\xbd", 3);
|
|
336
|
+
o += 3;
|
|
337
|
+
}
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
uint8_t byte = in[i];
|
|
341
|
+
if (needed == 0) {
|
|
342
|
+
if (byte <= 0x7f) {
|
|
343
|
+
out[o++] = (char)byte;
|
|
344
|
+
} else if (byte >= 0xc2 && byte <= 0xdf) {
|
|
345
|
+
needed = 1; cp = byte & 0x1f;
|
|
346
|
+
} else if (byte >= 0xe0 && byte <= 0xef) {
|
|
347
|
+
if (byte == 0xe0) lower = 0xa0;
|
|
348
|
+
if (byte == 0xed) upper = 0x9f;
|
|
349
|
+
needed = 2; cp = byte & 0xf;
|
|
350
|
+
} else if (byte >= 0xf0 && byte <= 0xf4) {
|
|
351
|
+
if (byte == 0xf0) lower = 0x90;
|
|
352
|
+
if (byte == 0xf4) upper = 0x8f;
|
|
353
|
+
needed = 3; cp = byte & 0x7;
|
|
354
|
+
} else {
|
|
355
|
+
memcpy(out + o, "\xef\xbf\xbd", 3);
|
|
356
|
+
o += 3;
|
|
357
|
+
}
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (byte < lower || byte > upper) {
|
|
361
|
+
/* Invalid continuation: replace the subpart, REPROCESS this byte. */
|
|
362
|
+
memcpy(out + o, "\xef\xbf\xbd", 3);
|
|
363
|
+
o += 3;
|
|
364
|
+
needed = 0; lower = 0x80; upper = 0xbf;
|
|
365
|
+
i--;
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
lower = 0x80; upper = 0xbf;
|
|
369
|
+
cp = (cp << 6) | (byte & 0x3f);
|
|
370
|
+
if (--needed == 0) {
|
|
371
|
+
/* Re-encode the (valid, non-surrogate, <= 10FFFF) code point. */
|
|
372
|
+
if (cp <= 0x7f) {
|
|
373
|
+
out[o++] = (char)cp;
|
|
374
|
+
} else if (cp <= 0x7ff) {
|
|
375
|
+
out[o++] = (char)(0xc0 | (cp >> 6));
|
|
376
|
+
out[o++] = (char)(0x80 | (cp & 0x3f));
|
|
377
|
+
} else if (cp <= 0xffff) {
|
|
378
|
+
out[o++] = (char)(0xe0 | (cp >> 12));
|
|
379
|
+
out[o++] = (char)(0x80 | ((cp >> 6) & 0x3f));
|
|
380
|
+
out[o++] = (char)(0x80 | (cp & 0x3f));
|
|
381
|
+
} else {
|
|
382
|
+
out[o++] = (char)(0xf0 | (cp >> 18));
|
|
383
|
+
out[o++] = (char)(0x80 | ((cp >> 12) & 0x3f));
|
|
384
|
+
out[o++] = (char)(0x80 | ((cp >> 6) & 0x3f));
|
|
385
|
+
out[o++] = (char)(0x80 | (cp & 0x3f));
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
ScrStr *s = scr_str_new(out, o);
|
|
390
|
+
free(out);
|
|
391
|
+
return s;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* WHATWG TextDecoder.decode (utf-8, default options): the SAME maximal-
|
|
395
|
+
* subpart replacement decode as toString("utf8") above, with one
|
|
396
|
+
* difference — a leading UTF-8 BOM is stripped (ignoreBOM defaults to
|
|
397
|
+
* false in the spec; Buffer.toString keeps the BOM as U+FEFF). */
|
|
398
|
+
ScrStr *scr_text_decode(const ScrBytes *b) {
|
|
399
|
+
const uint8_t *in = b->data;
|
|
400
|
+
size_t n = b->len;
|
|
401
|
+
if (n >= 3 && in[0] == 0xef && in[1] == 0xbb && in[2] == 0xbf) {
|
|
402
|
+
in += 3;
|
|
403
|
+
n -= 3;
|
|
404
|
+
}
|
|
405
|
+
return scr_bytes_decode_utf8(in, n);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/* ── node:string_decoder, the utf8 StringDecoder ─────────────────────────
|
|
409
|
+
* The decoder VALUE is a one-field record holding the pending partial
|
|
410
|
+
* sequence PACKED into an f64 (count in the low byte, then up to three
|
|
411
|
+
* raw bytes — at most 3 pend, so 32 bits): the compiler's interned
|
|
412
|
+
* %strdec helpers thread it through these three pure functions. The
|
|
413
|
+
* algorithm is Node's utf8 StringDecoder pinned by oracle (corpus 1474):
|
|
414
|
+
* write() decodes pending+chunk minus the trailing INCOMPLETE sequence
|
|
415
|
+
* (the decode above — invalid bytes become U+FFFD immediately, only a
|
|
416
|
+
* truncated valid lead buffers), end() flushes the buffered partial as
|
|
417
|
+
* its replacement chars. */
|
|
418
|
+
|
|
419
|
+
/* Encoding helpers defined beside toString below (the strdec steps share
|
|
420
|
+
* them). */
|
|
421
|
+
static ScrStr *scr_bytes_encode_b64(const uint8_t *in, size_t n, bool url);
|
|
422
|
+
static ScrStr *scr_bytes_decode_utf16le(const uint8_t *in, size_t n);
|
|
423
|
+
static bool scr_enc_is(const ScrStr *enc, const char *name);
|
|
424
|
+
|
|
425
|
+
static size_t scr_strdec_unpack(double pending, uint8_t out[3]) {
|
|
426
|
+
uint32_t p = (uint32_t)pending;
|
|
427
|
+
size_t n = p & 0xff;
|
|
428
|
+
if (n > 3) n = 3;
|
|
429
|
+
out[0] = (uint8_t)((p >> 8) & 0xff);
|
|
430
|
+
out[1] = (uint8_t)((p >> 16) & 0xff);
|
|
431
|
+
out[2] = (uint8_t)((p >> 24) & 0xff);
|
|
432
|
+
return n;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
static double scr_strdec_pack(const uint8_t *bytes, size_t n) {
|
|
436
|
+
uint32_t p = (uint32_t)n;
|
|
437
|
+
if (n > 0) p |= (uint32_t)bytes[0] << 8;
|
|
438
|
+
if (n > 1) p |= (uint32_t)bytes[1] << 16;
|
|
439
|
+
if (n > 2) p |= (uint32_t)bytes[2] << 24;
|
|
440
|
+
return (double)p;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/* Node's utf8CheckIncomplete over the COMBINED tail: the length (0-3) of
|
|
444
|
+
* a trailing truncated-but-valid sequence prefix. Bare continuations and
|
|
445
|
+
* invalid leads are NOT incomplete — they decode (to U+FFFD) now. */
|
|
446
|
+
static size_t scr_strdec_tail(const uint8_t *buf, size_t n) {
|
|
447
|
+
size_t scan = n < 3 ? n : 3;
|
|
448
|
+
for (size_t back = 1; back <= scan; back++) {
|
|
449
|
+
uint8_t b = buf[n - back];
|
|
450
|
+
if ((b & 0xc0) == 0x80) continue; /* continuation: keep walking */
|
|
451
|
+
size_t need = 0;
|
|
452
|
+
if ((b & 0xe0) == 0xc0) need = 2;
|
|
453
|
+
else if ((b & 0xf0) == 0xe0) need = 3;
|
|
454
|
+
else if ((b & 0xf8) == 0xf0) need = 4;
|
|
455
|
+
else return 0; /* ascii or invalid lead: nothing buffers */
|
|
456
|
+
return back < need ? back : 0; /* complete: decode now */
|
|
457
|
+
}
|
|
458
|
+
return 0; /* 3 continuations (or empty): invalid, decode now */
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/* The combined pending+chunk buffer (malloc'd; *out_n set). */
|
|
462
|
+
static uint8_t *scr_strdec_combined(double pending, const ScrBytes *chunk, size_t *out_n) {
|
|
463
|
+
uint8_t pend[3];
|
|
464
|
+
size_t np = scr_strdec_unpack(pending, pend);
|
|
465
|
+
size_t n = np + chunk->len;
|
|
466
|
+
uint8_t *buf = malloc(n > 0 ? n : 1);
|
|
467
|
+
if (!buf) scr_bytes_oom();
|
|
468
|
+
memcpy(buf, pend, np);
|
|
469
|
+
memcpy(buf + np, chunk->data, chunk->len);
|
|
470
|
+
*out_n = n;
|
|
471
|
+
return buf;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/* The utf16le step, Node's utf16Text/fillLast: a pending partial fills
|
|
475
|
+
* first (an odd byte completes its unit; a held LEAD surrogate completes
|
|
476
|
+
* its pair — 4 bytes total), then the rest holds back an odd tail byte
|
|
477
|
+
* (with NO surrogate check — Node's own quirk emits a lead surrogate
|
|
478
|
+
* before an odd boundary) or a trailing lead surrogate's 2 bytes. The
|
|
479
|
+
* emitted bytes decode JOINTLY, so pair halves split across the fill
|
|
480
|
+
* boundary reassemble exactly like Node's string concatenation. */
|
|
481
|
+
static ScrStr *scr_strdec_u16(double pending, const ScrBytes *chunk, bool want_str, double *out_hold) {
|
|
482
|
+
uint8_t held[3];
|
|
483
|
+
size_t k = scr_strdec_unpack(pending, held);
|
|
484
|
+
const uint8_t *c = chunk->data;
|
|
485
|
+
size_t cn = chunk->len;
|
|
486
|
+
uint8_t complete[4];
|
|
487
|
+
size_t comp_n = 0;
|
|
488
|
+
if (k > 0) {
|
|
489
|
+
size_t total = k == 1 ? 2 : 4; /* 1 = odd byte; 2 or 3 = lead-surrogate hold */
|
|
490
|
+
size_t need = total - k;
|
|
491
|
+
if (cn < need) {
|
|
492
|
+
uint8_t nh[3];
|
|
493
|
+
memcpy(nh, held, k);
|
|
494
|
+
memcpy(nh + k, c, cn);
|
|
495
|
+
*out_hold = scr_strdec_pack(nh, k + cn);
|
|
496
|
+
return want_str ? scr_str_new("", 0) : NULL;
|
|
497
|
+
}
|
|
498
|
+
memcpy(complete, held, k);
|
|
499
|
+
memcpy(complete + k, c, need);
|
|
500
|
+
comp_n = total;
|
|
501
|
+
c += need;
|
|
502
|
+
cn -= need;
|
|
503
|
+
}
|
|
504
|
+
size_t keep = cn;
|
|
505
|
+
if (cn % 2 == 1) {
|
|
506
|
+
keep = cn - 1;
|
|
507
|
+
} else if (cn >= 2) {
|
|
508
|
+
uint32_t last = (uint32_t)c[cn - 2] | ((uint32_t)c[cn - 1] << 8);
|
|
509
|
+
if (last >= 0xd800 && last <= 0xdbff) keep = cn - 2;
|
|
510
|
+
}
|
|
511
|
+
*out_hold = scr_strdec_pack(c + keep, cn - keep);
|
|
512
|
+
if (!want_str) return NULL;
|
|
513
|
+
size_t n = comp_n + keep;
|
|
514
|
+
uint8_t *buf = malloc(n > 0 ? n : 1);
|
|
515
|
+
if (!buf) scr_bytes_oom();
|
|
516
|
+
memcpy(buf, complete, comp_n);
|
|
517
|
+
memcpy(buf + comp_n, c, keep);
|
|
518
|
+
ScrStr *s = scr_bytes_decode_utf16le(buf, n);
|
|
519
|
+
free(buf);
|
|
520
|
+
return s;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/* The base64/base64url step: complete 3-byte groups encode now, the
|
|
524
|
+
* 1-2-byte remainder buffers (the combined walk is Node's fillLast+text
|
|
525
|
+
* exactly — base64 of a concatenation splits at group boundaries). */
|
|
526
|
+
static ScrStr *scr_strdec_b64(double pending, const ScrBytes *chunk, bool url, bool want_str, double *out_hold) {
|
|
527
|
+
size_t n;
|
|
528
|
+
uint8_t *buf = scr_strdec_combined(pending, chunk, &n);
|
|
529
|
+
size_t tail = n % 3;
|
|
530
|
+
*out_hold = scr_strdec_pack(buf + (n - tail), tail);
|
|
531
|
+
ScrStr *s = want_str ? scr_bytes_encode_b64(buf, n - tail, url) : NULL;
|
|
532
|
+
free(buf);
|
|
533
|
+
return s;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/* One dispatcher computes the decoded string (when wanted) and the new
|
|
537
|
+
* packed pending for a write. latin1/ascii/hex are stateless (write IS
|
|
538
|
+
* toString); utf8 keeps the oracle-pinned combined walk. */
|
|
539
|
+
static ScrStr *scr_strdec_step(const ScrStr *enc, double pending, const ScrBytes *chunk,
|
|
540
|
+
bool want_str, double *out_hold) {
|
|
541
|
+
if (scr_enc_is(enc, "utf16le")) return scr_strdec_u16(pending, chunk, want_str, out_hold);
|
|
542
|
+
if (scr_enc_is(enc, "base64")) return scr_strdec_b64(pending, chunk, false, want_str, out_hold);
|
|
543
|
+
if (scr_enc_is(enc, "base64url")) return scr_strdec_b64(pending, chunk, true, want_str, out_hold);
|
|
544
|
+
if (scr_enc_is(enc, "latin1") || scr_enc_is(enc, "ascii") || scr_enc_is(enc, "hex")) {
|
|
545
|
+
*out_hold = 0;
|
|
546
|
+
return want_str ? scr_bytes_to_str(chunk, enc) : NULL;
|
|
547
|
+
}
|
|
548
|
+
size_t n;
|
|
549
|
+
uint8_t *buf = scr_strdec_combined(pending, chunk, &n);
|
|
550
|
+
size_t tail = scr_strdec_tail(buf, n);
|
|
551
|
+
*out_hold = scr_strdec_pack(buf + (n - tail), tail);
|
|
552
|
+
ScrStr *s = want_str ? scr_bytes_decode_utf8(buf, n - tail) : NULL;
|
|
553
|
+
free(buf);
|
|
554
|
+
return s;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/* decoder.write(chunk): the decoded complete prefix (+1). */
|
|
558
|
+
ScrStr *scr_strdec_write(const ScrStr *enc, double pending, const ScrBytes *chunk) {
|
|
559
|
+
double hold;
|
|
560
|
+
return scr_strdec_step(enc, pending, chunk, true, &hold);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/* The decoder state AFTER a write: the packed trailing partial sequence. */
|
|
564
|
+
double scr_strdec_next(const ScrStr *enc, double pending, const ScrBytes *chunk) {
|
|
565
|
+
double hold = 0;
|
|
566
|
+
scr_strdec_step(enc, pending, chunk, false, &hold);
|
|
567
|
+
return hold;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/* decoder.end(): the buffered partial flushes — utf8's truncated sequence
|
|
571
|
+
* becomes its replacement chars (the maximal-subpart rule), base64's
|
|
572
|
+
* remainder encodes (padded; unpadded for base64url), utf16le's held
|
|
573
|
+
* bytes decode as they stand (an odd byte drops; a held lead surrogate is
|
|
574
|
+
* the documented U+FFFD divergence), and the stateless encodings flush
|
|
575
|
+
* nothing. +1. */
|
|
576
|
+
ScrStr *scr_strdec_end(const ScrStr *enc, double pending) {
|
|
577
|
+
uint8_t pend[3];
|
|
578
|
+
size_t np = scr_strdec_unpack(pending, pend);
|
|
579
|
+
if (scr_enc_is(enc, "base64")) return scr_bytes_encode_b64(pend, np, false);
|
|
580
|
+
if (scr_enc_is(enc, "base64url")) return scr_bytes_encode_b64(pend, np, true);
|
|
581
|
+
if (scr_enc_is(enc, "utf16le")) return scr_bytes_decode_utf16le(pend, np);
|
|
582
|
+
if (scr_enc_is(enc, "latin1") || scr_enc_is(enc, "ascii") || scr_enc_is(enc, "hex")) {
|
|
583
|
+
return scr_str_new("", 0);
|
|
584
|
+
}
|
|
585
|
+
return scr_bytes_decode_utf8(pend, np);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/* toString(enc, start, end): Node slices then decodes — start/end clamp
|
|
589
|
+
* to [0, len] with start > end collapsing to empty and negative ends
|
|
590
|
+
* clamping to 0 (Node's slice-then-decode; an OMITTED end never reaches
|
|
591
|
+
* here — the emitter supplies the receiver's length for the 2-arg
|
|
592
|
+
* form). Delegates to the whole-buffer decoder
|
|
593
|
+
* through a stack view — no allocation, no rc traffic. */
|
|
594
|
+
ScrStr *scr_bytes_to_str_range(const ScrBytes *b, const ScrStr *enc, double start, double end) {
|
|
595
|
+
size_t len = b->len;
|
|
596
|
+
size_t s0 = start <= 0 ? 0 : ((size_t)start > len ? len : (size_t)start);
|
|
597
|
+
size_t e0 = end <= 0 ? 0 : ((size_t)end > len ? len : (size_t)end);
|
|
598
|
+
if (e0 < s0) e0 = s0;
|
|
599
|
+
ScrBytes view = { .rc = 1, .len = e0 - s0, .elem = b->elem, .data = b->data + s0, .backing = NULL };
|
|
600
|
+
return scr_bytes_to_str(&view, enc);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/* The base64 encoder behind toString("base64") and toString("base64url"):
|
|
604
|
+
* the url flavor swaps the alphabet's last two chars for -_ and drops the
|
|
605
|
+
* padding, exactly Node. */
|
|
606
|
+
static ScrStr *scr_bytes_encode_b64(const uint8_t *in, size_t n, bool url) {
|
|
607
|
+
static const char std_abc[] =
|
|
608
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
609
|
+
static const char url_abc[] =
|
|
610
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
611
|
+
const char *abc = url ? url_abc : std_abc;
|
|
612
|
+
size_t outlen = (n + 2) / 3 * 4;
|
|
613
|
+
char *out = malloc(outlen + 1);
|
|
614
|
+
if (!out) scr_bytes_oom();
|
|
615
|
+
size_t o = 0;
|
|
616
|
+
for (size_t i = 0; i < n; i += 3) {
|
|
617
|
+
unsigned v = (unsigned)in[i] << 16;
|
|
618
|
+
if (i + 1 < n) v |= (unsigned)in[i + 1] << 8;
|
|
619
|
+
if (i + 2 < n) v |= (unsigned)in[i + 2];
|
|
620
|
+
out[o++] = abc[(v >> 18) & 63];
|
|
621
|
+
out[o++] = abc[(v >> 12) & 63];
|
|
622
|
+
if (i + 1 < n) out[o++] = abc[(v >> 6) & 63];
|
|
623
|
+
else if (!url) out[o++] = '=';
|
|
624
|
+
if (i + 2 < n) out[o++] = abc[v & 63];
|
|
625
|
+
else if (!url) out[o++] = '=';
|
|
626
|
+
}
|
|
627
|
+
ScrStr *s = scr_str_new(out, o);
|
|
628
|
+
free(out);
|
|
629
|
+
return s;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/* Append one code point as UTF-8 (the caller sized the buffer). */
|
|
633
|
+
static size_t scr_bytes_put_cp(char *out, size_t o, uint32_t cp) {
|
|
634
|
+
if (cp <= 0x7f) {
|
|
635
|
+
out[o++] = (char)cp;
|
|
636
|
+
} else if (cp <= 0x7ff) {
|
|
637
|
+
out[o++] = (char)(0xc0 | (cp >> 6));
|
|
638
|
+
out[o++] = (char)(0x80 | (cp & 0x3f));
|
|
639
|
+
} else if (cp <= 0xffff) {
|
|
640
|
+
out[o++] = (char)(0xe0 | (cp >> 12));
|
|
641
|
+
out[o++] = (char)(0x80 | ((cp >> 6) & 0x3f));
|
|
642
|
+
out[o++] = (char)(0x80 | (cp & 0x3f));
|
|
643
|
+
} else {
|
|
644
|
+
out[o++] = (char)(0xf0 | (cp >> 18));
|
|
645
|
+
out[o++] = (char)(0x80 | ((cp >> 12) & 0x3f));
|
|
646
|
+
out[o++] = (char)(0x80 | ((cp >> 6) & 0x3f));
|
|
647
|
+
out[o++] = (char)(0x80 | (cp & 0x3f));
|
|
648
|
+
}
|
|
649
|
+
return o;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/* Decode the next code point from an ScrStr's storage — ALWAYS valid
|
|
653
|
+
* UTF-8 (the string runtime never stores ill-formed sequences), so no
|
|
654
|
+
* validation re-runs here. */
|
|
655
|
+
static uint32_t scr_bytes_next_cp(const uint8_t *in, size_t *ip) {
|
|
656
|
+
uint8_t b = in[*ip];
|
|
657
|
+
if (b < 0x80) {
|
|
658
|
+
*ip += 1;
|
|
659
|
+
return b;
|
|
660
|
+
}
|
|
661
|
+
if ((b & 0xe0) == 0xc0) {
|
|
662
|
+
uint32_t cp = ((uint32_t)(b & 0x1f) << 6) | (in[*ip + 1] & 0x3f);
|
|
663
|
+
*ip += 2;
|
|
664
|
+
return cp;
|
|
665
|
+
}
|
|
666
|
+
if ((b & 0xf0) == 0xe0) {
|
|
667
|
+
uint32_t cp = ((uint32_t)(b & 0xf) << 12) | ((uint32_t)(in[*ip + 1] & 0x3f) << 6) |
|
|
668
|
+
(in[*ip + 2] & 0x3f);
|
|
669
|
+
*ip += 3;
|
|
670
|
+
return cp;
|
|
671
|
+
}
|
|
672
|
+
uint32_t cp = ((uint32_t)(b & 0x7) << 18) | ((uint32_t)(in[*ip + 1] & 0x3f) << 12) |
|
|
673
|
+
((uint32_t)(in[*ip + 2] & 0x3f) << 6) | (in[*ip + 3] & 0x3f);
|
|
674
|
+
*ip += 4;
|
|
675
|
+
return cp;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
static bool scr_enc_is(const ScrStr *enc, const char *name) {
|
|
679
|
+
size_t n = strlen(name);
|
|
680
|
+
return enc->len == n && memcmp(enc->data, name, n) == 0;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/* toString("utf16le"): LE code-unit pairs (an odd tail byte drops, like
|
|
684
|
+
* Node). Valid surrogate pairs combine into their code point; a LONE
|
|
685
|
+
* surrogate becomes U+FFFD — Node keeps it as a lone UTF-16 unit, which
|
|
686
|
+
* UTF-8 string storage cannot hold (SEMANTICS.md divergence; stdout
|
|
687
|
+
* agrees byte-for-byte because Node's own write replaces it there too). */
|
|
688
|
+
static ScrStr *scr_bytes_decode_utf16le(const uint8_t *in, size_t n) {
|
|
689
|
+
size_t units = n / 2;
|
|
690
|
+
char *out = malloc(units * 3 + 2);
|
|
691
|
+
if (!out) scr_bytes_oom();
|
|
692
|
+
size_t o = 0;
|
|
693
|
+
for (size_t u = 0; u < units; u++) {
|
|
694
|
+
uint32_t cu = (uint32_t)in[u * 2] | ((uint32_t)in[u * 2 + 1] << 8);
|
|
695
|
+
if (cu >= 0xd800 && cu <= 0xdbff && u + 1 < units) {
|
|
696
|
+
uint32_t lo = (uint32_t)in[(u + 1) * 2] | ((uint32_t)in[(u + 1) * 2 + 1] << 8);
|
|
697
|
+
if (lo >= 0xdc00 && lo <= 0xdfff) {
|
|
698
|
+
o = scr_bytes_put_cp(out, o, 0x10000 + ((cu - 0xd800) << 10) + (lo - 0xdc00));
|
|
699
|
+
u++;
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
o = scr_bytes_put_cp(out, o, cu >= 0xd800 && cu <= 0xdfff ? 0xfffd : cu);
|
|
704
|
+
}
|
|
705
|
+
ScrStr *s = scr_str_new(out, o);
|
|
706
|
+
free(out);
|
|
707
|
+
return s;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
ScrStr *scr_bytes_to_str(const ScrBytes *b, const ScrStr *enc) {
|
|
711
|
+
const uint8_t *in = b->data;
|
|
712
|
+
size_t n = b->len; /* u8: len == byte length */
|
|
713
|
+
if (scr_enc_is(enc, "hex")) {
|
|
714
|
+
char *out = malloc(n * 2 + 1);
|
|
715
|
+
if (!out) scr_bytes_oom();
|
|
716
|
+
for (size_t i = 0; i < n; i++) {
|
|
717
|
+
out[i * 2] = scr_hex_digits[in[i] >> 4];
|
|
718
|
+
out[i * 2 + 1] = scr_hex_digits[in[i] & 0xf];
|
|
719
|
+
}
|
|
720
|
+
ScrStr *s = scr_str_new(out, n * 2);
|
|
721
|
+
free(out);
|
|
722
|
+
return s;
|
|
723
|
+
}
|
|
724
|
+
if (scr_enc_is(enc, "base64")) return scr_bytes_encode_b64(in, n, false);
|
|
725
|
+
if (scr_enc_is(enc, "base64url")) return scr_bytes_encode_b64(in, n, true);
|
|
726
|
+
if (scr_enc_is(enc, "latin1")) {
|
|
727
|
+
/* Each byte is U+00XX ("binary" normalizes here upstream). */
|
|
728
|
+
char *out = malloc(n * 2 + 1);
|
|
729
|
+
if (!out) scr_bytes_oom();
|
|
730
|
+
size_t o = 0;
|
|
731
|
+
for (size_t i = 0; i < n; i++) o = scr_bytes_put_cp(out, o, in[i]);
|
|
732
|
+
ScrStr *s = scr_str_new(out, o);
|
|
733
|
+
free(out);
|
|
734
|
+
return s;
|
|
735
|
+
}
|
|
736
|
+
if (scr_enc_is(enc, "ascii")) {
|
|
737
|
+
/* Node's ascii decode masks the high bit: byte & 0x7f. */
|
|
738
|
+
char *out = malloc(n + 1);
|
|
739
|
+
if (!out) scr_bytes_oom();
|
|
740
|
+
for (size_t i = 0; i < n; i++) out[i] = (char)(in[i] & 0x7f);
|
|
741
|
+
ScrStr *s = scr_str_new(out, n);
|
|
742
|
+
free(out);
|
|
743
|
+
return s;
|
|
744
|
+
}
|
|
745
|
+
if (scr_enc_is(enc, "utf16le")) return scr_bytes_decode_utf16le(in, n);
|
|
746
|
+
/* utf8 (the compiler completes an omitted encoding to "utf8") */
|
|
747
|
+
return scr_bytes_decode_utf8(in, n);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
static int scr_hex_val(uint8_t c) {
|
|
751
|
+
if (c >= '0' && c <= '9') return c - '0';
|
|
752
|
+
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
|
753
|
+
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
|
754
|
+
return -1;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
static int scr_b64_val(uint8_t c) {
|
|
758
|
+
if (c >= 'A' && c <= 'Z') return c - 'A';
|
|
759
|
+
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
|
|
760
|
+
if (c >= '0' && c <= '9') return c - '0' + 52;
|
|
761
|
+
if (c == '+' || c == '-') return 62; /* '-': base64url, accepted like Node */
|
|
762
|
+
if (c == '/' || c == '_') return 63; /* '_': base64url */
|
|
763
|
+
return -1;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
ScrBytes *scr_bytes_from_str(const ScrStr *s, const ScrStr *enc) {
|
|
767
|
+
const uint8_t *in = (const uint8_t *)s->data;
|
|
768
|
+
size_t n = s->len;
|
|
769
|
+
if (scr_enc_is(enc, "latin1") || scr_enc_is(enc, "ascii")) {
|
|
770
|
+
/* Node writes charCodeAt(i) & 0xFF for BOTH spellings — an astral
|
|
771
|
+
* code point contributes its two surrogates' low bytes. */
|
|
772
|
+
ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n);
|
|
773
|
+
size_t o = 0, i = 0;
|
|
774
|
+
while (i < n) {
|
|
775
|
+
uint32_t cp = scr_bytes_next_cp(in, &i);
|
|
776
|
+
if (cp > 0xffff) {
|
|
777
|
+
cp -= 0x10000;
|
|
778
|
+
b->data[o++] = (uint8_t)(0xd800 + (cp >> 10));
|
|
779
|
+
b->data[o++] = (uint8_t)(0xdc00 + (cp & 0x3ff));
|
|
780
|
+
} else {
|
|
781
|
+
b->data[o++] = (uint8_t)cp;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
b->len = o; /* never grows past n: multi-byte cps shrink */
|
|
785
|
+
return b;
|
|
786
|
+
}
|
|
787
|
+
if (scr_enc_is(enc, "utf16le")) {
|
|
788
|
+
ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n * 2);
|
|
789
|
+
size_t o = 0, i = 0;
|
|
790
|
+
while (i < n) {
|
|
791
|
+
uint32_t cp = scr_bytes_next_cp(in, &i);
|
|
792
|
+
if (cp > 0xffff) {
|
|
793
|
+
cp -= 0x10000;
|
|
794
|
+
uint32_t hi = 0xd800 + (cp >> 10), lo = 0xdc00 + (cp & 0x3ff);
|
|
795
|
+
b->data[o++] = (uint8_t)hi;
|
|
796
|
+
b->data[o++] = (uint8_t)(hi >> 8);
|
|
797
|
+
b->data[o++] = (uint8_t)lo;
|
|
798
|
+
b->data[o++] = (uint8_t)(lo >> 8);
|
|
799
|
+
} else {
|
|
800
|
+
b->data[o++] = (uint8_t)cp;
|
|
801
|
+
b->data[o++] = (uint8_t)(cp >> 8);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
b->len = o;
|
|
805
|
+
return b;
|
|
806
|
+
}
|
|
807
|
+
if (enc->len == 3 && memcmp(enc->data, "hex", 3) == 0) {
|
|
808
|
+
/* Node-lenient: parse pairs, stop at the first invalid pair or the
|
|
809
|
+
* odd tail (Buffer.from("a1g2", "hex") is <Buffer a1>). */
|
|
810
|
+
ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n / 2);
|
|
811
|
+
size_t o = 0;
|
|
812
|
+
for (size_t i = 0; i + 1 < n; i += 2) {
|
|
813
|
+
int hi = scr_hex_val(in[i]);
|
|
814
|
+
int lo = scr_hex_val(in[i + 1]);
|
|
815
|
+
if (hi < 0 || lo < 0) break;
|
|
816
|
+
b->data[o++] = (uint8_t)((hi << 4) | lo);
|
|
817
|
+
}
|
|
818
|
+
b->len = o; /* never grows: shrinking the count is safe */
|
|
819
|
+
return b;
|
|
820
|
+
}
|
|
821
|
+
if (scr_enc_is(enc, "base64") || scr_enc_is(enc, "base64url")) {
|
|
822
|
+
/* Node-lenient: skip bytes outside the (standard + url-safe)
|
|
823
|
+
* alphabets — whitespace, '=', stray punctuation; decode 4-char
|
|
824
|
+
* groups, and a 2/3-char tail into 1/2 bytes. Both spellings share
|
|
825
|
+
* the decoder (Node accepts either alphabet under either name). */
|
|
826
|
+
ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n / 4 * 3 + 2);
|
|
827
|
+
size_t o = 0;
|
|
828
|
+
unsigned acc = 0;
|
|
829
|
+
int have = 0;
|
|
830
|
+
for (size_t i = 0; i < n; i++) {
|
|
831
|
+
int v = scr_b64_val(in[i]);
|
|
832
|
+
if (v < 0) continue;
|
|
833
|
+
acc = (acc << 6) | (unsigned)v;
|
|
834
|
+
if (++have == 4) {
|
|
835
|
+
b->data[o++] = (uint8_t)(acc >> 16);
|
|
836
|
+
b->data[o++] = (uint8_t)(acc >> 8);
|
|
837
|
+
b->data[o++] = (uint8_t)acc;
|
|
838
|
+
acc = 0;
|
|
839
|
+
have = 0;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
if (have == 2) b->data[o++] = (uint8_t)(acc >> 4);
|
|
843
|
+
else if (have == 3) {
|
|
844
|
+
b->data[o++] = (uint8_t)(acc >> 10);
|
|
845
|
+
b->data[o++] = (uint8_t)(acc >> 2);
|
|
846
|
+
}
|
|
847
|
+
b->len = o;
|
|
848
|
+
return b;
|
|
849
|
+
}
|
|
850
|
+
/* utf8: ScrStr storage IS the bytes */
|
|
851
|
+
ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n);
|
|
852
|
+
memcpy(b->data, in, n);
|
|
853
|
+
return b;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
ScrBytes *scr_bytes_from_arr(ScrBytesElem elem, const ScrArr *arr) {
|
|
857
|
+
ScrBytes *b = scr_bytes_alloc(elem, arr->len);
|
|
858
|
+
for (size_t i = 0; i < arr->len; i++) {
|
|
859
|
+
double v;
|
|
860
|
+
memcpy(&v, &arr->data[i], sizeof v); /* SCR_ELEM_F64 slots hold doubles */
|
|
861
|
+
switch (elem) {
|
|
862
|
+
case SCR_BYTES_U8:
|
|
863
|
+
b->data[i] = (uint8_t)scr_bytes_to_u32(v);
|
|
864
|
+
break;
|
|
865
|
+
case SCR_BYTES_U32: {
|
|
866
|
+
uint32_t u = scr_bytes_to_u32(v);
|
|
867
|
+
memcpy(b->data + i * 4, &u, 4);
|
|
868
|
+
break;
|
|
869
|
+
}
|
|
870
|
+
case SCR_BYTES_F32: {
|
|
871
|
+
float f = (float)v;
|
|
872
|
+
memcpy(b->data + i * 4, &f, 4);
|
|
873
|
+
break;
|
|
874
|
+
}
|
|
875
|
+
case SCR_BYTES_I32: {
|
|
876
|
+
uint32_t u = scr_bytes_to_u32(v);
|
|
877
|
+
memcpy(b->data + i * 4, &u, 4); /* same residue reinterpreted */
|
|
878
|
+
break;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
return b;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/* ── equals / compare / indexOf / fill / copy / swap / write (u8; the
|
|
886
|
+
* error ladders mirror Node's validateOffset — 'an integer' first, then
|
|
887
|
+
* the '>= 0 && <= max' render, ERR_OUT_OF_RANGE's Received rules — and
|
|
888
|
+
* copy's C++-side ladder; pinned by corpus 1663) ─────────────────────── */
|
|
889
|
+
|
|
890
|
+
static size_t scr_bytes_received(double v, char out[48]); /* the numeric section below */
|
|
891
|
+
|
|
892
|
+
/* validateOffset(name, 0, max): non-integers are 'an integer', the rest
|
|
893
|
+
* '>= 0 && <= max' (Node spells '&&' here, unlike the read/write
|
|
894
|
+
* families' 'and'). max < 0 means copy's no-upper-bound '>= 0' render. */
|
|
895
|
+
static bool scr_bytes_validate_off(const char *name, double value, double max) {
|
|
896
|
+
if (floor(value) == value && value >= 0 && (max < 0 || value <= max)) return true;
|
|
897
|
+
char recv[48];
|
|
898
|
+
scr_bytes_received(value, recv);
|
|
899
|
+
char msg[160];
|
|
900
|
+
int mlen;
|
|
901
|
+
if (floor(value) != value) {
|
|
902
|
+
mlen = snprintf(msg, sizeof msg,
|
|
903
|
+
"The value of \"%s\" is out of range. It must be an integer. Received %s",
|
|
904
|
+
name, recv);
|
|
905
|
+
} else if (max < 0) {
|
|
906
|
+
mlen = snprintf(msg, sizeof msg,
|
|
907
|
+
"The value of \"%s\" is out of range. It must be >= 0. Received %s", name, recv);
|
|
908
|
+
} else {
|
|
909
|
+
char maxb[32];
|
|
910
|
+
scr_f64_to_str(max, maxb);
|
|
911
|
+
mlen = snprintf(msg, sizeof msg,
|
|
912
|
+
"The value of \"%s\" is out of range. It must be >= 0 && <= %s. Received %s",
|
|
913
|
+
name, maxb, recv);
|
|
914
|
+
}
|
|
915
|
+
scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
|
|
916
|
+
return false;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
bool scr_bytes_equals(const ScrBytes *a, const ScrBytes *b) {
|
|
920
|
+
return a->len == b->len && memcmp(a->data, b->data, a->len) == 0;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/* src.compare(target, targetStart?, targetEnd?, sourceStart?, sourceEnd?)
|
|
924
|
+
* — nargs counts the PRESENT index args (defaults skip validation, like
|
|
925
|
+
* Node). Empty-range shortcuts and the memcmp-with-length-tiebreak are
|
|
926
|
+
* Node's exactly. */
|
|
927
|
+
double scr_bytes_compare(const ScrBytes *src, const ScrBytes *target, double nargs,
|
|
928
|
+
double ts, double te, double ss, double se) {
|
|
929
|
+
size_t n = (size_t)nargs;
|
|
930
|
+
if (n < 1) ts = 0;
|
|
931
|
+
else if (!scr_bytes_validate_off("targetStart", ts, 9007199254740991.0)) return 0;
|
|
932
|
+
if (n < 2) te = (double)target->len;
|
|
933
|
+
else if (!scr_bytes_validate_off("targetEnd", te, (double)target->len)) return 0;
|
|
934
|
+
if (n < 3) ss = 0;
|
|
935
|
+
else if (!scr_bytes_validate_off("sourceStart", ss, 9007199254740991.0)) return 0;
|
|
936
|
+
if (n < 4) se = (double)src->len;
|
|
937
|
+
else if (!scr_bytes_validate_off("sourceEnd", se, (double)src->len)) return 0;
|
|
938
|
+
if (ts >= te) return ss >= se ? 0 : 1;
|
|
939
|
+
if (ss >= se) return -1;
|
|
940
|
+
/* Clamp the starts into range (a start past the length reads empty —
|
|
941
|
+
* handled above; here both windows are non-empty). */
|
|
942
|
+
size_t t0 = ts > (double)target->len ? target->len : (size_t)ts;
|
|
943
|
+
size_t s0 = ss > (double)src->len ? src->len : (size_t)ss;
|
|
944
|
+
size_t tn = (size_t)te - t0, sn = (size_t)se - s0;
|
|
945
|
+
size_t m = sn < tn ? sn : tn;
|
|
946
|
+
int c = memcmp(src->data + s0, target->data + t0, m);
|
|
947
|
+
if (c != 0) return c < 0 ? -1 : 1;
|
|
948
|
+
if (sn == tn) return 0;
|
|
949
|
+
return sn < tn ? -1 : 1;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
/* The shared search core: needle bytes, a coerced byteOffset (trunc; NaN
|
|
953
|
+
* means 'search everything' — 0 forward, the end backward; negatives
|
|
954
|
+
* count from the end, and a still-negative backward search answers -1),
|
|
955
|
+
* and the utf16le alignment stride. */
|
|
956
|
+
double scr_bytes_index_of(const ScrBytes *b, const ScrBytes *needle, double off, double align, bool fwd) {
|
|
957
|
+
size_t len = b->len, nlen = needle->len;
|
|
958
|
+
size_t step = align == 2 ? 2 : 1;
|
|
959
|
+
double o = (off != off) ? (fwd ? 0 : (double)len) : trunc(off);
|
|
960
|
+
if (o < 0) {
|
|
961
|
+
o += (double)len;
|
|
962
|
+
if (o < 0) {
|
|
963
|
+
if (!fwd) return -1;
|
|
964
|
+
o = 0;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
if (nlen == 0) return o > (double)len ? (double)len : o; /* '' matches at the clamp */
|
|
968
|
+
if (nlen > len) return -1;
|
|
969
|
+
if (fwd) {
|
|
970
|
+
size_t start = o > (double)len ? len : (size_t)o;
|
|
971
|
+
if (step == 2) start += start % 2;
|
|
972
|
+
for (size_t i = start; i + nlen <= len; i += step) {
|
|
973
|
+
if (memcmp(b->data + i, needle->data, nlen) == 0) return (double)i;
|
|
974
|
+
}
|
|
975
|
+
return -1;
|
|
976
|
+
}
|
|
977
|
+
size_t start = o > (double)(len - nlen) ? len - nlen : (size_t)o;
|
|
978
|
+
if (step == 2) start -= start % 2;
|
|
979
|
+
for (size_t i = start;; i -= step) {
|
|
980
|
+
if (memcmp(b->data + i, needle->data, nlen) == 0) return (double)i;
|
|
981
|
+
if (i < step) break;
|
|
982
|
+
}
|
|
983
|
+
return -1;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
double scr_bytes_index_of_num(const ScrBytes *b, double v, double off, bool fwd) {
|
|
987
|
+
uint8_t byte = (uint8_t)scr_bytes_to_u32(v);
|
|
988
|
+
ScrBytes needle = { .rc = 1, .len = 1, .elem = SCR_BYTES_U8, .data = &byte, .backing = NULL };
|
|
989
|
+
return scr_bytes_index_of(b, &needle, off, 1, fwd);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/* fill's shared core over a normalized byte pattern. nargs counts the
|
|
993
|
+
* present offset/end args. An EMPTY pattern zero-fills when zero_ok
|
|
994
|
+
* (Node's '' string) and is the constant TypeError otherwise (an empty
|
|
995
|
+
* Uint8Array value). Returns the receiver (+1) — fill chains. */
|
|
996
|
+
static ScrBytes *scr_bytes_fill_core(ScrBytes *b, const uint8_t *pat, size_t patn,
|
|
997
|
+
bool zero_ok, double nargs, double offset, double end) {
|
|
998
|
+
if (patn == 0 && !zero_ok) {
|
|
999
|
+
static const char msg[] = "The argument 'value' is invalid. Received <Buffer >";
|
|
1000
|
+
scr_throw_error_msg(SCR_ERR_TYPE, msg, sizeof msg - 1);
|
|
1001
|
+
return NULL;
|
|
1002
|
+
}
|
|
1003
|
+
size_t n = (size_t)nargs;
|
|
1004
|
+
if (n < 1) offset = 0;
|
|
1005
|
+
else if (!scr_bytes_validate_off("offset", offset, 9007199254740991.0)) return NULL;
|
|
1006
|
+
if (n < 2) end = (double)b->len;
|
|
1007
|
+
else if (!scr_bytes_validate_off("end", end, (double)b->len)) return NULL;
|
|
1008
|
+
if (offset < end) {
|
|
1009
|
+
size_t o = (size_t)offset > b->len ? b->len : (size_t)offset;
|
|
1010
|
+
size_t e = (size_t)end;
|
|
1011
|
+
if (patn == 0) {
|
|
1012
|
+
memset(b->data + o, 0, e - o);
|
|
1013
|
+
} else if (patn == 1) {
|
|
1014
|
+
memset(b->data + o, pat[0], e - o);
|
|
1015
|
+
} else {
|
|
1016
|
+
for (size_t i = o; i < e; i++) b->data[i] = pat[(i - o) % patn];
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
return scr_bytes_retain(b);
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
ScrBytes *scr_bytes_fill(ScrBytes *b, const ScrBytes *pattern, double nargs, double offset, double end) {
|
|
1023
|
+
return scr_bytes_fill_core(b, pattern->data, pattern->len, false, nargs, offset, end);
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
ScrBytes *scr_bytes_fill_num(ScrBytes *b, double v, double nargs, double offset, double end) {
|
|
1027
|
+
uint8_t byte = (uint8_t)scr_bytes_to_u32(v);
|
|
1028
|
+
return scr_bytes_fill_core(b, &byte, 1, false, nargs, offset, end);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
ScrBytes *scr_bytes_fill_str(ScrBytes *b, const ScrStr *s, const ScrStr *enc,
|
|
1032
|
+
double nargs, double offset, double end) {
|
|
1033
|
+
ScrBytes *pat = scr_bytes_from_str(s, enc);
|
|
1034
|
+
ScrBytes *r = scr_bytes_fill_core(b, pat->data, pat->len, true, nargs, offset, end);
|
|
1035
|
+
scr_bytes_release(pat);
|
|
1036
|
+
return r;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
/* src.copy(dst, targetStart?, sourceStart?, sourceEnd?): Node's C++-side
|
|
1040
|
+
* ladder — fractional indices TRUNCATE silently, targetStart/sourceEnd
|
|
1041
|
+
* check only >= 0 (past-the-end clamps to nothing), sourceStart is
|
|
1042
|
+
* bounded by the source length. Returns the byte count copied. */
|
|
1043
|
+
double scr_bytes_copy_into(const ScrBytes *src, ScrBytes *dst, double nargs,
|
|
1044
|
+
double ts, double ss, double se) {
|
|
1045
|
+
size_t n = (size_t)nargs;
|
|
1046
|
+
ts = n < 1 ? 0 : trunc(ts);
|
|
1047
|
+
ss = n < 2 ? 0 : trunc(ss);
|
|
1048
|
+
se = n < 3 ? (double)src->len : trunc(se);
|
|
1049
|
+
if (!scr_bytes_validate_off("targetStart", ts, -1)) return 0;
|
|
1050
|
+
if (!scr_bytes_validate_off("sourceStart", ss, (double)src->len)) return 0;
|
|
1051
|
+
if (!scr_bytes_validate_off("sourceEnd", se, -1)) return 0;
|
|
1052
|
+
if (ts >= (double)dst->len) return 0;
|
|
1053
|
+
size_t t0 = (size_t)ts;
|
|
1054
|
+
size_t s0 = (size_t)ss;
|
|
1055
|
+
size_t e0 = se > (double)src->len ? src->len : (size_t)se;
|
|
1056
|
+
if (s0 >= e0) return 0;
|
|
1057
|
+
size_t count = e0 - s0;
|
|
1058
|
+
if (count > dst->len - t0) count = dst->len - t0;
|
|
1059
|
+
memmove(dst->data + t0, src->data + s0, count);
|
|
1060
|
+
return (double)count;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/* swap16/32/64: in-place byte reversal per group; the receiver answers
|
|
1064
|
+
* (+1, chaining like fill). A length off the width is Node's constant
|
|
1065
|
+
* ERR_INVALID_BUFFER_SIZE RangeError. */
|
|
1066
|
+
ScrBytes *scr_bytes_swap(ScrBytes *b, double width) {
|
|
1067
|
+
size_t w = (size_t)width;
|
|
1068
|
+
if (b->len % w != 0) {
|
|
1069
|
+
char msg[64];
|
|
1070
|
+
int mlen = snprintf(msg, sizeof msg, "Buffer size must be a multiple of %zu-bits", w * 8);
|
|
1071
|
+
scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
|
|
1072
|
+
return NULL;
|
|
1073
|
+
}
|
|
1074
|
+
for (size_t g = 0; g < b->len; g += w) {
|
|
1075
|
+
for (size_t i = 0; i < w / 2; i++) {
|
|
1076
|
+
uint8_t t = b->data[g + i];
|
|
1077
|
+
b->data[g + i] = b->data[g + w - 1 - i];
|
|
1078
|
+
b->data[g + w - 1 - i] = t;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
return scr_bytes_retain(b);
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
/* buf.write(string, offset?, length?, enc): encodes, clamps the byte
|
|
1085
|
+
* budget (offset and an explicit length validate against the buffer
|
|
1086
|
+
* length with Node's '&&' render; the length then clamps to the space
|
|
1087
|
+
* left), and truncates at a UNIT boundary — whole UTF-8 code points,
|
|
1088
|
+
* whole utf16le code units (a surrogate pair CAN split — Node writes the
|
|
1089
|
+
* lone lead), byte-level for the rest. Returns the bytes written. */
|
|
1090
|
+
double scr_bytes_write_str(ScrBytes *b, const ScrStr *s, const ScrStr *enc,
|
|
1091
|
+
double offset, double len, bool has_len) {
|
|
1092
|
+
if (!scr_bytes_validate_off("offset", offset, (double)b->len)) return 0;
|
|
1093
|
+
size_t o = (size_t)offset;
|
|
1094
|
+
size_t remaining = b->len - o;
|
|
1095
|
+
size_t budget;
|
|
1096
|
+
if (has_len) {
|
|
1097
|
+
if (!scr_bytes_validate_off("length", len, (double)b->len)) return 0;
|
|
1098
|
+
budget = (size_t)len > remaining ? remaining : (size_t)len;
|
|
1099
|
+
} else {
|
|
1100
|
+
budget = remaining;
|
|
1101
|
+
}
|
|
1102
|
+
ScrBytes *encd = scr_bytes_from_str(s, enc);
|
|
1103
|
+
size_t k = encd->len < budget ? encd->len : budget;
|
|
1104
|
+
if (k < encd->len) {
|
|
1105
|
+
if (scr_enc_is(enc, "utf16le")) {
|
|
1106
|
+
k -= k % 2;
|
|
1107
|
+
} else if (!scr_enc_is(enc, "hex") && !scr_enc_is(enc, "base64") &&
|
|
1108
|
+
!scr_enc_is(enc, "base64url") && !scr_enc_is(enc, "latin1") &&
|
|
1109
|
+
!scr_enc_is(enc, "ascii")) {
|
|
1110
|
+
/* utf8: back off a split multi-byte sequence (whole chars only). */
|
|
1111
|
+
size_t lead = k;
|
|
1112
|
+
while (lead > 0 && (encd->data[lead] & 0xc0) == 0x80) lead--;
|
|
1113
|
+
if (lead < k) {
|
|
1114
|
+
uint8_t l = encd->data[lead];
|
|
1115
|
+
size_t need = (l & 0xf8) == 0xf0 ? 4 : (l & 0xf0) == 0xe0 ? 3 : (l & 0xe0) == 0xc0 ? 2 : 1;
|
|
1116
|
+
if (lead + need > k) k = lead;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
memcpy(b->data + o, encd->data, k);
|
|
1121
|
+
scr_bytes_release(encd);
|
|
1122
|
+
return (double)k;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/* Buffer.concat(list, totalLength): the same concatenation truncated or
|
|
1126
|
+
* zero-padded to the validated total. */
|
|
1127
|
+
ScrBytes *scr_bytes_concat_len(const ScrArr *list, double total) {
|
|
1128
|
+
/* An empty list short-circuits BEFORE the total validates — Node's
|
|
1129
|
+
* own `if (list.length === 0) return new FastBuffer()`. */
|
|
1130
|
+
if (list->len == 0) return scr_bytes_alloc(SCR_BYTES_U8, 0);
|
|
1131
|
+
if (!scr_bytes_validate_off("length", total, 9007199254740991.0)) return NULL;
|
|
1132
|
+
ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, (size_t)total);
|
|
1133
|
+
size_t o = 0;
|
|
1134
|
+
for (size_t i = 0; i < list->len && o < b->len; i++) {
|
|
1135
|
+
const ScrBytes *part = (const ScrBytes *)(uintptr_t)list->data[i];
|
|
1136
|
+
size_t take = part->len < b->len - o ? part->len : b->len - o;
|
|
1137
|
+
memcpy(b->data + o, part->data, take);
|
|
1138
|
+
o += take;
|
|
1139
|
+
}
|
|
1140
|
+
return b;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
/* Buffer.byteLength(string, enc): utf8 is the storage length (ScrStr IS
|
|
1144
|
+
* utf8 bytes), latin1/ascii count UTF-16 units, utf16le doubles them,
|
|
1145
|
+
* hex halves the length, base64/base64url use Node's padding-trimmed
|
|
1146
|
+
* (len * 3) >>> 2. The enc arrives NORMALIZED (the compiler folds
|
|
1147
|
+
* aliases). */
|
|
1148
|
+
double scr_bytes_byte_length_str(ScrStr *s, const ScrStr *enc) {
|
|
1149
|
+
if (scr_enc_is(enc, "latin1") || scr_enc_is(enc, "ascii")) {
|
|
1150
|
+
return scr_str_utf16_len(s);
|
|
1151
|
+
}
|
|
1152
|
+
if (scr_enc_is(enc, "utf16le")) return 2 * scr_str_utf16_len(s);
|
|
1153
|
+
if (scr_enc_is(enc, "hex")) {
|
|
1154
|
+
return floor(scr_str_utf16_len(s) / 2);
|
|
1155
|
+
}
|
|
1156
|
+
if (scr_enc_is(enc, "base64") || scr_enc_is(enc, "base64url")) {
|
|
1157
|
+
size_t units = (size_t)scr_str_utf16_len(s);
|
|
1158
|
+
/* Trailing '=' padding trims (at most two) — checked on the raw
|
|
1159
|
+
* bytes: '=' is ASCII, so the last byte IS the last unit. */
|
|
1160
|
+
if (units > 0 && s->len >= 1 && s->data[s->len - 1] == '=') units--;
|
|
1161
|
+
if (units > 1 && s->len >= 2 && s->data[s->len - 2] == '=') units--;
|
|
1162
|
+
return (double)((units * 3) >> 2);
|
|
1163
|
+
}
|
|
1164
|
+
return (double)s->len; /* utf8 */
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/* Buffer.isEncoding(name): case-insensitive over Node's alias set. */
|
|
1168
|
+
bool scr_bytes_is_encoding(const ScrStr *s) {
|
|
1169
|
+
static const char *const names[] = {
|
|
1170
|
+
"utf8", "utf-8", "ascii", "latin1", "binary", "base64",
|
|
1171
|
+
"hex", "ucs2", "ucs-2", "utf16le", "utf-16le", "base64url",
|
|
1172
|
+
};
|
|
1173
|
+
if (s->len < 3 || s->len > 9) return false;
|
|
1174
|
+
char low[10];
|
|
1175
|
+
for (size_t i = 0; i < s->len; i++) {
|
|
1176
|
+
char c = s->data[i];
|
|
1177
|
+
low[i] = c >= 'A' && c <= 'Z' ? (char)(c + 32) : c;
|
|
1178
|
+
}
|
|
1179
|
+
low[s->len] = 0;
|
|
1180
|
+
for (size_t i = 0; i < sizeof names / sizeof names[0]; i++) {
|
|
1181
|
+
if (strlen(names[i]) == s->len && memcmp(low, names[i], s->len) == 0) return true;
|
|
1182
|
+
}
|
|
1183
|
+
return false;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
ScrBytes *scr_bytes_concat(const ScrArr *list) {
|
|
1187
|
+
size_t total = 0;
|
|
1188
|
+
for (size_t i = 0; i < list->len; i++) {
|
|
1189
|
+
const ScrBytes *part = (const ScrBytes *)(uintptr_t)list->data[i];
|
|
1190
|
+
total += part->len;
|
|
1191
|
+
}
|
|
1192
|
+
ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, total);
|
|
1193
|
+
size_t o = 0;
|
|
1194
|
+
for (size_t i = 0; i < list->len; i++) {
|
|
1195
|
+
const ScrBytes *part = (const ScrBytes *)(uintptr_t)list->data[i];
|
|
1196
|
+
memcpy(b->data + o, part->data, part->len);
|
|
1197
|
+
o += part->len;
|
|
1198
|
+
}
|
|
1199
|
+
return b;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
/* ── the buf.read* / buf.write* numeric families (Node's exact bounds
|
|
1203
|
+
* discipline; the error ladders below mirror lib/internal/buffer.js's
|
|
1204
|
+
* boundsError/checkInt/checkBounds byte-for-byte — pinned by corpus
|
|
1205
|
+
* 1660 against the live Node oracle) ───────────────────────────────── */
|
|
1206
|
+
|
|
1207
|
+
/* ERR_OUT_OF_RANGE's "Received" rendering: integers with |v| > 2^32 get
|
|
1208
|
+
* Node's addNumericalSeparator underscores applied to the plain String()
|
|
1209
|
+
* form — INCLUDING its quirks on exponent renderings ("1e_+21",
|
|
1210
|
+
* "1e+_300"); everything else is the shortest-roundtrip number. */
|
|
1211
|
+
static size_t scr_bytes_received(double v, char out[48]) {
|
|
1212
|
+
char plain[32];
|
|
1213
|
+
size_t n = scr_f64_to_str(v, plain);
|
|
1214
|
+
if (!(isfinite(v) && trunc(v) == v && fabs(v) > 4294967296.0)) {
|
|
1215
|
+
memcpy(out, plain, n + 1);
|
|
1216
|
+
return n;
|
|
1217
|
+
}
|
|
1218
|
+
/* addNumericalSeparator: head of 1-3 chars (past a leading '-'), then
|
|
1219
|
+
* '_'-joined groups of 3 — walked over the STRING, exactly Node. */
|
|
1220
|
+
size_t start = plain[0] == '-' ? 1 : 0;
|
|
1221
|
+
size_t head = n;
|
|
1222
|
+
while (head >= start + 4) head -= 3;
|
|
1223
|
+
memcpy(out, plain, head);
|
|
1224
|
+
size_t o = head;
|
|
1225
|
+
for (size_t p = head; p < n; p += 3) {
|
|
1226
|
+
out[o++] = '_';
|
|
1227
|
+
memcpy(out + o, plain + p, 3);
|
|
1228
|
+
o += 3;
|
|
1229
|
+
}
|
|
1230
|
+
out[o] = 0;
|
|
1231
|
+
return o;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
/* Node's boundsError: a non-integer index is "an integer" first, a
|
|
1235
|
+
* negative capacity (buffer shorter than the read/write width) is the
|
|
1236
|
+
* constant ERR_BUFFER_OUT_OF_BOUNDS text, and everything else renders
|
|
1237
|
+
* the ">= min and <= max" range. type NULL means "offset" (min 0);
|
|
1238
|
+
* "byteLength" renders min 1. All catchable RangeErrors. */
|
|
1239
|
+
static void scr_bytes_bounds_error(double value, double length, const char *type) {
|
|
1240
|
+
char recv[48];
|
|
1241
|
+
scr_bytes_received(value, recv);
|
|
1242
|
+
char msg[160];
|
|
1243
|
+
int mlen;
|
|
1244
|
+
if (floor(value) != value) {
|
|
1245
|
+
mlen = snprintf(msg, sizeof msg,
|
|
1246
|
+
"The value of \"%s\" is out of range. It must be an integer. Received %s",
|
|
1247
|
+
type ? type : "offset", recv);
|
|
1248
|
+
} else if (length < 0) {
|
|
1249
|
+
static const char oob[] = "Attempt to access memory outside buffer bounds";
|
|
1250
|
+
scr_throw_error_msg(SCR_ERR_RANGE, oob, sizeof oob - 1);
|
|
1251
|
+
return;
|
|
1252
|
+
} else {
|
|
1253
|
+
char lenbuf[32];
|
|
1254
|
+
scr_f64_to_str(length, lenbuf);
|
|
1255
|
+
mlen = snprintf(msg, sizeof msg,
|
|
1256
|
+
"The value of \"%s\" is out of range. It must be >= %d and <= %s. Received %s",
|
|
1257
|
+
type ? type : "offset", type ? 1 : 0, lenbuf, recv);
|
|
1258
|
+
}
|
|
1259
|
+
scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/* The shared offset gate: width bytes at offset must lie inside b. */
|
|
1263
|
+
static bool scr_bytes_rw_check(const ScrBytes *b, double offset, size_t width) {
|
|
1264
|
+
double cap = (double)b->len - (double)width;
|
|
1265
|
+
if (floor(offset) != offset || cap < 0 || offset < 0 || offset > cap) {
|
|
1266
|
+
scr_bytes_bounds_error(offset, cap, NULL);
|
|
1267
|
+
return false;
|
|
1268
|
+
}
|
|
1269
|
+
return true;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
/* Node's checkInt for the integer writes: the VALUE range throws before
|
|
1273
|
+
* any offset check; widths past 4 bytes render the "2 ** N" range form
|
|
1274
|
+
* (checkInt's byteLength > 3 branch). NaN passes both comparisons —
|
|
1275
|
+
* exactly Node — and writes zeros downstream. */
|
|
1276
|
+
static bool scr_bytes_check_int(const ScrBytes *b, double value, double offset,
|
|
1277
|
+
size_t width, bool sign) {
|
|
1278
|
+
double max = sign ? exp2((double)(8 * width - 1)) - 1 : exp2((double)(8 * width)) - 1;
|
|
1279
|
+
double min = sign ? -exp2((double)(8 * width - 1)) : 0;
|
|
1280
|
+
if (value > max || value < min) {
|
|
1281
|
+
char recv[48];
|
|
1282
|
+
scr_bytes_received(value, recv);
|
|
1283
|
+
char msg[160];
|
|
1284
|
+
int mlen;
|
|
1285
|
+
if (width > 4) {
|
|
1286
|
+
if (sign) {
|
|
1287
|
+
mlen = snprintf(msg, sizeof msg,
|
|
1288
|
+
"The value of \"value\" is out of range. It must be >= -(2 ** %zu) and < 2 ** %zu. Received %s",
|
|
1289
|
+
8 * width - 1, 8 * width - 1, recv);
|
|
1290
|
+
} else {
|
|
1291
|
+
mlen = snprintf(msg, sizeof msg,
|
|
1292
|
+
"The value of \"value\" is out of range. It must be >= 0 and < 2 ** %zu. Received %s",
|
|
1293
|
+
8 * width, recv);
|
|
1294
|
+
}
|
|
1295
|
+
} else {
|
|
1296
|
+
char minb[32], maxb[32];
|
|
1297
|
+
scr_f64_to_str(min, minb);
|
|
1298
|
+
scr_f64_to_str(max, maxb);
|
|
1299
|
+
mlen = snprintf(msg, sizeof msg,
|
|
1300
|
+
"The value of \"value\" is out of range. It must be >= %s and <= %s. Received %s",
|
|
1301
|
+
minb, maxb, recv);
|
|
1302
|
+
}
|
|
1303
|
+
scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
|
|
1304
|
+
return false;
|
|
1305
|
+
}
|
|
1306
|
+
return scr_bytes_rw_check(b, offset, width);
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
static size_t scr_bytes_num_width(ScrBytesNumKind kind) {
|
|
1310
|
+
switch (kind) {
|
|
1311
|
+
case SCR_BN_U8:
|
|
1312
|
+
case SCR_BN_I8:
|
|
1313
|
+
return 1;
|
|
1314
|
+
case SCR_BN_U16:
|
|
1315
|
+
case SCR_BN_I16:
|
|
1316
|
+
return 2;
|
|
1317
|
+
case SCR_BN_F64:
|
|
1318
|
+
return 8;
|
|
1319
|
+
default:
|
|
1320
|
+
return 4; /* u32 / i32 / f32 */
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
double scr_bytes_read_num(const ScrBytes *b, double offset, ScrBytesNumKind kind, bool le) {
|
|
1325
|
+
size_t width = scr_bytes_num_width(kind);
|
|
1326
|
+
if (!scr_bytes_rw_check(b, offset, width)) return 0;
|
|
1327
|
+
const uint8_t *p = b->data + (size_t)offset;
|
|
1328
|
+
uint64_t u = 0;
|
|
1329
|
+
for (size_t i = 0; i < width; i++) {
|
|
1330
|
+
u |= (uint64_t)p[le ? i : width - 1 - i] << (8 * i);
|
|
1331
|
+
}
|
|
1332
|
+
switch (kind) {
|
|
1333
|
+
case SCR_BN_U8:
|
|
1334
|
+
case SCR_BN_U16:
|
|
1335
|
+
case SCR_BN_U32:
|
|
1336
|
+
return (double)u;
|
|
1337
|
+
case SCR_BN_I8:
|
|
1338
|
+
return (double)(int8_t)u;
|
|
1339
|
+
case SCR_BN_I16:
|
|
1340
|
+
return (double)(int16_t)u;
|
|
1341
|
+
case SCR_BN_I32:
|
|
1342
|
+
return (double)(int32_t)u;
|
|
1343
|
+
case SCR_BN_F32: {
|
|
1344
|
+
uint32_t bits = (uint32_t)u;
|
|
1345
|
+
float f;
|
|
1346
|
+
memcpy(&f, &bits, 4);
|
|
1347
|
+
return (double)f;
|
|
1348
|
+
}
|
|
1349
|
+
case SCR_BN_F64: {
|
|
1350
|
+
double d;
|
|
1351
|
+
memcpy(&d, &u, 8);
|
|
1352
|
+
return d;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
return 0; /* unreachable */
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
double scr_bytes_write_num(ScrBytes *b, double value, double offset, ScrBytesNumKind kind, bool le) {
|
|
1359
|
+
size_t width = scr_bytes_num_width(kind);
|
|
1360
|
+
uint64_t u;
|
|
1361
|
+
if (kind == SCR_BN_F32 || kind == SCR_BN_F64) {
|
|
1362
|
+
/* Float writes carry no value check (any double stores; the float
|
|
1363
|
+
* cast rounds to nearest exactly like Float32Array assignment). */
|
|
1364
|
+
if (!scr_bytes_rw_check(b, offset, width)) return 0;
|
|
1365
|
+
if (kind == SCR_BN_F32) {
|
|
1366
|
+
float f = (float)value;
|
|
1367
|
+
uint32_t bits;
|
|
1368
|
+
memcpy(&bits, &f, 4);
|
|
1369
|
+
u = bits;
|
|
1370
|
+
} else {
|
|
1371
|
+
memcpy(&u, &value, 8);
|
|
1372
|
+
}
|
|
1373
|
+
} else {
|
|
1374
|
+
bool sign = kind == SCR_BN_I8 || kind == SCR_BN_I16 || kind == SCR_BN_I32;
|
|
1375
|
+
if (!scr_bytes_check_int(b, value, offset, width, sign)) return 0;
|
|
1376
|
+
double t = trunc(value);
|
|
1377
|
+
if (t != t) t = 0; /* NaN passed the range gate: zeros, like Node */
|
|
1378
|
+
u = (uint64_t)(int64_t)t; /* two's complement of the truncation */
|
|
1379
|
+
}
|
|
1380
|
+
uint8_t *p = b->data + (size_t)offset;
|
|
1381
|
+
for (size_t i = 0; i < width; i++) {
|
|
1382
|
+
p[le ? i : width - 1 - i] = (uint8_t)(u >> (8 * i));
|
|
1383
|
+
}
|
|
1384
|
+
return offset + (double)width;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
/* readUIntLE/BE / readIntLE/BE — the variable-width family: byteLength
|
|
1388
|
+
* validates FIRST (1-6, its own error ladder), then the offset gate. */
|
|
1389
|
+
double scr_bytes_read_var(const ScrBytes *b, double offset, double byte_length, bool sign, bool le) {
|
|
1390
|
+
if (floor(byte_length) != byte_length || byte_length < 1 || byte_length > 6) {
|
|
1391
|
+
scr_bytes_bounds_error(byte_length, 6, "byteLength");
|
|
1392
|
+
return 0;
|
|
1393
|
+
}
|
|
1394
|
+
size_t width = (size_t)byte_length;
|
|
1395
|
+
if (!scr_bytes_rw_check(b, offset, width)) return 0;
|
|
1396
|
+
const uint8_t *p = b->data + (size_t)offset;
|
|
1397
|
+
uint64_t u = 0;
|
|
1398
|
+
for (size_t i = 0; i < width; i++) {
|
|
1399
|
+
u |= (uint64_t)p[le ? i : width - 1 - i] << (8 * i);
|
|
1400
|
+
}
|
|
1401
|
+
if (sign && (u & ((uint64_t)1 << (8 * width - 1)))) {
|
|
1402
|
+
return (double)(int64_t)(u - ((uint64_t)1 << (8 * width)));
|
|
1403
|
+
}
|
|
1404
|
+
return (double)u;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
/* writeUIntLE/BE / writeIntLE/BE: byteLength, then value, then offset —
|
|
1408
|
+
* Node's exact check order. Returns offset + byteLength. */
|
|
1409
|
+
double scr_bytes_write_var(ScrBytes *b, double value, double offset, double byte_length, bool sign, bool le) {
|
|
1410
|
+
if (floor(byte_length) != byte_length || byte_length < 1 || byte_length > 6) {
|
|
1411
|
+
scr_bytes_bounds_error(byte_length, 6, "byteLength");
|
|
1412
|
+
return 0;
|
|
1413
|
+
}
|
|
1414
|
+
size_t width = (size_t)byte_length;
|
|
1415
|
+
if (!scr_bytes_check_int(b, value, offset, width, sign)) return 0;
|
|
1416
|
+
double t = trunc(value);
|
|
1417
|
+
if (t != t) t = 0;
|
|
1418
|
+
uint64_t u = (uint64_t)(int64_t)t;
|
|
1419
|
+
uint8_t *p = b->data + (size_t)offset;
|
|
1420
|
+
for (size_t i = 0; i < width; i++) {
|
|
1421
|
+
p[le ? i : width - 1 - i] = (uint8_t)(u >> (8 * i));
|
|
1422
|
+
}
|
|
1423
|
+
return offset + (double)width;
|
|
1424
|
+
}
|
|
1425
|
+
|