mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
5.4 KiB
229 lines
5.4 KiB
/*
|
|
* Misc duk_hstring support functions.
|
|
*/
|
|
|
|
#include "duk_internal.h"
|
|
|
|
/*
|
|
* Simple getters and setters.
|
|
*/
|
|
|
|
DUK_INTERNAL duk_bool_t duk_hstring_is_ascii(duk_hstring *h) {
|
|
return DUK_HSTRING_HAS_ASCII(h);
|
|
}
|
|
|
|
DUK_INTERNAL duk_bool_t duk_hstring_is_empty(duk_hstring *h) {
|
|
return duk_hstring_get_bytelen(h) == 0U;
|
|
}
|
|
|
|
DUK_INTERNAL duk_uint32_t duk_hstring_get_hash(duk_hstring *h) {
|
|
#if defined(DUK_USE_STRHASH16)
|
|
return (duk_uint32_t) h->hash;
|
|
#else
|
|
return h->hash;
|
|
#endif
|
|
}
|
|
|
|
DUK_INTERNAL void duk_hstring_set_hash(duk_hstring *h, duk_uint32_t hash) {
|
|
#if defined(DUK_USE_STRHASH16)
|
|
DUK_ASSERT(hash <= 0xffffUL);
|
|
h->hash = hash;
|
|
#else
|
|
h->hash = hash;
|
|
#endif
|
|
}
|
|
|
|
#if defined(DUK_USE_HSTRING_EXTDATA)
|
|
DUK_INTERNAL const duk_uint8_t *duk_hstring_get_extdata(duk_hstring *h) {
|
|
DUK_ASSERT(DUK_HSTRING_HAS_EXTDATA(h));
|
|
return h->extdata;
|
|
}
|
|
#endif
|
|
|
|
DUK_INTERNAL const duk_uint8_t *duk_hstring_get_data(duk_hstring *h) {
|
|
#if defined(DUK_USE_HSTRING_EXTDATA)
|
|
if (DUK_HSTRING_HAS_EXTDATA(h)) {
|
|
return duk_hstring_get_extdata(h);
|
|
} else {
|
|
return (const duk_uint8_t *) (x + 1);
|
|
}
|
|
#else
|
|
return (const duk_uint8_t *) (h + 1);
|
|
#endif
|
|
}
|
|
|
|
DUK_INTERNAL const duk_uint8_t *duk_hstring_get_data_and_bytelen(duk_hstring *h, duk_size_t *out_blen) {
|
|
DUK_ASSERT(out_blen != NULL);
|
|
*out_blen = duk_hstring_get_bytelen(h);
|
|
return duk_hstring_get_data(h);
|
|
}
|
|
|
|
DUK_INTERNAL const duk_uint8_t *duk_hstring_get_data_end(duk_hstring *h) {
|
|
return duk_hstring_get_data(h) + duk_hstring_get_bytelen(h);
|
|
}
|
|
|
|
/*
|
|
* duk_hstring charlen
|
|
*/
|
|
|
|
DUK_INTERNAL void duk_hstring_set_charlen(duk_hstring *h, duk_size_t len) {
|
|
#if defined(DUK_USE_HSTRING_CLEN)
|
|
#if defined(DUK_USE_STRLEN16)
|
|
DUK_ASSERT(len <= 0xffffUL);
|
|
h->clen16 = len;
|
|
#else
|
|
DUK_ASSERT(len <= 0xffffffffUL);
|
|
h->clen = len;
|
|
#endif
|
|
#else
|
|
DUK_UNREF(len);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* duk_hstring charlen, when lazy charlen enabled.
|
|
*/
|
|
|
|
DUK_LOCAL duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {
|
|
if (DUK_LIKELY(DUK_HSTRING_HAS_ASCII(h))) {
|
|
/* Most practical strings will go here. */
|
|
DUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(h));
|
|
return duk_hstring_get_bytelen(h);
|
|
} else {
|
|
duk_size_t res;
|
|
|
|
/* XXX: here we could use the strcache to speed up the
|
|
* computation (matters for 'i < str.length' loops).
|
|
*/
|
|
|
|
if (DUK_HSTRING_HAS_SYMBOL(h)) {
|
|
return 0;
|
|
}
|
|
res = duk_unicode_wtf8_charlength(duk_hstring_get_data(h), duk_hstring_get_bytelen(h));
|
|
|
|
return res;
|
|
}
|
|
}
|
|
|
|
#if defined(DUK_USE_HSTRING_CLEN)
|
|
DUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {
|
|
#if defined(DUK_USE_STRLEN16)
|
|
return h->clen16;
|
|
#else
|
|
return h->clen;
|
|
#endif
|
|
}
|
|
#else /* DUK_USE_HSTRING_CLEN */
|
|
DUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {
|
|
/* Always use slow path. */
|
|
return duk__hstring_get_charlen_slowpath(h);
|
|
}
|
|
#endif /* DUK_USE_HSTRING_CLEN */
|
|
|
|
/*
|
|
* duk_hstring charCodeAt, with and without surrogate awareness.
|
|
*/
|
|
|
|
DUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr,
|
|
duk_hstring *h,
|
|
duk_uint_t pos,
|
|
duk_bool_t surrogate_aware) {
|
|
return duk_unicode_wtf8_charcodeat_helper(thr, h, pos, surrogate_aware);
|
|
}
|
|
|
|
/*
|
|
* Bytelen.
|
|
*/
|
|
|
|
DUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_bytelen(duk_hstring *h) {
|
|
#if defined(DUK_USE_STRLEN16)
|
|
return h->hdr.h_strextra16;
|
|
#else
|
|
return h->blen;
|
|
#endif
|
|
}
|
|
|
|
DUK_INTERNAL void duk_hstring_set_bytelen(duk_hstring *h, duk_size_t len) {
|
|
#if defined(DUK_USE_STRLEN16)
|
|
DUK_ASSERT(len <= 0xffffUL);
|
|
h->hdr.h_strextra16 = len;
|
|
#else
|
|
DUK_ASSERT(len <= 0xffffffffUL);
|
|
h->blen = len;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Arridx.
|
|
*/
|
|
|
|
DUK_INTERNAL duk_uarridx_t duk_hstring_get_arridx_fast(duk_hstring *h) {
|
|
#if defined(DUK_USE_HSTRING_ARRIDX)
|
|
return h->arridx;
|
|
#else
|
|
/* Get array index related to string (or return DUK_ARRIDX_NONE);
|
|
* avoids helper call if string has no array index value.
|
|
*/
|
|
if (DUK_HSTRING_HAS_ARRIDX(h)) {
|
|
return duk_js_to_arrayindex_hstring_fast_known(h);
|
|
} else {
|
|
return DUK_ARRIDX_NONE;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
DUK_INTERNAL duk_uarridx_t duk_hstring_get_arridx_fast_known(duk_hstring *h) {
|
|
DUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(h));
|
|
|
|
#if defined(DUK_USE_HSTRING_ARRIDX)
|
|
return h->arridx;
|
|
#else
|
|
return duk_js_to_arrayindex_hstring_fast_known(h);
|
|
#endif
|
|
}
|
|
|
|
DUK_INTERNAL duk_uarridx_t duk_hstring_get_arridx_slow(duk_hstring *h) {
|
|
#if defined(DUK_USE_HSTRING_ARRIDX)
|
|
return h->arridx;
|
|
#else
|
|
return duk_js_to_arrayindex_hstring_fast(h);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Compare duk_hstring to an ASCII cstring.
|
|
*/
|
|
|
|
DUK_INTERNAL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr) {
|
|
duk_size_t len;
|
|
|
|
DUK_ASSERT(h != NULL);
|
|
DUK_ASSERT(cstr != NULL);
|
|
|
|
len = DUK_STRLEN(cstr);
|
|
if (len != duk_hstring_get_bytelen(h)) {
|
|
return 0;
|
|
}
|
|
if (duk_memcmp((const void *) cstr, (const void *) duk_hstring_get_data(h), len) == 0) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DUK_INTERNAL duk_bool_t duk_hstring_is_symbol_initial_byte(duk_uint8_t t) {
|
|
return (t >= 0x80) && (t <= 0x82U || t == 0xffU);
|
|
}
|
|
|
|
DUK_INTERNAL duk_bool_t duk_hstring_is_valid_hstring_data(const duk_uint8_t *p, duk_size_t blen) {
|
|
DUK_ASSERT(p != NULL || blen == 0);
|
|
if (blen > 0) {
|
|
duk_uint8_t ib = p[0];
|
|
if (duk_hstring_is_symbol_initial_byte(ib)) {
|
|
/* Should validate Symbol, no validation now. */
|
|
return 1;
|
|
} else {
|
|
return duk_unicode_is_valid_wtf8(p, blen);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|