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