Back to index

php5  5.3.10
Classes | Defines | Typedefs | Enumerations | Functions
php_stream_filter_api.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _php_stream_bucket
struct  _php_stream_bucket_brigade
struct  _php_stream_filter_ops
struct  _php_stream_filter_chain
struct  _php_stream_filter
struct  _php_stream_filter_factory

Defines

#define PHP_STREAM_FILTER_READ   0x0001
#define PHP_STREAM_FILTER_WRITE   0x0002
#define PHP_STREAM_FILTER_ALL   (PHP_STREAM_FILTER_READ | PHP_STREAM_FILTER_WRITE)
#define php_stream_bucket_addref(bucket)   (bucket)->refcount++
#define PSFS_FLAG_NORMAL   0 /* regular read/write */
#define PSFS_FLAG_FLUSH_INC   1 /* an incremental flush */
#define PSFS_FLAG_FLUSH_CLOSE   2 /* final flush prior to closing */
#define php_stream_filter_alloc(fops, thisptr, persistent)   _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC TSRMLS_CC)
#define php_stream_filter_alloc_rel(fops, thisptr, persistent)   _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC TSRMLS_CC)
#define php_stream_filter_prepend(chain, filter)   _php_stream_filter_prepend((chain), (filter) TSRMLS_CC)
#define php_stream_filter_append(chain, filter)   _php_stream_filter_append((chain), (filter) TSRMLS_CC)
#define php_stream_filter_flush(filter, finish)   _php_stream_filter_flush((filter), (finish) TSRMLS_CC)
#define php_stream_is_filtered(stream)   ((stream)->readfilters.head || (stream)->writefilters.head)

Typedefs

typedef struct _php_stream_bucket
typedef struct _php_stream_bucket_brigade
typedef struct
_php_stream_filter_ops 
php_stream_filter_ops
typedef struct
_php_stream_filter_chain 
php_stream_filter_chain
typedef struct
_php_stream_filter_factory 
php_stream_filter_factory

Enumerations

enum  php_stream_filter_status_t { PSFS_ERR_FATAL, PSFS_FEED_ME, PSFS_PASS_ON }

Functions

PHPAPI php_stream_bucket * php_stream_bucket_new (php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent TSRMLS_DC)
PHPAPI int php_stream_bucket_split (php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length TSRMLS_DC)
PHPAPI void php_stream_bucket_delref (php_stream_bucket *bucket TSRMLS_DC)
PHPAPI void php_stream_bucket_prepend (php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC)
PHPAPI void php_stream_bucket_append (php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC)
PHPAPI void php_stream_bucket_unlink (php_stream_bucket *bucket TSRMLS_DC)
PHPAPI php_stream_bucket * php_stream_bucket_make_writeable (php_stream_bucket *bucket TSRMLS_DC)
PHPAPI void _php_stream_filter_prepend (php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC)
PHPAPI int php_stream_filter_prepend_ex (php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC)
PHPAPI void _php_stream_filter_append (php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC)
PHPAPI int php_stream_filter_append_ex (php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC)
PHPAPI int _php_stream_filter_flush (php_stream_filter *filter, int finish TSRMLS_DC)
PHPAPI php_stream_filter * php_stream_filter_remove (php_stream_filter *filter, int call_dtor TSRMLS_DC)
PHPAPI void php_stream_filter_free (php_stream_filter *filter TSRMLS_DC)
PHPAPI php_stream_filter * _php_stream_filter_alloc (php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC)
PHPAPI int php_stream_filter_register_factory (const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC)
PHPAPI int php_stream_filter_unregister_factory (const char *filterpattern TSRMLS_DC)
PHPAPI int php_stream_filter_register_factory_volatile (const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC)
PHPAPI php_stream_filter * php_stream_filter_create (const char *filtername, zval *filterparams, int persistent TSRMLS_DC)

Class Documentation

struct _php_stream_bucket

Definition at line 44 of file php_stream_filter_api.h.

Class Members
php_stream_bucket_brigade * brigade
char * buf
size_t buflen
int is_persistent
php_stream_bucket * next
int own_buf
php_stream_bucket * prev
int refcount
struct _php_stream_bucket_brigade

Definition at line 58 of file php_stream_filter_api.h.

