jscript: Use helpers to access string buffer in string.c.

This commit is contained in:
Jacek Caban 2013-03-30 18:00:20 +01:00 committed by Alexandre Julliard
parent c3cf79ac25
commit c79180a978
1 changed files with 93 additions and 73 deletions

View File

@ -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, &regexp);
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);