jscript: Use helpers to access string buffer in string.c.
This commit is contained in:
parent
c3cf79ac25
commit
c79180a978
|
@ -643,36 +643,54 @@ typedef struct {
|
|||
DWORD len;
|
||||
} strbuf_t;
|
||||
|
||||
static BOOL strbuf_ensure_size(strbuf_t *buf, unsigned len)
|
||||
{
|
||||
WCHAR *new_buf;
|
||||
DWORD new_size;
|
||||
|
||||
if(len <= buf->size)
|
||||
return TRUE;
|
||||
|
||||
new_size = buf->size ? buf->size<<1 : 16;
|
||||
if(new_size < len)
|
||||
new_size = len;
|
||||
if(buf->buf)
|
||||
new_buf = heap_realloc(buf->buf, new_size*sizeof(WCHAR));
|
||||
else
|
||||
new_buf = heap_alloc(new_size*sizeof(WCHAR));
|
||||
if(!new_buf)
|
||||
return FALSE;
|
||||
|
||||
buf->buf = new_buf;
|
||||
buf->size = new_size;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static HRESULT strbuf_append(strbuf_t *buf, const WCHAR *str, DWORD len)
|
||||
{
|
||||
if(!len)
|
||||
return S_OK;
|
||||
|
||||
if(len + buf->len > buf->size) {
|
||||
WCHAR *new_buf;
|
||||
DWORD new_size;
|
||||
|
||||
new_size = buf->size ? buf->size<<1 : 16;
|
||||
if(new_size < buf->len+len)
|
||||
new_size = buf->len+len;
|
||||
if(buf->buf)
|
||||
new_buf = heap_realloc(buf->buf, new_size*sizeof(WCHAR));
|
||||
else
|
||||
new_buf = heap_alloc(new_size*sizeof(WCHAR));
|
||||
if(!new_buf)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
buf->buf = new_buf;
|
||||
buf->size = new_size;
|
||||
}
|
||||
if(!strbuf_ensure_size(buf, buf->len+len))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
memcpy(buf->buf+buf->len, str, len*sizeof(WCHAR));
|
||||
buf->len += len;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT strbuf_append_jsstr(strbuf_t *buf, jsstr_t *str)
|
||||
{
|
||||
if(!strbuf_ensure_size(buf, buf->len+jsstr_length(str)))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
jsstr_flush(str, buf->buf+buf->len);
|
||||
buf->len += jsstr_length(str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
|
||||
jsstr_t *str, match_state_t *match, jsstr_t **ret)
|
||||
jsstr_t *jsstr, const WCHAR *str, match_state_t *match, jsstr_t **ret)
|
||||
{
|
||||
jsval_t *argv;
|
||||
unsigned argc;
|
||||
|
@ -694,7 +712,7 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
|
|||
if(SUCCEEDED(hres)) {
|
||||
for(i=0; i < match->paren_count; i++) {
|
||||
if(match->parens[i].index != -1)
|
||||
tmp_str = jsstr_substr(str, match->parens[i].index, match->parens[i].length);
|
||||
tmp_str = jsstr_substr(jsstr, match->parens[i].index, match->parens[i].length);
|
||||
else
|
||||
tmp_str = jsstr_empty();
|
||||
if(!tmp_str) {
|
||||
|
@ -706,8 +724,8 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
|
|||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
argv[match->paren_count+1] = jsval_number(match->cp-str->str - match->match_len);
|
||||
argv[match->paren_count+2] = jsval_string(str);
|
||||
argv[match->paren_count+1] = jsval_number(match->cp-str - match->match_len);
|
||||
argv[match->paren_count+2] = jsval_string(jsstr);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
|
@ -729,25 +747,26 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
|
|||
static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
DWORD rep_len=0;
|
||||
jsstr_t *rep_str = NULL, *match_str = NULL, *str;
|
||||
const WCHAR *str, *match_str = NULL, *rep_str = NULL;
|
||||
jsstr_t *rep_jsstr, *match_jsstr, *jsstr;
|
||||
jsdisp_t *rep_func = NULL, *regexp = NULL;
|
||||
match_state_t *match = NULL, last_match = {0};
|
||||
strbuf_t ret = {NULL,0,0};
|
||||
DWORD re_flags = REM_NO_CTX_UPDATE|REM_ALLOC_RESULT;
|
||||
DWORD rep_len=0;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_string_val(ctx, jsthis, &str);
|
||||
hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(!argc) {
|
||||
if(r)
|
||||
*r = jsval_string(str);
|
||||
*r = jsval_string(jsstr);
|
||||
else
|
||||
jsstr_release(str);
|
||||
jsstr_release(jsstr);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -760,9 +779,9 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
}
|
||||
|
||||
if(!regexp) {
|
||||
hres = to_string(ctx, argv[0], &match_str);
|
||||
hres = to_flat_string(ctx, argv[0], &match_jsstr, &match_str);
|
||||
if(FAILED(hres)) {
|
||||
jsstr_release(str);
|
||||
jsstr_release(jsstr);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
@ -777,18 +796,18 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
}
|
||||
|
||||
if(!rep_func) {
|
||||
hres = to_string(ctx, argv[1], &rep_str);
|
||||
hres = to_flat_string(ctx, argv[1], &rep_jsstr, &rep_str);
|
||||
if(SUCCEEDED(hres))
|
||||
rep_len = jsstr_length(rep_str);
|
||||
rep_len = jsstr_length(rep_jsstr);
|
||||
}
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
const WCHAR *ecp = str->str;
|
||||
const WCHAR *ecp = str;
|
||||
|
||||
while(1) {
|
||||
if(regexp) {
|
||||
hres = regexp_match_next(ctx, regexp, re_flags, str, &match);
|
||||
hres = regexp_match_next(ctx, regexp, re_flags, jsstr, &match);
|
||||
re_flags = (re_flags | REM_CHECK_GLOBAL) & (~REM_ALLOC_RESULT);
|
||||
|
||||
if(hres == S_FALSE) {
|
||||
|
@ -804,13 +823,13 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
if(re_flags & REM_ALLOC_RESULT) {
|
||||
re_flags &= ~REM_ALLOC_RESULT;
|
||||
match = &last_match;
|
||||
match->cp = str->str;
|
||||
match->cp = str;
|
||||
}
|
||||
|
||||
match->cp = strstrW(match->cp, match_str->str);
|
||||
match->cp = strstrW(match->cp, match_str);
|
||||
if(!match->cp)
|
||||
break;
|
||||
match->match_len = jsstr_length(match_str);
|
||||
match->match_len = jsstr_length(match_jsstr);
|
||||
match->cp += match->match_len;
|
||||
}
|
||||
|
||||
|
@ -822,16 +841,16 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
if(rep_func) {
|
||||
jsstr_t *cstr;
|
||||
|
||||
hres = rep_call(ctx, rep_func, str, match, &cstr);
|
||||
hres = rep_call(ctx, rep_func, jsstr, str, match, &cstr);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
hres = strbuf_append(&ret, cstr->str, jsstr_length(cstr));
|
||||
hres = strbuf_append_jsstr(&ret, cstr);
|
||||
jsstr_release(cstr);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
}else if(rep_str && regexp) {
|
||||
const WCHAR *ptr = rep_str->str, *ptr2;
|
||||
const WCHAR *ptr = rep_str, *ptr2;
|
||||
|
||||
while((ptr2 = strchrW(ptr, '$'))) {
|
||||
hres = strbuf_append(&ret, ptr, ptr2-ptr);
|
||||
|
@ -848,11 +867,11 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
ptr = ptr2+2;
|
||||
break;
|
||||
case '`':
|
||||
hres = strbuf_append(&ret, str->str, match->cp-str->str-match->match_len);
|
||||
hres = strbuf_append(&ret, str, match->cp-str-match->match_len);
|
||||
ptr = ptr2+2;
|
||||
break;
|
||||
case '\'':
|
||||
hres = strbuf_append(&ret, ecp, (str->str+jsstr_length(str))-ecp);
|
||||
hres = strbuf_append(&ret, ecp, (str+jsstr_length(jsstr))-ecp);
|
||||
ptr = ptr2+2;
|
||||
break;
|
||||
default: {
|
||||
|
@ -877,7 +896,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
}
|
||||
|
||||
if(match->parens[idx-1].index != -1)
|
||||
hres = strbuf_append(&ret, str->str+match->parens[idx-1].index,
|
||||
hres = strbuf_append(&ret, str+match->parens[idx-1].index,
|
||||
match->parens[idx-1].length);
|
||||
}
|
||||
}
|
||||
|
@ -887,11 +906,11 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
}
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
hres = strbuf_append(&ret, ptr, (rep_str->str+rep_len)-ptr);
|
||||
hres = strbuf_append(&ret, ptr, (rep_str+rep_len)-ptr);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
}else if(rep_str) {
|
||||
hres = strbuf_append(&ret, rep_str->str, rep_len);
|
||||
hres = strbuf_append(&ret, rep_str, rep_len);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
}else {
|
||||
|
@ -909,28 +928,28 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
}
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
hres = strbuf_append(&ret, ecp, str->str+jsstr_length(str)-ecp);
|
||||
hres = strbuf_append(&ret, ecp, str+jsstr_length(jsstr)-ecp);
|
||||
}
|
||||
|
||||
if(rep_func)
|
||||
jsdisp_release(rep_func);
|
||||
if(rep_str)
|
||||
jsstr_release(rep_str);
|
||||
jsstr_release(rep_jsstr);
|
||||
if(match_str)
|
||||
jsstr_release(match_str);
|
||||
jsstr_release(match_jsstr);
|
||||
if(regexp)
|
||||
heap_free(match);
|
||||
|
||||
if(SUCCEEDED(hres) && last_match.cp && regexp) {
|
||||
jsstr_release(ctx->last_match);
|
||||
ctx->last_match = jsstr_addref(str);
|
||||
ctx->last_match_index = last_match.cp-str->str-last_match.match_len;
|
||||
ctx->last_match = jsstr_addref(jsstr);
|
||||
ctx->last_match_index = last_match.cp-str-last_match.match_len;
|
||||
ctx->last_match_length = last_match.match_len;
|
||||
}
|
||||
|
||||
if(regexp)
|
||||
jsdisp_release(regexp);
|
||||
jsstr_release(str);
|
||||
jsstr_release(jsstr);
|
||||
|
||||
if(SUCCEEDED(hres) && r) {
|
||||
jsstr_t *ret_str;
|
||||
|
@ -951,20 +970,21 @@ static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
|||
jsval_t *r)
|
||||
{
|
||||
jsdisp_t *regexp = NULL;
|
||||
jsstr_t *str;
|
||||
const WCHAR *str;
|
||||
jsstr_t *jsstr;
|
||||
match_state_t match, *match_ptr = &match;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_string_val(ctx, jsthis, &str);
|
||||
hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(!argc) {
|
||||
if(r)
|
||||
*r = jsval_null();
|
||||
jsstr_release(str);
|
||||
jsstr_release(jsstr);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -979,20 +999,20 @@ static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
|||
if(!regexp) {
|
||||
hres = create_regexp_var(ctx, argv[0], NULL, ®exp);
|
||||
if(FAILED(hres)) {
|
||||
jsstr_release(str);
|
||||
jsstr_release(jsstr);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
match.cp = str->str;
|
||||
hres = regexp_match_next(ctx, regexp, REM_RESET_INDEX|REM_NO_PARENS, str, &match_ptr);
|
||||
jsstr_release(str);
|
||||
match.cp = str;
|
||||
hres = regexp_match_next(ctx, regexp, REM_RESET_INDEX|REM_NO_PARENS, jsstr, &match_ptr);
|
||||
jsstr_release(jsstr);
|
||||
jsdisp_release(regexp);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(r)
|
||||
*r = jsval_number(hres == S_OK ? match.cp-match.match_len-str->str : -1);
|
||||
*r = jsval_number(hres == S_OK ? match.cp-match.match_len-str : -1);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1085,10 +1105,10 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
|||
{
|
||||
match_state_t match_result, *match_ptr = &match_result;
|
||||
DWORD length, i, match_len = 0;
|
||||
const WCHAR *ptr, *ptr2;
|
||||
const WCHAR *ptr, *ptr2, *str, *match_str = NULL;
|
||||
unsigned limit = UINT32_MAX;
|
||||
jsdisp_t *array, *regexp = NULL;
|
||||
jsstr_t *str, *match_str = NULL, *tmp_str;
|
||||
jsstr_t *jsstr, *match_jsstr, *tmp_str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -1098,16 +1118,16 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
hres = get_string_val(ctx, jsthis, &str);
|
||||
hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
length = jsstr_length(str);
|
||||
length = jsstr_length(jsstr);
|
||||
|
||||
if(argc > 1 && !is_undefined(argv[1])) {
|
||||
hres = to_uint32(ctx, argv[1], &limit);
|
||||
if(FAILED(hres)) {
|
||||
jsstr_release(str);
|
||||
jsstr_release(jsstr);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
@ -1123,15 +1143,15 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
|||
}
|
||||
|
||||
if(!regexp) {
|
||||
hres = to_string(ctx, argv[0], &match_str);
|
||||
hres = to_flat_string(ctx, argv[0], &match_jsstr, &match_str);
|
||||
if(FAILED(hres)) {
|
||||
jsstr_release(str);
|
||||
jsstr_release(jsstr);
|
||||
return hres;
|
||||
}
|
||||
|
||||
match_len = jsstr_length(match_str);
|
||||
match_len = jsstr_length(match_jsstr);
|
||||
if(!match_len) {
|
||||
jsstr_release(match_str);
|
||||
jsstr_release(match_jsstr);
|
||||
match_str = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1139,16 +1159,16 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
|||
hres = create_array(ctx, 0, &array);
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
ptr = str->str;
|
||||
match_result.cp = str->str;
|
||||
ptr = str;
|
||||
match_result.cp = str;
|
||||
for(i=0; i<limit; i++) {
|
||||
if(regexp) {
|
||||
hres = regexp_match_next(ctx, regexp, REM_NO_PARENS, str, &match_ptr);
|
||||
hres = regexp_match_next(ctx, regexp, REM_NO_PARENS, jsstr, &match_ptr);
|
||||
if(hres != S_OK)
|
||||
break;
|
||||
ptr2 = match_result.cp - match_result.match_len;
|
||||
}else if(match_str) {
|
||||
ptr2 = strstrW(ptr, match_str->str);
|
||||
ptr2 = strstrW(ptr, match_str);
|
||||
if(!ptr2)
|
||||
break;
|
||||
}else {
|
||||
|
@ -1178,7 +1198,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
|||
}
|
||||
|
||||
if(SUCCEEDED(hres) && (match_str || regexp) && i<limit) {
|
||||
DWORD len = (str->str+length) - ptr;
|
||||
DWORD len = (str+length) - ptr;
|
||||
|
||||
if(len || match_str) {
|
||||
tmp_str = jsstr_alloc_len(ptr, len);
|
||||
|
@ -1195,8 +1215,8 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
|||
if(regexp)
|
||||
jsdisp_release(regexp);
|
||||
if(match_str)
|
||||
jsstr_release(match_str);
|
||||
jsstr_release(str);
|
||||
jsstr_release(match_jsstr);
|
||||
jsstr_release(jsstr);
|
||||
|
||||
if(SUCCEEDED(hres) && r)
|
||||
*r = jsval_obj(array);
|
||||
|
|
Loading…
Reference in New Issue