Back to index

php5  5.3.10
Classes | Defines | Typedefs | Functions | Variables
spl_dllist.c File Reference
#include "php.h"
#include "zend_exceptions.h"
#include "zend_hash.h"
#include "php_spl.h"
#include "spl_functions.h"
#include "spl_engine.h"
#include "spl_iterators.h"
#include "spl_dllist.h"
#include "spl_exceptions.h"

Go to the source code of this file.

Classes

struct  _spl_ptr_llist_element
struct  _spl_ptr_llist
struct  _spl_dllist_object
struct  _spl_dllist_it

Defines

#define SPL_LLIST_DELREF(elem)
#define SPL_LLIST_CHECK_DELREF(elem)
#define SPL_LLIST_ADDREF(elem)   (elem)->rc++
#define SPL_LLIST_CHECK_ADDREF(elem)   if(elem) (elem)->rc++
#define SPL_DLLIST_IT_DELETE   0x00000001 /* Delete flag makes the iterator delete the current element on next */
#define SPL_DLLIST_IT_LIFO   0x00000002 /* LIFO flag makes the iterator traverse the structure as a LastInFirstOut */
#define SPL_DLLIST_IT_MASK   0x00000003 /* Mask to isolate flags related to iterators */
#define SPL_DLLIST_IT_FIX   0x00000004 /* Backward/Forward bit is fixed */

Typedefs

typedef struct
_spl_ptr_llist_element 
spl_ptr_llist_element
typedef void(* spl_ptr_llist_dtor_func )(spl_ptr_llist_element *TSRMLS_DC)
typedef void(* spl_ptr_llist_ctor_func )(spl_ptr_llist_element *TSRMLS_DC)
typedef struct _spl_ptr_llist spl_ptr_llist
typedef struct _spl_dllist_object
typedef struct _spl_dllist_it

Functions

