]> granicus.if.org Git - php/commitdiff
Convert serializer to smart_str.. avoids lots of sprintf's and
authorSascha Schumann <sas@php.net>
Fri, 3 Aug 2001 07:25:27 +0000 (07:25 +0000)
committerSascha Schumann <sas@php.net>
Fri, 3 Aug 2001 07:25:27 +0000 (07:25 +0000)
copying of data.

ext/session/session.c
ext/standard/php_smart_str.h
ext/standard/php_var.h
ext/standard/var.c
ext/sysvshm/sysvshm.c

index 1212cefb2a2f96c27d5d8665fbf20a4486768234..ab491a96b3cd42c25ac4b8d3be47f3aad9a7194d 100644 (file)
@@ -279,36 +279,26 @@ int php_get_session_var(char *name, size_t namelen, zval ***state_var TSRMLS_DC)
 
 PS_SERIALIZER_ENCODE_FUNC(php_binary)
 {
-       zval *buf;
-       unsigned char strbuf[MAX_STR + 1];
+       smart_str buf = {0};
        php_serialize_data_t var_hash;
        PS_ENCODE_VARS;
 
-
-       buf = ecalloc(sizeof(*buf), 1);
-       Z_TYPE_P(buf) = IS_STRING;
-       buf->refcount++;
-
        PHP_VAR_SERIALIZE_INIT(var_hash);
 
        PS_ENCODE_LOOP(
                        if (key_length > PS_BIN_MAX) continue;
-                       strbuf[0] = (unsigned char) key_length;
-                       memcpy(strbuf + 1, key, key_length);
+                       smart_str_appendc(&buf, key_length);
+                       smart_str_appendl(&buf, key, key_length);
                        
-                       STR_CAT(buf, strbuf, key_length + 1);
-                       php_var_serialize(buf, struc, &var_hash);
+                       php_var_serialize(&buf, struc, &var_hash);
                } else {
                        if (key_length > PS_BIN_MAX) continue;
-                       strbuf[0] = (unsigned char) (key_length & PS_BIN_UNDEF);
-                       memcpy(strbuf + 1, key, key_length);
-                       
-                       STR_CAT(buf, strbuf, key_length + 1);
+                       smart_str_appendc(&buf, (key_length & PS_BIN_UNDEF));
+                       smart_str_appendl(&buf, key, key_length);
        );
 
-       if (newlen) *newlen = Z_STRLEN_P(buf);
-       *newstr = Z_STRVAL_P(buf);
-       efree(buf);
+       if (newlen) *newlen = buf.len;
+       *newstr = buf.c;
        PHP_VAR_SERIALIZE_DESTROY(var_hash);
 
        return SUCCESS;
@@ -355,36 +345,27 @@ PS_SERIALIZER_DECODE_FUNC(php_binary)
 
 PS_SERIALIZER_ENCODE_FUNC(php)
 {
-       zval *buf;
-       char strbuf[MAX_STR + 1];
+       smart_str buf = {0};
        php_serialize_data_t var_hash;
        PS_ENCODE_VARS;
 
-       buf = ecalloc(sizeof(*buf), 1);
-       Z_TYPE_P(buf) = IS_STRING;
-       buf->refcount++;
-
        PHP_VAR_SERIALIZE_INIT(var_hash);
 
        PS_ENCODE_LOOP(
                        if (key_length + 1 > MAX_STR) continue;
-                       memcpy(strbuf, key, key_length);
-                       strbuf[key_length] = PS_DELIMITER;
-                       STR_CAT(buf, strbuf, key_length + 1);
+                       smart_str_appendl(&buf, key, key_length);
+                       smart_str_appendc(&buf, PS_DELIMITER);
                        
-                       php_var_serialize(buf, struc, &var_hash);
+                       php_var_serialize(&buf, struc, &var_hash);
                } else {
                        if (key_length + 2 > MAX_STR) continue;
-                       strbuf[0] = PS_UNDEF_MARKER;
-                       memcpy(strbuf + 1, key, key_length);
-                       strbuf[key_length + 1] = PS_DELIMITER;
-                       
-                       STR_CAT(buf, strbuf, key_length + 2);
+                       smart_str_appendc(&buf, PS_UNDEF_MARKER);
+                       smart_str_appendl(&buf, key, key_length);
+                       smart_str_appendc(&buf, PS_DELIMITER);
        );
 
-       if (newlen) *newlen = Z_STRLEN_P(buf);
-       *newstr = Z_STRVAL_P(buf);
-       efree(buf);
+       if (newlen) *newlen = buf.len;
+       *newstr = buf.c;
 
        PHP_VAR_SERIALIZE_DESTROY(var_hash);
        return SUCCESS;
index 4681b4a6639cb2767088c39cd5808348f730f516..8146a057d3f7fb1ceefc0cba0162152766207954 100644 (file)
@@ -46,6 +46,7 @@
 #define smart_str_free(s) smart_str_free_ex(s, 0)
 #define smart_str_appendl(dest,src,len) smart_str_appendl_ex(dest,src,len,0)
 #define smart_str_append(dest, src) smart_str_append_ex(dest,src,0)
+#define smart_str_append_long(dest, val) smart_str_append_long_ex(dest,val,0)
 
 static inline void smart_str_appendc_ex(smart_str *dest, char c, int what)
 {
@@ -75,6 +76,36 @@ static inline void smart_str_appendl_ex(smart_str *dest, const char *src, size_t
        dest->len = newlen;
 }
 
+static inline char *smart_str_print_long(char *buf, long num)
+{
+       char *p = buf;
+       long tmp = 0;
+       
+       if (num < 0) {
+               num = -num;
+               *p++ = '-';
+       }
+
+       while (num > 0) {
+               tmp = tmp * 10 + (num % 10);
+               num /= 10;
+       }
+
+       do {
+               *p++ = (tmp % 10) + '0';
+               tmp /= 10;
+       } while (tmp > 0);
+
+       return p;
+}
+
+static inline void smart_str_append_long_ex(smart_str *dest, long num, int type)
+{
+       char buf[32];
+       char *p = smart_str_print_long(buf, num);
+       smart_str_appendl_ex(dest, buf, p - buf, type);
+}
+
 static inline void smart_str_append_ex(smart_str *dest, smart_str *src, int what)
 {
        smart_str_appendl_ex(dest, src->c, src->len, what);
index fd77d92045ab78b9af5116f094a338e83a1447ea..aceeb34e7a394070145ade8505b829daf29880f8 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef PHP_VAR_H
 #define PHP_VAR_H
 
+#include "ext/standard/php_smart_str_public.h"
+
 PHP_FUNCTION(var_dump);
 PHP_FUNCTION(serialize);
 PHP_FUNCTION(unserialize);
@@ -30,7 +32,7 @@ void php_var_dump(zval **struc, int level);
 /* typdef HashTable php_serialize_data_t; */
 #define php_serialize_data_t HashTable
 
-PHPAPI void php_var_serialize(zval *buf, zval **struc, php_serialize_data_t *var_hash);
+PHPAPI void php_var_serialize(smart_str *buf, zval **struc, php_serialize_data_t *var_hash);
 PHPAPI int php_var_unserialize(zval **rval, const char **p, const char *max, php_serialize_data_t *var_hash);
 
 #define PHP_VAR_SERIALIZE_INIT(var_hash) \
index dd2cd9d8b81b6e8665a828be3db6abf6cfd5d184..55f58581fd247f2f840708ed8264e7f2e5d2f8f1 100644 (file)
@@ -30,6 +30,7 @@
 #include "php.h"
 #include "php_string.h"
 #include "php_var.h"
+#include "php_smart_str.h"
 #include "basic_functions.h"
 #include "php_incomplete_class.h"
 
@@ -137,34 +138,17 @@ PHP_FUNCTION(var_dump)
 /* }}} */
 
 
-/* {{{ php_var_dump */
-
-
-#define STR_CAT(P,S,I) {\
-       zval *__p = (P);\
-       ulong __i = Z_STRLEN_P(__p);\
-       Z_STRLEN_P(__p) += (I);\
-       if (Z_STRVAL_P(__p)) {\
-               Z_STRVAL_P(__p) = (char *)erealloc(Z_STRVAL_P(__p), Z_STRLEN_P(__p) + 1);\
-       } else {\
-               Z_STRVAL_P(__p) = emalloc(Z_STRLEN_P(__p) + 1);\
-               *Z_STRVAL_P(__p) = 0;\
-       }\
-       strcat(Z_STRVAL_P(__p) + __i, (S));\
-}
-
-/* }}} */
 /* {{{ php_var_serialize */
 
 static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old)
 {
        ulong var_no;
-       char id[sizeof(void *)*2+3];
+       char id[32], *p;
 
-       snprintf(id,sizeof(id)-1, "%p", var);
-       id[sizeof(id)-1]='\0';
+       p = smart_str_print_long(id, (long) var);
+       *p = '\0';
 
-       if(var_old && zend_hash_find(var_hash, id, strlen(id), var_old) == SUCCESS) {
+       if(var_old && zend_hash_find(var_hash, id, p - id, var_old) == SUCCESS) {
                if(!var->is_ref) {
                        /* we still need to bump up the counter, since non-refs will
                           be counted separately by unserializer */
@@ -175,11 +159,11 @@ static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old
        }
        
        var_no = zend_hash_num_elements(var_hash)+1; /* +1 because otherwise hash will think we are trying to store NULL pointer */
-       zend_hash_add(var_hash, id, strlen(id), &var_no, sizeof(var_no), NULL);
+       zend_hash_add(var_hash, id, p - id, &var_no, sizeof(var_no), NULL);
        return SUCCESS;
 }
 
-PHPAPI void php_var_serialize(zval *buf, zval **struc, HashTable *var_hash)
+PHPAPI void php_var_serialize(smart_str *buf, zval **struc, HashTable *var_hash)
 {
        char s[256];
        ulong slen;
@@ -189,47 +173,41 @@ PHPAPI void php_var_serialize(zval *buf, zval **struc, HashTable *var_hash)
        TSRMLS_FETCH();
 
        if(var_hash != NULL && php_add_var_hash(var_hash,*struc,(void *)&var_already) == FAILURE && (*struc)->is_ref) {
-               slen = sprintf(s,"R:%ld;",*var_already);
-               STR_CAT(buf, s, slen);
+               smart_str_appendl(buf, "R:", 2);
+               smart_str_append_long(buf, *var_already);
+               smart_str_appendc(buf, ';');
                return;
        }
 
        switch ((*struc)->type) {
                case IS_BOOL:
-                       slen = sprintf(s, "b:%ld;", Z_LVAL_PP(struc));
-                       STR_CAT(buf, s, slen);
+                       smart_str_appendl(buf, "b:", 2);
+                       smart_str_append_long(buf, Z_LVAL_PP(struc));
+                       smart_str_appendc(buf, ';');
                        return;
 
                case IS_NULL:
-                       STR_CAT(buf, "N;", 2);
+                       smart_str_appendl(buf, "N;", 2);
                        return;
 
                case IS_LONG:
-                       slen = sprintf(s, "i:%ld;", Z_LVAL_PP(struc));
-                       STR_CAT(buf, s, slen);
+                       smart_str_appendl(buf, "i:", 2);
+                       smart_str_append_long(buf, Z_LVAL_PP(struc));
+                       smart_str_appendc(buf, ';');
                        return;
 
-               case IS_DOUBLE: {
-                               slen = sprintf(s, "d:%.*G;",(int) EG(precision), Z_DVAL_PP(struc));
-                               STR_CAT(buf, s, slen);
-                       }
+               case IS_DOUBLE:
+                       slen = sprintf(s, "d:%.*G;",(int) EG(precision), Z_DVAL_PP(struc));
+                       smart_str_appendl(buf, s, slen);
                        return;
 
-               case IS_STRING:{
-                               char *p;
-                               
-                               i = buf->value.str.len;
-                               slen = sprintf(s, "s:%d:\"", Z_STRLEN_PP(struc));
-                               STR_CAT(buf, s, slen + Z_STRLEN_PP(struc) + 2);
-                               p = Z_STRVAL_P(buf) + i + slen;
-                               if (Z_STRLEN_PP(struc) > 0) {
-                                       memcpy(p, Z_STRVAL_PP(struc), Z_STRLEN_PP(struc));
-                                       p += Z_STRLEN_PP(struc);
-                               }
-                               *p++ = '\"';
-                               *p++ = ';';
-                               *p = 0;
-                       }
+               case IS_STRING:
+                       smart_str_appendl(buf, "s:", 2);
+                       smart_str_append_long(buf, Z_STRLEN_PP(struc));
+                       smart_str_appendl(buf, ":\"", 2);
+                       smart_str_appendl(buf, Z_STRVAL_PP(struc), Z_STRLEN_PP(struc));
+                       smart_str_appendl(buf, "\";", 2);
+                       
                        return;
                case IS_OBJECT: {
                                zval *retval_ptr = NULL;
@@ -240,17 +218,22 @@ PHPAPI void php_var_serialize(zval *buf, zval **struc, HashTable *var_hash)
                                MAKE_STD_ZVAL(fname);
                                ZVAL_STRING(fname,"__sleep",1);
 
-                               res =  call_user_function_ex(CG(function_table), struc, fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
+                               res = call_user_function_ex(CG(function_table), struc, fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
 
                                if (res == SUCCESS) {
                                        if (retval_ptr && HASH_OF(retval_ptr)) {
                                                int count = zend_hash_num_elements(HASH_OF(retval_ptr));
                                                
                                                PHP_SET_CLASS_ATTRIBUTES(*struc);
-                                               slen = sprintf(s, "O:%d:\"%s\":%d:{",name_len,class_name, count);
+                                               smart_str_appendl(buf, "O:", 2);
+                                               smart_str_append_long(buf, name_len);
+                                               smart_str_appendl(buf, ":\"", 2);
+                                               smart_str_appendl(buf, class_name, name_len);
+                                               smart_str_appendl(buf, "\":", 2);
+                                               smart_str_append_long(buf, count);
+                                               smart_str_appendl(buf, ":{", 2);
                                                PHP_CLEANUP_CLASS_ATTRIBUTES();
                                                
-                                               STR_CAT(buf, s, slen);
                                                if (count > 0) {
                                                        char *key;
                                                        zval **d,**name;
@@ -272,11 +255,11 @@ PHPAPI void php_var_serialize(zval *buf, zval **struc, HashTable *var_hash)
 
                                                                if (zend_hash_find(Z_OBJPROP_PP(struc), Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, (void*)&d) == SUCCESS) {
                                                                        php_var_serialize(buf, name, NULL);
-                                                                       php_var_serialize(buf,d,var_hash);      
+                                                                       php_var_serialize(buf, d, var_hash);    
                                                                }
                                                        }
                                                }
-                                               STR_CAT(buf, "}", 1);
+                                               smart_str_appendc(buf, '}');
                                        }
                                } else {
                                        zval_dtor(fname);
@@ -301,15 +284,20 @@ PHPAPI void php_var_serialize(zval *buf, zval **struc, HashTable *var_hash)
                        myht = HASH_OF(*struc);
                        i = zend_hash_num_elements(myht);
                        if ((*struc)->type == IS_ARRAY) {
-                               slen = sprintf(s, "a:%d:{", i);
+                               smart_str_appendl(buf, "a:", 2);
                        } else {
                                PHP_CLASS_ATTRIBUTES;
 
                                PHP_SET_CLASS_ATTRIBUTES(*struc);
-                               slen = sprintf(s, "O:%d:\"%s\":%d:{",name_len,class_name,i);
+                               smart_str_appendl(buf, "O:", 2);
+                               smart_str_append_long(buf, name_len);
+                               smart_str_appendl(buf, ":\"", 2);
+                               smart_str_appendl(buf, class_name, name_len);
+                               smart_str_appendl(buf, "\":", 2);
                                PHP_CLEANUP_CLASS_ATTRIBUTES();
                        }
-                       STR_CAT(buf, s, slen);
+                       smart_str_append_long(buf, i);
+                       smart_str_appendl(buf, ":{", 2);
                        if (i > 0) {
                                char *key;
                                zval **data,*d;
@@ -342,10 +330,10 @@ PHPAPI void php_var_serialize(zval *buf, zval **struc, HashTable *var_hash)
                                        php_var_serialize(buf, data, var_hash);
                                }
                        }
-                       STR_CAT(buf, "}", 1);
+                       smart_str_appendc(buf, '}');
                        return;
                default:
-                       STR_CAT(buf, "i:0;", 4);
+                       smart_str_appendl(buf, "i:0;", 4);
                        return;
        } 
 }
@@ -605,6 +593,7 @@ PHP_FUNCTION(serialize)
 {
        zval **struc;
        php_serialize_data_t var_hash;
+       smart_str buf = {0};
 
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &struc) == FAILURE) {
                WRONG_PARAM_COUNT;
@@ -615,8 +604,9 @@ PHP_FUNCTION(serialize)
        return_value->value.str.len = 0;
 
        PHP_VAR_SERIALIZE_INIT(var_hash);
-       php_var_serialize(return_value, struc, &var_hash);
+       php_var_serialize(&buf, struc, &var_hash);
        PHP_VAR_SERIALIZE_DESTROY(var_hash);
+       RETVAL_STRINGL(buf.c, buf.len, 0);
 }
 
 /* }}} */
index 174e9f030155541042c66d2c41cadc1a0df8bf6c..9255f3677fc32d1b4813e1d8202df87e659cfa42 100644 (file)
@@ -222,7 +222,7 @@ PHP_FUNCTION(shm_put_var)
        long key, id;
        sysvshm_shm *shm_list_ptr;
        int type;
-       pval shm_var;
+       smart_str shm_var = {0};
        int ret;        
        php_serialize_data_t var_hash;
 
@@ -243,17 +243,14 @@ PHP_FUNCTION(shm_put_var)
 
        /* setup string-variable and serialize */
 
-       shm_var.type=IS_STRING;
-       shm_var.value.str.len=0;
-       shm_var.value.str.val=0;
        PHP_VAR_SERIALIZE_INIT(var_hash);
        php_var_serialize(&shm_var,arg_var,&var_hash);
        PHP_VAR_SERIALIZE_DESTROY(var_hash);
        /* insert serialized variable into shared memory */
-       ret=php_put_shm_data(shm_list_ptr->ptr,key,shm_var.value.str.val,shm_var.value.str.len);
+       ret=php_put_shm_data(shm_list_ptr->ptr,key,shm_var.c,shm_var.len);
 
        /* free string */
-       efree(shm_var.value.str.val);
+       smart_str_free(&shm_var);
        
        if(ret==-1) {
                php_error(E_WARNING, "not enough shared memory left");