static int jsstr_cmp_str(jsstr_t *jsstr, const WCHAR *str, unsigned len) { int ret; switch(jsstr_tag(jsstr)) { case JSSTR_INLINE: ret = memcmp(jsstr_as_inline(jsstr)->buf, str, len*sizeof(WCHAR)); return ret || jsstr_length(jsstr) == len ? ret : 1; case JSSTR_HEAP: ret = memcmp(jsstr_as_heap(jsstr)->buf, str, len*sizeof(WCHAR)); return ret || jsstr_length(jsstr) == len ? ret : 1; case JSSTR_ROPE: { jsstr_rope_t *rope = jsstr_as_rope(jsstr); unsigned left_len = jsstr_length(rope->left); ret = jsstr_cmp_str(rope->left, str, min(len, left_len)); if(ret || len <= left_len) return ret; return jsstr_cmp_str(rope->right, str+left_len, len-left_len); } } assert(0); return 0; }
void jsstr_extract(jsstr_t *str, unsigned off, unsigned len, WCHAR *buf) { switch(jsstr_tag(str)) { case JSSTR_INLINE: memcpy(buf, jsstr_as_inline(str)->buf+off, len*sizeof(WCHAR)); return; case JSSTR_HEAP: memcpy(buf, jsstr_as_heap(str)->buf+off, len*sizeof(WCHAR)); return; case JSSTR_ROPE: return jsstr_rope_extract(jsstr_as_rope(str), off, len, buf); } }
void jsstr_free(jsstr_t *str) { switch(jsstr_tag(str)) { case JSSTR_HEAP: heap_free(jsstr_as_heap(str)->buf); break; case JSSTR_ROPE: { jsstr_rope_t *rope = jsstr_as_rope(str); jsstr_release(rope->left); jsstr_release(rope->right); break; } case JSSTR_INLINE: break; } heap_free(str); }
const WCHAR *jsstr_rope_flatten(jsstr_rope_t *str) { WCHAR *buf; buf = heap_alloc((jsstr_length(&str->str)+1) * sizeof(WCHAR)); if(!buf) return NULL; jsstr_flush(str->left, buf); jsstr_flush(str->right, buf+jsstr_length(str->left)); buf[jsstr_length(&str->str)] = 0; /* Trasform to heap string */ jsstr_release(str->left); jsstr_release(str->right); str->str.length_flags |= JSSTR_FLAG_FLAT; return jsstr_as_heap(&str->str)->buf = buf; }
const char *debugstr_jsstr(jsstr_t *str) { return jsstr_is_inline(str) ? debugstr_wn(jsstr_as_inline(str)->buf, jsstr_length(str)) : jsstr_is_heap(str) ? debugstr_wn(jsstr_as_heap(str)->buf, jsstr_length(str)) : wine_dbg_sprintf("%s...", debugstr_jsstr(jsstr_as_rope(str)->left)); }
static inline const WCHAR *jsstr_try_flat(jsstr_t *str) { return jsstr_is_inline(str) ? jsstr_as_inline(str)->buf : jsstr_is_heap(str) ? jsstr_as_heap(str)->buf : NULL; }