static void spl_ptr_llist_zval_dtor (spl_ptr_llist_element *elem TSRMLS_DC)
static void spl_ptr_llist_zval_ctor (spl_ptr_llist_element *elem TSRMLS_DC)
static spl_ptr_llistspl_ptr_llist_init (spl_ptr_llist_ctor_func ctor, spl_ptr_llist_dtor_func dtor)
static long spl_ptr_llist_count (spl_ptr_llist *llist)
static void spl_ptr_llist_destroy (spl_ptr_llist *llist TSRMLS_DC)
static spl_ptr_llist_elementspl_ptr_llist_offset (spl_ptr_llist *llist, long offset, int backward)
static void spl_ptr_llist_unshift (spl_ptr_llist *llist, void *data TSRMLS_DC)
static void spl_ptr_llist_push (spl_ptr_llist *llist, void *data TSRMLS_DC)
static void * spl_ptr_llist_pop (spl_ptr_llist *llist TSRMLS_DC)
static void * spl_ptr_llist_last (spl_ptr_llist *llist)
static void * spl_ptr_llist_first (spl_ptr_llist *llist)
static void * spl_ptr_llist_shift (spl_ptr_llist *llist TSRMLS_DC)
static void spl_ptr_llist_copy (spl_ptr_llist *from, spl_ptr_llist *to TSRMLS_DC)
static void spl_dllist_object_free_storage (void *object TSRMLS_DC)
zend_object_iterator * spl_dllist_get_iterator (zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
static zend_object_value spl_dllist_object_new_ex (zend_class_entry *class_type, spl_dllist_object **obj, zval *orig, int clone_orig TSRMLS_DC)
static zend_object_value spl_dllist_object_new (zend_class_entry *class_type TSRMLS_DC)
static zend_object_value spl_dllist_object_clone (zval *zobject TSRMLS_DC)
static int spl_dllist_object_count_elements (zval *object, long *count TSRMLS_DC)
static HashTablespl_dllist_object_get_debug_info (zval *obj, int *is_temp TSRMLS_DC)
 SPL_METHOD (SplDoublyLinkedList, push)
 SPL_METHOD (SplDoublyLinkedList, unshift)
 SPL_METHOD (SplDoublyLinkedList, pop)
 SPL_METHOD (SplDoublyLinkedList, shift)
 SPL_METHOD (SplDoublyLinkedList, top)
 SPL_METHOD (SplDoublyLinkedList, bottom)
 SPL_METHOD (SplDoublyLinkedList, count)
 SPL_METHOD (SplDoublyLinkedList, isEmpty)
 SPL_METHOD (SplDoublyLinkedList, setIteratorMode)
 SPL_METHOD (SplDoublyLinkedList, getIteratorMode)
 SPL_METHOD (SplDoublyLinkedList, offsetExists)
 SPL_METHOD (SplDoublyLinkedList, offsetGet)
 SPL_METHOD (SplDoublyLinkedList, offsetSet)
 SPL_METHOD (SplDoublyLinkedList, offsetUnset)
static void spl_dllist_it_dtor (zend_object_iterator *iter TSRMLS_DC)
static void spl_dllist_it_helper_rewind (spl_ptr_llist_element **traverse_pointer_ptr, int *traverse_position_ptr, spl_ptr_llist *llist, int flags TSRMLS_DC)
static void spl_dllist_it_helper_move_forward (spl_ptr_llist_element **traverse_pointer_ptr, int *traverse_position_ptr, spl_ptr_llist *llist, int flags TSRMLS_DC)
static void spl_dllist_it_rewind (zend_object_iterator *iter TSRMLS_DC)
static int spl_dllist_it_valid (zend_object_iterator *iter TSRMLS_DC)
static void spl_dllist_it_get_current_data (zend_object_iterator *iter, zval ***data TSRMLS_DC)
static int spl_dllist_it_get_current_key (zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
static void spl_dllist_it_move_forward (zend_object_iterator *iter TSRMLS_DC)
 SPL_METHOD (SplDoublyLinkedList, key)
 SPL_METHOD (SplDoublyLinkedList, prev)
 SPL_METHOD (SplDoublyLinkedList, next)
 SPL_METHOD (SplDoublyLinkedList, valid)
 SPL_METHOD (SplDoublyLinkedList, rewind)
 SPL_METHOD (SplDoublyLinkedList, current)
 PHP_MINIT_FUNCTION (spl_dllist)

Variables

zend_object_handlers spl_handler_SplDoublyLinkedList
PHPAPI zend_class_entry * spl_ce_SplDoublyLinkedList
PHPAPI zend_class_entry * spl_ce_SplQueue
PHPAPI zend_class_entry * spl_ce_SplStack
zend_object_iterator_funcs spl_dllist_it_funcs
static const zend_function_entry spl_funcs_SplQueue []
static const zend_function_entry spl_funcs_SplDoublyLinkedList []

Class Documentation

struct _spl_ptr_llist_element

Definition at line 63 of file spl_dllist.c.

Collaboration diagram for _spl_ptr_llist_element:
Class Members
void * data
struct _spl_ptr_llist_element * next
struct _spl_ptr_llist_element * prev
int rc
struct _spl_ptr_llist

Definition at line 73 of file spl_dllist.c.

Collaboration diagram for _spl_ptr_llist:
Class Members
int count
spl_ptr_llist_ctor_func ctor
spl_ptr_llist_dtor_func dtor
spl_ptr_llist_element * head
spl_ptr_llist_element * tail
struct _spl_dllist_object

Definition at line 84 of file spl_dllist.c.

Collaboration diagram for _spl_dllist_object:
Class Members
zend_class_entry * ce_get_iterator
HashTable * debug_info
int flags
zend_function * fptr_count
zend_function * fptr_offset_del
zend_function * fptr_offset_get
zend_function * fptr_offset_has
zend_function * fptr_offset_set
spl_ptr_llist * llist
zval * retval
zend_object std
spl_ptr_llist_element * traverse_pointer
int traverse_position
struct _spl_dllist_it

Definition at line 101 of file spl_dllist.c.

Collaboration diagram for _spl_dllist_it:
Class Members
int flags
zend_user_iterator intern
spl_dllist_object * object
spl_ptr_llist_element * traverse_pointer
int traverse_position

Define Documentation

#define SPL_DLLIST_IT_DELETE   0x00000001 /* Delete flag makes the iterator delete the current element on next */

Definition at line 54 of file spl_dllist.c.

#define SPL_DLLIST_IT_FIX   0x00000004 /* Backward/Forward bit is fixed */

Definition at line 57 of file spl_dllist.c.

#define SPL_DLLIST_IT_LIFO   0x00000002 /* LIFO flag makes the iterator traverse the structure as a LastInFirstOut */

Definition at line 55 of file spl_dllist.c.

#define SPL_DLLIST_IT_MASK   0x00000003 /* Mask to isolate flags related to iterators */

Definition at line 56 of file spl_dllist.c.

#define SPL_LLIST_ADDREF (   elem)    (elem)->rc++

Definition at line 51 of file spl_dllist.c.

#define SPL_LLIST_CHECK_ADDREF (   elem)    if(elem) (elem)->rc++

Definition at line 52 of file spl_dllist.c.

#define SPL_LLIST_CHECK_DELREF (   elem)
Value:
if((elem) && !--(elem)->rc) { \
       efree(elem); \
       elem = NULL; \
}

Definition at line 46 of file spl_dllist.c.

#define SPL_LLIST_DELREF (   elem)
Value:
if(!--(elem)->rc) { \
       efree(elem); \
       elem = NULL; \
}

Definition at line 41 of file spl_dllist.c.


Typedef Documentation

typedef struct _spl_dllist_it

Definition at line 82 of file spl_dllist.c.

typedef struct _spl_dllist_object

Definition at line 81 of file spl_dllist.c.

typedef struct _spl_ptr_llist spl_ptr_llist

Definition at line 71 of file spl_dllist.c.

Definition at line 70 of file spl_dllist.c.


Function Documentation

PHP_MINIT_FUNCTION ( spl_dllist  )
zend_object_iterator * spl_dllist_get_iterator ( zend_class_entry *  ce,
zval *  object,
int by_ref  TSRMLS_DC 
)

Definition at line 1141 of file spl_dllist.c.

{
       spl_dllist_it     *iterator;
       spl_dllist_object *dllist_object = (spl_dllist_object*)zend_object_store_get_object(object TSRMLS_CC);

       if (by_ref) {
              zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0 TSRMLS_CC);
              return NULL;
       }

       Z_ADDREF_P(object);

       iterator                     = emalloc(sizeof(spl_dllist_it));
       iterator->intern.it.data     = (void*)object;
       iterator->intern.it.funcs    = &spl_dllist_it_funcs;
       iterator->intern.ce          = ce;
       iterator->intern.value       = NULL;
       iterator->traverse_position  = dllist_object->traverse_position;
       iterator->traverse_pointer   = dllist_object->traverse_pointer;
       iterator->flags              = dllist_object->flags & SPL_DLLIST_IT_MASK;
       iterator->object             = dllist_object;

       SPL_LLIST_CHECK_ADDREF(iterator->traverse_pointer);


       return (zend_object_iterator*)iterator;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void spl_dllist_it_dtor ( zend_object_iterator *iter  TSRMLS_DC) [static]

Definition at line 924 of file spl_dllist.c.

{
       spl_dllist_it *iterator = (spl_dllist_it *)iter;

       SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer);

       zend_user_it_invalidate_current(iter TSRMLS_CC);
       zval_ptr_dtor((zval**)&iterator->intern.it.data);

       efree(iterator);
}

Here is the call graph for this function:

static void spl_dllist_it_get_current_data ( zend_object_iterator *  iter,
zval ***data  TSRMLS_DC 
) [static]

Definition at line 1008 of file spl_dllist.c.

{
       spl_dllist_it         *iterator = (spl_dllist_it *)iter;
       spl_ptr_llist_element *element  = iterator->traverse_pointer;

       if (element == NULL || element->data == NULL) {
              *data = NULL;
       } else {
              *data = (zval **)&element->data;
       }
}
static int spl_dllist_it_get_current_key ( zend_object_iterator *  iter,
char **  str_key,
uint str_key_len,
ulong *int_key  TSRMLS_DC 
) [static]

Definition at line 1021 of file spl_dllist.c.

{
       spl_dllist_it *iterator = (spl_dllist_it *)iter;

       *int_key = (ulong) iterator->traverse_position;
       return HASH_KEY_IS_LONG;
}
static void spl_dllist_it_helper_move_forward ( spl_ptr_llist_element **  traverse_pointer_ptr,
int traverse_position_ptr,
spl_ptr_llist llist,
int flags  TSRMLS_DC 
) [static]

Definition at line 953 of file spl_dllist.c.

{
       if (*traverse_pointer_ptr) {
              spl_ptr_llist_element *old = *traverse_pointer_ptr;

              if (flags & SPL_DLLIST_IT_LIFO) {
                     *traverse_pointer_ptr = old->prev;
                     (*traverse_position_ptr)--;

                     if (flags & SPL_DLLIST_IT_DELETE) {
                            zval *prev = (zval *)spl_ptr_llist_pop(llist TSRMLS_CC);

                            if (prev) {
                                   zval_ptr_dtor((zval **)&prev);
                            }
                     }
              } else {
                     *traverse_pointer_ptr = old->next;

                     if (flags & SPL_DLLIST_IT_DELETE) {
                            zval *prev = (zval *)spl_ptr_llist_shift(llist TSRMLS_CC);

                            if (prev) {
                                   zval_ptr_dtor((zval **)&prev);
                            }
                     } else {
                            (*traverse_position_ptr)++;
                     }
              }

              SPL_LLIST_DELREF(old);
              SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void spl_dllist_it_helper_rewind ( spl_ptr_llist_element **  traverse_pointer_ptr,
int traverse_position_ptr,
spl_ptr_llist llist,
int flags  TSRMLS_DC 
) [static]

Definition at line 937 of file spl_dllist.c.

{
       SPL_LLIST_CHECK_DELREF(*traverse_pointer_ptr);

       if (flags & SPL_DLLIST_IT_LIFO) {
              *traverse_position_ptr = llist->count-1;
              *traverse_pointer_ptr  = llist->tail;
       } else {
              *traverse_position_ptr = 0;
              *traverse_pointer_ptr  = llist->head;
       }

       SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr);
}

Here is the caller graph for this function:

static void spl_dllist_it_move_forward ( zend_object_iterator *iter  TSRMLS_DC) [static]

Definition at line 1030 of file spl_dllist.c.

{
       spl_dllist_it     *iterator = (spl_dllist_it *)iter;
       spl_dllist_object *object   = iterator->object;

       zend_user_it_invalidate_current(iter TSRMLS_CC);

       spl_dllist_it_helper_move_forward(&iterator->traverse_pointer, &iterator->traverse_position, object->llist, object->flags TSRMLS_CC);
}

Here is the call graph for this function:

static void spl_dllist_it_rewind ( zend_object_iterator *iter  TSRMLS_DC) [static]

Definition at line 989 of file spl_dllist.c.

{
       spl_dllist_it     *iterator = (spl_dllist_it *)iter;
       spl_dllist_object *object   = iterator->object;
       spl_ptr_llist     *llist    = object->llist;

       spl_dllist_it_helper_rewind(&iterator->traverse_pointer, &iterator->traverse_position, llist, object->flags TSRMLS_CC);
}

Here is the call graph for this function:

static int spl_dllist_it_valid ( zend_object_iterator *iter  TSRMLS_DC) [static]

Definition at line 999 of file spl_dllist.c.

{
       spl_dllist_it         *iterator = (spl_dllist_it *)iter;
       spl_ptr_llist_element *element  = iterator->traverse_pointer;

       return (element != NULL ? SUCCESS : FAILURE);
}
static zend_object_value spl_dllist_object_clone ( zval *zobject  TSRMLS_DC) [static]

Definition at line 464 of file spl_dllist.c.

{
       zend_object_value   new_obj_val;
       zend_object        *old_object;
       zend_object        *new_object;
       zend_object_handle  handle = Z_OBJ_HANDLE_P(zobject);
       spl_dllist_object  *intern;

       old_object  = zend_objects_get_address(zobject TSRMLS_CC);
       new_obj_val = spl_dllist_object_new_ex(old_object->ce, &intern, zobject, 1 TSRMLS_CC);
       new_object  = &intern->std;

       zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);

       return new_obj_val;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int spl_dllist_object_count_elements ( zval *  object,
long *count  TSRMLS_DC 
) [static]

Definition at line 482 of file spl_dllist.c.

{
       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(object TSRMLS_CC);

       if (intern->fptr_count) {
              zval *rv;
              zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count", &rv);
              if (rv) {
                     zval_ptr_dtor(&intern->retval);
                     MAKE_STD_ZVAL(intern->retval);
                     ZVAL_ZVAL(intern->retval, rv, 1, 1);
                     convert_to_long(intern->retval);
                     *count = (long) Z_LVAL_P(intern->retval);
                     return SUCCESS;
              }
              *count = 0;
              return FAILURE;
       }

       *count = spl_ptr_llist_count(intern->llist);
       return SUCCESS;
} 

Here is the call graph for this function:

Here is the caller graph for this function:

static void spl_dllist_object_free_storage ( void *object  TSRMLS_DC) [static]

Definition at line 339 of file spl_dllist.c.

{
       spl_dllist_object *intern = (spl_dllist_object *)object;
       zval              *tmp    = NULL;

       zend_object_std_dtor(&intern->std TSRMLS_CC);

       while(intern->llist->count > 0) {
              tmp = (zval *)spl_ptr_llist_pop(intern->llist TSRMLS_CC);
              zval_ptr_dtor(&tmp);
       }

       spl_ptr_llist_destroy(intern->llist TSRMLS_CC);
       SPL_LLIST_CHECK_DELREF(intern->traverse_pointer);
       zval_ptr_dtor(&intern->retval);

       if (intern->debug_info != NULL) {
              zend_hash_destroy(intern->debug_info);
              efree(intern->debug_info);
       }

       efree(object);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static HashTable* spl_dllist_object_get_debug_info ( zval *  obj,
int *is_temp  TSRMLS_DC 
) [static]

Definition at line 506 of file spl_dllist.c.

{
       spl_dllist_object     *intern  = (spl_dllist_object*)zend_object_store_get_object(obj TSRMLS_CC);
       spl_ptr_llist_element *current = intern->llist->head, *next;
       zval *tmp, zrv, *dllist_array;
       char *pnstr;
       int  pnlen;
       int  i = 0;

       *is_temp = 0;

       if (intern->debug_info == NULL) {
              ALLOC_HASHTABLE(intern->debug_info);
              zend_hash_init(intern->debug_info, 1, NULL, ZVAL_PTR_DTOR, 0);
       }

       if (intern->debug_info->nApplyCount == 0) {
              INIT_PZVAL(&zrv);
              Z_ARRVAL(zrv) = intern->debug_info;

              zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));

              pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC);
              add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags);
              efree(pnstr);

              ALLOC_INIT_ZVAL(dllist_array);
              array_init(dllist_array);

              while (current) {
                     next = current->next;

                     add_index_zval(dllist_array, i, (zval *)current->data);
                     Z_ADDREF_P(current->data);
                     i++;

                     current = next;
              }

              pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1, &pnlen TSRMLS_CC);
              add_assoc_zval_ex(&zrv, pnstr, pnlen+1, dllist_array);
              efree(pnstr);
       }

       return intern->debug_info;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static zend_object_value spl_dllist_object_new ( zend_class_entry *class_type  TSRMLS_DC) [static]

