7 #ifndef PHPSTR_DEFAULT_SIZE
8 #define PHPSTR_DEFAULT_SIZE 256
11 PHPSTR_API phpstr
*phpstr_init_ex(phpstr
*buf
, size_t chunk_size
, zend_bool pre_alloc
)
14 buf
= emalloc(sizeof(phpstr
));
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;
25 PHPSTR_API phpstr
*phpstr_from_string_ex(phpstr
*buf
, const char *string
, size_t length
)
27 buf
= phpstr_init(buf
);
28 phpstr_append(buf
, string
, length
);
32 PHPSTR_API
void phpstr_resize_ex(phpstr
*buf
, size_t len
, size_t override_size
)
34 if (buf
->free
< len
) {
35 size_t size
= override_size
? override_size
: buf
->size
;
36 while ((size
+ buf
->free
) < len
) {
40 buf
->data
= erealloc(buf
->data
, buf
->used
+ buf
->free
+ size
);
42 buf
->data
= emalloc(size
);
48 PHPSTR_API
size_t phpstr_append(phpstr
*buf
, const char *append
, size_t append_len
)
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
;
57 PHPSTR_API
size_t phpstr_appendf(phpstr
*buf
, const char *format
, ...)
63 va_start(argv
, format
);
64 append_len
= vspprintf(&append
, 0, format
, argv
);
67 phpstr_append(buf
, append
, append_len
);
73 PHPSTR_API
size_t phpstr_insert(phpstr
*buf
, const char *insert
, size_t insert_len
, size_t offset
)
75 phpstr_resize(buf
, insert_len
);
76 memmove(buf
->data
+ offset
+ insert_len
, buf
->data
+ offset
, insert_len
);
77 memcpy(buf
->data
+ offset
, insert
, insert_len
);
78 buf
->used
+= insert_len
;
79 buf
->free
-= insert_len
;
83 PHPSTR_API
size_t phpstr_insertf(phpstr
*buf
, size_t offset
, const char *format
, ...)
89 va_start(argv
, format
);
90 insert_len
= vspprintf(&insert
, 0, format
, argv
);
93 phpstr_insert(buf
, insert
, insert_len
, offset
);
99 PHPSTR_API
size_t phpstr_prepend(phpstr
*buf
, const char *prepend
, size_t prepend_len
)
101 phpstr_resize(buf
, prepend_len
);
102 memmove(buf
->data
+ prepend_len
, buf
->data
, buf
->used
);
103 memcpy(buf
->data
, prepend
, prepend_len
);
104 buf
->used
+= prepend_len
;
105 buf
->free
-= prepend_len
;
109 PHPSTR_API
size_t phpstr_prependf(phpstr
*buf
, const char *format
, ...)
115 va_start(argv
, format
);
116 prepend_len
= vspprintf(&prepend
, 0, format
, argv
);
119 phpstr_prepend(buf
, prepend
, prepend_len
);
125 PHPSTR_API
char *phpstr_data(const phpstr
*buf
, char **into
, size_t *len
)
127 char *copy
= ecalloc(1, buf
->used
+ 1);
128 memcpy(copy
, buf
->data
, buf
->used
);
138 PHPSTR_API phpstr
*phpstr_dup(const phpstr
*buf
)
140 phpstr
*dup
= phpstr_clone(buf
);
141 phpstr_append(dup
, buf
->data
, buf
->used
);
145 PHPSTR_API
size_t phpstr_cut(phpstr
*buf
, size_t offset
, size_t length
)
147 if (offset
>= buf
->used
) {
150 if (offset
+ length
> buf
->used
) {
151 length
= buf
->used
- offset
;
153 memmove(buf
->data
+ offset
, buf
->data
+ offset
+ length
, buf
->used
- length
);
159 PHPSTR_API phpstr
*phpstr_sub(const phpstr
*buf
, size_t offset
, size_t length
)
161 if (offset
>= buf
->used
) {
164 size_t need
= (length
+ offset
) > buf
->used
? (buf
->used
- offset
) : (length
- offset
);
165 phpstr
*sub
= phpstr_init_ex(NULL
, need
, 1);
166 phpstr_append(sub
, buf
->data
+ offset
, need
);
167 sub
->size
= buf
->size
;
172 PHPSTR_API phpstr
*phpstr_right(const phpstr
*buf
, size_t length
)
174 if (length
< buf
->used
) {
175 return phpstr_sub(buf
, buf
->used
- length
, length
);
177 return phpstr_sub(buf
, 0, buf
->used
);
182 PHPSTR_API phpstr
*phpstr_merge_va(phpstr
*buf
, unsigned argc
, va_list argv
)
185 buf
= phpstr_init(buf
);
188 phpstr_free_t f
= va_arg(argv
, phpstr_free_t
);
189 phpstr
*current
= va_arg(argv
, phpstr
*);
190 phpstr_append(buf
, current
->data
, current
->used
);
191 FREE_PHPSTR(f
, current
);
197 PHPSTR_API phpstr
*phpstr_merge_ex(phpstr
*buf
, unsigned argc
, ...)
202 va_start(argv
, argc
);
203 ret
= phpstr_merge_va(buf
, argc
, argv
);
208 PHPSTR_API phpstr
*phpstr_merge(unsigned argc
, ...)
213 va_start(argv
, argc
);
214 ret
= phpstr_merge_va(NULL
, argc
, argv
);
219 PHPSTR_API
void phpstr_fix(phpstr
*buf
)
221 phpstr_resize_ex(buf
, 1, 1);
222 buf
->data
[buf
->used
] = '\0';
225 PHPSTR_API
int phpstr_cmp(phpstr
*left
, phpstr
*right
)
227 if (left
->used
> right
->used
) {
229 } else if (right
->used
> left
->used
) {
232 return memcmp(left
->data
, right
->data
, left
->used
);
236 PHPSTR_API
void phpstr_dtor(phpstr
*buf
)
246 PHPSTR_API
void phpstr_free(phpstr
*buf
)
259 * vim600: sw=4 ts=4 fdm=marker