[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