summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_string.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2017-01-17 20:00:00 +0300
committerIgor Sysoev <igor@sysoev.ru>2017-01-17 20:00:00 +0300
commit16cbf3c076a0aca6d47adaf3f719493674cf2363 (patch)
treee6530480020f62a2bdbf249988ec3e2a751d3927 /src/nxt_string.c
downloadunit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.gz
unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.bz2
Initial version.
Diffstat (limited to 'src/nxt_string.c')
-rw-r--r--src/nxt_string.c317
1 files changed, 317 insertions, 0 deletions
diff --git a/src/nxt_string.c b/src/nxt_string.c
new file mode 100644
index 00000000..45301e94
--- /dev/null
+++ b/src/nxt_string.c
@@ -0,0 +1,317 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) NGINX, Inc.
+ */
+
+#include <nxt_main.h>
+
+
+nxt_str_t *
+nxt_str_alloc(nxt_mem_pool_t *mp, size_t len)
+{
+ nxt_str_t *s;
+
+ /* The string data is allocated aligned to be close to nxt_str_t. */
+ s = nxt_mem_alloc(mp, sizeof(nxt_str_t) + len);
+
+ if (nxt_fast_path(s != NULL)) {
+ s->len = len;
+ s->data = (u_char *) s + sizeof(nxt_str_t);
+ }
+
+ return s;
+}
+
+
+/*
+ * nxt_str_dup() creates a new string with a copy of a source string.
+ * If length of the source string is zero, then the new string anyway
+ * gets a pointer somewhere in mem_pool.
+ */
+
+nxt_str_t *
+nxt_str_dup(nxt_mem_pool_t *mp, nxt_str_t *dst, const nxt_str_t *src)
+{
+ u_char *p;
+
+ if (dst == NULL) {
+ /* The string data is allocated aligned to be close to nxt_str_t. */
+ dst = nxt_mem_alloc(mp, sizeof(nxt_str_t) + src->len);
+ if (nxt_slow_path(dst == NULL)) {
+ return NULL;
+ }
+
+ p = (u_char *) dst;
+ p += sizeof(nxt_str_t);
+ dst->data = p;
+
+ } else {
+ dst->data = nxt_mem_nalloc(mp, src->len);
+ if (nxt_slow_path(dst->data == NULL)) {
+ return NULL;
+ }
+ }
+
+ nxt_memcpy(dst->data, src->data, src->len);
+ dst->len = src->len;
+
+ return dst;
+}
+
+
+/*
+ * nxt_str_copy() creates a C style zero-terminated copy of a source
+ * nxt_str_t. The function is intended to create strings suitable
+ * for libc and kernel interfaces so result is pointer to char instead
+ * of u_char to minimize casts. The copy is aligned to 2 bytes thus
+ * the lowest bit may be used as marker.
+ */
+
+char *
+nxt_str_copy(nxt_mem_pool_t *mp, const nxt_str_t *src)
+{
+ char *p, *dst;
+
+ dst = nxt_mem_align(mp, 2, src->len + 1);
+
+ if (nxt_fast_path(dst != NULL)) {
+ p = nxt_cpymem(dst, src->data, src->len);
+ *p = '\0';
+ }
+
+ return dst;
+}
+
+
+void
+nxt_memcpy_lowcase(u_char *dst, const u_char *src, size_t len)
+{
+ u_char c;
+
+ while (len != 0) {
+ c = *src++;
+ *dst++ = nxt_lowcase(c);
+ len--;
+ }
+}
+
+
+u_char *
+nxt_cpystrn(u_char *dst, const u_char *src, size_t len)
+{
+ if (len == 0) {
+ return dst;
+ }
+
+ while (--len != 0) {
+ *dst = *src;
+
+ if (*dst == '\0') {
+ return dst;
+ }
+
+ dst++;
+ src++;
+ }
+
+ *dst = '\0';
+
+ return dst;
+}
+
+
+nxt_int_t
+nxt_strcasecmp(const u_char *s1, const u_char *s2)
+{
+ u_char c1, c2;
+ nxt_int_t n;
+
+ for ( ;; ) {
+ c1 = *s1++;
+ c2 = *s2++;
+
+ c1 = nxt_lowcase(c1);
+ c2 = nxt_lowcase(c2);
+
+ n = c1 - c2;
+
+ if (n != 0) {
+ return n;
+ }
+
+ if (c1 == 0) {
+ return 0;
+ }
+ }
+}
+
+
+nxt_int_t
+nxt_strncasecmp(const u_char *s1, const u_char *s2, size_t len)
+{
+ u_char c1, c2;
+ nxt_int_t n;
+
+ while (len-- != 0) {
+ c1 = *s1++;
+ c2 = *s2++;
+
+ c1 = nxt_lowcase(c1);
+ c2 = nxt_lowcase(c2);
+
+ n = c1 - c2;
+
+ if (n != 0) {
+ return n;
+ }
+
+ if (c1 == 0) {
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+
+nxt_int_t
+nxt_memcasecmp(const u_char *s1, const u_char *s2, size_t len)
+{
+ u_char c1, c2;
+ nxt_int_t n;
+
+ while (len-- != 0) {
+ c1 = *s1++;
+ c2 = *s2++;
+
+ c1 = nxt_lowcase(c1);
+ c2 = nxt_lowcase(c2);
+
+ n = c1 - c2;
+
+ if (n != 0) {
+ return n;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * nxt_memstrn() is intended for search of static substring "ss"
+ * with known length "len" in string "s" limited by parameter "end".
+ * Zeros are ignored in both strings.
+ */
+
+u_char *
+nxt_memstrn(const u_char *s, const u_char *end, const char *ss, size_t len)
+{
+ u_char c1, c2, *s2;
+
+ s2 = (u_char *) ss;
+ c2 = *s2++;
+ len--;
+
+ while (s < end) {
+ c1 = *s++;
+
+ if (c1 == c2) {
+
+ if (s + len > end) {
+ return NULL;
+ }
+
+ if (nxt_memcmp(s, s2, len) == 0) {
+ return (u_char *) s - 1;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+ * nxt_strcasestrn() is intended for caseless search of static substring
+ * "ss" with known length "len" in string "s" limited by parameter "end".
+ * Zeros are ignored in both strings.
+ */
+
+u_char *
+nxt_memcasestrn(const u_char *s, const u_char *end, const char *ss, size_t len)
+{
+ u_char c1, c2, *s2;
+
+ s2 = (u_char *) ss;
+ c2 = *s2++;
+ c2 = nxt_lowcase(c2);
+ len--;
+
+ while (s < end) {
+ c1 = *s++;
+ c1 = nxt_lowcase(c1);
+
+ if (c1 == c2) {
+
+ if (s + len > end) {
+ return NULL;
+ }
+
+ if (nxt_memcasecmp(s, s2, len) == 0) {
+ return (u_char *) s - 1;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+ * nxt_rstrstrn() is intended to search for static substring "ss"
+ * with known length "len" in string "s" limited by parameter "end"
+ * in reverse order. Zeros are ignored in both strings.
+ */
+
+u_char *
+nxt_rmemstrn(const u_char *s, const u_char *end, const char *ss, size_t len)
+{
+ u_char c1, c2;
+ const u_char *s1, *s2;
+
+ s1 = end - len;
+ s2 = (u_char *) ss;
+ c2 = *s2++;
+ len--;
+
+ while (s < s1) {
+ c1 = *s1;
+
+ if (c1 == c2) {
+ if (nxt_memcmp(s1 + 1, s2, len) == 0) {
+ return (u_char *) s1;
+ }
+ }
+
+ s1--;
+ }
+
+ return NULL;
+}
+
+
+size_t
+nxt_str_strip(u_char *start, u_char *end)
+{
+ u_char *p;
+
+ for (p = end - 1; p >= start; p--) {
+ if (*p != NXT_CR && *p != NXT_LF) {
+ break;
+ }
+ }
+
+ return (p + 1) - start;
+}