xref: /php-src/ext/dom/lexbor/lexbor/core/str.h (revision bffab33a)
1 /*
2  * Copyright (C) 2018-2023 Alexander Borisov
3  *
4  * Author: Alexander Borisov <borisov@lexbor.com>
5  */
6 
7 #ifndef LEXBOR_STR_H
8 #define LEXBOR_STR_H
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #include "lexbor/core/base.h"
15 #include "lexbor/core/mraw.h"
16 #include "lexbor/core/utils.h"
17 
18 
19 #define lexbor_str_get(str, attr) str->attr
20 #define lexbor_str_set(str, attr) lexbor_str_get(str, attr)
21 #define lexbor_str_len(str) lexbor_str_get(str, length)
22 #define lexbor_str(p) {.data = (lxb_char_t *) (p), sizeof(p) - 1}
23 
24 
25 #define lexbor_str_check_size_arg_m(str, size, mraw, plus_len, return_fail)    \
26     do {                                                                       \
27         void *tmp;                                                             \
28                                                                                \
29         if (str->length > (SIZE_MAX - (plus_len)))                             \
30             return (return_fail);                                              \
31                                                                                \
32         if ((str->length + (plus_len)) > (size)) {                             \
33             tmp = lexbor_mraw_realloc(mraw, str->data,                         \
34                                       (str->length + plus_len));               \
35                                                                                \
36             if (tmp == NULL) {                                                 \
37                 return (return_fail);                                          \
38             }                                                                  \
39                                                                                \
40             str->data = (lxb_char_t *) tmp;                                    \
41         }                                                                      \
42     }                                                                          \
43     while (0)
44 
45 
46 typedef struct {
47     lxb_char_t *data;
48     size_t     length;
49 }
50 lexbor_str_t;
51 
52 
53 LXB_API lexbor_str_t *
54 lexbor_str_create(void);
55 
56 LXB_API lxb_char_t *
57 lexbor_str_init(lexbor_str_t *str, lexbor_mraw_t *mraw, size_t size);
58 
59 LXB_API lxb_char_t *
60 lexbor_str_init_append(lexbor_str_t *str, lexbor_mraw_t *mraw,
61                        const lxb_char_t *data, size_t length);
62 
63 LXB_API void
64 lexbor_str_clean(lexbor_str_t *str);
65 
66 LXB_API void
67 lexbor_str_clean_all(lexbor_str_t *str);
68 
69 LXB_API lexbor_str_t *
70 lexbor_str_destroy(lexbor_str_t *str, lexbor_mraw_t *mraw, bool destroy_obj);
71 
72 
73 LXB_API lxb_char_t *
74 lexbor_str_realloc(lexbor_str_t *str, lexbor_mraw_t *mraw, size_t new_size);
75 
76 LXB_API lxb_char_t *
77 lexbor_str_check_size(lexbor_str_t *str, lexbor_mraw_t *mraw, size_t plus_len);
78 
79 /* Append */
80 LXB_API lxb_char_t *
81 lexbor_str_append(lexbor_str_t *str, lexbor_mraw_t *mraw,
82                   const lxb_char_t *data, size_t length);
83 
84 LXB_API lxb_char_t *
85 lexbor_str_append_before(lexbor_str_t *str, lexbor_mraw_t *mraw,
86                          const lxb_char_t *buff, size_t length);
87 
88 LXB_API lxb_char_t *
89 lexbor_str_append_one(lexbor_str_t *str, lexbor_mraw_t *mraw,
90                       const lxb_char_t data);
91 
92 LXB_API lxb_char_t *
93 lexbor_str_append_lowercase(lexbor_str_t *str, lexbor_mraw_t *mraw,
94                             const lxb_char_t *data, size_t length);
95 
96 LXB_API lxb_char_t *
97 lexbor_str_append_with_rep_null_chars(lexbor_str_t *str, lexbor_mraw_t *mraw,
98                                       const lxb_char_t *buff, size_t length);
99 
100 /* Other functions */
101 LXB_API lxb_char_t *
102 lexbor_str_copy(lexbor_str_t *dest, const lexbor_str_t *target,
103                 lexbor_mraw_t *mraw);
104 
105 LXB_API void
106 lexbor_str_stay_only_whitespace(lexbor_str_t *target);
107 
108 LXB_API void
109 lexbor_str_strip_collapse_whitespace(lexbor_str_t *target);
110 
111 LXB_API size_t
112 lexbor_str_crop_whitespace_from_begin(lexbor_str_t *target);
113 
114 LXB_API size_t
115 lexbor_str_whitespace_from_begin(lexbor_str_t *target);
116 
117 LXB_API size_t
118 lexbor_str_whitespace_from_end(lexbor_str_t *target);
119 
120 
121 /* Data utils */
122 /*
123  * [in] first: must be null-terminated
124  * [in] sec: no matter what data
125  * [in] sec_size: size of the 'sec' buffer
126  *
127  * Function compare two lxb_char_t data until find '\0' in first arg.
128  * Successfully if the function returned a pointer starting with '\0',
129  * otherwise, if the data of the second buffer is insufficient function returned
130  * position in first buffer.
131  * If function returns NULL, the data are not equal.
132  */
133 LXB_API const lxb_char_t *
134 lexbor_str_data_ncasecmp_first(const lxb_char_t *first, const lxb_char_t *sec,
135                                size_t sec_size);
136 LXB_API bool
137 lexbor_str_data_ncasecmp_end(const lxb_char_t *first, const lxb_char_t *sec,
138                              size_t size);
139 LXB_API bool
140 lexbor_str_data_ncasecmp_contain(const lxb_char_t *where, size_t where_size,
141                                  const lxb_char_t *what, size_t what_size);
142 LXB_API bool
143 lexbor_str_data_ncasecmp(const lxb_char_t *first, const lxb_char_t *sec,
144                          size_t size);
145 LXB_API bool
146 lexbor_str_data_nlocmp_right(const lxb_char_t *first, const lxb_char_t *sec,
147                              size_t size);
148 LXB_API bool
149 lexbor_str_data_nupcmp_right(const lxb_char_t *first, const lxb_char_t *sec,
150                              size_t size);
151 LXB_API bool
152 lexbor_str_data_casecmp(const lxb_char_t *first, const lxb_char_t *sec);
153 
154 LXB_API bool
155 lexbor_str_data_ncmp_end(const lxb_char_t *first, const lxb_char_t *sec,
156                          size_t size);
157 LXB_API bool
158 lexbor_str_data_ncmp_contain(const lxb_char_t *where, size_t where_size,
159                              const lxb_char_t *what, size_t what_size);
160 LXB_API bool
161 lexbor_str_data_ncmp(const lxb_char_t *first, const lxb_char_t *sec,
162                      size_t size);
163 
164 LXB_API bool
165 lexbor_str_data_cmp(const lxb_char_t *first, const lxb_char_t *sec);
166 
167 LXB_API bool
168 lexbor_str_data_cmp_ws(const lxb_char_t *first, const lxb_char_t *sec);
169 
170 LXB_API void
171 lexbor_str_data_to_lowercase(lxb_char_t *to, const lxb_char_t *from, size_t len);
172 
173 LXB_API void
174 lexbor_str_data_to_uppercase(lxb_char_t *to, const lxb_char_t *from, size_t len);
175 
176 LXB_API const lxb_char_t *
177 lexbor_str_data_find_lowercase(const lxb_char_t *data, size_t len);
178 
179 LXB_API const lxb_char_t *
180 lexbor_str_data_find_uppercase(const lxb_char_t *data, size_t len);
181 
182 
183 /*
184  * Inline functions
185  */
186 lxb_inline lxb_char_t *
lexbor_str_data(lexbor_str_t * str)187 lexbor_str_data(lexbor_str_t *str)
188 {
189     return str->data;
190 }
191 
192 lxb_inline size_t
lexbor_str_length(lexbor_str_t * str)193 lexbor_str_length(lexbor_str_t *str)
194 {
195     return str->length;
196 }
197 
198 lxb_inline size_t
lexbor_str_size(lexbor_str_t * str)199 lexbor_str_size(lexbor_str_t *str)
200 {
201     return lexbor_mraw_data_size(str->data);
202 }
203 
204 lxb_inline void
lexbor_str_data_set(lexbor_str_t * str,lxb_char_t * data)205 lexbor_str_data_set(lexbor_str_t *str, lxb_char_t *data)
206 {
207     str->data = data;
208 }
209 
210 lxb_inline lxb_char_t *
lexbor_str_length_set(lexbor_str_t * str,lexbor_mraw_t * mraw,size_t length)211 lexbor_str_length_set(lexbor_str_t *str, lexbor_mraw_t *mraw, size_t length)
212 {
213     if (length >= lexbor_str_size(str)) {
214         lxb_char_t *tmp;
215 
216         tmp = lexbor_str_realloc(str, mraw, length + 1);
217         if (tmp == NULL) {
218             return NULL;
219         }
220     }
221 
222     str->length = length;
223     str->data[length] = 0x00;
224 
225     return str->data;
226 }
227 
228 /*
229  * No inline functions for ABI.
230  */
231 LXB_API lxb_char_t *
232 lexbor_str_data_noi(lexbor_str_t *str);
233 
234 LXB_API size_t
235 lexbor_str_length_noi(lexbor_str_t *str);
236 
237 LXB_API size_t
238 lexbor_str_size_noi(lexbor_str_t *str);
239 
240 LXB_API void
241 lexbor_str_data_set_noi(lexbor_str_t *str, lxb_char_t *data);
242 
243 LXB_API lxb_char_t *
244 lexbor_str_length_set_noi(lexbor_str_t *str, lexbor_mraw_t *mraw,
245                           size_t length);
246 
247 
248 #ifdef __cplusplus
249 } /* extern "C" */
250 #endif
251 
252 #endif /* LEXBOR_STR_H */
253