예제 #1
0
파일: object.c 프로젝트: crocodile2u/zephir
/**
 * Unsets an index in an array property
 */
int zephir_unset_property_array(zval *object, char *property, unsigned int property_length, zval *index)
{
	zval tmp;
	int separated = 0;

	if (Z_TYPE_P(object) == IS_OBJECT) {

		zephir_read_property(&tmp, object, property, property_length, PH_NOISY_CC);
		Z_TRY_DELREF(tmp);

		/** Separation only when refcount > 1 */
		if (Z_REFCOUNTED(tmp) && Z_REFCOUNT(tmp) > 1) {
			if (!Z_ISREF(tmp)) {
				zval new_zv;
				ZVAL_DUP(&new_zv, &tmp);
				ZVAL_COPY_VALUE(&tmp, &new_zv);
				Z_TRY_DELREF(new_zv);
				separated = 1;
			}
		}

		zephir_array_unset(&tmp, index, PH_SEPARATE);

		if (separated) {
			zephir_update_property_zval(object, property, property_length, &tmp);
		}
	}

	return SUCCESS;
}
예제 #2
0
파일: object.c 프로젝트: phalcon/zephir
/**
 * Increments an object property
 */
int zephir_property_incr_decr(zval *object, char *property_name, unsigned int property_length, unsigned int increment)
{
	zval tmp;
	zend_class_entry *ce;
	int separated = 0;

	ZVAL_UNDEF(&tmp);

	if (Z_TYPE_P(object) != IS_OBJECT) {
		php_error_docref(NULL, E_WARNING, "Attempt to assign property of non-object");
		return FAILURE;
	}

	ce = Z_OBJCE_P(object);
	if (ce->parent) {
		ce = zephir_lookup_class_ce(ce, property_name, property_length);
	}

	zephir_read_property(&tmp, object, property_name, property_length, 0);
	if (Z_TYPE(tmp) > IS_UNDEF) {

		Z_TRY_DELREF(tmp);

		/** Separation only when refcount > 1 */
		if (Z_REFCOUNTED(tmp)) {
			if (Z_REFCOUNT(tmp) > 1) {
				if (!Z_ISREF(tmp)) {
					zval new_zv;
					ZVAL_DUP(&new_zv, &tmp);
					ZVAL_COPY_VALUE(&tmp, &new_zv);
					Z_TRY_DELREF(new_zv);
					separated = 1;
				}
			}
		} else {
			zval new_zv;
			ZVAL_DUP(&new_zv, &tmp);
			ZVAL_COPY_VALUE(&tmp, &new_zv);
			Z_TRY_DELREF(new_zv);
			separated = 1;
		}

		if (increment) {
			zephir_increment(&tmp);
		} else {
			zephir_decrement(&tmp);
		}

		if (separated) {
			zephir_update_property_zval(object, property_name, property_length, &tmp);
		}
	}

	return SUCCESS;
}
예제 #3
0
파일: object.c 프로젝트: phalcon/zephir
/**
 * Appends a zval value to an array property
 */
int zephir_update_property_array_append(zval *object, char *property, unsigned int property_length, zval *value)
{
	zval tmp;
	int separated = 0;

	ZVAL_UNDEF(&tmp);

	if (Z_TYPE_P(object) != IS_OBJECT) {
		return SUCCESS;
	}

	zephir_read_property(&tmp, object, property, property_length, PH_NOISY_CC);

	Z_TRY_DELREF(tmp);

	/** Separation only when refcount > 1 */
	if (Z_REFCOUNTED(tmp)) {
		if (Z_REFCOUNT(tmp) > 1) {
			if (!Z_ISREF(tmp)) {
				zval new_zv;
				ZVAL_DUP(&new_zv, &tmp);
				ZVAL_COPY_VALUE(&tmp, &new_zv);
				Z_TRY_DELREF(new_zv);
				separated = 1;
			}
		}
	} else {
		zval new_zv;
		ZVAL_DUP(&new_zv, &tmp);
		ZVAL_COPY_VALUE(&tmp, &new_zv);
		Z_TRY_DELREF(new_zv);
		separated = 1;
	}

	/** Convert the value to array if not is an array */
	if (Z_TYPE(tmp) != IS_ARRAY) {
		if (separated) {
			convert_to_array(&tmp);
		} else {
			array_init(&tmp);
			separated = 1;
		}
		Z_DELREF(tmp);
	}

	Z_TRY_ADDREF_P(value);
	add_next_index_zval(&tmp, value);

	if (separated) {
		zephir_update_property_zval(object, property, property_length, &tmp);
	}

	return SUCCESS;
}
예제 #4
0
파일: object.c 프로젝트: phalcon/zephir
/**
 * Updates an array property
 */
