- use size_t and return 0 on fail
[m6w6/ext-http] / phpstr / phpstr.c
1
2 /* $Id$ */
3
4 #include "php.h"
5 #include "phpstr.h"
6
7 #ifndef PHPSTR_DEFAULT_SIZE
8 #define PHPSTR_DEFAULT_SIZE 256
9 #endif
10
11 PHPSTR_API phpstr *phpstr_init_ex(phpstr *buf, size_t chunk_size, zend_bool pre_alloc)
12 {
13 if (!buf) {
14 buf = ecalloc(1, sizeof(phpstr));
15 }
16
17 buf->size = chunk_size > 0 ? chunk_size : PHPSTR_DEFAULT_SIZE;
18 buf->data = pre_alloc ? emalloc(buf->size) : NULL;
19 buf->free = pre_alloc ? buf->size : 0;
20 buf->used = 0;
21
22 return buf;
23 }
24
25 PHPSTR_API phpstr *phpstr_from_string_ex(phpstr *buf, char *string, size_t length)
26 {
27 buf = phpstr_init(buf);
28 phpstr_append(buf, string, length);
29 return buf;
30 }
31
32 PHPSTR_API void phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size)
33 {
34 if (buf->free < len) {
35 size_t size = override_size ? override_size : buf->size;
36 while ((size + buf->free) < len) {
37 size *= 2;
38 }
39 if (buf->data) {
40 buf->data = erealloc(buf->data, buf->used + buf->free + size);
41 } else {
42 buf->data = emalloc(size);
43 }
44 buf->free += size;
45 }
46 }
47
48 PHPSTR_API void phpstr_append(phpstr *buf, const char *append, size_t append_len)
49 {
50 phpstr_resize(buf, append_len);
51 memcpy(buf->data + buf->used, append, append_len);
52 buf->used += append_len;
53 buf->free -= append_len;
54 }
55
56 PHPSTR_API size_t phpstr_appendf(phpstr *buf, const char *format, ...)
57 {
58 va_list argv;
59 char *append;
60 size_t append_len;
61
62 va_start(argv, format);
63 append_len = vspprintf(&append, 0, format, argv);
64 va_end(argv);
65
66 phpstr_append(buf, append, append_len);
67 efree(append);
68
69 return append_len;
70 }
71
72 PHPSTR_API void phpstr_insert(phpstr *buf, const char *insert, size_t insert_len, size_t offset)
73 {
74 phpstr_resize(buf, insert_len);
75 memmove(buf->data + offset + insert_len, buf->data + offset, insert_len);
76 memcpy(buf->data + offset, insert, insert_len);
77 buf->used += insert_len;
78 buf->free -= insert_len;
79 }
80
81 PHPSTR_API size_t phpstr_insertf(phpstr *buf, size_t offset, const char *format, ...)
82 {
83 va_list argv;
84 char *insert;
85 size_t insert_len;
86
87 va_start(argv, format);
88 insert_len = vspprintf(&insert, 0, format, argv);
89 va_end(argv);
90
91 phpstr_insert(buf, insert, insert_len, offset);
92 efree(insert);
93
94 return insert_len;
95 }
96
97 PHPSTR_API void phpstr_prepend(phpstr *buf, const char *prepend, size_t prepend_len)
98 {
99 phpstr_resize(buf, prepend_len);
100 memmove(buf->data + prepend_len, buf->data, buf->used);
101 memcpy(buf->data, prepend, prepend_len);
102 buf->used += prepend_len;
103 buf->free -= prepend_len;
104 }
105
106 PHPSTR_API size_t phpstr_prependf(phpstr *buf, const char *format, ...)
107 {
108 va_list argv;
109 char *prepend;
110 size_t prepend_len;
111
112 va_start(argv, format);
113 prepend_len = vspprintf(&prepend, 0, format, argv);
114 va_end(argv);
115
116 phpstr_prepend(buf, prepend, prepend_len);
117 efree(prepend);
118
119 return prepend_len;
120 }
121
122 PHPSTR_API char *phpstr_data(const phpstr *buf, char **into, size_t *len)
123 {
124 char *copy = ecalloc(1, buf->used + 1);
125 memcpy(copy, buf->data, buf->used);
126 if (into) {
127 *into = copy;
128 }
129 if (len) {
130 *len = buf->used;
131 }
132 return copy;
133 }
134
135 PHPSTR_API phpstr *phpstr_dup(const phpstr *buf)
136 {
137 phpstr *dup = phpstr_clone(buf);
138 phpstr_append(dup, buf->data, buf->used);
139 return dup;
140 }
141
142 PHPSTR_API size_t phpstr_cut(phpstr *buf, size_t offset, size_t length)
143 {
144 if (offset >= buf->used) {
145 return 0;
146 }
147 if (offset + length > buf->used) {
148 length = buf->used - offset;
149 }
150 memmove(buf->data + offset, buf->data + offset + length, buf->used - length);
151 buf->used -= length;
152 buf->free += length;
153 return length;
154 }
155
156 PHPSTR_API phpstr *phpstr_sub(const phpstr *buf, size_t offset, size_t length)
157 {
158 if (offset >= buf->used) {
159 return NULL;
160 } else {
161 size_t need = (length + offset) > buf->used ? (buf->used - offset) : (length - offset);
162 phpstr *sub = phpstr_init_ex(NULL, need, 1);
163 phpstr_append(sub, buf->data + offset, need);
164 sub->size = buf->size;
165 return sub;
166 }
167 }
168
169 PHPSTR_API phpstr *phpstr_right(const phpstr *buf, size_t length)
170 {
171 if (length < buf->used) {
172 return phpstr_sub(buf, buf->used - length, length);
173 } else {
174 return phpstr_sub(buf, 0, buf->used);
175 }
176 }
177
178
179 PHPSTR_API phpstr *phpstr_merge_va(phpstr *buf, unsigned argc, va_list argv)
180 {
181 unsigned i = 0;
182 buf = phpstr_init(buf);
183
184 while (argc > i++) {
185 phpstr_free_t f = va_arg(argv, phpstr_free_t);
186 phpstr *current = va_arg(argv, phpstr *);
187 phpstr_append(buf, current->data, current->used);
188 FREE_PHPSTR(f, current);
189 }
190
191 return buf;
192 }
193
194 PHPSTR_API phpstr *phpstr_merge_ex(phpstr *buf, unsigned argc, ...)
195 {
196 va_list argv;
197 phpstr *ret;
198
199 va_start(argv, argc);
200 ret = phpstr_merge_va(buf, argc, argv);
201 va_end(argv);
202 return ret;
203 }
204
205 PHPSTR_API phpstr *phpstr_merge(unsigned argc, ...)
206 {
207 va_list argv;
208 phpstr *ret;
209
210 va_start(argv, argc);
211 ret = phpstr_merge_va(NULL, argc, argv);
212 va_end(argv);
213 return ret;
214 }
215
216 PHPSTR_API void phpstr_fix(phpstr *buf)
217 {
218 phpstr_resize_ex(buf, 1, 1);
219 buf->data[buf->used] = '\0';
220 }
221
222 PHPSTR_API int phpstr_cmp(phpstr *left, phpstr *right)
223 {
224 if (left->used > right->used) {
225 return -1;
226 } else if (right->used > left->used) {
227 return 1;
228 } else {
229 return memcmp(left->data, right->data, left->used);
230 }
231 }
232
233 PHPSTR_API void phpstr_dtor(phpstr *buf)
234 {
235 if (buf->data) {
236 efree(buf->data);
237 buf->data = NULL;
238 }
239 buf->used = 0;
240 buf->free = 0;
241 }
242
243 PHPSTR_API void phpstr_free(phpstr *buf)
244 {
245 if (buf) {
246 phpstr_dtor(buf);
247 efree(buf);
248 }
249 }
250
251 /*
252 * Local variables:
253 * tab-width: 4
254 * c-basic-offset: 4
255 * End:
256 * vim600: sw=4 ts=4 fdm=marker
257 * vim<600: sw=4 ts=4
258 */
259