Definition at line 457 of file spl_dllist.c.

{
       spl_dllist_object *tmp;
       return spl_dllist_object_new_ex(class_type, &tmp, NULL, 0 TSRMLS_CC);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static zend_object_value spl_dllist_object_new_ex ( zend_class_entry *  class_type,
spl_dllist_object **  obj,
zval *  orig,
int clone_orig  TSRMLS_DC 
) [static]

Definition at line 366 of file spl_dllist.c.

{
       zend_object_value  retval;
       spl_dllist_object *intern;
       zval              *tmp;
       zend_class_entry  *parent = class_type;
       int                inherited = 0;

       intern = ecalloc(1, sizeof(spl_dllist_object));
       *obj = intern;
       ALLOC_INIT_ZVAL(intern->retval);

       zend_object_std_init(&intern->std, class_type TSRMLS_CC);
       zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));

       intern->flags = 0;
       intern->traverse_position = 0;
       intern->debug_info = NULL;

       if (orig) {
              spl_dllist_object *other = (spl_dllist_object*)zend_object_store_get_object(orig TSRMLS_CC);
              intern->ce_get_iterator = other->ce_get_iterator;

              if (clone_orig) {
                     intern->llist = (spl_ptr_llist *)spl_ptr_llist_init(other->llist->ctor, other->llist->dtor);
                     spl_ptr_llist_copy(other->llist, intern->llist TSRMLS_CC);
                     intern->traverse_pointer  = intern->llist->head;
                     SPL_LLIST_CHECK_ADDREF(intern->traverse_pointer);
              } else {
                     intern->llist = other->llist;
                     intern->traverse_pointer  = intern->llist->head;
                     SPL_LLIST_CHECK_ADDREF(intern->traverse_pointer);
              }

              intern->flags = other->flags;
       } else {
              intern->llist = (spl_ptr_llist *)spl_ptr_llist_init(spl_ptr_llist_zval_ctor, spl_ptr_llist_zval_dtor);
              intern->traverse_pointer  = intern->llist->head;
              SPL_LLIST_CHECK_ADDREF(intern->traverse_pointer);
       }

       while (parent) {
              if (parent == spl_ce_SplStack) {
                     intern->flags |= (SPL_DLLIST_IT_FIX | SPL_DLLIST_IT_LIFO);
                     retval.handlers = &spl_handler_SplDoublyLinkedList;
              } else if (parent == spl_ce_SplQueue) {
                     intern->flags |= SPL_DLLIST_IT_FIX;
                     retval.handlers = &spl_handler_SplDoublyLinkedList;
              }

              if (parent == spl_ce_SplDoublyLinkedList) {
                     retval.handlers = &spl_handler_SplDoublyLinkedList;
                     break;
              }

              parent = parent->parent;
              inherited = 1;
       }

       retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, spl_dllist_object_free_storage, NULL TSRMLS_CC);

       if (!parent) { /* this must never happen */
              php_error_docref(NULL TSRMLS_CC, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplDoublyLinkedList");
       }
       if (inherited) {
              zend_hash_find(&class_type->function_table, "offsetget",    sizeof("offsetget"),    (void **) &intern->fptr_offset_get);
              if (intern->fptr_offset_get->common.scope == parent) {
                     intern->fptr_offset_get = NULL;
              }
              zend_hash_find(&class_type->function_table, "offsetset",    sizeof("offsetset"),    (void **) &intern->fptr_offset_set);
              if (intern->fptr_offset_set->common.scope == parent) {
                     intern->fptr_offset_set = NULL;
              }
              zend_hash_find(&class_type->function_table, "offsetexists", sizeof("offsetexists"), (void **) &intern->fptr_offset_has);
              if (intern->fptr_offset_has->common.scope == parent) {
                     intern->fptr_offset_has = NULL;
              }
              zend_hash_find(&class_type->function_table, "offsetunset",  sizeof("offsetunset"),  (void **) &intern->fptr_offset_del);
              if (intern->fptr_offset_del->common.scope == parent) {
                     intern->fptr_offset_del = NULL;
              }
              zend_hash_find(&class_type->function_table, "count",        sizeof("count"),        (void **) &intern->fptr_count);
              if (intern->fptr_count->common.scope == parent) {
                     intern->fptr_count = NULL;
              }
       }

       return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 556 of file spl_dllist.c.

{
       zval *value;
       spl_dllist_object *intern;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
              return;
       }

       SEPARATE_ARG_IF_REF(value);

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       spl_ptr_llist_push(intern->llist, value TSRMLS_CC);

       RETURN_TRUE;
} 

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
unshift   
)

