LTP GCOV extension - code coverage report
Current view: directory - ext/http/phpstr - phpstr.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 201
Code covered: 59.7 % Executed lines: 120
Legend: not executed executed

       1                 : 
       2                 : /* $Id: phpstr.c,v 1.19 2006/04/24 17:17:09 mike Exp $ */
       3                 : 
       4                 : #include "php.h"
       5                 : #include "phpstr.h"
       6                 : 
       7                 : PHPSTR_API phpstr *phpstr_init_ex(phpstr *buf, size_t chunk_size, int flags)
       8             828 : {
       9             828 :         if (!buf) {
      10              44 :                 buf = pemalloc(sizeof(phpstr), flags & PHPSTR_INIT_PERSISTENT);
      11                 :         }
      12                 : 
      13             828 :         if (buf) {
      14             828 :                 buf->size = (chunk_size) ? chunk_size : PHPSTR_DEFAULT_SIZE;
      15             828 :                 buf->pmem = (flags & PHPSTR_INIT_PERSISTENT) ? 1 : 0;
      16             828 :                 buf->data = (flags & PHPSTR_INIT_PREALLOC) ? pemalloc(buf->size, buf->pmem) : NULL;
      17             828 :                 buf->free = (flags & PHPSTR_INIT_PREALLOC) ? buf->size : 0;
      18             828 :                 buf->used = 0;
      19                 :         }
      20                 :         
      21             828 :         return buf;
      22                 : }
      23                 : 
      24                 : PHPSTR_API phpstr *phpstr_from_string_ex(phpstr *buf, const char *string, size_t length)
      25              89 : {
      26              89 :         if ((buf = phpstr_init(buf))) {
      27              89 :                 if (PHPSTR_NOMEM == phpstr_append(buf, string, length)) {
      28               0 :                         pefree(buf, buf->pmem);
      29               0 :                         buf = NULL;
      30                 :                 }
      31                 :         }
      32              89 :         return buf;
      33                 : }
      34                 : 
      35                 : PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size, int allow_error)
      36            3183 : {
      37            3183 :         char *ptr = NULL;
      38                 : #if 0
      39                 :         fprintf(stderr, "RESIZE: size=%lu, used=%lu, free=%lu\n", buf->size, buf->used, buf->free);
      40                 : #endif
      41            3183 :         if (buf->free < len) {
      42             694 :                 size_t size = override_size ? override_size : buf->size;
      43                 :                 
      44            1685 :                 while ((size + buf->free) < len) {
      45             297 :                         size <<= 1;
      46                 :                 }
      47                 :                 
      48             694 :                 if (allow_error) {
      49              40 :                         ptr = perealloc_recoverable(buf->data, buf->used + buf->free + size, buf->pmem);
      50                 :                 } else {
      51             654 :                         ptr = perealloc(buf->data, buf->used + buf->free + size, buf->pmem);
      52                 :                 }
      53                 :                 
      54             694 :                 if (ptr) {
      55             694 :                         buf->data = ptr;
      56                 :                 } else {
      57               0 :                         return PHPSTR_NOMEM;
      58                 :                 }
      59                 :                 
      60             694 :                 buf->free += size;
      61             694 :                 return size;
      62                 :         }
      63            2489 :         return 0;
      64                 : }
      65                 : 
      66                 : PHPSTR_API size_t phpstr_shrink(phpstr *buf)
      67              27 : {
      68                 :         /* avoid another realloc on fixation */
      69              27 :         if (buf->free > 1) {
      70              27 :                 char *ptr = perealloc(buf->data, buf->used + 1, buf->pmem);
      71                 :                 
      72              27 :                 if (ptr) {
      73              27 :                         buf->data = ptr;
      74                 :                 } else {
      75               0 :                         return PHPSTR_NOMEM;
      76                 :                 }
      77              27 :                 buf->free = 1;
      78                 :         }
      79              27 :         return buf->used;
      80                 : }
      81                 : 
      82                 : PHPSTR_API size_t phpstr_append(phpstr *buf, const char *append, size_t append_len)
      83            2636 : {
      84            2636 :         if (PHPSTR_NOMEM == phpstr_resize(buf, append_len)) {
      85               0 :                 return PHPSTR_NOMEM;
      86                 :         }
      87            2636 :         memcpy(buf->data + buf->used, append, append_len);
      88            2636 :         buf->used += append_len;
      89            2636 :         buf->free -= append_len;
      90            2636 :         return append_len;
      91                 : }
      92                 : 
      93                 : PHPSTR_API size_t phpstr_appendf(phpstr *buf, const char *format, ...)
      94             165 : {
      95                 :         va_list argv;
      96                 :         char *append;
      97                 :         size_t append_len, alloc;
      98                 : 
      99             165 :         va_start(argv, format);
     100             165 :         append_len = vspprintf(&append, 0, format, argv);
     101             165 :         va_end(argv);
     102                 : 
     103             165 :         alloc = phpstr_append(buf, append, append_len);
     104             165 :         efree(append);
     105                 : 
     106             165 :         if (PHPSTR_NOMEM == alloc) {
     107               0 :                 return PHPSTR_NOMEM;
     108                 :         }
     109             165 :         return append_len;
     110                 : }
     111                 : 
     112                 : PHPSTR_API size_t phpstr_insert(phpstr *buf, const char *insert, size_t insert_len, size_t offset)
     113               0 : {
     114               0 :         if (PHPSTR_NOMEM == phpstr_resize(buf, insert_len)) {
     115               0 :                 return PHPSTR_NOMEM;
     116                 :         }
     117               0 :         memmove(buf->data + offset + insert_len, buf->data + offset, insert_len);
     118               0 :         memcpy(buf->data + offset, insert, insert_len);
     119               0 :         buf->used += insert_len;
     120               0 :         buf->free -= insert_len;
     121               0 :         return insert_len;
     122                 : }
     123                 : 
     124                 : PHPSTR_API size_t phpstr_insertf(phpstr *buf, size_t offset, const char *format, ...)
     125               0 : {
     126                 :         va_list argv;
     127                 :         char *insert;
     128                 :         size_t insert_len, alloc;
     129                 : 
     130               0 :         va_start(argv, format);
     131               0 :         insert_len = vspprintf(&insert, 0, format, argv);
     132               0 :         va_end(argv);
     133                 : 
     134               0 :         alloc = phpstr_insert(buf, insert, insert_len, offset);
     135               0 :         efree(insert);
     136                 : 
     137               0 :         if (PHPSTR_NOMEM == alloc) {
     138               0 :                 return PHPSTR_NOMEM;
     139                 :         }
     140               0 :         return insert_len;
     141                 : }
     142                 : 
     143                 : PHPSTR_API size_t phpstr_prepend(phpstr *buf, const char *prepend, size_t prepend_len)
     144              43 : {
     145              43 :         if (PHPSTR_NOMEM == phpstr_resize(buf, prepend_len)) {
     146               0 :                 return PHPSTR_NOMEM;
     147                 :         }
     148              43 :         memmove(buf->data + prepend_len, buf->data, buf->used);
     149              43 :         memcpy(buf->data, prepend, prepend_len);
     150              43 :         buf->used += prepend_len;
     151              43 :         buf->free -= prepend_len;
     152              43 :         return prepend_len;
     153                 : }
     154                 : 
     155                 : PHPSTR_API size_t phpstr_prependf(phpstr *buf, const char *format, ...)
     156               0 : {
     157                 :         va_list argv;
     158                 :         char *prepend;
     159                 :         size_t prepend_len, alloc;
     160                 : 
     161               0 :         va_start(argv, format);
     162               0 :         prepend_len = vspprintf(&prepend, 0, format, argv);
     163               0 :         va_end(argv);
     164                 : 
     165               0 :         alloc = phpstr_prepend(buf, prepend, prepend_len);
     166               0 :         efree(prepend);
     167                 : 
     168               0 :         if (PHPSTR_NOMEM == alloc) {
     169               0 :                 return PHPSTR_NOMEM;
     170                 :         }
     171               0 :         return prepend_len;
     172                 : }
     173                 : 
     174                 : PHPSTR_API char *phpstr_data(const phpstr *buf, char **into, size_t *len)
     175              85 : {
     176              85 :         char *copy = ecalloc(1, buf->used + 1);
     177              85 :         memcpy(copy, buf->data, buf->used);
     178              85 :         if (into) {
     179              85 :                 *into = copy;
     180                 :         }
     181              85 :         if (len) {
     182              85 :                 *len = buf->used;
     183                 :         }
     184              85 :         return copy;
     185                 : }
     186                 : 
     187                 : PHPSTR_API phpstr *phpstr_dup(const phpstr *buf)
     188               0 : {
     189               0 :         phpstr *dup = phpstr_clone(buf);
     190               0 :         if (PHPSTR_NOMEM == phpstr_append(dup, buf->data, buf->used)) {
     191               0 :                 phpstr_free(&dup);
     192                 :         }
     193               0 :         return dup;
     194                 : }
     195                 : 
     196                 : PHPSTR_API size_t phpstr_cut(phpstr *buf, size_t offset, size_t length)
     197             145 : {
     198             145 :         if (offset >= buf->used) {
     199              11 :                 return 0;
     200                 :         }
     201             134 :         if (offset + length > buf->used) {
     202               0 :                 length = buf->used - offset;
     203                 :         }
     204             134 :         memmove(buf->data + offset, buf->data + offset + length, buf->used - length);
     205             134 :         buf->used -= length;
     206             134 :         buf->free += length;
     207             134 :         return length;
     208                 : }
     209                 : 
     210                 : PHPSTR_API phpstr *phpstr_sub(const phpstr *buf, size_t offset, size_t length)
     211               0 : {
     212               0 :         if (offset >= buf->used) {
     213               0 :                 return NULL;
     214                 :         } else {
     215               0 :                 size_t need = 1 + ((length + offset) > buf->used ? (buf->used - offset) : (length - offset));
     216               0 :                 phpstr *sub = phpstr_init_ex(NULL, need, PHPSTR_INIT_PREALLOC | (buf->pmem ? PHPSTR_INIT_PERSISTENT:0));
     217               0 :                 if (sub) {
     218               0 :                         if (PHPSTR_NOMEM == phpstr_append(sub, buf->data + offset, need)) {
     219               0 :                                 phpstr_free(&sub);
     220                 :                         } else {
     221               0 :                                 sub->size = buf->size;
     222                 :                         }
     223                 :                 }
     224               0 :                 return sub;
     225                 :         }
     226                 : }
     227                 : 
     228                 : PHPSTR_API phpstr *phpstr_right(const phpstr *buf, size_t length)
     229               0 : {
     230               0 :         if (length < buf->used) {
     231               0 :                 return phpstr_sub(buf, buf->used - length, length);
     232                 :         } else {
     233               0 :                 return phpstr_sub(buf, 0, buf->used);
     234                 :         }
     235                 : }
     236                 : 
     237                 : 
     238                 : PHPSTR_API phpstr *phpstr_merge_va(phpstr *buf, unsigned argc, va_list argv)
     239               0 : {
     240               0 :         unsigned i = 0;
     241               0 :         buf = phpstr_init(buf);
     242                 : 
     243               0 :         if (buf) {
     244               0 :                 while (argc > i++) {
     245               0 :                         phpstr_free_t f = va_arg(argv, phpstr_free_t);
     246               0 :                         phpstr *current = va_arg(argv, phpstr *);
     247               0 :                         phpstr_append(buf, current->data, current->used);
     248               0 :                         FREE_PHPSTR(f, current);
     249                 :                 }
     250                 :         }
     251                 : 
     252               0 :         return buf;
     253                 : }
     254                 : 
     255                 : PHPSTR_API phpstr *phpstr_merge_ex(phpstr *buf, unsigned argc, ...)
     256               0 : {
     257                 :         va_list argv;
     258                 :         phpstr *ret;
     259                 : 
     260               0 :         va_start(argv, argc);
     261               0 :         ret = phpstr_merge_va(buf, argc, argv);
     262               0 :         va_end(argv);
     263               0 :         return ret;
     264                 : }
     265                 : 
     266                 : PHPSTR_API phpstr *phpstr_merge(unsigned argc, ...)
     267               0 : {
     268                 :         va_list argv;
     269                 :         phpstr *ret;
     270                 : 
     271               0 :         va_start(argv, argc);
     272               0 :         ret = phpstr_merge_va(NULL, argc, argv);
     273               0 :         va_end(argv);
     274               0 :         return ret;
     275                 : }
     276                 : 
     277                 : PHPSTR_API phpstr *phpstr_fix(phpstr *buf)
     278             435 : {
     279             435 :         if (PHPSTR_NOMEM == phpstr_resize_ex(buf, 1, 1, 0)) {
     280               0 :                 return NULL;
     281                 :         }
     282             435 :         buf->data[buf->used] = '\0';
     283             435 :         return buf;
     284                 : }
     285                 : 
     286                 : PHPSTR_API int phpstr_cmp(phpstr *left, phpstr *right)
     287               0 : {
     288               0 :         if (left->used > right->used) {
     289               0 :                 return -1;
     290               0 :         } else if (right->used > left->used) {
     291               0 :                 return 1;
     292                 :         } else {
     293               0 :                 return memcmp(left->data, right->data, left->used);
     294                 :         }
     295                 : }
     296                 : 
     297                 : PHPSTR_API void phpstr_reset(phpstr *buf)
     298             206 : {
     299             206 :         buf->free += buf->used;
     300             206 :         buf->used = 0;
     301             206 : }
     302                 : 
     303                 : PHPSTR_API void phpstr_dtor(phpstr *buf)
     304             889 : {
     305             889 :         if (buf->data) {
     306             569 :                 pefree(buf->data, buf->pmem);
     307             569 :                 buf->data = NULL;
     308                 :         }
     309             889 :         buf->used = 0;
     310             889 :         buf->free = 0;
     311             889 : }
     312                 : 
     313                 : PHPSTR_API void phpstr_free(phpstr **buf)
     314              44 : {
     315              44 :         if (*buf) {
     316              44 :                 phpstr_dtor(*buf);
     317              44 :                 pefree(*buf, (*buf)->pmem);
     318              44 :                 *buf = NULL;
     319                 :         }
     320              44 : }
     321                 : 
     322                 : PHPSTR_API size_t phpstr_chunk_buffer(phpstr **s, const char *data, size_t data_len, char **chunk, size_t chunk_size)
     323              41 : {
     324                 :         phpstr *storage;
     325                 :         
     326              41 :         *chunk = NULL;
     327                 :         
     328              41 :         if (!*s) {
     329               1 :                 *s = phpstr_init_ex(NULL, chunk_size << 1, chunk_size ? PHPSTR_INIT_PREALLOC : 0);
     330                 :         }
     331              41 :         storage = *s;
     332                 :         
     333              41 :         if (data_len) {
     334              20 :                 phpstr_append(storage, data, data_len);
     335                 :         }
     336                 :         
     337              41 :         if (!chunk_size) {
     338               1 :                 phpstr_data(storage, chunk, &chunk_size);
     339               1 :                 phpstr_free(s);
     340               1 :                 return chunk_size;
     341                 :         }
     342                 :         
     343              40 :         if (storage->used >= (chunk_size = storage->size >> 1)) {
     344              20 :                 *chunk = estrndup(storage->data, chunk_size);
     345              20 :                 phpstr_cut(storage, 0, chunk_size);
     346              20 :                 return chunk_size;
     347                 :         }
     348                 :         
     349              20 :         return 0;
     350                 : }
     351                 : 
     352                 : PHPSTR_API void phpstr_chunked_output(phpstr **s, const char *data, size_t data_len, size_t chunk_len, phpstr_passthru_func passthru, void *opaque TSRMLS_DC)
     353              21 : {
     354              21 :         char *chunk = NULL;
     355              21 :         size_t got = 0;
     356                 :         
     357              62 :         while ((got = phpstr_chunk_buffer(s, data, data_len, &chunk, chunk_len))) {
     358              20 :                 passthru(opaque, chunk, got TSRMLS_CC);
     359              20 :                 if (!chunk_len) {
     360                 :                         /*      we already got the last chunk,
     361                 :                                 and freed all resources */
     362               0 :                         break;
     363                 :                 }
     364              20 :                 data = NULL;
     365              20 :                 data_len = 0;
     366              20 :                 STR_SET(chunk, NULL);
     367                 :         }
     368              21 :         STR_FREE(chunk);
     369              21 : }
     370                 : 
     371                 : /*
     372                 :  * Local variables:
     373                 :  * tab-width: 4
     374                 :  * c-basic-offset: 4
     375                 :  * End:
     376                 :  * vim600: sw=4 ts=4 fdm=marker
     377                 :  * vim<600: sw=4 ts=4
     378                 :  */
     379                 : 

Generated by: LTP GCOV extension version 1.5