Class Members
php_stream_bucket * head
php_stream_bucket * tail
struct _php_stream_filter_chain

Definition at line 101 of file php_stream_filter_api.h.

Class Members
php_stream_filter * head
php_stream * stream
php_stream_filter * tail
struct _php_stream_filter

Definition at line 108 of file php_stream_filter_api.h.

Collaboration diagram for _php_stream_filter:
Class Members
void * abstract
php_stream_bucket_brigade buffer
php_stream_filter_chain * chain
php_stream_filter_ops * fops
int is_persistent
php_stream_filter * next
php_stream_filter * prev
int rsrc_id

Define Documentation

#define php_stream_bucket_addref (   bucket)    (bucket)->refcount++

Definition at line 73 of file php_stream_filter_api.h.

Definition at line 39 of file php_stream_filter_api.h.

#define php_stream_filter_alloc (   fops,
  thisptr,
  persistent 
)    _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC TSRMLS_CC)

Definition at line 136 of file php_stream_filter_api.h.

#define php_stream_filter_alloc_rel (   fops,
  thisptr,
  persistent 
)    _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC TSRMLS_CC)

Definition at line 137 of file php_stream_filter_api.h.

#define php_stream_filter_append (   chain,
  filter 
)    _php_stream_filter_append((chain), (filter) TSRMLS_CC)

Definition at line 139 of file php_stream_filter_api.h.

#define php_stream_filter_flush (   filter,
  finish 
)    _php_stream_filter_flush((filter), (finish) TSRMLS_CC)

Definition at line 140 of file php_stream_filter_api.h.

#define php_stream_filter_prepend (   chain,
  filter 
)    _php_stream_filter_prepend((chain), (filter) TSRMLS_CC)

Definition at line 138 of file php_stream_filter_api.h.

#define PHP_STREAM_FILTER_READ   0x0001

Definition at line 37 of file php_stream_filter_api.h.

#define PHP_STREAM_FILTER_WRITE   0x0002

Definition at line 38 of file php_stream_filter_api.h.

Definition at line 142 of file php_stream_filter_api.h.

#define PSFS_FLAG_FLUSH_CLOSE   2 /* final flush prior to closing */

Definition at line 82 of file php_stream_filter_api.h.

#define PSFS_FLAG_FLUSH_INC   1 /* an incremental flush */

Definition at line 81 of file php_stream_filter_api.h.

#define PSFS_FLAG_NORMAL   0 /* regular read/write */

Definition at line 80 of file php_stream_filter_api.h.


Typedef Documentation

typedef struct _php_stream_bucket

Definition at line 41 of file php_stream_filter_api.h.

Definition at line 42 of file php_stream_filter_api.h.


Enumeration Type Documentation

Enumerator:
PSFS_ERR_FATAL 
PSFS_FEED_ME 
PSFS_PASS_ON 

Definition at line 62 of file php_stream_filter_api.h.

             {
       PSFS_ERR_FATAL,      /* error in data stream */
       PSFS_FEED_ME, /* filter needs more data; stop processing chain until more is available */
       PSFS_PASS_ON  /* filter generated output buckets; pass them on to next in chain */
} php_stream_filter_status_t;

Function Documentation

PHPAPI php_stream_filter* _php_stream_filter_alloc ( php_stream_filter_ops fops,
void *  abstract,
int persistent STREAMS_DC  TSRMLS_DC 
)

Definition at line 295 of file filter.c.

{
       php_stream_filter *filter;

       filter = (php_stream_filter*) pemalloc_rel_orig(sizeof(php_stream_filter), persistent);
       memset(filter, 0, sizeof(php_stream_filter));

       filter->fops = fops;
       filter->abstract = abstract;
       filter->is_persistent = persistent;
       
       return filter;
}
PHPAPI void _php_stream_filter_append ( php_stream_filter_chain chain,
php_stream_filter *filter  TSRMLS_DC 
)

Definition at line 418 of file filter.c.

{
       if (php_stream_filter_append_ex(chain, filter TSRMLS_CC) != SUCCESS) {
              if (chain->head == filter) {
                     chain->head = NULL;
                     chain->tail = NULL;
              } else {
                     filter->prev->next = NULL;
                     chain->tail = filter->prev;
              }
       }
}