Definition at line 576 of file spl_dllist.c.

{
       zval *value;
       spl_dllist_object *intern;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
              return;
       }

       SEPARATE_ARG_IF_REF(value);

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       spl_ptr_llist_unshift(intern->llist, value TSRMLS_CC);

       RETURN_TRUE;
}

Here is the call graph for this function:

Definition at line 596 of file spl_dllist.c.

{
       zval *value;
       spl_dllist_object *intern;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
              return;
       }

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       value = (zval *)spl_ptr_llist_pop(intern->llist TSRMLS_CC);

       if (value == NULL) {
              zend_throw_exception(spl_ce_RuntimeException, "Can't pop from an empty datastructure", 0 TSRMLS_CC);
              return;
       }

       RETURN_ZVAL(value, 1, 1);
} 

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
shift   
)

Definition at line 619 of file spl_dllist.c.

{
       zval *value;
       spl_dllist_object *intern;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
              return;
       }

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       value  = (zval *)spl_ptr_llist_shift(intern->llist TSRMLS_CC);

       if (value == NULL) {
              zend_throw_exception(spl_ce_RuntimeException, "Can't shift from an empty datastructure", 0 TSRMLS_CC);
              return;
       }

       RETURN_ZVAL(value, 1, 1);
} 

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
top   
)

