Beispiel #1
0
/* {{{ 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);
}
Beispiel #2
0
/* {{{ 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);
	}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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);

}
Beispiel #7
0
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;
}
Beispiel #8
0
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);
}
Beispiel #9
0
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);
}
Beispiel #10
0
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);
}
Beispiel #11
0
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;
}