static inline zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *intern, zval *offset) /* {{{ */ { zend_long index; /* we have to return NULL on error here to avoid memleak because of * ZE duplicating uninitialized_zval_ptr */ if (!offset) { zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return NULL; } if (Z_TYPE_P(offset) != IS_LONG) { index = spl_offset_convert_to_long(offset); } else { index = Z_LVAL_P(offset); } if (index < 0 || intern->array == NULL || index >= intern->array->size) { zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return NULL; } else if (Z_ISUNDEF(intern->array->elements[index])) { return NULL; } else { return &intern->array->elements[index]; } }
static inline int spl_fixedarray_object_has_dimension_helper(spl_fixedarray_object *intern, zval *offset, int check_empty) /* {{{ */ { zend_long index; int retval; if (Z_TYPE_P(offset) != IS_LONG) { index = spl_offset_convert_to_long(offset); } else { index = Z_LVAL_P(offset); } if (index < 0 || intern->array == NULL || index >= intern->array->size) { retval = 0; } else { if (Z_ISUNDEF(intern->array->elements[index])) { retval = 0; } else if (check_empty) { if (zend_is_true(&intern->array->elements[index])) { retval = 1; } else { retval = 0; } } else { /* != NULL and !check_empty */ retval = 1; } } return retval; }
static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *intern, zval *offset, zval *value) /* {{{ */ { zend_long index; if (!offset) { /* '$array[] = value' syntax is not supported */ zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return; } if (Z_TYPE_P(offset) != IS_LONG) { index = spl_offset_convert_to_long(offset); } else { index = Z_LVAL_P(offset); } if (index < 0 || intern->array == NULL || index >= intern->array->size) { zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return; } else { if (!Z_ISUNDEF(intern->array->elements[index])) { zval_ptr_dtor(&(intern->array->elements[index])); } ZVAL_DEREF(value); ZVAL_COPY(&intern->array->elements[index], value); } }
/* {{{ proto mixed SplDoublyLinkedList::offsetGet(mixed index) Returns the value at the specified $index. */ SPL_METHOD(SplDoublyLinkedList, offsetGet) { zval *zindex; zend_long index; spl_dllist_object *intern; spl_ptr_llist_element *element; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zindex) == FAILURE) { return; } intern = Z_SPLDLLIST_P(ZEND_THIS); index = spl_offset_convert_to_long(zindex); if (index < 0 || index >= intern->llist->count) { zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0); return; } element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); if (element != NULL) { zval *value = &element->data; ZVAL_COPY_DEREF(return_value, value); } else { zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0); } } /* }}} */
/* {{{ proto void SplDoublyLinkedList::add(mixed $index, mixed $newval) Inserts a new entry before the specified $index consisting of $newval. */ SPL_METHOD(SplDoublyLinkedList, add) { zval *zindex, *value; spl_dllist_object *intern; spl_ptr_llist_element *element; zend_long index; if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &zindex, &value) == FAILURE) { return; } intern = Z_SPLDLLIST_P(getThis()); index = spl_offset_convert_to_long(zindex); if (index < 0 || index > intern->llist->count) { zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0); return; } if (Z_REFCOUNTED_P(value)) { Z_ADDREF_P(value); } if (index == intern->llist->count) { /* If index is the last entry+1 then we do a push because we're not inserting before any entry */ spl_ptr_llist_push(intern->llist, value); } else { /* Create the new element we want to insert */ spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element)); /* Get the element we want to insert before */ element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); ZVAL_COPY_VALUE(&elem->data, value); elem->rc = 1; /* connect to the neighbours */ elem->next = element; elem->prev = element->prev; /* connect the neighbours to this new element */ if (elem->prev == NULL) { intern->llist->head = elem; } else { element->prev->next = elem; } element->prev = elem; intern->llist->count++; if (intern->llist->ctor) { intern->llist->ctor(elem); } } } /* }}} */
/* {{{ proto void SplDoublyLinkedList::offsetSet(mixed $index, mixed $newval) Sets the value at the specified $index to $newval. */ SPL_METHOD(SplDoublyLinkedList, offsetSet) { zval *zindex, *value; spl_dllist_object *intern; if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &zindex, &value) == FAILURE) { return; } intern = Z_SPLDLLIST_P(getThis()); if (Z_TYPE_P(zindex) == IS_NULL) { /* $obj[] = ... */ spl_ptr_llist_push(intern->llist, value); } else { /* $obj[$foo] = ... */ zend_long index; spl_ptr_llist_element *element; index = spl_offset_convert_to_long(zindex); if (index < 0 || index >= intern->llist->count) { zval_ptr_dtor(value); zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0); 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); } /* the element is replaced, delref the old one as in * SplDoublyLinkedList::pop() */ zval_ptr_dtor(&element->data); ZVAL_COPY_VALUE(&element->data, value); /* new element, call ctor as in spl_ptr_llist_push */ if (intern->llist->ctor) { intern->llist->ctor(element); } } else { zval_ptr_dtor(value); zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0); return; } } } /* }}} */
/* {{{ proto bool SplDoublyLinkedList::offsetExists(mixed index) Returns whether the requested $index exists. */ SPL_METHOD(SplDoublyLinkedList, offsetExists) { zval *zindex; spl_dllist_object *intern; zend_long index; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zindex) == FAILURE) { return; } intern = Z_SPLDLLIST_P(ZEND_THIS); index = spl_offset_convert_to_long(zindex); RETURN_BOOL(index >= 0 && index < intern->llist->count); } /* }}} */
static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object *intern, zval *offset) /* {{{ */ { zend_long index; if (Z_TYPE_P(offset) != IS_LONG) { index = spl_offset_convert_to_long(offset); } else { index = Z_LVAL_P(offset); } if (index < 0 || intern->array == NULL || index >= intern->array->size) { zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return; } else { zval_ptr_dtor(&(intern->array->elements[index])); ZVAL_UNDEF(&intern->array->elements[index]); } }
/* {{{ proto void SplDoublyLinkedList::offsetUnset(mixed index) Unsets the value at the specified $index. */ SPL_METHOD(SplDoublyLinkedList, offsetUnset) { zval *zindex; zend_long index; spl_dllist_object *intern; spl_ptr_llist_element *element; spl_ptr_llist *llist; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zindex) == FAILURE) { return; } intern = Z_SPLDLLIST_P(ZEND_THIS); index = spl_offset_convert_to_long(zindex); llist = intern->llist; if (index < 0 || index >= intern->llist->count) { zend_throw_exception(spl_ce_OutOfRangeException, "Offset out of range", 0); 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); } if (intern->traverse_pointer == element) { SPL_LLIST_DELREF(element); intern->traverse_pointer = NULL; } zval_ptr_dtor(&element->data); ZVAL_UNDEF(&element->data); SPL_LLIST_DELREF(element); } else { zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0); return; } } /* }}} */