Here is the call graph for this function:

PHPAPI int _php_stream_filter_flush ( php_stream_filter *  filter,
int finish  TSRMLS_DC 
)

Definition at line 431 of file filter.c.

{
       php_stream_bucket_brigade brig_a = { NULL, NULL }, brig_b = { NULL, NULL }, *inp = &brig_a, *outp = &brig_b, *brig_temp;
       php_stream_bucket *bucket;
       php_stream_filter_chain *chain;
       php_stream_filter *current;
       php_stream *stream;
       size_t flushed_size = 0;
       long flags = (finish ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC);

       if (!filter->chain || !filter->chain->stream) {
              /* Filter is not attached to a chain, or chain is somehow not part of a stream */
              return FAILURE;
       }

       chain = filter->chain;
       stream = chain->stream;

       for(current = filter; current; current = current->next) {
              php_stream_filter_status_t status;

              status = filter->fops->filter(stream, filter, inp, outp, NULL, flags TSRMLS_CC);
              if (status == PSFS_FEED_ME) {
                     /* We've flushed the data far enough */
                     return SUCCESS;
              }
              if (status == PSFS_ERR_FATAL) {
                     return FAILURE;
              }
              /* Otherwise we have data available to PASS_ON
                     Swap the brigades and continue */
              brig_temp = inp;
              inp = outp;
              outp = brig_temp;
              outp->head = NULL;
              outp->tail = NULL;

              flags = PSFS_FLAG_NORMAL;
       }

       /* Last filter returned data via PSFS_PASS_ON
              Do something with it */

       for(bucket = inp->head; bucket; bucket = bucket->next) {
              flushed_size += bucket->buflen;
       }

       if (flushed_size == 0) {
              /* Unlikely, but possible */
              return SUCCESS;
       }

       if (chain == &(stream->readfilters)) {
              /* Dump any newly flushed data to the read buffer */
              if (stream->readpos > 0) {
                     /* Back the buffer up */
                     memcpy(stream->readbuf, stream->readbuf + stream->readpos, stream->writepos - stream->readpos);
                     stream->readpos = 0;
                     stream->writepos -= stream->readpos;
              }
              if (flushed_size > (stream->readbuflen - stream->writepos)) {
                     /* Grow the buffer */
                     stream->readbuf = perealloc(stream->readbuf, stream->writepos + flushed_size + stream->chunk_size, stream->is_persistent);
              }
              while ((bucket = inp->head)) {
                     memcpy(stream->readbuf + stream->writepos, bucket->buf, bucket->buflen);
                     stream->writepos += bucket->buflen;
                     php_stream_bucket_unlink(bucket TSRMLS_CC);
                     php_stream_bucket_delref(bucket TSRMLS_CC);
              }
       } else if (chain == &(stream->writefilters)) {
              /* Send flushed data to the stream */
              while ((bucket = inp->head)) {
                     stream->ops->write(stream, bucket->buf, bucket->buflen TSRMLS_CC);
                     php_stream_bucket_unlink(bucket TSRMLS_CC);
                     php_stream_bucket_delref(bucket TSRMLS_CC);
              }
       }

       return SUCCESS;
}

Here is the call graph for this function:

PHPAPI void _php_stream_filter_prepend ( php_stream_filter_chain chain,
php_stream_filter *filter  TSRMLS_DC 
)

Definition at line 332 of file filter.c.

Here is the call graph for this function:

PHPAPI void php_stream_bucket_append ( php_stream_bucket_brigade *  brigade,
php_stream_bucket *bucket  TSRMLS_DC 
)

Definition at line 206 of file filter.c.

{
       if (brigade->tail == bucket) {
              return;
       }

       bucket->prev = brigade->tail;
       bucket->next = NULL;

       if (brigade->tail) {
              brigade->tail->next = bucket;
       } else {
              brigade->head = bucket;
       }
       brigade->tail = bucket;
       bucket->brigade = brigade;
}

Here is the caller graph for this function:

PHPAPI void php_stream_bucket_delref ( php_stream_bucket *bucket  TSRMLS_DC)

Definition at line 182 of file filter.c.