Definition at line 642 of file spl_dllist.c.

{
       zval *value;
       spl_dllist_object *intern;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
              return;
       }

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       value  = (zval *)spl_ptr_llist_last(intern->llist);

       if (value == NULL) {
              zend_throw_exception(spl_ce_RuntimeException, "Can't peek at an empty datastructure", 0 TSRMLS_CC);
              return;
       }

       RETURN_ZVAL(value, 1, 0);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
bottom   
)

Definition at line 665 of file spl_dllist.c.

{
       zval *value;
       spl_dllist_object *intern;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
              return;
       }

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       value  = (zval *)spl_ptr_llist_first(intern->llist);

       if (value == NULL) {
              zend_throw_exception(spl_ce_RuntimeException, "Can't peek at an empty datastructure", 0 TSRMLS_CC);
              return;
       }

       RETURN_ZVAL(value, 1, 0);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
count   
)

Definition at line 688 of file spl_dllist.c.

{
       long count;
       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
              return;
       }

       count = spl_ptr_llist_count(intern->llist);
       RETURN_LONG(count);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
isEmpty   
)

Definition at line 704 of file spl_dllist.c.

{
       long count;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
              return;
       }

       spl_dllist_object_count_elements(getThis(), &count TSRMLS_CC);
       RETURN_BOOL(count==0);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
