PHPAPI zend_class_entry *spl_ce_SplQueue;
PHPAPI zend_class_entry *spl_ce_SplStack;
-#define SPL_LLIST_DELREF(elem, dtor) if(!--(elem)->rc) { \
- if(dtor) { \
- dtor(elem); \
- } \
+#define SPL_LLIST_DELREF(elem) if(!--(elem)->rc) { \
efree(elem); \
elem = NULL; \
}
-#define SPL_LLIST_CHECK_DELREF(elem, dtor) if((elem) && !--(elem)->rc) { \
- if(dtor) { \
- dtor(elem); \
- } \
+#define SPL_LLIST_CHECK_DELREF(elem) if((elem) && !--(elem)->rc) { \
efree(elem); \
elem = NULL; \
}
/* {{{ spl_ptr_llist */
static void spl_ptr_llist_zval_dtor(spl_ptr_llist_element *elem) { /* {{{ */
- zval_ptr_dtor((zval **)&elem->data);
+ if (elem->data) {
+ zval_ptr_dtor((zval **)&elem->data);
+ elem->data = NULL;
+ }
+
}
/* }}} */
while (current) {
next = current->next;
- SPL_LLIST_DELREF(current, dtor);
+ if(current && dtor) {
+ dtor(current);
+ }
+ SPL_LLIST_DELREF(current);
current = next;
}
{
void *data;
spl_ptr_llist_element *tail = llist->tail;
- spl_ptr_llist_dtor_func dtor = NULL;
if (tail == NULL) {
return NULL;
llist->tail = tail->prev;
llist->count--;
data = tail->data;
+ tail->data = NULL;
- SPL_LLIST_DELREF(tail, dtor);
+ SPL_LLIST_DELREF(tail);
return data;
}
{
void *data;
spl_ptr_llist_element *head = llist->head;
- spl_ptr_llist_dtor_func dtor = NULL;
if (head == NULL) {
return NULL;
llist->head = head->next;
llist->count--;
data = head->data;
+ head->data = NULL;
- SPL_LLIST_DELREF(head, dtor);
+ SPL_LLIST_DELREF(head);
return data;
}
return Z_LVAL_P(offset);
}
}
- zend_throw_exception(spl_ce_OutOfRangeException, "Invalid offset", 0 TSRMLS_CC);
- return 0;
+ return -1;
}
/* }}} */
index = spl_dllist_offset_convert(zindex TSRMLS_CC);
if (index < 0 || index >= intern->llist->count) {
- zend_throw_exception(spl_ce_OutOfRangeException, "Offset out of range", 0 TSRMLS_CC);
+ zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
return;
}
index = spl_dllist_offset_convert(zindex TSRMLS_CC);
if (index < 0 || index >= intern->llist->count) {
- zend_throw_exception(spl_ce_OutOfRangeException, "Offset out of range", 0 TSRMLS_CC);
+ zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
return;
}
}
/* finally, delete the element */
llist->count--;
- SPL_LLIST_DELREF(element, llist->dtor);
+
+ if(llist->dtor) {
+ llist->dtor(element);
+ }
+ SPL_LLIST_DELREF(element);
} else {
zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0 TSRMLS_CC);
return;
{
spl_dllist_it *iterator = (spl_dllist_it *)iter;
- SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer, iterator->object->llist->dtor);
+ SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer);
zend_user_it_invalidate_current(iter TSRMLS_CC);
zval_ptr_dtor((zval**)&iterator->intern.it.data);
spl_dllist_it *iterator = (spl_dllist_it *)iter;
spl_ptr_llist_element *element = iterator->traverse_pointer;
- if (element == NULL) {
+ if (element == NULL || element->data == NULL) {
*data = NULL;
} else {
*data = (zval **)&element->data;
iterator->traverse_pointer = old->prev;
iterator->traverse_position--;
if (iterator->flags & SPL_DLLIST_IT_DELETE) {
- spl_ptr_llist_pop(object->llist);
+ zval *prev = (zval *)spl_ptr_llist_pop(object->llist);
+ if (prev) {
+ zval_ptr_dtor((zval **)&prev);
+ }
}
} else {
iterator->traverse_pointer = old->next;
iterator->traverse_position++;
if (iterator->flags & SPL_DLLIST_IT_DELETE) {
- spl_ptr_llist_shift(object->llist);
+ zval *prev = (zval *)spl_ptr_llist_shift(object->llist);
+ if (prev) {
+ zval_ptr_dtor((zval **)&prev);
+ }
}
}
- SPL_LLIST_DELREF(old, object->llist->dtor);
+ SPL_LLIST_DELREF(old);
SPL_LLIST_CHECK_ADDREF(iterator->traverse_pointer);
}
}
spl_dllist_object *object = iterator->object;
spl_ptr_llist *llist = object->llist;
- SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer, llist->dtor);
+ SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer);
if (iterator->flags & SPL_DLLIST_IT_LIFO) {
iterator->traverse_position = llist->count-1;
iterator->traverse_pointer = llist->tail;