- pmem aware phpstr
authorMichael Wallner <mike@php.net>
Mon, 14 Nov 2005 16:53:43 +0000 (16:53 +0000)
committerMichael Wallner <mike@php.net>
Mon, 14 Nov 2005 16:53:43 +0000 (16:53 +0000)
- tests fixup

# uhm.. where's the valgrind patch for run-tests?

http_filter_api.c
phpstr/phpstr.c
phpstr/phpstr.h
tests/exceptions.phpt
tests/stream_filters_001.phpt

index 4f76a509897c39d315b4ce042534d45aecc1614a..ee42d608486e524523244da2ca2d5e83e1d66475 100644 (file)
 
 #include "php_streams.h"
 
-/*
- * TODO: allow use with persistent streams
- */
-
 PHP_MINIT_FUNCTION(http_filter)
 {
        php_stream_filter_register_factory("http.*", &http_filter_factory TSRMLS_CC);
@@ -104,13 +100,17 @@ static HTTP_FILTER_FUNCTION(chunked_decode)
                                *bytes_consumed += ptr->buflen;
                        }
                
-                       phpstr_append(PHPSTR(buffer), ptr->buf, ptr->buflen);
+                       if ((size_t) -1 == phpstr_append(PHPSTR(buffer), ptr->buf, ptr->buflen)) {
+                               return PSFS_ERR_FATAL;
+                       }
+                       
                        php_stream_bucket_unlink(ptr TSRMLS_CC);
                        php_stream_bucket_delref(ptr TSRMLS_CC);
-                       
                }
        }