setIteratorMode   
)

Definition at line 719 of file spl_dllist.c.

{
       long value;
       spl_dllist_object *intern;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == FAILURE) {
              return;
       }

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);

       if (intern->flags & SPL_DLLIST_IT_FIX
              && (intern->flags & SPL_DLLIST_IT_LIFO) != (value & SPL_DLLIST_IT_LIFO)) {
              zend_throw_exception(spl_ce_RuntimeException, "Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen", 0 TSRMLS_CC);
              return;
       }

       intern->flags = value & SPL_DLLIST_IT_MASK;

       RETURN_LONG(intern->flags);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
getIteratorMode   
)

Definition at line 744 of file spl_dllist.c.

{
       spl_dllist_object *intern;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
              return;
       }

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);

       RETURN_LONG(intern->flags);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
offsetExists   
)

Definition at line 760 of file spl_dllist.c.

{
       zval              *zindex;
       spl_dllist_object *intern;
       long               index;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zindex) == FAILURE) {
              return;
       }

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       index  = spl_offset_convert_to_long(zindex TSRMLS_CC);

       RETURN_BOOL(index >= 0 && index < intern->llist->count);
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
offsetGet   
)

Definition at line 778 of file spl_dllist.c.

{
       zval                  *zindex, *value;
       long                   index;
       spl_dllist_object     *intern;
       spl_ptr_llist_element *element;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zindex) == FAILURE) {
              return;
       }

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       index  = spl_offset_convert_to_long(zindex TSRMLS_CC);

    if (index < 0 || index >= intern->llist->count) {
              zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
              return;
       }

       element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO);

       if (element != NULL) {
              value = (zval *)element->data;
              RETURN_ZVAL(value, 1, 0);
       } else {
              zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0 TSRMLS_CC);
              return;
       }
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
offsetSet   
)

Definition at line 810 of file spl_dllist.c.

