[njs] String.padStart() and String.padEnd() methods.
Valentin Bartenev
vbart at nginx.com
Mon Jul 2 13:34:31 UTC 2018
details: http://hg.nginx.org/njs/rev/31e0580b3c02
branches:
changeset: 547:31e0580b3c02
user: Valentin Bartenev <vbart at nginx.com>
date: Fri Jun 29 22:36:41 2018 +0300
description:
String.padStart() and String.padEnd() methods.
diffstat:
njs/njs_string.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++
njs/test/njs_unit_test.c | 99 +++++++++++++++++++++++++++++++++++++
2 files changed, 224 insertions(+), 0 deletions(-)
diffs (258 lines):
diff -r f2a2c9674082 -r 31e0580b3c02 njs/njs_string.c
--- a/njs/njs_string.c Mon Jul 02 16:10:52 2018 +0300
+++ b/njs/njs_string.c Fri Jun 29 22:36:41 2018 +0300
@@ -64,6 +64,8 @@ static njs_ret_t njs_string_from_char_co
njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
static njs_ret_t njs_string_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, nxt_bool_t starts);
+static njs_ret_t njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, nxt_bool_t pad_start);
static njs_ret_t njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args,
njs_regexp_pattern_t *pattern);
static njs_ret_t njs_string_split_part_add(njs_vm_t *vm, njs_array_t *array,
@@ -2073,6 +2075,113 @@ njs_string_prototype_repeat(njs_vm_t *vm
}
+static njs_ret_t
+njs_string_prototype_pad_start(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ return njs_string_prototype_pad(vm, args, nargs, 1);
+}
+
+
+static njs_ret_t
+njs_string_prototype_pad_end(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ return njs_string_prototype_pad(vm, args, nargs, 0);
+}
+
+
+static njs_ret_t
+njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+ nxt_bool_t pad_start)
+{
+ u_char *p, *start;
+ size_t padding, trunc, new_size;
+ int32_t length, new_length;
+ uint32_t n, pad_length;
+ const u_char *end;
+ njs_string_prop_t string, pad_string;
+
+ length = njs_string_prop(&string, &args[0]);
+ new_length = nargs > 1 ? args[1].data.u.number : 0;
+
+ if (new_length <= length) {
+ vm->retval = args[0];
+ return NJS_OK;
+ }
+
+ if (nxt_slow_path(new_length >= NJS_STRING_MAX_LENGTH)) {
+ njs_range_error(vm, NULL);
+ return NJS_ERROR;
+ }
+
+ padding = new_length - length;
+
+ /* GCC and Clang complain about uninitialized n and trunc. */
+ n = 0;
+ trunc = 0;
+
+ if (nargs > 2) {
+ pad_length = njs_string_prop(&pad_string, &args[2]);
+
+ if (pad_string.size == 0) {
+ vm->retval = args[0];
+ return NJS_OK;
+ }
+
+ if (pad_string.size > 1) {
+ n = padding / pad_length;
+ trunc = padding % pad_length;
+
+ if (pad_string.size != (size_t) pad_length) {
+ /* UTF-8 string. */
+ end = pad_string.start + pad_string.size;
+ end = njs_string_offset(pad_string.start, end, trunc);
+
+ trunc = end - pad_string.start;
+ padding = pad_string.size * n + trunc;
+ }
+ }
+ }
+
+ new_size = string.size + padding;
+
+ start = njs_string_alloc(vm, &vm->retval, new_size, new_length);
+ if (nxt_slow_path(start == NULL)) {
+ return NJS_ERROR;
+ }
+
+ p = start;
+
+ if (pad_start) {
+ start += padding;
+
+ } else {
+ p += string.size;
+ }
+
+ memcpy(start, string.start, string.size);
+
+ if (nargs == 2) {
+ memset(p, ' ', padding);
+
+ } else if (pad_string.size == 1) {
+ memset(p, pad_string.start[0], padding);
+
+ } else {
+ while (n != 0) {
+ memcpy(p, pad_string.start, pad_string.size);
+ p += pad_string.size;
+ n--;
+ }
+
+ memcpy(p, pad_string.start, trunc);
+ }
+
+ return NJS_OK;
+}
+
+
/*
* String.search([regexp])
*/
@@ -3490,6 +3599,22 @@ static const njs_object_prop_t njs_stri
NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG),
},
+ /* ES8. */
+ {
+ .type = NJS_METHOD,
+ .name = njs_string("padStart"),
+ .value = njs_native_function(njs_string_prototype_pad_start, 0,
+ NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_STRING_ARG),
+ },
+
+ /* ES8. */
+ {
+ .type = NJS_METHOD,
+ .name = njs_string("padEnd"),
+ .value = njs_native_function(njs_string_prototype_pad_end, 0,
+ NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_STRING_ARG),
+ },
+
{
.type = NJS_METHOD,
.name = njs_string("search"),
diff -r f2a2c9674082 -r 31e0580b3c02 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Mon Jul 02 16:10:52 2018 +0300
+++ b/njs/test/njs_unit_test.c Fri Jun 29 22:36:41 2018 +0300
@@ -4557,6 +4557,105 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("''.repeat(NaN)"),
nxt_string("") },
+ { nxt_string("'abc'.padStart(7)"),
+ nxt_string(" abc") },
+
+ { nxt_string("'абв'.padStart(7)"),
+ nxt_string(" абв") },
+
+ { nxt_string("'abc'.padStart(3)"),
+ nxt_string("abc") },
+
+ { nxt_string("'абв'.padStart(0)"),
+ nxt_string("абв") },
+
+ { nxt_string("'abc'.padStart(NaN)"),
+ nxt_string("abc") },
+
+ { nxt_string("'abc'.padStart(2147483647)"),
+ nxt_string("RangeError") },
+
+ { nxt_string("'abc'.padStart(2147483646, '')"),
+ nxt_string("abc") },
+
+ { nxt_string("''.padStart(0, '')"),
+ nxt_string("") },
+
+ { nxt_string("'1'.padStart(5, 0)"),
+ nxt_string("00001") },
+
+ { nxt_string("''.padStart(1, 'я')"),
+ nxt_string("я") },
+
+ { nxt_string("'abc'.padStart(6, NaN)"),
+ nxt_string("NaNabc") },
+
+ { nxt_string("'abc'.padStart(11, 123)"),
+ nxt_string("12312312abc") },
+
+ { nxt_string("'abc'.padStart(6, 12345)"),
+ nxt_string("123abc") },
+
+ { nxt_string("'абв'.padStart(6, 'эюя')"),
+ nxt_string("эюяабв") },
+
+ { nxt_string("'абв'.padStart(4, 'эюя')"),
+ nxt_string("эабв") },
+
+ { nxt_string("'абв'.padStart(7, 'эюя')"),
+ nxt_string("эюяэабв") },
+
+ { nxt_string("'абв'.padStart(10, 'эю')"),
+ nxt_string("эюэюэюэабв") },
+
+ { nxt_string("'1234'.padEnd(4)"),
+ nxt_string("1234") },
+
+ { nxt_string("'1234'.padEnd(-1)"),
+ nxt_string("1234") },
+
+ { nxt_string("'я'.padEnd(1)"),
+ nxt_string("я") },
+
+ { nxt_string("'1234'.padEnd(5)"),
+ nxt_string("1234 ") },
+
+ { nxt_string("'я'.padEnd(6)"),
+ nxt_string("я ") },
+
+ { nxt_string("'я'.padEnd(2147483647)"),
+ nxt_string("RangeError") },
+
+ { nxt_string("'я'.padEnd(2147483646, '')"),
+ nxt_string("я") },
+
+ { nxt_string("''.padEnd(0, '')"),
+ nxt_string("") },
+
+ { nxt_string("'эю'.padEnd(3, 'я')"),
+ nxt_string("эюя") },
+
+ { nxt_string("''.padEnd(1, 0)"),
+ nxt_string("0") },
+
+ { nxt_string("'1234'.padEnd(8, 'abcd')"),
+ nxt_string("1234abcd") },
+
+ { nxt_string("'1234'.padEnd(10, 'abcd')"),
+ nxt_string("1234abcdab") },
+
+ { nxt_string("'1234'.padEnd(7, 'abcd')"),
+ nxt_string("1234abc") },
+
+ { nxt_string("'абв'.padEnd(5, 'ГД')"),
+ nxt_string("абвГД") },
+
+ { nxt_string("'абв'.padEnd(4, 'ГДУ')"),
+ nxt_string("абвГ") },
+
+ { nxt_string("'абвг'.padEnd(10, 'ДЕЖЗ')"),
+ nxt_string("абвгДЕЖЗДЕ") },
+
{ nxt_string("encodeURI()"),
nxt_string("undefined")},
More information about the nginx-devel
mailing list