1 /* 2 +----------------------------------------------------------------------+ 3 | PHP Version 7 | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1997-2018 The PHP Group | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 3.01 of the PHP license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | http://www.php.net/license/3_01.txt | 11 | If you did not receive a copy of the PHP license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@php.net so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 | Author: Sascha Schumann <sascha@schumann.cx> | 16 | Xinchen Hui <laruence@php.net> | 17 +----------------------------------------------------------------------+ 18 */ 19 20 /* $Id$ */ 21 22 #ifndef PHP_SMART_STRING_H 23 #define PHP_SMART_STRING_H 24 25 #include "php_smart_string_public.h" 26 27 #include <stdlib.h> 28 #ifndef SMART_STR_USE_REALLOC 29 #include <zend.h> 30 #endif 31 32 #define smart_string_0(x) do { \ 33 if ((x)->c) { \ 34 (x)->c[(x)->len] = '\0'; \ 35 } \ 36 } while (0) 37 38 #ifndef SMART_STRING_PREALLOC 39 #define SMART_STRING_PREALLOC 128 40 #endif 41 42 #ifndef SMART_STRING_START_SIZE 43 #define SMART_STRING_START_SIZE 78 44 #endif 45 46 #ifdef SMART_STRING_USE_REALLOC 47 #define SMART_STRING_REALLOC(a,b,c) realloc((a),(b)) 48 #else 49 #define SMART_STRING_REALLOC(a,b,c) perealloc((a),(b),(c)) 50 #endif 51 52 #define SMART_STRING_DO_REALLOC(d, what) \ 53 (d)->c = (char *) SMART_STRING_REALLOC((d)->c, (d)->a + 1, (what)) 54 55 #define smart_string_alloc4(d, n, what, newlen) do { \ 56 if (!(d)->c) { \ 57 (d)->len = 0; \ 58 newlen = (n); \ 59 (d)->a = newlen < SMART_STRING_START_SIZE \ 60 ? SMART_STRING_START_SIZE \ 61 : newlen + SMART_STRING_PREALLOC; \ 62 SMART_STRING_DO_REALLOC(d, what); \ 63 } else { \ 64 if(UNEXPECTED((size_t)n > SIZE_MAX - (d)->len)) { \ 65 zend_error(E_ERROR, "String size overflow"); \ 66 } \ 67 newlen = (d)->len + (n); \ 68 if (newlen >= (d)->a) { \ 69 (d)->a = newlen + SMART_STRING_PREALLOC; \ 70 SMART_STRING_DO_REALLOC(d, what); \ 71 } \ 72 } \ 73 } while (0) 74 75 #define smart_string_alloc(d, n, what) \ 76 smart_string_alloc4((d), (n), (what), newlen) 77 78 /* wrapper */ 79 80 #define smart_string_appends_ex(dest, src, what) \ 81 smart_string_appendl_ex((dest), (src), strlen(src), (what)) 82 #define smart_string_appends(dest, src) \ 83 smart_string_appendl((dest), (src), strlen(src)) 84 85 #define smart_string_appendc(dest, c) \ 86 smart_string_appendc_ex((dest), (c), 0) 87 #define smart_string_free(s) \ 88 smart_string_free_ex((s), 0) 89 #define smart_string_appendl(dest, src, len) \ 90 smart_string_appendl_ex((dest), (src), (len), 0) 91 #define smart_string_append(dest, src) \ 92 smart_string_append_ex((dest), (src), 0) 93 #define smart_string_append_long(dest, val) \ 94 smart_string_append_long_ex((dest), (val), 0) 95 #define smart_string_append_unsigned(dest, val) \ 96 smart_string_append_unsigned_ex((dest), (val), 0) 97 98 #define smart_string_appendc_ex(dest, ch, what) do { \ 99 size_t __nl; \ 100 smart_string_alloc4((dest), 1, (what), __nl); \ 101 (dest)->len = __nl; \ 102 ((unsigned char *) (dest)->c)[(dest)->len - 1] = (ch); \ 103 } while (0) 104 105 #define smart_string_free_ex(s, what) do { \ 106 smart_string *__s = (smart_string *) (s); \ 107 if (__s->c) { \ 108 pefree(__s->c, what); \ 109 __s->c = NULL; \ 110 } \ 111 __s->a = __s->len = 0; \ 112 } while (0) 113 114 #define smart_string_appendl_ex(dest, src, nlen, what) do { \ 115 size_t __nl; \ 116 smart_string *__dest = (smart_string *) (dest); \ 117 \ 118 smart_string_alloc4(__dest, (nlen), (what), __nl); \ 119 memcpy(__dest->c + __dest->len, (src), (nlen)); \ 120 __dest->len = __nl; \ 121 } while (0) 122 123 #define smart_string_append_generic_ex(dest, num, type, vartype, func) do { \ 124 char __b[32]; \ 125 char *__t = zend_print##func##_to_buf(__b + sizeof(__b) - 1, (num)); \ 126 smart_string_appendl_ex((dest), __t, __b + sizeof(__b) - 1 - __t, (type)); \ 127 } while (0) 128 129 #define smart_string_append_unsigned_ex(dest, num, type) \ 130 smart_string_append_generic_ex((dest), (num), (type), zend_ulong, _ulong) 131 132 #define smart_string_append_long_ex(dest, num, type) \ 133 smart_string_append_generic_ex((dest), (num), (type), zend_ulong, _long) 134 135 #define smart_string_append_ex(dest, src, what) \ 136 smart_string_appendl_ex((dest), ((smart_string *)(src))->c, \ 137 ((smart_string *)(src))->len, (what)); 138 139 140 #define smart_string_setl(dest, src, nlen) do { \ 141 (dest)->len = (nlen); \ 142 (dest)->a = (nlen) + 1; \ 143 (dest)->c = (char *) (src); \ 144 } while (0) 145 146 #define smart_string_sets(dest, src) \ 147 smart_string_setl((dest), (src), strlen(src)); 148 149 #endif 150