/* {{{ proto void SplFixedArray::__construct([int size]) */ SPL_METHOD(SplFixedArray, __construct) { zval *object = getThis(); spl_fixedarray_object *intern; zend_long size = 0; if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "|l", &size) == FAILURE) { return; } if (size < 0) { zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "array size cannot be less than zero"); return; } intern = Z_SPLFIXEDARRAY_P(object); if (intern->array) { /* called __construct() twice, bail out */ return; } intern->array = emalloc(sizeof(spl_fixedarray)); spl_fixedarray_init(intern->array, size); }
/* {{{ proto void SplFixedArray::__wakeup() */ SPL_METHOD(SplFixedArray, __wakeup) { spl_fixedarray_object *intern = Z_SPLFIXEDARRAY_P(getThis()); HashTable *intern_ht = zend_std_get_properties(getThis()); zval *data; if (zend_parse_parameters_none() == FAILURE) { return; } if (!intern->array) { int index = 0; int size = zend_hash_num_elements(intern_ht); intern->array = emalloc(sizeof(spl_fixedarray)); spl_fixedarray_init(intern->array, size); ZEND_HASH_FOREACH_VAL(intern_ht, data) { if (Z_REFCOUNTED_P(data)) { Z_ADDREF_P(data); } ZVAL_COPY_VALUE(&intern->array->elements[index], data); index++; } ZEND_HASH_FOREACH_END(); /* Remove the unserialised properties, since we now have the elements * within the spl_fixedarray_object structure. */ zend_hash_clean(intern_ht); }
static HashTable* spl_fixedarray_object_get_properties(zval *obj) /* {{{{ */ { spl_fixedarray_object *intern = Z_SPLFIXEDARRAY_P(obj); HashTable *ht = zend_std_get_properties(obj); zend_long i = 0; if (intern->array) { zend_long j = zend_hash_num_elements(ht); for (i = 0; i < intern->array->size; i++) { if (!Z_ISUNDEF(intern->array->elements[i])) { zend_hash_index_update(ht, i, &intern->array->elements[i]); if (Z_REFCOUNTED(intern->array->elements[i])){ Z_ADDREF(intern->array->elements[i]); } } else { zend_hash_index_update(ht, i, &EG(uninitialized_zval)); } } if (j > intern->array->size) { for (i = intern->array->size; i < j; ++i) { zend_hash_index_del(ht, i); } } } return ht; }
static HashTable* spl_fixedarray_object_get_gc(zval *obj, zval **table, int *n) /* {{{{ */ { spl_fixedarray_object *intern = Z_SPLFIXEDARRAY_P(obj); HashTable *ht = zend_std_get_properties(obj); *table = intern->array.elements; *n = (int)intern->array.size; return ht; }
static HashTable* spl_fixedarray_object_get_gc(zval *obj, zval **table, int *n) /* {{{{ */ { spl_fixedarray_object *intern = Z_SPLFIXEDARRAY_P(obj); HashTable *ht = zend_std_get_properties(obj); if (intern->array) { *table = intern->array->elements; *n = (int)intern->array->size; } else { *table = NULL; *n = 0; } return ht; }
static void spl_fixedarray_object_unset_dimension(zval *object, zval *offset) /* {{{ */ { spl_fixedarray_object *intern; intern = Z_SPLFIXEDARRAY_P(object); if (intern->fptr_offset_del) { SEPARATE_ARG_IF_REF(offset); zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_del, "offsetUnset", NULL, offset); zval_ptr_dtor(offset); return; } spl_fixedarray_object_unset_dimension_helper(intern, offset); }
static int spl_fixedarray_object_count_elements(zval *object, zend_long *count) /* {{{ */ { spl_fixedarray_object *intern; intern = Z_SPLFIXEDARRAY_P(object); if (intern->fptr_count) { zval rv; zend_call_method_with_0_params(object, intern->std.ce, &intern->fptr_count, "count", &rv); if (!Z_ISUNDEF(rv)) { *count = zval_get_long(&rv); zval_ptr_dtor(&rv); } else { *count = 0; } } else { *count = intern->array.size; } return SUCCESS; }
static int spl_fixedarray_object_has_dimension(zval *object, zval *offset, int check_empty) /* {{{ */ { spl_fixedarray_object *intern; intern = Z_SPLFIXEDARRAY_P(object); if (intern->fptr_offset_get) { zval rv; SEPARATE_ARG_IF_REF(offset); zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_has, "offsetExists", &rv, offset); zval_ptr_dtor(offset); if (!Z_ISUNDEF(rv)) { zend_bool result = zend_is_true(&rv); zval_ptr_dtor(&rv); return result; } return 0; } return spl_fixedarray_object_has_dimension_helper(intern, offset, check_empty); }
static void spl_fixedarray_object_write_dimension(zval *object, zval *offset, zval *value) /* {{{ */ { spl_fixedarray_object *intern; zval tmp; intern = Z_SPLFIXEDARRAY_P(object); if (intern->fptr_offset_set) { if (!offset) { ZVAL_NULL(&tmp); offset = &tmp; } else { SEPARATE_ARG_IF_REF(offset); } SEPARATE_ARG_IF_REF(value); zend_call_method_with_2_params(object, intern->std.ce, &intern->fptr_offset_set, "offsetSet", NULL, offset, value); zval_ptr_dtor(value); zval_ptr_dtor(offset); return; } spl_fixedarray_object_write_dimension_helper(intern, offset, value); }
static zval *spl_fixedarray_object_read_dimension(zval *object, zval *offset, int type, zval *rv) /* {{{ */ { spl_fixedarray_object *intern; intern = Z_SPLFIXEDARRAY_P(object); if (intern->fptr_offset_get) { zval tmp; if (!offset) { ZVAL_UNDEF(&tmp); offset = &tmp; } else { SEPARATE_ARG_IF_REF(offset); } zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_get, "offsetGet", rv, offset); zval_ptr_dtor(offset); if (!Z_ISUNDEF_P(rv)) { return rv; } return &EG(uninitialized_zval); } return spl_fixedarray_object_read_dimension_helper(intern, offset); }
static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, zval *orig, int clone_orig) /* {{{ */ { spl_fixedarray_object *intern; zend_class_entry *parent = class_type; int inherited = 0; intern = ecalloc(1, sizeof(spl_fixedarray_object) + zend_object_properties_size(parent)); zend_object_std_init(&intern->std, class_type); object_properties_init(&intern->std, class_type); intern->current = 0; intern->flags = 0; if (orig && clone_orig) { spl_fixedarray_object *other = Z_SPLFIXEDARRAY_P(orig); intern->ce_get_iterator = other->ce_get_iterator; if (!other->array) { /* leave a empty object, will be dtor later by CLONE handler */ zend_throw_exception(spl_ce_RuntimeException, "The instance wasn't initialized properly", 0); } else { intern->array = emalloc(sizeof(spl_fixedarray)); spl_fixedarray_init(intern->array, other->array->size); spl_fixedarray_copy(intern->array, other->array); } } while (parent) { if (parent == spl_ce_SplFixedArray) { intern->std.handlers = &spl_handler_SplFixedArray; class_type->get_iterator = spl_fixedarray_get_iterator; break; } parent = parent->parent; inherited = 1; } if (!parent) { /* this must never happen */ php_error_docref(NULL, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplFixedArray"); } if (!class_type->iterator_funcs.zf_current) { class_type->iterator_funcs.zf_rewind = zend_hash_str_find_ptr(&class_type->function_table, "rewind", sizeof("rewind") - 1); class_type->iterator_funcs.zf_valid = zend_hash_str_find_ptr(&class_type->function_table, "valid", sizeof("valid") - 1); class_type->iterator_funcs.zf_key = zend_hash_str_find_ptr(&class_type->function_table, "key", sizeof("key") - 1); class_type->iterator_funcs.zf_current = zend_hash_str_find_ptr(&class_type->function_table, "current", sizeof("current") - 1); class_type->iterator_funcs.zf_next = zend_hash_str_find_ptr(&class_type->function_table, "next", sizeof("next") - 1); } if (inherited) { if (class_type->iterator_funcs.zf_rewind->common.scope != parent) { intern->flags |= SPL_FIXEDARRAY_OVERLOADED_REWIND; } if (class_type->iterator_funcs.zf_valid->common.scope != parent) { intern->flags |= SPL_FIXEDARRAY_OVERLOADED_VALID; } if (class_type->iterator_funcs.zf_key->common.scope != parent) { intern->flags |= SPL_FIXEDARRAY_OVERLOADED_KEY; } if (class_type->iterator_funcs.zf_current->common.scope != parent) { intern->flags |= SPL_FIXEDARRAY_OVERLOADED_CURRENT; } if (class_type->iterator_funcs.zf_next->common.scope != parent) { intern->flags |= SPL_FIXEDARRAY_OVERLOADED_NEXT; } intern->fptr_offset_get = zend_hash_str_find_ptr(&class_type->function_table, "offsetget", sizeof("offsetget") - 1); if (intern->fptr_offset_get->common.scope == parent) { intern->fptr_offset_get = NULL; } intern->fptr_offset_set = zend_hash_str_find_ptr(&class_type->function_table, "offsetset", sizeof("offsetset") - 1); if (intern->fptr_offset_set->common.scope == parent) { intern->fptr_offset_set = NULL; } intern->fptr_offset_has = zend_hash_str_find_ptr(&class_type->function_table, "offsetexists", sizeof("offsetexists") - 1); if (intern->fptr_offset_has->common.scope == parent) { intern->fptr_offset_has = NULL; } intern->fptr_offset_del = zend_hash_str_find_ptr(&class_type->function_table, "offsetunset", sizeof("offsetunset") - 1); if (intern->fptr_offset_del->common.scope == parent) { intern->fptr_offset_del = NULL; } intern->fptr_count = zend_hash_str_find_ptr(&class_type->function_table, "count", sizeof("count") - 1); if (intern->fptr_count->common.scope == parent) { intern->fptr_count = NULL; } } return &intern->std; }