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 length) 12 { 13 nxt_str_t *s; 14 15 /* The string start is allocated aligned to be close to nxt_str_t. */ 16 s = nxt_mem_alloc(mp, sizeof(nxt_str_t) + length); 17 18 if (nxt_fast_path(s != NULL)) { 19 s->length = length; 20 s->start = (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 start is allocated aligned to be close to nxt_str_t. */ 40 dst = nxt_mem_alloc(mp, sizeof(nxt_str_t) + src->length); 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->start = p; 48 49 } else { 50 dst->start = nxt_mem_nalloc(mp, src->length); 51 if (nxt_slow_path(dst->start == NULL)) { 52 return NULL; 53 } 54 } 55 56 nxt_memcpy(dst->start, src->start, src->length); 57 dst->length = src->length; 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->length + 1); 77 78 if (nxt_fast_path(dst != NULL)) { 79 p = nxt_cpymem(dst, src->start, src->length); 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 length) 89 { 90 u_char c; 91 92 while (length != 0) { 93 c = *src++; 94 *dst++ = nxt_lowcase(c); 95 length--; 96 } 97 } 98 99 100 u_char * 101 nxt_cpystrn(u_char *dst, const u_char *src, size_t length) 102 { 103 if (length == 0) { 104 return dst; 105 } 106 107 while (--length != 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 length) 152 { 153 u_char c1, c2; 154 nxt_int_t n; 155 156 while (length-- != 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 length) 180 { 181 u_char c1, c2; 182 nxt_int_t n; 183 184 while (length-- != 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 "length" 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 length) 210 { 211 u_char c1, c2, *s2; 212 213 s2 = (u_char *) ss; 214 c2 = *s2++; 215 length--; 216 217 while (s < end) { 218 c1 = *s++; 219 220 if (c1 == c2) { 221 222 if (s + length > end) { 223 return NULL; 224 } 225 226 if (nxt_memcmp(s, s2, length) == 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 "length" 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, 244 size_t length) 245 { 246 u_char c1, c2, *s2; 247 248 s2 = (u_char *) ss; 249 c2 = *s2++; 250 c2 = nxt_lowcase(c2); 251 length--; 252 253 while (s < end) { 254 c1 = *s++; 255 c1 = nxt_lowcase(c1); 256 257 if (c1 == c2) { 258 259 if (s + length > end) { 260 return NULL; 261 } 262 263 if (nxt_memcasecmp(s, s2, length) == 0) { 264 return (u_char *) s - 1; 265 } 266 } 267 } 268 269 return NULL; 270 } 271 272 273 /* 274 * nxt_rstrstrn() is intended to search for static substring "ss" 275 * with known length "length" in string "s" limited by parameter "end" 276 * in reverse order. Zeros are ignored in both strings. 277 */ 278 279 u_char * 280 nxt_rmemstrn(const u_char *s, const u_char *end, const char *ss, size_t length) 281 { 282 u_char c1, c2; 283 const u_char *s1, *s2; 284 285 s1 = end - length; 286 s2 = (u_char *) ss; 287 c2 = *s2++; 288 length--; 289 290 while (s < s1) { 291 c1 = *s1; 292 293 if (c1 == c2) { 294 if (nxt_memcmp(s1 + 1, s2, length) == 0) { 295 return (u_char *) s1; 296 } 297 } 298 299 s1--; 300 } 301 302 return NULL; 303 } 304 305 306 size_t 307 nxt_str_strip(u_char *start, u_char *end) 308 { 309 u_char *p; 310 311 for (p = end - 1; p >= start; p--) { 312 if (*p != NXT_CR && *p != NXT_LF) { 313 break; 314 } 315 } 316 317 return (p + 1) - start; 318 } 319