int zephir_update_property_array(zval *object, const char *property, zend_uint property_length, const zval *index, zval *value)
{
	zval tmp;
	int separated = 0;

	if (Z_TYPE_P(object) == IS_OBJECT) {
		zephir_read_property(&tmp, object, property, property_length, PH_NOISY | PH_READONLY);

		/** Separation only when refcount > 1 */
		if (Z_REFCOUNTED(tmp)) {
			if (Z_REFCOUNT(tmp) > 1) {
				if (!Z_ISREF(tmp)) {
					zval new_zv;
					ZVAL_DUP(&new_zv, &tmp);
					ZVAL_COPY_VALUE(&tmp, &new_zv);
					Z_TRY_DELREF(new_zv);
					separated = 1;
				}
			}
		} else {
			zval new_zv;
			ZVAL_DUP(&new_zv, &tmp);
			ZVAL_COPY_VALUE(&tmp, &new_zv);
			Z_TRY_DELREF(new_zv);
			separated = 1;
		}

		/** Convert the value to array if not is an array */
		if (Z_TYPE(tmp) != IS_ARRAY) {
			if (separated) {
				convert_to_array(&tmp);
			} else {
				array_init(&tmp);
				separated = 1;
			}
			Z_DELREF(tmp);
		}
		Z_TRY_ADDREF_P(value);

		if (Z_TYPE_P(index) == IS_STRING) {
			zend_symtable_str_update(Z_ARRVAL(tmp), Z_STRVAL_P(index), Z_STRLEN_P(index), value);
		} else if (Z_TYPE_P(index) == IS_LONG) {
			zend_hash_index_update(Z_ARRVAL(tmp), Z_LVAL_P(index), value);
		} else if (Z_TYPE_P(index) == IS_NULL) {
			zend_hash_next_index_insert(Z_ARRVAL(tmp), value);
		}

		if (separated) {
			zephir_update_property_zval(object, property, property_length, &tmp);
		}
	}

	return SUCCESS;
}
예제 #5
0
파일: object.c 프로젝트: phalcon/zephir
/*
 * Multiple array-offset update
 */
int zephir_update_static_property_array_multi_ce(zend_class_entry *ce, const char *property, zend_uint property_length, zval *value, const char *types, int types_length, int types_count, ...)
{
	va_list ap;
	zval tmp_arr;
	int separated = 0;

	ZVAL_UNDEF(&tmp_arr);

	zephir_read_static_property_ce(&tmp_arr, ce, property, property_length, PH_NOISY | PH_READONLY);

	/** Separation only when refcount > 1 */
	if (Z_REFCOUNTED(tmp_arr)) {
		if (Z_REFCOUNT(tmp_arr) > 1) {
			if (!Z_ISREF(tmp_arr)) {
				zval new_zv;
				ZVAL_DUP(&new_zv, &tmp_arr);
				ZVAL_COPY_VALUE(&tmp_arr, &new_zv);
				Z_TRY_DELREF(new_zv);
				separated = 1;
			}
		}
	} else {
		zval new_zv;
		ZVAL_DUP(&new_zv, &tmp_arr);
		ZVAL_COPY_VALUE(&tmp_arr, &new_zv);
		Z_TRY_DELREF(new_zv);
		separated = 1;
	}

	/** Convert the value to array if not is an array */
	if (Z_TYPE(tmp_arr) != IS_ARRAY) {
		if (separated) {
			convert_to_array(&tmp_arr);
		} else {
			array_init(&tmp_arr);
			separated = 1;
		}
		Z_DELREF(tmp_arr);
	}

	va_start(ap, types_count);
	SEPARATE_ZVAL_IF_NOT_REF(&tmp_arr);
	zephir_array_update_multi_ex(&tmp_arr, value, types, types_length, types_count, ap);
	va_end(ap);

	if (separated) {
		zephir_update_static_property_ce(ce, property, property_length, &tmp_arr);
	}

	return SUCCESS;
}