[njs] Array.splice() function.

Igor Sysoev igor at sysoev.ru
Thu Aug 11 13:39:53 UTC 2016


details:   http://hg.nginx.org/njs/rev/3dc4385c805c
branches:  
changeset: 151:3dc4385c805c
user:      Igor Sysoev <igor at sysoev.ru>
date:      Wed Aug 10 18:03:54 2016 +0300
description:
Array.splice() function.

diffstat:

 njs/njs_array.c          |  88 ++++++++++++++++++++++++++++++++++++++++++++++++
 njs/test/njs_unit_test.c |  15 ++++++++
 2 files changed, 103 insertions(+), 0 deletions(-)

diffs (130 lines):

diff -r 050db82b0d46 -r 3dc4385c805c njs/njs_array.c
--- a/njs/njs_array.c	Wed Aug 10 15:52:25 2016 +0300
+++ b/njs/njs_array.c	Wed Aug 10 18:03:54 2016 +0300
@@ -530,6 +530,87 @@ njs_array_prototype_shift(njs_vm_t *vm, 
 
 
 static njs_ret_t
+njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    njs_index_t unused)
+{
+    njs_ret_t    ret;
+    nxt_int_t    items, delta;
+    nxt_uint_t   i, n, start, delete, length;
+    njs_array_t  *array, *deleted;
+
+    array = NULL;
+    start = 0;
+    delete = 0;
+
+    if (njs_is_array(&args[0])) {
+        array = args[0].data.u.array;
+
+        if (nargs > 1) {
+            start = args[1].data.u.number;
+
+            if (nargs > 2) {
+                delete = args[2].data.u.number;
+
+            } else {
+                delete = array->length - start;
+            }
+        }
+    }
+
+    deleted = njs_array_alloc(vm, delete, 0);
+    if (nxt_slow_path(deleted == NULL)) {
+        return NXT_ERROR;
+    }
+
+    if (array != NULL && (delete != 0 || nargs > 3)) {
+        length = array->length;
+
+        /* Move deleted items to a new array to return. */
+        for (i = 0, n = start; i < delete && n < length; i++, n++) {
+            /* No retention required. */
+            deleted->start[i] = array->start[n];
+        }
+
+        items = nargs - 3;
+        items = items >= 0 ? items : 0;
+        delta = items - delete;
+
+        if (delta != 0) {
+            /*
+             * Relocate the rest of items.
+             * Index of the first item is in "n".
+             */
+            if (delta > 0) {
+                ret = njs_array_realloc(vm, array, 0, array->size + delta);
+                if (nxt_slow_path(ret != NXT_OK)) {
+                    return ret;
+                }
+            }
+
+            memmove(&array->start[start + items], &array->start[n],
+                    (array->length - n) * sizeof(njs_value_t));
+
+            array->length += delta;
+        }
+
+        /* Copy new items. */
+        n = start;
+
+        for (i = 3; i < nargs; i++) {
+            /* GC: njs_retain(&args[i]); */
+            array->start[n++] = args[i];
+        }
+    }
+
+    vm->retval.data.u.array = deleted;
+    vm->retval.type = NJS_ARRAY;
+    vm->retval.data.truth = 1;
+
+    return NXT_OK;
+}
+
+
+static njs_ret_t
 njs_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     njs_index_t unused)
 {
@@ -1437,6 +1518,13 @@ static const njs_object_prop_t  njs_arra
 
     {
         .type = NJS_METHOD,
+        .name = njs_string("splice"),
+        .value = njs_native_function(njs_array_prototype_splice, 0,
+                    NJS_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+    },
+
+    {
+        .type = NJS_METHOD,
         .name = njs_string("reverse"),
         .value = njs_native_function(njs_array_prototype_reverse, 0,
                     NJS_OBJECT_ARG),
diff -r 050db82b0d46 -r 3dc4385c805c njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Wed Aug 10 15:52:25 2016 +0300
+++ b/njs/test/njs_unit_test.c	Wed Aug 10 18:03:54 2016 +0300
@@ -2256,6 +2256,21 @@ static njs_unit_test_t  njs_test[] =
                  "len +' '+ a +' '+ a.shift()"),
       nxt_string("5 3,4,5,1,2 3") },
 
+    { nxt_string("var a = []; a.splice()"),
+      nxt_string("") },
+
+    { nxt_string("var a = [0,1,2,3,4,5,6,7];"
+                 "a.splice(3).join(':') + '|' + a"),
+      nxt_string("3:4:5:6:7|0,1,2") },
+
+    { nxt_string("var a = [0,1,2,3,4,5,6,7];"
+                 "a.splice(3, 2).join(':') + '|' + a"),
+      nxt_string("3:4|0,1,2,5,6,7") },
+
+    { nxt_string("var a = [0,1,2,3,4,5,6,7];"
+                 "a.splice(3, 2, 8, 9, 10, 11 ).join(':') + '|' + a"),
+      nxt_string("3:4|0,1,2,8,9,10,11,5,6,7") },
+
     { nxt_string("var a = []; a.reverse()"),
       nxt_string("") },
 



More information about the nginx-devel mailing list