[njs] String.prototype.trim() method.

Igor Sysoev igor at sysoev.ru
Fri Oct 28 10:37:42 UTC 2016


details:   http://hg.nginx.org/njs/rev/5de122a4031a
branches:  
changeset: 226:5de122a4031a
user:      Igor Sysoev <igor at sysoev.ru>
date:      Fri Oct 28 13:32:33 2016 +0300
description:
String.prototype.trim() method.

In collaboration with Valentin Bartenev.

diffstat:

 njs/njs_string.c         |  136 +++++++++++++++++++++++++++++++++++++++++++++++
 njs/test/njs_unit_test.c |   30 ++++++++++
 2 files changed, 166 insertions(+), 0 deletions(-)

diffs (193 lines):

diff -r d84e34c2dbde -r 5de122a4031a njs/njs_string.c
--- a/njs/njs_string.c	Thu Oct 27 16:38:05 2016 +0300
+++ b/njs/njs_string.c	Fri Oct 28 13:32:33 2016 +0300
@@ -1614,6 +1614,135 @@ njs_string_prototype_to_upper_case(njs_v
 }
 
 
+static njs_ret_t
+njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    njs_index_t unused)
+{
+    uint32_t           u, trim, length;
+    const u_char       *p, *prev, *start, *end;
+    njs_string_prop_t  string;
+
+    trim = 0;
+
+    njs_string_prop(&string, &args[0]);
+
+    p = string.start;
+    end = string.start + string.size;
+
+    if (string.length == 0 || string.length == string.size) {
+        /* Byte or ASCII string. */
+
+        while (p < end) {
+
+            switch (*p) {
+            case 0x09:  /* <TAB>  */
+            case 0x0A:  /* <LF>   */
+            case 0x0B:  /* <VT>   */
+            case 0x0C:  /* <FF>   */
+            case 0x0D:  /* <CR>   */
+            case 0x20:  /* <SP>   */
+            case 0xA0:  /* <NBSP> */
+                trim++;
+                p++;
+                continue;
+
+            default:
+                start = p;
+                p = end;
+
+                for ( ;; ) {
+                    p--;
+
+                    switch (*p) {
+                    case 0x09:  /* <TAB>  */
+                    case 0x0A:  /* <LF>   */
+                    case 0x0B:  /* <VT>   */
+                    case 0x0C:  /* <FF>   */
+                    case 0x0D:  /* <CR>   */
+                    case 0x20:  /* <SP>   */
+                    case 0xA0:  /* <NBSP> */
+                        trim++;
+                        continue;
+
+                    default:
+                        p++;
+                        goto done;
+                    }
+                }
+            }
+        }
+
+    } else {
+        /* UTF-8 string. */
+
+        while (p < end) {
+            prev = p;
+            u = nxt_utf8_decode(&p, end);
+
+            switch (u) {
+            case 0x0009:  /* <TAB>  */
+            case 0x000A:  /* <LF>   */
+            case 0x000B:  /* <VT>   */
+            case 0x000C:  /* <FF>   */
+            case 0x000D:  /* <CR>   */
+            case 0x0020:  /* <SP>   */
+            case 0x00A0:  /* <NBSP> */
+            case 0x2028:  /* <LS>   */
+            case 0x2029:  /* <PS>   */
+            case 0xFEFF:  /* <BOM>  */
+                trim++;
+                continue;
+
+            default:
+                start = prev;
+                prev = end;
+
+                for ( ;; ) {
+                    prev = nxt_utf8_prev(prev);
+                    p = prev;
+                    u = nxt_utf8_decode(&p, end);
+
+                    switch (u) {
+                    case 0x0009:  /* <TAB>  */
+                    case 0x000A:  /* <LF>   */
+                    case 0x000B:  /* <VT>   */
+                    case 0x000C:  /* <FF>   */
+                    case 0x000D:  /* <CR>   */
+                    case 0x0020:  /* <SP>   */
+                    case 0x00A0:  /* <NBSP> */
+                    case 0x2028:  /* <LS>   */
+                    case 0x2029:  /* <PS>   */
+                    case 0xFEFF:  /* <BOM>  */
+                        trim++;
+                        continue;
+
+                    default:
+                        goto done;
+                    }
+                }
+            }
+        }
+    }
+
+    vm->retval = njs_string_empty;
+
+    return NXT_OK;
+
+done:
+
+    if (trim == 0) {
+        /* GC: retain. */
+        vm->retval = args[0];
+
+        return NXT_OK;
+    }
+
+    length = (string.length != 0) ? string.length - trim : 0;
+
+    return njs_string_new(vm, &vm->retval, start, p - start, length);
+}
+
+
 /*
  * String.search([regexp])
  */
@@ -2908,6 +3037,13 @@ static const njs_object_prop_t  njs_stri
 
     {
         .type = NJS_METHOD,
+        .name = njs_string("trim"),
+        .value = njs_native_function(njs_string_prototype_trim, 0,
+                     NJS_STRING_OBJECT_ARG),
+    },
+
+    {
+        .type = NJS_METHOD,
         .name = njs_string("search"),
         .value = njs_native_function(njs_string_prototype_search, 0,
                      NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG),
diff -r d84e34c2dbde -r 5de122a4031a njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Thu Oct 27 16:38:05 2016 +0300
+++ b/njs/test/njs_unit_test.c	Fri Oct 28 13:32:33 2016 +0300
@@ -3326,6 +3326,36 @@ static njs_unit_test_t  njs_test[] =
                  "} a"),
       nxt_string("304,453,456,459,498,1012,7838,8486,8490,8491") },
 
+    { nxt_string("'abc'.trim()"),
+      nxt_string("abc") },
+
+    { nxt_string("''.trim()"),
+      nxt_string("") },
+
+    { nxt_string("'    '.trim()"),
+      nxt_string("") },
+
+    { nxt_string("'abc  '.trim()"),
+      nxt_string("abc") },
+
+    { nxt_string("'   abc'.trim()"),
+      nxt_string("abc") },
+
+    { nxt_string("'   abc  '.trim()"),
+      nxt_string("abc") },
+
+    { nxt_string("'абв  '.trim()"),
+      nxt_string("абв") },
+
+    { nxt_string("'   абв'.trim()"),
+      nxt_string("абв") },
+
+    { nxt_string("'   абв  '.trim()"),
+      nxt_string("абв") },
+
+    { nxt_string("'\\u2029abc\\uFEFF\\u2028'.trim()"),
+      nxt_string("abc") },
+
     { nxt_string("'abcdefgh'.search()"),
       nxt_string("0") },
 


More information about the nginx-devel mailing list