1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #include <nxt_main.h> 8 9 10 nxt_str_t * 11 nxt_str_alloc(nxt_mem_pool_t *mp, size_t len) 12 { 13 nxt_str_t *s; 14 15 /* The string data is allocated aligned to be close to nxt_str_t. */ 16 s = nxt_mem_alloc(mp, sizeof(nxt_str_t) + len); 17 18 if (nxt_fast_path(s != NULL)) { 19 s->len = len; 20 s->data = (u_char *) s + sizeof(nxt_str_t); 21 } 22 23 return s; 24 } 25 26 27 /* 28 * nxt_str_dup() creates a new string with a copy of a source string. 29 * If length of the source string is zero, then the new string anyway 30 * gets a pointer somewhere in mem_pool. 31 */ 32 33 nxt_str_t * 34 nxt_str_dup(nxt_mem_pool_t *mp, nxt_str_t *dst, const nxt_str_t *src) 35 { 36 u_char *p; 37 38 if (dst == NULL) { 39 /* The string data is allocated aligned to be close to nxt_str_t. */ 40 dst = nxt_mem_alloc(mp, sizeof(nxt_str_t) + src->len); 41 if (nxt_slow_path(dst == NULL)) { 42 return NULL; 43 } 44 45 p = (u_char *) dst; 46 p += sizeof(nxt_str_t); 47 dst->data = p; 48 49 } else { 50 dst->data = nxt_mem_nalloc(mp, src->len); 51 if (nxt_slow_path(dst->data == NULL)) { 52 return NULL; 53 } 54 } 55 56 nxt_memcpy(dst->data, src->data, src->len); 57 dst->len = src->len; 58 59 return dst; 60 } 61 62 63 /* 64 * nxt_str_copy() creates a C style zero-terminated copy of a source 65 * nxt_str_t. The function is intended to create strings suitable 66 * for libc and kernel interfaces so result is pointer to char instead 67 * of u_char to minimize casts. The copy is aligned to 2 bytes thus 68 * the lowest bit may be used as marker. 69 */ 70 71 char * 72 nxt_str_copy(nxt_mem_pool_t *mp, const nxt_str_t *src) 73 { 74 char *p, *dst; 75 76 dst = nxt_mem_align(mp, 2, src->len + 1); 77 78 if (nxt_fast_path(dst != NULL)) { 79 p = nxt_cpymem(dst, src->data, src->len); 80 *p = '\0'; 81 } 82 83 return dst; 84 } 85 86 87 void 88 nxt_memcpy_lowcase(u_char *dst, const u_char *src, size_t len) 89 { 90 u_char c; 91 92 while (len != 0) { 93 c = *src++; 94 *dst++ = nxt_lowcase(c); 95 len--; 96 } 97 } 98 99 100 u_char * 101 nxt_cpystrn(u_char *dst, const u_char *src, size_t len) 102 { 103 if (len == 0) { 104 return dst; 105 } 106 107 while (--len != 0) { 108 *dst = *src; 109 110 if (*dst == '\0') { 111 return dst; 112 } 113 114 dst++; 115 src++; 116 } 117 118 *dst = '\0'; 119 120 return dst; 121 } 122 123 124 nxt_int_t 125 nxt_strcasecmp(const u_char *s1, const u_char *s2) 126 { 127 u_char c1, c2; 128 nxt_int_t n; 129 130 for ( ;; ) { 131 c1 = *s1++; 132 c2 = *s2++; 133 134 c1 = nxt_lowcase(c1); 135 c2 = nxt_lowcase(c2); 136 137 n = c1 - c2; 138 139 if (n != 0) { 140 return n; 141 } 142 143 if (c1 == 0) { 144 return 0; 145 } 146 } 147 } 148 149 150 nxt_int_t 151 nxt_strncasecmp(const u_char *s1, const u_char *s2, size_t len) 152 { 153 u_char c1, c2; 154 nxt_int_t n; 155 156 while (len-- != 0) { 157 c1 = *s1++; 158 c2 = *s2++; 159 160 c1 = nxt_lowcase(c1); 161 c2 = nxt_lowcase(c2); 162 163 n = c1 - c2; 164 165 if (n != 0) { 166 return n; 167 } 168 169 if (c1 == 0) { 170 return 0; 171 } 172 } 173 174 return 0; 175 } 176 177 178 nxt_int_t 179 nxt_memcasecmp(const u_char *s1, const u_char *s2, size_t len) 180 { 181 u_char c1, c2; 182 nxt_int_t n; 183 184 while (len-- != 0) { 185 c1 = *s1++; 186 c2 = *s2++; 187 188 c1 = nxt_lowcase(c1); 189 c2 = nxt_lowcase(c2); 190 191 n = c1 - c2; 192 193 if (n != 0) { 194 return n; 195 } 196 } 197 198 return 0; 199 } 200 201 202 /* 203 * nxt_memstrn() is intended for search of static substring "ss" 204 * with known length "len" in string "s" limited by parameter "end". 205 * Zeros are ignored in both strings. 206 */ 207 208 u_char * 209 nxt_memstrn(const u_char *s, const u_char *end, const char *ss, size_t len) 210 { 211 u_char c1, c2, *s2; 212 213 s2 = (u_char *) ss; 214 c2 = *s2++; 215 len--; 216 217 while (s < end) { 218 c1 = *s++; 219 220 if (c1 == c2) { 221 222 if (s + len > end) { 223 return NULL; 224 } 225 226 if (nxt_memcmp(s, s2, len) == 0) { 227 return (u_char *) s - 1; 228 } 229 } 230 } 231 232 return NULL; 233 } 234 235 236 /* 237 * nxt_strcasestrn() is intended for caseless search of static substring 238 * "ss" with known length "len" in string "s" limited by parameter "end". 239 * Zeros are ignored in both strings. 240 */ 241 242 u_char * 243 nxt_memcasestrn(const u_char *s, const u_char *end, const char *ss, size_t len) 244 { 245 u_char c1, c2, *s2; 246 247 s2 = (u_char *) ss; 248 c2 = *s2++; 249 c2 = nxt_lowcase(c2); 250 len--; 251 252 while (s < end) { 253 c1 = *s++; 254 c1 = nxt_lowcase(c1); 255 256 if (c1 == c2) { 257 258 if (s + len > end) { 259 return NULL; 260 } 261 262 if (nxt_memcasecmp(s, s2, len) == 0) { 263 return (u_char *) s - 1; 264 } 265 } 266 } 267 268 return NULL; 269 } 270 271 272 /* 273 * nxt_rstrstrn() is intended to search for static substring "ss" 274 * with known length "len" in string "s" limited by parameter "end" 275 * in reverse order. Zeros are ignored in both strings. 276 */ 277 278 u_char * 279 nxt_rmemstrn(const u_char *s, const u_char *end, const char *ss, size_t len) 280 { 281 u_char c1, c2; 282 const u_char *s1, *s2; 283 284 s1 = end - len; 285 s2 = (u_char *) ss; 286 c2 = *s2++; 287 len--; 288 289 while (s < s1) { 290 c1 = *s1; 291 292 if (c1 == c2) { 293 if (nxt_memcmp(s1 + 1, s2, len) == 0) { 294 return (u_char *) s1; 295 } 296 } 297 298 s1--; 299 } 300 301 return NULL; 302 } 303 304 305 size_t 306 nxt_str_strip(u_char *start, u_char *end) 307 { 308 u_char *p; 309 310 for (p = end - 1; p >= start; p--) { 311 if (*p != NXT_CR && *p != NXT_LF) { 312 break; 313 } 314 } 315 316 return (p + 1) - start; 317 } 318