From: Dmitry Volyntsev Date: Tue, 30 Jun 2020 15:36:31 +0000 (+0000) Subject: Introduced StringIndexOf(). X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=5f8ec9ea798318d30f29eac355540c9ce57c7116;p=njs.git Introduced StringIndexOf(). --- diff --git a/src/njs_string.c b/src/njs_string.c index c57b278d..5c2997be 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -1981,98 +1981,99 @@ range_error: } -static njs_int_t -njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) +static int64_t +njs_string_index_of(njs_string_prop_t *string, njs_string_prop_t *search, + size_t from) { - int64_t index, length, search_length; - njs_int_t ret; - njs_value_t *value; - const u_char *p, *end; - njs_string_prop_t string, search; - - ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0)); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } + size_t index, length, search_length; + const u_char *p, *end; - if (nargs > 1) { - length = njs_string_prop(&string, njs_argument(args, 0)); + length = (string->length == 0) ? string->size : string->length; - value = njs_argument(args, 1); + if (njs_slow_path(search->size == 0)) { + return (from < length) ? from : length; + } - if (njs_slow_path(!njs_is_string(value))) { - ret = njs_value_to_string(vm, value, value); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } + index = from; + search_length = (search->length == 0) ? search->size : search->length; - search_length = njs_string_prop(&search, value); + if (length - index >= search_length) { + end = string->start + string->size; - index = 0; + if (string->size == length) { + /* Byte or ASCII string. */ - if (nargs > 2) { - value = njs_argument(args, 2); + end -= (search->size - 1); - if (njs_slow_path(!njs_is_number(value))) { - ret = njs_value_to_integer(vm, value, &index); - if (njs_slow_path(ret != NJS_OK)) { - return ret; + for (p = string->start + index; p < end; p++) { + if (memcmp(p, search->start, search->size) == 0) { + return index; } - } else { - index = njs_number_to_integer(njs_number(value)); + index++; } - if (index < 0) { - index = 0; - } - } + } else { + /* UTF-8 string. */ - if (length - index >= search_length) { - end = string.start + string.size; + p = njs_string_offset(string->start, end, index); + end -= search->size - 1; - if (string.size == (size_t) length) { - /* Byte or ASCII string. */ + while (p < end) { + if (memcmp(p, search->start, search->size) == 0) { + return index; + } - end -= (search.size - 1); + index++; + p = njs_utf8_next(p, end); + } + } + } - for (p = string.start + index; p < end; p++) { - if (memcmp(p, search.start, search.size) == 0) { - goto done; - } + return -1; +} - index++; - } - } else { - /* UTF-8 string. */ +static njs_int_t +njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, + njs_index_t unused) +{ + int64_t from; + njs_int_t ret; + njs_value_t *this, *search, *pos, search_lvalue, pos_lvalue; + njs_string_prop_t string, s; - p = njs_string_offset(string.start, end, index); - end -= search.size - 1; + this = njs_argument(args, 0); - while (p < end) { - if (memcmp(p, search.start, search.size) == 0) { - goto done; - } + if (njs_slow_path(njs_is_null_or_undefined(this))) { + njs_type_error(vm, "cannot convert \"%s\"to object", + njs_type_string(this->type)); + return NJS_ERROR; + } - index++; - p = njs_utf8_next(p, end); - } - } + ret = njs_value_to_string(vm, this, this); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } - } else if (search.size == 0) { - index = length; - goto done; - } + search = njs_lvalue_arg(&search_lvalue, args, nargs, 1); + ret = njs_value_to_string(vm, search, search); + if (njs_slow_path(ret != NJS_OK)) { + return ret; } - index = -1; + pos = njs_lvalue_arg(&pos_lvalue, args, nargs, 2); + ret = njs_value_to_integer(vm, pos, &from); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } -done: + (void) njs_string_prop(&string, this); + (void) njs_string_prop(&s, search); - njs_set_number(&vm->retval, index); + from = njs_min(njs_max(from, 0), (int64_t) string.length); + + njs_set_number(&vm->retval, njs_string_index_of(&string, &s, from)); return NJS_OK; }