1
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7 #ifndef _NJS_STR_H_INCLUDED_
8 #define _NJS_STR_H_INCLUDED_
9
10
11 typedef struct {
12 size_t length;
13 u_char *start;
14 } njs_str_t;
15
16
17 /*
18 * C99 allows to assign struct as compound literal with struct name cast only.
19 * SunC however issues error on the cast in struct static initialization:
20 * non-constant initializer: op "NAME"
21 * So a separate njs_str_value() macro is intended to use in assignment.
22 */
23
24 #define njs_length(s) (sizeof(s) - 1)
25 #define njs_str(s) { njs_length(s), (u_char *) s }
26 #define njs_null_str { 0, NULL }
27 #define njs_str_value(s) (njs_str_t) njs_str(s)
28
29
30 njs_inline u_char
njs_lower_case(u_char c)31 njs_lower_case(u_char c)
32 {
33 return (u_char) ((c >= 'A' && c <= 'Z') ? c | 0x20 : c);
34 }
35
36
37 njs_inline u_char
njs_upper_case(u_char c)38 njs_upper_case(u_char c)
39 {
40 return (u_char) ((c >= 'a' && c <= 'z') ? c & 0xDF : c);
41 }
42
43
44 njs_inline njs_bool_t
njs_is_whitespace(u_char c)45 njs_is_whitespace(u_char c)
46 {
47 switch (c) {
48 case 0x09: /* <TAB> */
49 case 0x0A: /* <LF> */
50 case 0x0B: /* <VT> */
51 case 0x0C: /* <FF> */
52 case 0x0D: /* <CR> */
53 case 0x20: /* <SP> */
54 case 0xA0: /* <NBSP> */
55 return 1;
56
57 default:
58 return 0;
59 }
60 }
61
62
63 njs_inline u_char *
njs_strlchr(u_char * p,u_char * last,u_char c)64 njs_strlchr(u_char *p, u_char *last, u_char c)
65 {
66 while (p < last) {
67
68 if (*p == c) {
69 return p;
70 }
71
72 p++;
73 }
74
75 return NULL;
76 }
77
78
79 #define \
80 njs_strlen(s) \
81 strlen((char *) s)
82
83
84 #define \
85 njs_cpymem(dst, src, n) \
86 (((u_char *) memcpy(dst, src, n)) + (n))
87
88
89 #define \
90 njs_strncmp(s1, s2, n) \
91 strncmp((char *) s1, (char *) s2, n)
92
93
94 #define \
95 njs_strchr(s1, c) \
96 (u_char *) strchr((const char *) s1, (int) c)
97
98
99 #define \
100 njs_memset(buf, c, length) \
101 (void) memset(buf, c, length)
102
103
104 #define \
105 njs_memzero(buf, length) \
106 (void) memset(buf, 0, length)
107
108
109 #if (NJS_HAVE_EXPLICIT_BZERO && !NJS_HAVE_MEMORY_SANITIZER)
110 #define \
111 njs_explicit_memzero(buf, length) \
112 explicit_bzero(buf, length)
113 #elif (NJS_HAVE_EXPLICIT_MEMSET)
114 #define \
115 njs_explicit_memzero(buf, length) \
116 (void) explicit_memset(buf, 0, length)
117 #else
118 njs_inline void
njs_explicit_memzero(void * buf,size_t length)119 njs_explicit_memzero(void *buf, size_t length)
120 {
121 volatile u_char *p = (volatile u_char *) buf;
122
123 while (length != 0) {
124 *p++ = 0;
125 length--;
126 }
127 }
128 #endif
129
130
131 #define \
132 njs_strstr_eq(s1, s2) \
133 (((s1)->length == (s2)->length) \
134 && (memcmp((s1)->start, (s2)->start, (s1)->length) == 0))
135
136
137 #define \
138 njs_strstr_case_eq(s1, s2) \
139 (((s1)->length == (s2)->length) \
140 && (njs_strncasecmp((s1)->start, (s2)->start, (s1)->length) == 0))
141
142
143 NJS_EXPORT njs_int_t njs_strncasecmp(u_char *s1, u_char *s2, size_t n);
144
145
146 #endif /* _NJS_STR_H_INCLUDED_ */
147