1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | http://www.php.net/license/3_01.txt                                  |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Author: Israel Ekpo <iekpo@php.net>                                  |
14    +----------------------------------------------------------------------+
15 */
16 
17 #include "php_solr.h"
18 
19 /* {{{ static inline void solr_string_alloc(solr_string_t *dest, size_t length, size_t *new_length SOLR_MEM_DEBUG_DC) */
solr_string_alloc(solr_string_t * dest,size_t length,size_t * new_length SOLR_MEM_DEBUG_DC)20 static inline void solr_string_alloc(solr_string_t *dest, size_t length, size_t *new_length SOLR_MEM_DEBUG_DC)
21 {
22 	/* If buffer is empty */
23 	if (!dest->str)
24 	{
25 		(*new_length) = length;
26 
27 		dest->cap     = ((*new_length) < SOLR_STRING_START_SIZE) ? SOLR_STRING_START_SIZE : (length + SOLR_STRING_INCREMENT_SIZE);
28 		dest->str     = (solr_char_t *) perealloc(dest->str, dest->cap * sizeof(solr_char_t), SOLR_STRING_PERSISTENT);
29 
30 	} else {
31 
32 		(*new_length) = dest->len + length;
33 
34 		/* If the buffer full, get more space */
35 		if ((*new_length) >= dest->cap)
36 		{
37 			dest->cap = (*new_length) + SOLR_STRING_INCREMENT_SIZE;
38 
39 			dest->str = (solr_char_t *) perealloc(dest->str, dest->cap * sizeof(solr_char_t), SOLR_STRING_PERSISTENT);
40 		}
41 	}
42 
43 #ifdef SOLR_MEM_DEBUG
44 
45 php_printf("solr_string_alloc() [Re]allocated %u bytes at %p in %s(), %s Line %d \n", dest->cap, dest->str SOLR_MEM_DEBUG_CC);
46 
47 #endif
48 
49 }
50 /* }}} */
51 
52 /* {{{ PHP_SOLR_API void solr_string_appends(solr_string_t *dest, const solr_char_t *src, size_t length SOLR_MEM_DEBUG_DC) */
solr_string_appends_ex(solr_string_t * dest,const solr_char_t * src,size_t length SOLR_MEM_DEBUG_DC)53 PHP_SOLR_API void solr_string_appends_ex(solr_string_t *dest, const solr_char_t *src, size_t length SOLR_MEM_DEBUG_DC)
54 {
55 	auto size_t __new_length = 0U;
56 
57 	/* (Re)allocates memory and increases the capacity if necessary */
58 	solr_string_alloc(dest, length, &__new_length SOLR_MEM_DEBUG_CC);
59 
60 	/* Copy the data from the source to the destination */
61 	memcpy(dest->str + dest->len, src, length);
62 
63 	/* Reset the length of the solr_string to the new value */
64 	dest->len = __new_length;
65 
66 	/* Always make it a null-terminated string */
67 	dest->str[__new_length] = (solr_char_t) 0x00;
68 }
69 /* }}} */
70 
71 /* {{{ PHP_SOLR_API void solr_string_appendc(solr_string_t *dest, solr_char_t ch SOLR_MEM_DEBUG_DC) */
solr_string_appendc_ex(solr_string_t * dest,solr_char_t ch SOLR_MEM_DEBUG_DC)72 PHP_SOLR_API void solr_string_appendc_ex(solr_string_t *dest, solr_char_t ch SOLR_MEM_DEBUG_DC)
73 {
74 	auto size_t __new_length = 0U;
75 
76 	/* (Re)allocates memory and increases the capacity if necessary */
77 	solr_string_alloc(dest, 1, &__new_length SOLR_MEM_DEBUG_CC);
78 
79 	dest->str[dest->len] = ch;
80 
81 	/* Reset the length of the solr_string to the new value (dest->len + 1) */
82 	dest->len = __new_length;
83 
84 	/* Always make it a null-terminated string */
85 	dest->str[__new_length] = (solr_char_t) 0x00;
86 }
87 /* }}} */
88 
89 /* {{{ PHP_SOLR_API void solr_string_remove_last_char(solr_string_t *dest) */
solr_string_remove_last_char(solr_string_t * dest)90 PHP_SOLR_API void solr_string_remove_last_char(solr_string_t *dest)
91 {
92 	if (dest->str && dest->len)
93 	{
94 		dest->str[dest->len - 1] = (solr_char_t) 0x00;
95 
96 		dest->len--;
97 	}
98 }
99 /* }}} */
100 
101 /* {{{ PHP_SOLR_API void solr_string_append_long(solr_string_t *dest, long int long_val) */
solr_string_append_long_ex(solr_string_t * dest,long int long_val SOLR_MEM_DEBUG_DC)102 PHP_SOLR_API void solr_string_append_long_ex(solr_string_t *dest, long int long_val SOLR_MEM_DEBUG_DC)
103 {
104 	auto size_t __new_length = 0U;
105 	auto char tmp_buffer[SOLR_STRING_LONG_BUFFER_SIZE];
106 	size_t length = 0;
107 
108 	/* Write the formated long to the buffer */
109 	php_sprintf(tmp_buffer, "%ld", long_val);
110 
111 	length = strlen(tmp_buffer);
112 
113 	/* (Re)allocates memory and increases the capacity if necessary */
114 	solr_string_alloc(dest, length, &__new_length SOLR_MEM_DEBUG_CC);
115 
116 	/* Copy the data from the source to the destination */
117 	memcpy(dest->str + dest->len, tmp_buffer, length);
118 
119 	/* Reset the length of the solr_string to the new value */
120 	dest->len = __new_length;
121 
122 	/* Always make it a null-terminated string */
123 	dest->str[__new_length] = (solr_char_t) 0x00;
124 }
125 /* }}} */
126 
127 /* {{{ PHP_SOLR_API void solr_string_append_unsigned_long(solr_string_t *dest, unsigned long int long_val) */
solr_string_append_unsigned_long_ex(solr_string_t * dest,unsigned long int long_val SOLR_MEM_DEBUG_DC)128 PHP_SOLR_API void solr_string_append_unsigned_long_ex(solr_string_t *dest, unsigned long int long_val SOLR_MEM_DEBUG_DC)
129 {
130 	auto size_t __new_length = 0U;
131 	auto char tmp_buffer[SOLR_STRING_UNSIGNED_LONG_BUFFER_SIZE];
132 	size_t length = 0;
133 
134 	/* Write the formated unsigned long to the buffer */
135 	php_sprintf(tmp_buffer, "%lu", long_val);
136 
137 	length = strlen(tmp_buffer);
138 
139 	/* (Re)allocates memory and increases the capacity if necessary */
140 	solr_string_alloc(dest, length, &__new_length SOLR_MEM_DEBUG_CC);
141 
142 	/* Copy the data from the source to the destination */
143 	memcpy(dest->str + dest->len, tmp_buffer, length);
144 
145 	/* Reset the length of the solr_string to the new value */
146 	dest->len = __new_length;
147 
148 	/* Always make it a null-terminated string */
149 	dest->str[__new_length] = (solr_char_t) 0x00;
150 }
151 /* }}} */
152 
153 /**
154  * Checks if both strings are equal OR have same exact content.
155  *
156  * Returns 1 if they are equal, 0 if they are different.
157  */
158 /* {{{ PHP_SOLR_API int solr_string_equal(const solr_string_t *a, const solr_string_t *b) */
solr_string_equal(const solr_string_t * a,const solr_string_t * b)159 PHP_SOLR_API int solr_string_equal(const solr_string_t *a, const solr_string_t *b)
160 {
161 	const solr_char_t *str1 = a->str;
162 	const solr_char_t *str2 = b->str;
163 
164 	if (str1 == str2) return 1;
165     if (str1 == NULL) return 0;
166     if (str2 == NULL) return 0;
167 
168     do {
169 
170         if (*str1++ != *str2) return(0);
171 
172     } while (*str2++);
173 
174     return 1;
175 }
176 /* }}} */
177 
178 /* Deallocates memory for the buffer */
179 /* {{{ PHP_SOLR_API void solr_string_free(solr_string_t *dest SOLR_MEM_DEBUG_DC) */
solr_string_free_ex(solr_string_t * dest SOLR_MEM_DEBUG_DC)180 PHP_SOLR_API void solr_string_free_ex(solr_string_t *dest SOLR_MEM_DEBUG_DC)
181 {
182 	/* Only attempt this if the buffer is still valid */
183 	if (dest->str)
184 	{
185 
186 #ifdef SOLR_MEM_DEBUG
187 
188 php_printf("solr_string_free_ex() Releasing %u bytes at %p in %s(), %s Line %d \n", dest->cap, dest->str SOLR_MEM_DEBUG_CC);
189 
190 #endif
191 		pefree(dest->str, SOLR_STRING_PERSISTENT);
192 
193 		dest->str = (solr_char_t *) 0x00;
194 
195 		dest->cap = dest->len = 0U;
196 	}
197 }
198 /* }}} */
199 
solr_destory_solr_string_zv(zval * solr_string_zv)200 PHP_SOLR_API void solr_destory_solr_string_zv(zval *solr_string_zv)
201 {
202     solr_string_t *string = (solr_string_t *) Z_PTR_P(solr_string_zv);
203     solr_string_free_ex(string);
204     pefree(string, SOLR_STRING_PERSISTENT);
205 }
206 
207 /* Update the contents of the dest solr_string */
208 /* {{{ PHP_SOLR_API void solr_string_set(solr_string_t *dest, const solr_char_t *value, size_t length SOLR_MEM_DEBUG_DC) */
solr_string_set_ex(solr_string_t * dest,const solr_char_t * value,size_t length SOLR_MEM_DEBUG_DC)209 PHP_SOLR_API void solr_string_set_ex(solr_string_t *dest, const solr_char_t *value, size_t length SOLR_MEM_DEBUG_DC)
210 {
211 	solr_string_free(dest);
212 
213 	solr_string_appends(dest, value, length);
214 }
215 /* }}} */
216 
217 /*
218  * Local variables:
219  * tab-width: 4
220  * c-basic-offset: 4
221  * End:
222  * vim600: fdm=marker
223  * vim: noet sw=4 ts=4
224  */
225