{
       zval                  *zindex, *value;
       spl_dllist_object     *intern;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zindex, &value) == FAILURE) {
              return;
       }
       SEPARATE_ARG_IF_REF(value);

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);

       if (Z_TYPE_P(zindex) == IS_NULL) {
              /* $obj[] = ... */
              spl_ptr_llist_push(intern->llist, value TSRMLS_CC);
       } else {
              /* $obj[$foo] = ... */
              long                   index;
              spl_ptr_llist_element *element;

              index = spl_offset_convert_to_long(zindex TSRMLS_CC);

              if (index < 0 || index >= intern->llist->count) {
                     zval_ptr_dtor(&value);
                     zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
                     return;
              }

              element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO);

              if (element != NULL) {
                     /* call dtor on the old element as in spl_ptr_llist_pop */
                     if (intern->llist->dtor) {
                            intern->llist->dtor(element TSRMLS_CC);
                     }

                     /* the element is replaced, delref the old one as in
                      * SplDoublyLinkedList::pop() */
                     zval_ptr_dtor((zval **)&element->data);
                     element->data = value;

                     /* new element, call ctor as in spl_ptr_llist_push */
                     if (intern->llist->ctor) {
                            intern->llist->ctor(element TSRMLS_CC);
                     }
              } else {
                     zval_ptr_dtor(&value);
                     zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0 TSRMLS_CC);
                     return;
              }
       }
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
offsetUnset   
)

Definition at line 865 of file spl_dllist.c.

{
       zval                  *zindex;
       long                   index;
       spl_dllist_object     *intern;
       spl_ptr_llist_element *element;
       spl_ptr_llist         *llist;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zindex) == FAILURE) {
              return;
       }

       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       index  = (int)spl_offset_convert_to_long(zindex TSRMLS_CC);
    llist  = intern->llist;

    if (index < 0 || index >= intern->llist->count) {
              zend_throw_exception(spl_ce_OutOfRangeException, "Offset out of range", 0 TSRMLS_CC);
              return;
       }

       element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO);

       if (element != NULL) {
              /* connect the neightbors */
              if (element->prev) {
                     element->prev->next = element->next;
              }

              if (element->next) {
                     element->next->prev = element->prev;
              }

              /* take care of head/tail */
              if (element == llist->head) {
                     llist->head = element->next;
              }

              if (element == llist->tail) {
                     llist->tail = element->prev;
              }

              /* finally, delete the element */
              llist->count--;

              if(llist->dtor) {
                     llist->dtor(element TSRMLS_CC);
              }

              zval_ptr_dtor((zval **)&element->data);
              element->data = NULL;

              SPL_LLIST_DELREF(element);
       } else {
              zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0 TSRMLS_CC);
              return;
       }
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
key   
)

Definition at line 1043 of file spl_dllist.c.

{
       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       RETURN_LONG(intern->traverse_position);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
prev   
)

Definition at line 1057 of file spl_dllist.c.

{
       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       spl_dllist_it_helper_move_forward(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags ^ SPL_DLLIST_IT_LIFO TSRMLS_CC);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
next   
)

Definition at line 1071 of file spl_dllist.c.

{
       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       spl_dllist_it_helper_move_forward(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags TSRMLS_CC);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
valid   
)

Definition at line 1085 of file spl_dllist.c.

{
       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       RETURN_BOOL(intern->traverse_pointer != NULL);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
rewind   
)

Definition at line 1099 of file spl_dllist.c.

{
       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       spl_dllist_it_helper_rewind(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags TSRMLS_CC);
}

Here is the call graph for this function:

SPL_METHOD ( SplDoublyLinkedList  ,
current   
)

Definition at line 1113 of file spl_dllist.c.

{
       spl_dllist_object     *intern  = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
       spl_ptr_llist_element *element = intern->traverse_pointer;
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       if (element == NULL || element->data == NULL) {
              RETURN_NULL();
       } else {
              zval *data    = (zval *)element->data;
              RETURN_ZVAL(data, 1, 0);
       }
}

Here is the call graph for this function:

static void spl_ptr_llist_copy ( spl_ptr_llist from,
spl_ptr_llist *to  TSRMLS_DC 
) [static]

Definition at line 318 of file spl_dllist.c.

{
       spl_ptr_llist_element   *current = from->head, *next;
       spl_ptr_llist_ctor_func  ctor    = from->ctor;

       while (current) {
              next = current->next;

              if (ctor) {
                     ctor(current TSRMLS_CC);
              }

              spl_ptr_llist_push(to, current->data TSRMLS_CC);
              current = next;
       }

}

Here is the call graph for this function:

Here is the caller graph for this function:

static long spl_ptr_llist_count ( spl_ptr_llist llist) [static]

Definition at line 136 of file spl_dllist.c.

{
       return (long)llist->count;
}

Here is the caller graph for this function:

static void spl_ptr_llist_destroy ( spl_ptr_llist *llist  TSRMLS_DC) [static]

Definition at line 142 of file spl_dllist.c.

{
       spl_ptr_llist_element   *current = llist->head, *next;
       spl_ptr_llist_dtor_func  dtor    = llist->dtor;

       while (current) {
              next = current->next;
              if(current && dtor) {
                     dtor(current TSRMLS_CC);
              }
              SPL_LLIST_DELREF(current);
              current = next;
       }

       efree(llist);
}

Here is the caller graph for this function:

static void* spl_ptr_llist_first ( spl_ptr_llist llist) [static]

