[njs] Introduced StringIndexOf().

Dmitry Volyntsev xeioex at nginx.com
Tue Jun 30 15:36:53 UTC 2020


details:   https://hg.nginx.org/njs/rev/e8a941b394a3
branches:  
changeset: 1443:e8a941b394a3
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Tue Jun 30 15:36:31 2020 +0000
description:
Introduced StringIndexOf().

diffstat:

 src/njs_string.c |  167 +++++++++++++++++++++++++++---------------------------
 1 files changed, 84 insertions(+), 83 deletions(-)

diffs (186 lines):

diff -r 85c1b6ba326b -r e8a941b394a3 src/njs_string.c
--- a/src/njs_string.c	Tue Jun 30 15:33:58 2020 +0000
+++ b/src/njs_string.c	Tue Jun 30 15:36:31 2020 +0000
@@ -1981,98 +1981,99 @@ range_error:
 }
 
 
+static int64_t
+njs_string_index_of(njs_string_prop_t *string, njs_string_prop_t *search,
+    size_t from)
+{
+    size_t        index, length, search_length;
+    const u_char  *p, *end;
+
+    length = (string->length == 0) ? string->size : string->length;
+
+    if (njs_slow_path(search->size == 0)) {
+        return (from < length) ? from : length;
+    }
+
+    index = from;
+    search_length = (search->length == 0) ? search->size : search->length;
+
+    if (length - index >= search_length) {
+        end = string->start + string->size;
+
+        if (string->size == length) {
+            /* Byte or ASCII string. */
+
+            end -= (search->size - 1);
+
+            for (p = string->start + index; p < end; p++) {
+                if (memcmp(p, search->start, search->size) == 0) {
+                    return index;
+                }
+
+                index++;
+            }
+
+        } else {
+            /* UTF-8 string. */
+
+            p = njs_string_offset(string->start, end, index);
+            end -= search->size - 1;
+
+            while (p < end) {
+                if (memcmp(p, search->start, search->size) == 0) {
+                    return index;
+                }
+
+                index++;
+                p = njs_utf8_next(p, end);
+            }
+        }
+    }
+
+    return -1;
+}
+
+
 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            index, length, search_length;
+    int64_t            from;
     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));
+    njs_value_t        *this, *search, *pos, search_lvalue, pos_lvalue;
+    njs_string_prop_t  string, s;
+
+    this = njs_argument(args, 0);
+
+    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;
+    }
+
+    ret = njs_value_to_string(vm, this, this);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return NJS_ERROR;
+    }
+
+    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;
     }
 
-    if (nargs > 1) {
-        length = njs_string_prop(&string, njs_argument(args, 0));
-
-        value = njs_argument(args, 1);
-
-        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;
-            }
-        }
-
-        search_length = njs_string_prop(&search, value);
-
-        index = 0;
-
-        if (nargs > 2) {
-            value = njs_argument(args, 2);
-
-            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;
-                }
-
-            } else {
-                index = njs_number_to_integer(njs_number(value));
-            }
-
-            if (index < 0) {
-                index = 0;
-            }
-        }
-
-        if (length - index >= search_length) {
-            end = string.start + string.size;
-
-            if (string.size == (size_t) length) {
-                /* Byte or ASCII string. */
-
-                end -= (search.size - 1);
-
-                for (p = string.start + index; p < end; p++) {
-                    if (memcmp(p, search.start, search.size) == 0) {
-                        goto done;
-                    }
-
-                    index++;
-                }
-
-            } else {
-                /* UTF-8 string. */
-
-                p = njs_string_offset(string.start, end, index);
-                end -= search.size - 1;
-
-                while (p < end) {
-                    if (memcmp(p, search.start, search.size) == 0) {
-                        goto done;
-                    }
-
-                    index++;
-                    p = njs_utf8_next(p, end);
-                }
-            }
-
-        } else if (search.size == 0) {
-            index = length;
-            goto done;
-        }
-    }
-
-    index = -1;
-
-done:
-
-    njs_set_number(&vm->retval, index);
+    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;
+    }
+
+    (void) njs_string_prop(&string, this);
+    (void) njs_string_prop(&s, search);
+
+    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;
 }


More information about the nginx-devel mailing list