Back to index

php5  5.3.10
php_smart_str.h
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Sascha Schumann <sascha@schumann.cx>                         |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: php_smart_str.h 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #ifndef PHP_SMART_STR_H
00022 #define PHP_SMART_STR_H
00023 
00024 #include "php_smart_str_public.h"
00025 
00026 #include <stdlib.h>
00027 #ifndef SMART_STR_USE_REALLOC
00028 #include <zend.h>
00029 #endif
00030 
00031 #define smart_str_0(x) do {                                                                       \
00032        if ((x)->c) {                                                                                     \
00033               (x)->c[(x)->len] = '\0';                                                            \
00034        }                                                                                                               \
00035 } while (0)
00036 
00037 #ifndef SMART_STR_PREALLOC
00038 #define SMART_STR_PREALLOC 128
00039 #endif
00040 
00041 #ifndef SMART_STR_START_SIZE
00042 #define SMART_STR_START_SIZE 78
00043 #endif
00044 
00045 #ifdef SMART_STR_USE_REALLOC
00046 #define SMART_STR_REALLOC(a,b,c) realloc((a),(b))
00047 #else
00048 #define SMART_STR_REALLOC(a,b,c) perealloc((a),(b),(c))
00049 #endif
00050 
00051 #define SMART_STR_DO_REALLOC(d, what) \
00052        (d)->c = SMART_STR_REALLOC((d)->c, (d)->a + 1, (what))
00053 
00054 #define smart_str_alloc4(d, n, what, newlen) do {                                   \
00055        if (!(d)->c) {                                                                                           \
00056               (d)->len = 0;                                                                              \
00057               newlen = (n);                                                                              \
00058               (d)->a = newlen < SMART_STR_START_SIZE                                       \
00059                             ? SMART_STR_START_SIZE                                                       \
00060                             : newlen + SMART_STR_PREALLOC;                                        \
00061               SMART_STR_DO_REALLOC(d, what);                                                      \
00062        } else {                                                                                                 \
00063               newlen = (d)->len + (n);                                                            \
00064               if (newlen >= (d)->a) {                                                                    \
00065                      (d)->a = newlen + SMART_STR_PREALLOC;                                 \
00066                      SMART_STR_DO_REALLOC(d, what);                                               \
00067               }                                                                                                        \
00068        }                                                                                                               \
00069 } while (0)
00070 
00071 #define smart_str_alloc(d, n, what) \
00072        smart_str_alloc4((d), (n), (what), newlen)
00073 
00074 /* wrapper */
00075 
00076 #define smart_str_appends_ex(dest, src, what) \
00077        smart_str_appendl_ex((dest), (src), strlen(src), (what))
00078 #define smart_str_appends(dest, src) \
00079        smart_str_appendl((dest), (src), strlen(src))
00080 
00081 #define smart_str_appendc(dest, c) \
00082        smart_str_appendc_ex((dest), (c), 0)
00083 #define smart_str_free(s) \
00084        smart_str_free_ex((s), 0)
00085 #define smart_str_appendl(dest, src, len) \
00086        smart_str_appendl_ex((dest), (src), (len), 0)
00087 #define smart_str_append(dest, src) \
00088        smart_str_append_ex((dest), (src), 0)
00089 #define smart_str_append_long(dest, val) \
00090        smart_str_append_long_ex((dest), (val), 0)
00091 #define smart_str_append_off_t(dest, val) \
00092        smart_str_append_off_t_ex((dest), (val), 0)
00093 #define smart_str_append_unsigned(dest, val) \
00094        smart_str_append_unsigned_ex((dest), (val), 0)
00095 
00096 #define smart_str_appendc_ex(dest, ch, what) do {                                   \
00097        register size_t __nl;                                                                             \
00098        smart_str_alloc4((dest), 1, (what), __nl);                                          \
00099        (dest)->len = __nl;                                                                               \
00100        ((unsigned char *) (dest)->c)[(dest)->len - 1] = (ch);                \
00101 } while (0)
00102 
00103 #define smart_str_free_ex(s, what) do {                                                    \
00104        smart_str *__s = (smart_str *) (s);                                                        \
00105        if (__s->c) {                                                                                     \
00106               pefree(__s->c, what);                                                                      \
00107               __s->c = NULL;                                                                                    \
00108        }                                                                                                               \
00109        __s->a = __s->len = 0;                                                                            \
00110 } while (0)
00111 
00112 #define smart_str_appendl_ex(dest, src, nlen, what) do {                     \
00113        register size_t __nl;                                                                             \
00114        smart_str *__dest = (smart_str *) (dest);                                    \
00115                                                                                                                        \
00116        smart_str_alloc4(__dest, (nlen), (what), __nl);                              \
00117        memcpy(__dest->c + __dest->len, (src), (nlen));                              \
00118        __dest->len = __nl;                                                                               \
00119 } while (0)
00120 
00121 /* input: buf points to the END of the buffer */
00122 #define smart_str_print_unsigned4(buf, num, vartype, result) do {     \
00123        char *__p = (buf);                                                                                \
00124        vartype __num = (num);                                                                            \
00125        *__p = '\0';                                                                                      \
00126        do {                                                                                                     \
00127               *--__p = (char) (__num % 10) + '0';                                                 \
00128               __num /= 10;                                                                               \
00129        } while (__num > 0);                                                                       \
00130        result = __p;                                                                                     \
00131 } while (0)
00132 
00133 /* buf points to the END of the buffer */
00134 #define smart_str_print_long4(buf, num, vartype, result) do {  \
00135        if (num < 0) {                                                                                           \
00136               /* this might cause problems when dealing with LONG_MIN        \
00137                  and machines which don't support long long.  Works          \
00138                  flawlessly on 32bit x86 */                                                       \
00139               smart_str_print_unsigned4((buf), -(num), vartype, (result));   \
00140               *--(result) = '-';                                                                         \
00141        } else {                                                                                                 \
00142               smart_str_print_unsigned4((buf), (num), vartype, (result));    \
00143        }                                                                                                               \
00144 } while (0)
00145 
00146 /*
00147  * these could be replaced using a braced-group inside an expression
00148  * for GCC compatible compilers, e.g.
00149  *
00150  * #define f(..) ({char *r;..;__r;})
00151  */  
00152  
00153 static inline char *smart_str_print_long(char *buf, long num) {
00154        char *r; 
00155        smart_str_print_long4(buf, num, unsigned long, r); 
00156        return r;
00157 }
00158 
00159 static inline char *smart_str_print_unsigned(char *buf, long num) {
00160        char *r; 
00161        smart_str_print_unsigned4(buf, num, unsigned long, r); 
00162        return r;
00163 }
00164 
00165 #define smart_str_append_generic_ex(dest, num, type, vartype, func) do {     \
00166        char __b[32];                                                                                                   \
00167        char *__t;                                                                                                             \
00168        smart_str_print##func##4 (__b + sizeof(__b) - 1, (num), vartype, __t);       \
00169        smart_str_appendl_ex((dest), __t, __b + sizeof(__b) - 1 - __t, (type));      \
00170 } while (0)
00171        
00172 #define smart_str_append_unsigned_ex(dest, num, type) \
00173        smart_str_append_generic_ex((dest), (num), (type), unsigned long, _unsigned)
00174 
00175 #define smart_str_append_long_ex(dest, num, type) \
00176        smart_str_append_generic_ex((dest), (num), (type), unsigned long, _long)
00177 
00178 #define smart_str_append_off_t_ex(dest, num, type) \
00179        smart_str_append_generic_ex((dest), (num), (type), off_t, _long)
00180 
00181 #define smart_str_append_ex(dest, src, what) \
00182        smart_str_appendl_ex((dest), ((smart_str *)(src))->c, \
00183               ((smart_str *)(src))->len, (what));
00184 
00185 
00186 #define smart_str_setl(dest, src, nlen) do {                                        \
00187        (dest)->len = (nlen);                                                                             \
00188        (dest)->a = (nlen) + 1;                                                                           \
00189        (dest)->c = (char *) (src);                                                                \
00190 } while (0)
00191 
00192 #define smart_str_sets(dest, src) \
00193        smart_str_setl((dest), (src), strlen(src));
00194 
00195 #endif