]> granicus.if.org Git - php/commitdiff
simplify and improve speed of smart_str_print_long.
authorSascha Schumann <sas@php.net>
Sun, 21 Apr 2002 01:17:49 +0000 (01:17 +0000)
committerSascha Schumann <sas@php.net>
Sun, 21 Apr 2002 01:17:49 +0000 (01:17 +0000)
also add a variant for unsigned numbers.

ext/standard/php_smart_str.h
ext/standard/var.c

index bf9e3a63ad2d27d1f19ae5a156f56a222bddc26c..c0c2e770bb768a6408f611d347e98974988bd463 100644 (file)
@@ -47,6 +47,7 @@
 #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)
+#define smart_str_append_unsigned(dest, val) smart_str_append_unsigned_ex(dest, val, 0)
 
 static inline void smart_str_appendc_ex(smart_str *dest, char c, int what)
 {
@@ -76,47 +77,50 @@ 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)
+/* buf points to the END of the buffer */
+static inline char *smart_str_print_unsigned(char *buf, unsigned long num)
 {
-       char *p = buf, *end;
-       int n;
-       long tmp;
-       
-       if (num < 0) {
-               num = -num;
-               *p++ = '-';
-       }
-
-       /* many numbers are < 10 */
-       if (num < 10) {
-               *p++ = num + '0';
-               return p;
-       }
-
-       n = 1;
-       tmp = num;
-
-       /* calculate the number of digits we need */
-       do {
-               tmp /= 10;
-               n++;
-       } while (tmp >= 10);
-
-       end = p += n;
+       char *p = buf;
        
+       *p = '\0';
        do {
                *--p = (num % 10) + '0';
                num /= 10;
-       } while (--n > 0);
+       } while (num > 0);
+
+       return p;
+}
 
-       return end;
+/* buf points to the END of the buffer */
+static inline char *smart_str_print_long(char *buf, long num)
+{
+       char *p;
+       
+       if (num < 0) {
+               /* this might cause problems when dealing with LONG_MIN
+                  and machines which don't support long long.  Works
+                  flawlessly on 32bit x86 */
+               p = smart_str_print_unsigned(buf, -num);
+               *--p = '-';
+       } else {
+               p = smart_str_print_unsigned(buf, num);
+       }
+
+       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);
+       char *p = smart_str_print_long(buf + sizeof(buf) - 1, num);
+       smart_str_appendl_ex(dest, p, (buf + sizeof(buf) - 1) - p, type);
+}
+
+static inline void smart_str_append_unsigned_ex(smart_str *dest, long num, int type)
+{
+       char buf[32];
+       char *p = smart_str_print_unsigned(buf + sizeof(buf) - 1, num);
+       smart_str_appendl_ex(dest, p, (buf + sizeof(buf) - 1) - p, type);
 }
 
 static inline void smart_str_append_ex(smart_str *dest, smart_str *src, int what)
index 82dc1181678c94e1e4ea9b7e3ac4c0fd54aae89d..4b8e661aae6922d8af7fc63a7cfe15efc6c95bbc 100644 (file)
@@ -379,11 +379,13 @@ static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old
 {
        ulong var_no;
        char id[32], *p;
+       register int len;
 
-       p = smart_str_print_long(id, (long) var);
-       *p = '\0';
-
-       if (var_old && zend_hash_find(var_hash, id, p - id, var_old) == SUCCESS) {
+       /* relies on "(long)" being a perfect hash function for data pointers */
+       p = smart_str_print_long(id + sizeof(id) - 1, (long) var);
+       len = id + sizeof(id) - 1 - p;
+       
+       if (var_old && zend_hash_find(var_hash, p, len, var_old) == SUCCESS) {
                if (!var->is_ref) {
                        /* we still need to bump up the counter, since non-refs will
                           be counted separately by unserializer */
@@ -395,7 +397,7 @@ static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old
        
        /* +1 because otherwise hash will think we are trying to store NULL pointer */
        var_no = zend_hash_num_elements(var_hash) + 1;
-       zend_hash_add(var_hash, id, p - id, &var_no, sizeof(var_no), NULL);
+       zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL);
        return SUCCESS;
 }