Definition at line 276 of file spl_dllist.c.

{
       spl_ptr_llist_element *head = llist->head;

       if (head == NULL) {
              return NULL;
       } else {
              return head->data;
       }
}

Here is the caller graph for this function:

Definition at line 122 of file spl_dllist.c.

{
       spl_ptr_llist *llist = emalloc(sizeof(spl_ptr_llist));

       llist->head  = NULL;
       llist->tail  = NULL;
       llist->count = 0;
       llist->dtor  = dtor;
       llist->ctor  = ctor;

       return llist;
}

Here is the caller graph for this function:

static void* spl_ptr_llist_last ( spl_ptr_llist llist) [static]

Definition at line 264 of file spl_dllist.c.

{
       spl_ptr_llist_element *tail = llist->tail;

       if (tail == NULL) {
              return NULL;
       } else {
              return tail->data;
       }
}

Here is the caller graph for this function:

static spl_ptr_llist_element* spl_ptr_llist_offset ( spl_ptr_llist llist,
long  offset,
int  backward 
) [static]

Definition at line 160 of file spl_dllist.c.

{

       spl_ptr_llist_element *current;
       int pos = 0;

       if (backward) {
              current = llist->tail;
       } else {
              current = llist->head;
       }

       while (current && pos < offset) {
              pos++;
              if (backward) {
                     current = current->prev;
              } else {
                     current = current->next;
              }
       }

       return current;
}

Here is the caller graph for this function:

static void* spl_ptr_llist_pop ( spl_ptr_llist *llist  TSRMLS_DC) [static]

Definition at line 233 of file spl_dllist.c.

{
       void                     *data;
       spl_ptr_llist_element    *tail = llist->tail;

       if (tail == NULL) {
              return NULL;
       }

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

       llist->tail = tail->prev;
       llist->count--;
       data = tail->data;

       if (llist->dtor) {
              llist->dtor(tail TSRMLS_CC);
       }

       tail->data = NULL;

       SPL_LLIST_DELREF(tail);

       return data;
}

Here is the caller graph for this function:

static void spl_ptr_llist_push ( spl_ptr_llist llist,
void *data  TSRMLS_DC 
) [static]

Definition at line 209 of file spl_dllist.c.

{
       spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element));

       elem->data = data;
       elem->rc   = 1;
       elem->prev = llist->tail;
       elem->next = NULL;

       if (llist->tail) {
              llist->tail->next = elem;
       } else {
              llist->head = elem;
       }

       llist->tail = elem;
       llist->count++;

       if (llist->ctor) {
              llist->ctor(elem TSRMLS_CC);
       }
}

Here is the caller graph for this function:

static void* spl_ptr_llist_shift ( spl_ptr_llist *llist  TSRMLS_DC) [static]

Definition at line 288 of file spl_dllist.c.

{
       void                    *data;
       spl_ptr_llist_element   *head = llist->head;

       if (head == NULL) {
              return NULL;
       }

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

       llist->head = head->next;
       llist->count--;
       data = head->data;

       if (llist->dtor) {
              llist->dtor(head TSRMLS_CC);
       }
       head->data = NULL;

       SPL_LLIST_DELREF(head);

       return data;
}

Here is the caller graph for this function:

static void spl_ptr_llist_unshift ( spl_ptr_llist llist,
void *data  TSRMLS_DC 
) [static]

Definition at line 185 of file spl_dllist.c.

{
       spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element));

       elem->data = data;
       elem->rc   = 1;
       elem->prev = NULL;
       elem->next = llist->head;

       if (llist->head) {
              llist->head->prev = elem;
       } else {
              llist->tail = elem;
       }

       llist->head = elem;
       llist->count++;

       if (llist->ctor) {
              llist->ctor(elem TSRMLS_CC);
       }
}

Here is the caller graph for this function:

static void spl_ptr_llist_zval_ctor ( spl_ptr_llist_element *elem  TSRMLS_DC) [static]

Definition at line 117 of file spl_dllist.c.

                                                                           { /* {{{ */
       Z_ADDREF_P((zval *)elem->data);
}

Here is the caller graph for this function:

static void spl_ptr_llist_zval_dtor ( spl_ptr_llist_element *elem  TSRMLS_DC) [static]

Definition at line 110 of file spl_dllist.c.

                                                                           { /* {{{ */
       if (elem->data) {
              zval_ptr_dtor((zval **)&elem->data);
       }
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 37 of file spl_dllist.c.

PHPAPI zend_class_entry* spl_ce_SplQueue

Definition at line 38 of file spl_dllist.c.

PHPAPI zend_class_entry* spl_ce_SplStack

Definition at line 39 of file spl_dllist.c.

Initial value:

Definition at line 1197 of file spl_dllist.c.

Initial value:

Definition at line 1191 of file spl_dllist.c.

zend_object_handlers spl_handler_SplDoublyLinkedList

Definition at line 36 of file spl_dllist.c.