{
       if (--bucket->refcount == 0) {
              if (bucket->own_buf) {
                     pefree(bucket->buf, bucket->is_persistent);
              }
              pefree(bucket, bucket->is_persistent);
       }
}

Here is the caller graph for this function:

PHPAPI php_stream_bucket* php_stream_bucket_make_writeable ( php_stream_bucket *bucket  TSRMLS_DC)

Definition at line 117 of file filter.c.

{
       php_stream_bucket *retval;

       php_stream_bucket_unlink(bucket TSRMLS_CC);
       
       if (bucket->refcount == 1 && bucket->own_buf) {
              return bucket;
       }

       retval = (php_stream_bucket*)pemalloc(sizeof(php_stream_bucket), bucket->is_persistent);
       memcpy(retval, bucket, sizeof(*retval));

       retval->buf = pemalloc(retval->buflen, retval->is_persistent);
       memcpy(retval->buf, bucket->buf, retval->buflen);

       retval->refcount = 1;
       retval->own_buf = 1;

       php_stream_bucket_delref(bucket TSRMLS_CC);
       
       return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI php_stream_bucket* php_stream_bucket_new ( php_stream *  stream,
char *  buf,
size_t  buflen,
int  own_buf,
int buf_persistent  TSRMLS_DC 
)

Definition at line 73 of file filter.c.

{
       int is_persistent = php_stream_is_persistent(stream);
       php_stream_bucket *bucket;

       bucket = (php_stream_bucket*)pemalloc(sizeof(php_stream_bucket), is_persistent);

       if (bucket == NULL) {
              return NULL;
       }
       
       bucket->next = bucket->prev = NULL;

       if (is_persistent && !buf_persistent) {
              /* all data in a persistent bucket must also be persistent */
              bucket->buf = pemalloc(buflen, 1);
              
              if (bucket->buf == NULL) {
                     pefree(bucket, 1);
                     return NULL;
              }
              
              memcpy(bucket->buf, buf, buflen);
              bucket->buflen = buflen;
              bucket->own_buf = 1;
       } else {
              bucket->buf = buf;
              bucket->buflen = buflen;
              bucket->own_buf = own_buf;
       }
       bucket->is_persistent = is_persistent;
       bucket->refcount = 1;
       bucket->brigade = NULL;

       return bucket;
}

Here is the caller graph for this function:

PHPAPI void php_stream_bucket_prepend ( php_stream_bucket_brigade *  brigade,
php_stream_bucket *bucket  TSRMLS_DC 
)

Definition at line 192 of file filter.c.

{
       bucket->next = brigade->head;
       bucket->prev = NULL;

       if (brigade->head) {
              brigade->head->prev = bucket;
       } else {
              brigade->tail = bucket;
       }
       brigade->head = bucket;
       bucket->brigade = brigade;
}

Here is the caller graph for this function:

PHPAPI int php_stream_bucket_split ( php_stream_bucket *  in,
php_stream_bucket **  left,
php_stream_bucket **  right,
size_t length  TSRMLS_DC 
)

Definition at line 141 of file filter.c.

{
       *left = (php_stream_bucket*)pecalloc(1, sizeof(php_stream_bucket), in->is_persistent);
       *right = (php_stream_bucket*)pecalloc(1, sizeof(php_stream_bucket), in->is_persistent);

       if (*left == NULL || *right == NULL) {
              goto exit_fail;
       }

       (*left)->buf = pemalloc(length, in->is_persistent);
       (*left)->buflen = length;
       memcpy((*left)->buf, in->buf, length);
       (*left)->refcount = 1;
       (*left)->own_buf = 1;
       (*left)->is_persistent = in->is_persistent;
       
       (*right)->buflen = in->buflen - length;
       (*right)->buf = pemalloc((*right)->buflen, in->is_persistent);
       memcpy((*right)->buf, in->buf + length, (*right)->buflen);
       (*right)->refcount = 1;
       (*right)->own_buf = 1;
       (*right)->is_persistent = in->is_persistent;
       
       return SUCCESS;
       
exit_fail:
       if (*right) {
              if ((*right)->buf) {
                     pefree((*right)->buf, in->is_persistent);
              }
              pefree(*right, in->is_persistent);
       }
       if (*left) {
              if ((*left)->buf) {
                     pefree((*left)->buf, in->is_persistent);
              }
              pefree(*left, in->is_persistent);
       }
       return FAILURE;
}
PHPAPI void php_stream_bucket_unlink ( php_stream_bucket *bucket  TSRMLS_DC)

Definition at line 224 of file filter.c.

{
       if (bucket->prev) {
              bucket->prev->next = bucket->next;
       } else if (bucket->brigade) {
              bucket->brigade->head = bucket->next;
       }
       if (bucket->next) {
              bucket->next->prev = bucket->prev;
       } else if (bucket->brigade) {
              bucket->brigade->tail = bucket->prev;
       }
       bucket->brigade = NULL;
       bucket->next = bucket->prev = NULL;
}

Here is the caller graph for this function:

PHPAPI int php_stream_filter_append_ex ( php_stream_filter_chain chain,
php_stream_filter *filter  TSRMLS_DC 
)

Definition at line 337 of file filter.c.

{
       php_stream *stream = chain->stream;

       filter->prev = chain->tail;
       filter->next = NULL;
       if (chain->tail) {
              chain->tail->next = filter;
       } else {
              chain->head = filter;
       }
       chain->tail = filter;
       filter->chain = chain;

       if (&(stream->readfilters) == chain && (stream->writepos - stream->readpos) > 0) {
              /* Let's going ahead and wind anything in the buffer through this filter */
              php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL };
              php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out;
              php_stream_filter_status_t status;
              php_stream_bucket *bucket;
              size_t consumed = 0;

              bucket = php_stream_bucket_new(stream, (char*) stream->readbuf + stream->readpos, stream->writepos - stream->readpos, 0, 0 TSRMLS_CC);
              php_stream_bucket_append(brig_inp, bucket TSRMLS_CC);
              status = filter->fops->filter(stream, filter, brig_inp, brig_outp, &consumed, PSFS_FLAG_NORMAL TSRMLS_CC);

              if (stream->readpos + consumed > (uint)stream->writepos) {
                     /* No behaving filter should cause this. */
                     status = PSFS_ERR_FATAL;
              }

              switch (status) {
                     case PSFS_ERR_FATAL:
                            while (brig_in.head) {
                                   bucket = brig_in.head;
                                   php_stream_bucket_unlink(bucket TSRMLS_CC);
                                   php_stream_bucket_delref(bucket TSRMLS_CC);
                            }
                            while (brig_out.head) {
                                   bucket = brig_out.head;
                                   php_stream_bucket_unlink(bucket TSRMLS_CC);
                                   php_stream_bucket_delref(bucket TSRMLS_CC);
                            }
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filter failed to process pre-buffered data");
                            return FAILURE;
                     case PSFS_FEED_ME:
                            /* We don't actually need data yet,
                               leave this filter in a feed me state until data is needed. 
                               Reset stream's internal read buffer since the filter is "holding" it. */
                            stream->readpos = 0;
                            stream->writepos = 0;
                            break;
                     case PSFS_PASS_ON:
                            /* If any data is consumed, we cannot rely upon the existing read buffer,
                               as the filtered data must replace the existing data, so invalidate the cache */
                            /* note that changes here should be reflected in
                               main/streams/streams.c::php_stream_fill_read_buffer */
                            stream->writepos = 0;
                            stream->readpos = 0;

                            while (brig_outp->head) {
                                   bucket = brig_outp->head;
                                   /* Grow buffer to hold this bucket if need be.
                                      TODO: See warning in main/stream/streams.c::php_stream_fill_read_buffer */
                                   if (stream->readbuflen - stream->writepos < bucket->buflen) {
                                          stream->readbuflen += bucket->buflen;
                                          stream->readbuf = perealloc(stream->readbuf, stream->readbuflen, stream->is_persistent);
                                   }
                                   memcpy(stream->readbuf + stream->writepos, bucket->buf, bucket->buflen);
                                   stream->writepos += bucket->buflen;

                                   php_stream_bucket_unlink(bucket TSRMLS_CC);
                                   php_stream_bucket_delref(bucket TSRMLS_CC);
                            }
                            break;
              }
       }

       return SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI php_stream_filter* php_stream_filter_create ( const char *  filtername,
zval *  filterparams,
int persistent  TSRMLS_DC 
)

Definition at line 252 of file filter.c.

{
       HashTable *filter_hash = (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash);
       php_stream_filter_factory *factory = NULL;
       php_stream_filter *filter = NULL;
       int n;
       char *period;

       n = strlen(filtername);
       
       if (SUCCESS == zend_hash_find(filter_hash, (char*)filtername, n + 1, (void**)&factory)) {
              filter = factory->create_filter(filtername, filterparams, persistent TSRMLS_CC);
       } else if ((period = strrchr(filtername, '.'))) {
              /* try a wildcard */
              char *wildname;

              wildname = emalloc(n+3);
              memcpy(wildname, filtername, n+1);
              period = wildname + (period - filtername);
              while (period && !filter) {
                     *period = '\0';
                     strncat(wildname, ".*", 2);
                     if (SUCCESS == zend_hash_find(filter_hash, wildname, strlen(wildname) + 1, (void**)&factory)) {
                            filter = factory->create_filter(filtername, filterparams, persistent TSRMLS_CC);
                     }

                     *period = '\0';
                     period = strrchr(wildname, '.');
              }
              efree(wildname);
       }

       if (filter == NULL) {
              /* TODO: these need correct docrefs */
              if (factory == NULL)
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to locate filter \"%s\"", filtername);
              else
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to create or locate filter \"%s\"", filtername);
       }
       
       return filter;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI void php_stream_filter_free ( php_stream_filter *filter  TSRMLS_DC)