-       phpstr_fix(PHPSTR(buffer));
+       if (!phpstr_fix(PHPSTR(buffer))) {
+               return PSFS_ERR_FATAL;
+       }
 
        /* we have data in our buffer */
        while (PHPSTR_LEN(buffer)) {
@@ -287,13 +287,8 @@ static php_stream_filter *http_filter_create(const char *name, zval *params, int
        if (!strcasecmp(name, "http.chunked_decode")) {
                http_filter_buffer *b = NULL;
                
-               /* FIXXME: allow usage with persistent streams */
-               if (p) {
-                       return NULL;
-               }
-               
                if (b = pecalloc(1, sizeof(http_filter_buffer), p)) {
-                       phpstr_init(PHPSTR(b));
+                       phpstr_init_ex(PHPSTR(b), 4096, p ? PHPSTR_INIT_PERSISTENT : 0);
                        if (!(f = php_stream_filter_alloc(&HTTP_FILTER_OP(chunked_decode), b, p))) {
                                pefree(b, p);
                        }
index 5a153dbcbc00b3bb6b56fae42ed69cd2cfd0918a..69f577f2da079cf1221db19c90188b215063f7e4 100644 (file)
@@ -4,46 +4,70 @@
 #include "php.h"
 #include "phpstr.h"
 
-PHPSTR_API phpstr *phpstr_init_ex(phpstr *buf, size_t chunk_size, int pre_alloc)
+#define NOMEM ((size_t) -1)
+
+PHPSTR_API phpstr *phpstr_init_ex(phpstr *buf, size_t chunk_size, int flags)
 {
        if (!buf) {
-               buf = emalloc(sizeof(phpstr));
+               buf = pemalloc(sizeof(phpstr), flags & PHPSTR_INIT_PERSISTENT);
        }
 
-       buf->size = chunk_size > 0 ? chunk_size : PHPSTR_DEFAULT_SIZE;
-       buf->data = pre_alloc ? emalloc(buf->size) : NULL;
-       buf->free = pre_alloc ? buf->size : 0;
-       buf->used = 0;
-
+       if (buf) {
+               buf->size = (chunk_size > 0) ? chunk_size : PHPSTR_DEFAULT_SIZE;
+               buf->pmem = (flags & PHPSTR_INIT_PERSISTENT) ? 1 : 0;
+               buf->data = (flags & PHPSTR_INIT_PREALLOC) ? pemalloc(buf->size, buf->pmem) : NULL;
+               buf->free = (flags & PHPSTR_INIT_PREALLOC) ? buf->size : 0;
+               buf->used = 0;
+       }
+       
        return buf;
 }
 
 PHPSTR_API phpstr *phpstr_from_string_ex(phpstr *buf, const char *string, size_t length)
 {
-       buf = phpstr_init(buf);
-       phpstr_append(buf, string, length);
+       if (buf = phpstr_init(buf)) {
+               if (NOMEM == phpstr_append(buf, string, length)) {
+                       pefree(buf, buf->pmem);
+                       buf = NULL;
+               }
+       }
        return buf;
 }
 
-PHPSTR_API void phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size)
+PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size)
 {
        if (buf->free < len) {
                size_t size = override_size ? override_size : buf->size;
+               
                while ((size + buf->free) < len) {
                        size *= 2;
                }
                if (buf->data) {
-                       buf->data = erealloc(buf->data, buf->used + buf->free + size);
+                       char *ptr = perealloc(buf->data, buf->used + buf->free + size, buf->pmem);
+                       
+                       if (ptr) {
+                               buf->data = ptr;
+                       } else {
+                               return NOMEM;
+                       }
                } else {
-                       buf->data = emalloc(size);
+                       buf->data = pemalloc(size, buf->pmem);
+                       
+                       if (!buf->data) {
+                               return NOMEM;
+                       }
                }
                buf->free += size;
+               return size;
        }
+       return 0;
 }
 
 PHPSTR_API size_t phpstr_append(phpstr *buf, const char *append, size_t append_len)
 {
-       phpstr_resize(buf, append_len);
+       if (NOMEM == phpstr_resize(buf, append_len)) {
+               return NOMEM;
+       }
        memcpy(buf->data + buf->used, append, append_len);
        buf->used += append_len;
        buf->free -= append_len;
@@ -54,21 +78,26 @@ PHPSTR_API size_t phpstr_appendf(phpstr *buf, const char *format, ...)
 {
        va_list argv;
        char *append;
-       size_t append_len;
+       size_t append_len, alloc;
 
        va_start(argv, format);
        append_len = vspprintf(&append, 0, format, argv);
        va_end(argv);
 
-       phpstr_append(buf, append, append_len);
+       alloc = phpstr_append(buf, append, append_len);
        efree(append);
 
+       if (NOMEM == alloc) {
+               return NOMEM;
+       }
        return append_len;
 }
 
 PHPSTR_API size_t phpstr_insert(phpstr *buf, const char *insert, size_t insert_len, size_t offset)
 {
-       phpstr_resize(buf, insert_len);
+       if (NOMEM == phpstr_resize(buf, insert_len)) {
+               return NOMEM;
+       }
        memmove(buf->data + offset + insert_len, buf->data + offset, insert_len);
        memcpy(buf->data + offset, insert, insert_len);
        buf->used += insert_len;
@@ -80,21 +109,26 @@ PHPSTR_API size_t phpstr_insertf(phpstr *buf, size_t offset, const char *format,
 {
        va_list argv;
        char *insert;
-       size_t insert_len;
+       size_t insert_len, alloc;
 
        va_start(argv, format);
        insert_len = vspprintf(&insert, 0, format, argv);
        va_end(argv);
 
-       phpstr_insert(buf, insert, insert_len, offset);
+       alloc = phpstr_insert(buf, insert, insert_len, offset);
        efree(insert);
 
+       if (NOMEM == alloc) {
+               return NOMEM;
+       }
        return insert_len;
 }
 
 PHPSTR_API size_t phpstr_prepend(phpstr *buf, const char *prepend, size_t prepend_len)
 {
-       phpstr_resize(buf, prepend_len);
+       if (NOMEM == phpstr_resize(buf, prepend_len)) {
+               return NOMEM;
+       }
        memmove(buf->data + prepend_len, buf->data, buf->used);
        memcpy(buf->data, prepend, prepend_len);
        buf->used += prepend_len;
@@ -106,15 +140,18 @@ PHPSTR_API size_t phpstr_prependf(phpstr *buf, const char *format, ...)
 {
        va_list argv;
        char *prepend;
-       size_t prepend_len;
+       size_t prepend_len, alloc;
 
        va_start(argv, format);
        prepend_len = vspprintf(&prepend, 0, format, argv);
        va_end(argv);
 
-       phpstr_prepend(buf, prepend, prepend_len);
+       alloc = phpstr_prepend(buf, prepend, prepend_len);
        efree(prepend);
 
+       if (NOMEM == alloc) {
+               return NOMEM;
+       }
        return prepend_len;
 }
 
@@ -134,7 +171,9 @@ PHPSTR_API char *phpstr_data(const phpstr *buf, char **into, size_t *len)
 PHPSTR_API phpstr *phpstr_dup(const phpstr *buf)
 {
        phpstr *dup = phpstr_clone(buf);
-       phpstr_append(dup, buf->data, buf->used);
+       if (NOMEM == phpstr_append(dup, buf->data, buf->used)) {
+               phpstr_free(&dup);
+       }
        return dup;
 }
 
@@ -158,9 +197,14 @@ PHPSTR_API phpstr *phpstr_sub(const phpstr *buf, size_t offset, size_t length)
                return NULL;
        } else {
                size_t need = (length + offset) > buf->used ? (buf->used - offset) : (length - offset);
-               phpstr *sub = phpstr_init_ex(NULL, need, 1);
-               phpstr_append(sub, buf->data + offset, need);
-               sub->size = buf->size;
+               phpstr *sub = phpstr_init_ex(NULL, need, PHPSTR_INIT_PREALLOC | (buf->pmem ? PHPSTR_INIT_PERSISTENT:0));
+               if (sub) {
+                       if (NOMEM == phpstr_append(sub, buf->data + offset, need)) {
+                               phpstr_free(&sub);
+                       } else {
+                               sub->size = buf->size;
+                       }
+               }
                return sub;
        }
 }
@@ -177,14 +221,22 @@ PHPSTR_API phpstr *phpstr_right(const phpstr *buf, size_t length)
 
 PHPSTR_API phpstr *phpstr_merge_va(phpstr *buf, unsigned argc, va_list argv)
 {
-       unsigned i = 0;
+       unsigned f = 0, i = 0;
        buf = phpstr_init(buf);
 
-       while (argc > i++) {
-               phpstr_free_t f = va_arg(argv, phpstr_free_t);
-               phpstr *current = va_arg(argv, phpstr *);
-               phpstr_append(buf, current->data, current->used);
-               FREE_PHPSTR(f, current);
+       if (buf) {
+               while (argc > i++) {
+                       phpstr_free_t f = va_arg(argv, phpstr_free_t);
+                       phpstr *current = va_arg(argv, phpstr *);
+                       if (NOMEM == phpstr_append(buf, current->data, current->used)) {
+                               f = 1;
+                       }
+                       FREE_PHPSTR(f, current);
+               }
+               
+               if (f) {
+                       phpstr_free(&buf);
+               }
        }
 
        return buf;
@@ -212,10 +264,13 @@ PHPSTR_API phpstr *phpstr_merge(unsigned argc, ...)
        return ret;
 }
 
-PHPSTR_API void phpstr_fix(phpstr *buf)
+PHPSTR_API phpstr *phpstr_fix(phpstr *buf)
 {
-       phpstr_resize_ex(buf, 1, 1);
+       if (NOMEM == phpstr_resize_ex(buf, 1, 1)) {
+               return NULL;
+       }
        buf->data[buf->used] = '\0';
+       return buf;
 }
 
 PHPSTR_API int phpstr_cmp(phpstr *left, phpstr *right)
@@ -237,7 +292,10 @@ PHPSTR_API void phpstr_reset(phpstr *buf)
 
 PHPSTR_API void phpstr_dtor(phpstr *buf)
 {
-       STR_SET(buf->data, NULL);
+       if (buf->data) {
+               pefree(buf->data, buf->pmem);
+               buf->data = NULL;
+       }
        buf->used = 0;
        buf->free = 0;
 }
@@ -246,7 +304,7 @@ PHPSTR_API void phpstr_free(phpstr **buf)
 {
        if (*buf) {
                phpstr_dtor(*buf);
-               efree(*buf);
+               pefree(*buf, (*buf)->pmem);
                *buf = NULL;
        }
 }
@@ -258,7 +316,7 @@ PHPSTR_API size_t phpstr_chunk_buffer(phpstr **s, const char *data, size_t data_
        *chunk = NULL;
        
        if (!*s) {
-               *s = phpstr_init_ex(NULL, chunk_size * 2, chunk_size ? 1 : 0);
+               *s = phpstr_init_ex(NULL, chunk_size * 2, chunk_size ? PHPSTR_INIT_PREALLOC : 0);
        }
        storage = *s;
        
index 5b56e1124a77853fde611411acc1c2efd825b086..9e18e5464df99d55ede2ecc471a7d359c5b0ef0c 100644 (file)
 #define PHPSTR_VAL(p) (PHPSTR(p))->data
 #define PHPSTR_LEN(p) (PHPSTR(p))->used
 
-#define FREE_PHPSTR_PTR(STR) efree(STR)
+#define FREE_PHPSTR_PTR(STR) pefree(STR, STR->pmem)
 #define FREE_PHPSTR_VAL(STR) phpstr_dtor(STR)
 #define FREE_PHPSTR_ALL(STR) phpstr_free(&(STR))
 #define FREE_PHPSTR(free, STR) \
        switch (free) \
        { \
-               case PHPSTR_FREE_NOT:                                           break; \
-               case PHPSTR_FREE_PTR:   efree(STR);                     break; \
-               case PHPSTR_FREE_VAL:   phpstr_dtor(STR);       break; \
+               case PHPSTR_FREE_NOT:                                                   break; \
+               case PHPSTR_FREE_PTR:   pefree(STR, STR->pmem); break; \
+               case PHPSTR_FREE_VAL:   phpstr_dtor(STR);               break; \
                case PHPSTR_FREE_ALL: \
                { \
                        phpstr *PTR = (STR); \
                        phpstr_free(&PTR); \
                } \
                break; \
-               default:                                                                        break; \
+               default:                                                                                break; \
        }
 
 #define RETURN_PHPSTR_PTR(STR) RETURN_PHPSTR((STR), PHPSTR_FREE_PTR, 0)
@@ -71,11 +71,12 @@ typedef struct {
        char  *data;
        size_t used;
        size_t free;
+       int    pmem;
 } phpstr;
 
 typedef enum {
        PHPSTR_FREE_NOT = 0,
-       PHPSTR_FREE_PTR,        /* efree() */
+       PHPSTR_FREE_PTR,        /* pefree() */
        PHPSTR_FREE_VAL,        /* phpstr_dtor() */
        PHPSTR_FREE_ALL         /* phpstr_free() */
 } phpstr_free_t;
@@ -85,11 +86,14 @@ typedef enum {
 #define PHPSTR_VAL_FREE(STR) PHPSTR_FREE_VAL,(STR)
 #define PHPSTR_NOT_FREE(STR) PHPSTR_FREE_NOT,(STR)
 
+#define PHPSTR_INIT_PREALLOC   0x01
+#define PHPSTR_INIT_PERSISTENT 0x02
+
 /* create a new phpstr */
 #define phpstr_new() phpstr_init(NULL)
 #define phpstr_init(b) phpstr_init_ex(b, 0, 0)
-#define phpstr_clone(phpstr_pointer) phpstr_init_ex(NULL, (phpstr_pointer)->size, 0)
-PHPSTR_API phpstr *phpstr_init_ex(phpstr *buf, size_t chunk_size, int pre_alloc);
+#define phpstr_clone(phpstr_pointer) phpstr_init_ex(NULL, (phpstr_pointer)->size, (phpstr_pointer)->pmem ? PHPSTR_INIT_PERSISTENT:0)
+PHPSTR_API phpstr *phpstr_init_ex(phpstr *buf, size_t chunk_size, int flags);
 
 /* create a phpstr from a zval or c-string */
 #define phpstr_from_zval(z) phpstr_from_string(Z_STRVAL(z), Z_STRLEN(z))
@@ -99,7 +103,7 @@ PHPSTR_API phpstr *phpstr_from_string_ex(phpstr *buf, const char *string, size_t
 
 /* usually only called from within the internal functions */
 #define phpstr_resize(b, s) phpstr_resize_ex((b), (s), 0)
-PHPSTR_API void phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size);
+PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size);
 
 /* append data to the phpstr */
 #define phpstr_appends(b, a) phpstr_append((b), (a), sizeof(a)-1)
@@ -147,7 +151,7 @@ PHPSTR_API phpstr *phpstr_merge_ex(phpstr *buf, unsigned argc, ...);
 PHPSTR_API phpstr *phpstr_merge_va(phpstr *buf, unsigned argc, va_list argv);
 
 /* sets a trailing NUL byte */
-PHPSTR_API void phpstr_fix(phpstr *buf);
+PHPSTR_API phpstr *phpstr_fix(phpstr *buf);
 
 /* memcmp for phpstr objects */
 PHPSTR_API int phpstr_cmp(phpstr *left, phpstr *right);
index 9fddddd94f00950a65bbddb6bd14ac3d8e2fe8d1..43bb19041d32a10480bab698c9f2f514dc6f3985 100644 (file)
@@ -41,7 +41,7 @@ if (http_support(HTTP_SUPPORT_REQUESTS)) {
                printf("%s (%d)\n", $x->getMessage(), $x->getCode());
        }
 } else {
-       echo "Could not perform request: URL using bad/illegal format or missing URL (8)\n";
+       echo "URL using bad/illegal format or missing URL (8)\n";
 }
 echo "Done\n";
 ?>
@@ -59,5 +59,5 @@ echo "Done\n";
 10: HttpSocketException
 11: HttpResponseException
 12: HttpUrlException
-Could not perform request: URL using bad/illegal format or missing URL (8)
+URL using bad/illegal format or missing URL (8)
 Done
index 8b07c98f08e01934bf3b438000e90b02de1a1988..533b23760bd3eb01053e415989f09bb46f1ad041 100644 (file)
@@ -30,13 +30,14 @@ echo "Done\n";
 ?>
 --EXPECTF--
 %sTEST
-string(27) "5
+string(30) "5
 Here 
 2
 we
 5
  go!
 
+0
 "
 string(12) "Here we go!
 "