Definition at line 309 of file filter.c.

{
       if (filter->fops->dtor)
              filter->fops->dtor(filter TSRMLS_CC);
       pefree(filter, filter->is_persistent);
}

Here is the caller graph for this function:

PHPAPI int php_stream_filter_prepend_ex ( php_stream_filter_chain chain,
php_stream_filter *filter  TSRMLS_DC 
)

Definition at line 316 of file filter.c.

{
       filter->next = chain->head;
       filter->prev = NULL;

       if (chain->head) {
              chain->head->prev = filter;
       } else {
              chain->tail = filter;
       }
       chain->head = filter;
       filter->chain = chain;

       return SUCCESS;
}

Here is the caller graph for this function:

PHPAPI int php_stream_filter_register_factory ( const char *  filterpattern,
php_stream_filter_factory *factory  TSRMLS_DC 
)

Definition at line 47 of file filter.c.

{
       return zend_hash_add(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern) + 1, factory, sizeof(*factory), NULL);
}

Here is the caller graph for this function:

PHPAPI int php_stream_filter_register_factory_volatile ( const char *  filterpattern,
php_stream_filter_factory *factory  TSRMLS_DC 
)

Definition at line 58 of file filter.c.

{
       if (!FG(stream_filters)) {
              php_stream_filter_factory tmpfactory;

              ALLOC_HASHTABLE(FG(stream_filters));
              zend_hash_init(FG(stream_filters), zend_hash_num_elements(&stream_filters_hash), NULL, NULL, 1);
              zend_hash_copy(FG(stream_filters), &stream_filters_hash, NULL, &tmpfactory, sizeof(php_stream_filter_factory));
       }

       return zend_hash_add(FG(stream_filters), (char*)filterpattern, strlen(filterpattern) + 1, factory, sizeof(*factory), NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI php_stream_filter* php_stream_filter_remove ( php_stream_filter *  filter,
int call_dtor  TSRMLS_DC 
)

Definition at line 513 of file filter.c.

{
       if (filter->prev) {
              filter->prev->next = filter->next;
       } else {
              filter->chain->head = filter->next;
       }
       if (filter->next) {
              filter->next->prev = filter->prev;
       } else {
              filter->chain->tail = filter->prev;
       }

       if (filter->rsrc_id > 0) {
              zend_list_delete(filter->rsrc_id);
       }

       if (call_dtor) {
              php_stream_filter_free(filter TSRMLS_CC);
              return NULL;
       }
       return filter;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI int php_stream_filter_unregister_factory ( const char *filterpattern  TSRMLS_DC)

Definition at line 52 of file filter.c.

{
       return zend_hash_del(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern) + 1);
}

Here is the caller graph for this function: