/** * @brief Updates value in @a arr at position @a index with @a value * @param[in,out] arr Array * @param index Index * @param[in,out] value Value * @param flags Flags * @return Whether the operation succeeded * @retval @c FAILURE Failure, @a arr is not an array * @retval @c SUCCESS Success * @throw @c E_WARNING if @c arr is not an array * * Equivalent to <tt>$arr[$index] = $value</tt> in PHP where @c $index is an integer. * Flags may be a bitwise OR of the following values: * @arg @c PH_CTOR: create a copy of @a value and work with that copy; @c *value will be updated with the newly constructed value * @arg @c PH_SEPARATE: separate @a arr if its reference count is greater than 1; @c *arr will contain the separated version * @arg @c PH_COPY: increment the reference count on @c **value */ int zephir_array_update_long(zval **arr, unsigned long index, zval **value, int flags ZEPHIR_DEBUG_PARAMS) { if (Z_TYPE_PP(arr) != IS_ARRAY) { zend_error(E_WARNING, "Cannot use a scalar value as an array in %s on line %d", file, line); return FAILURE; } if ((flags & PH_CTOR) == PH_CTOR) { zval *new_zv; Z_DELREF_PP(value); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *value); *value = new_zv; zval_copy_ctor(new_zv); } if ((flags & PH_SEPARATE) == PH_SEPARATE) { SEPARATE_ZVAL_IF_NOT_REF(arr); } if ((flags & PH_COPY) == PH_COPY) { Z_ADDREF_PP(value); } return zend_hash_index_update(Z_ARRVAL_PP(arr), index, value, sizeof(zval *), NULL); }
/** * @brief Unsets @a index from array @a arr * @param[in,out] arr Array * @param index Index * @param flags Flags (@c PH_SEPARATE: separate array if its reference count is greater than 1; @c arr will contain the separated array) * @return Whether the operation succeeded * @retval @c FAILURE Failure, @a arr is not an array or @a index is of not supported type * @retval @c SUCCESS Success * @note @c index will be handled as follows: @c NULL is treated as an empty string, @c double values are cast to @c integer, @c bool or @c resource are treated as @c integer * @throw @c E_WARNING if @a offset is not a scalar */ int ZEPHIR_FASTCALL zephir_array_unset(zval **arr, zval *index, int flags) { HashTable *ht; if (Z_TYPE_PP(arr) != IS_ARRAY) { return FAILURE; } if ((flags & PH_SEPARATE) == PH_SEPARATE) { SEPARATE_ZVAL_IF_NOT_REF(arr); } ht = Z_ARRVAL_PP(arr); switch (Z_TYPE_P(index)) { case IS_NULL: return (zend_hash_del(ht, "", 1) == SUCCESS); case IS_DOUBLE: return (zend_hash_index_del(ht, (ulong)Z_DVAL_P(index)) == SUCCESS); case IS_LONG: case IS_BOOL: case IS_RESOURCE: return (zend_hash_index_del(ht, Z_LVAL_P(index)) == SUCCESS); case IS_STRING: return (zend_symtable_del(ht, Z_STRVAL_P(index), Z_STRLEN_P(index)+1) == SUCCESS); default: zend_error(E_WARNING, "Illegal offset type"); return 0; } }
/** * @brief Updates value in @a arr at position @a index with @a value using the precomputed hash @a key * @param[in,out] arr Array * @param index Index * @param index_length Length of the index, should include the trailing zero * @param key Precomputed hash of @c value * @param value Value * @param flags Flags * @return Whether the operation succeeded * @retval @c FAILURE Failure, @a arr is not an array * @retval @c SUCCESS Success * @throw @c E_WARNING if @a arr is not an array * * Equivalent to <tt>$arr[$index] = $value</tt> in PHP. * * Flags may be a bitwise OR of the following values: * @arg @c PH_CTOR: create a copy of @a value and work with that copy; @c *value will be updated with the newly constructed value * @arg @c PH_SEPARATE: separate @a arr if its reference count is greater than 1; @c *arr will contain the separated version * @arg @c PH_COPY: increment the reference count on @c **value */ int zephir_array_update_quick_string(zval **arr, const char *index, uint index_length, unsigned long key, zval **value, int flags) { if (Z_TYPE_PP(arr) != IS_ARRAY) { zend_error(E_WARNING, "Cannot use a scalar value as an array (3)"); return FAILURE; } if ((flags & PH_CTOR) == PH_CTOR) { zval *new_zv; Z_DELREF_PP(value); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *value); *value = new_zv; zval_copy_ctor(new_zv); } if ((flags & PH_SEPARATE) == PH_SEPARATE) { SEPARATE_ZVAL_IF_NOT_REF(arr); } if ((flags & PH_COPY) == PH_COPY) { Z_ADDREF_PP(value); } return zend_hash_quick_update(Z_ARRVAL_PP(arr), index, index_length, key, value, sizeof(zval *), NULL); }
/** * @brief Unsets numeric @a index from array @a arr * @param[in,out] arr Array * @param index Index * @param flags Flags (@c PH_SEPARATE: separate array if its reference count is greater than 1; @c arr will contain the separated array) * @return Whether the operation succeeded * @retval @c FAILURE Failure or @a arr is not an array * @retval @c SUCCESS Success */ int ZEPHIR_FASTCALL zephir_array_unset_long(zval **arr, unsigned long index, int flags) { if (Z_TYPE_PP(arr) != IS_ARRAY) { return 0; } if ((flags & PH_SEPARATE) == PH_SEPARATE) { SEPARATE_ZVAL_IF_NOT_REF(arr); } return zend_hash_index_del(Z_ARRVAL_PP(arr), index); }
/** * @brief Unsets string @a index from array @a arr * @param[in,out] arr Array * @param index Index * @param index_length strlen(index)+1 * @param flags Flags (@c PH_SEPARATE: separate array if its reference count is greater than 1; @c arr will contain the separated array) * @return Whether the operation succeeded * @retval @c FAILURE Failure or @a arr is not an array * @retval @c SUCCESS Success */ int ZEPHIR_FASTCALL zephir_array_unset_string(zval **arr, const char *index, uint index_length, int flags) { if (Z_TYPE_PP(arr) != IS_ARRAY) { return 0; } if ((flags & PH_SEPARATE) == PH_SEPARATE) { SEPARATE_ZVAL_IF_NOT_REF(arr); } return zend_hash_del(Z_ARRVAL_PP(arr), index, index_length); }
/* * 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; }
/** * @brief Pushes @a value onto the end of @a arr * @param[in,out] arr Array * @param[in,out] value Value to add; reference counter of @c *value will be incrememnted * @param flags Flags (@c PH_SEPARATE: separate array if its reference count is greater than 1; @c arr will contain the separated array) * @return Whether the operation succeeded * @retval @c FAILURE Failure or @a arr is not an array * @retval @c SUCCESS Success * @throw @c E_WARNING if @a is not an array */ int zephir_array_append(zval **arr, zval *value, int flags ZEPHIR_DEBUG_PARAMS) { if (Z_TYPE_PP(arr) != IS_ARRAY) { zend_error(E_WARNING, "Cannot use a scalar value as an array in %s on line %d", file, line); return FAILURE; } if ((flags & PH_SEPARATE) == PH_SEPARATE) { SEPARATE_ZVAL_IF_NOT_REF(arr); } Z_ADDREF_P(value); return add_next_index_zval(*arr, value); }
/** * @brief Updates value in @a arr at position @a index with @a value * @param[in,out] arr Array * @param index Index * @param[in,out] value Value * @param flags Flags * @return Whether the operation succeeded * @retval @c FAILURE Failure, @a arr is not an array or @a index is of not supported type * @retval @c SUCCESS Success * @note @c index will be handled as follows: @c NULL is treated as an empty string, @c double values are cast to @c integer, @c bool or @c resource are treated as @c integer * @throw @c E_WARNING if @a offset is not a scalar or @c arr is not an array * * Equivalent to <tt>$arr[$index] = $value</tt> in PHP. * Flags may be a bitwise OR of the following values: * @arg @c PH_CTOR: create a copy of @a value and work with that copy; @c *value will be updated with the newly constructed value * @arg @c PH_SEPARATE: separate @a arr if its reference count is greater than 1; @c *arr will contain the separated version * @arg @c PH_COPY: increment the reference count on @c **value */ int zephir_array_update_zval(zval **arr, zval *index, zval **value, int flags) { HashTable *ht; if (Z_TYPE_PP(arr) != IS_ARRAY) { zend_error(E_WARNING, "Cannot use a scalar value as an array (2)"); return FAILURE; } if ((flags & PH_CTOR) == PH_CTOR) { zval *new_zv; Z_DELREF_PP(value); ALLOC_ZVAL(new_zv); INIT_PZVAL_COPY(new_zv, *value); *value = new_zv; zval_copy_ctor(new_zv); } if ((flags & PH_SEPARATE) == PH_SEPARATE) { SEPARATE_ZVAL_IF_NOT_REF(arr); } if ((flags & PH_COPY) == PH_COPY) { Z_ADDREF_PP(value); } ht = Z_ARRVAL_PP(arr); switch (Z_TYPE_P(index)) { case IS_NULL: return zend_symtable_update(ht, "", 1, value, sizeof(zval*), NULL); case IS_DOUBLE: return zend_hash_index_update(ht, (ulong)Z_DVAL_P(index), value, sizeof(zval*), NULL); case IS_LONG: case IS_BOOL: case IS_RESOURCE: return zend_hash_index_update(ht, Z_LVAL_P(index), value, sizeof(zval*), NULL); case IS_STRING: return zend_symtable_update(ht, Z_STRVAL_P(index), Z_STRLEN_P(index)+1, value, sizeof(zval*), NULL); default: zend_error(E_WARNING, "Illegal offset type"); return FAILURE; } }
static int32_t qb_transfer_value_to_import_source(qb_interpreter_context *cxt, qb_variable *ivar, qb_import_scope *scope) { int32_t result = TRUE; if(ivar->flags & QB_VARIABLE_IMPORTED) { USE_TSRM zval *zvalue = ivar->value, **p_zvalue = ivar->value_pointer; if(!IS_READ_ONLY(ivar->address)) { if(zvalue) { // separate the zval first, since we're modifying it SEPARATE_ZVAL_IF_NOT_REF(&zvalue); } else { ALLOC_INIT_ZVAL(zvalue); } if(!qb_transfer_value_to_zval(scope->storage, ivar->address, zvalue)) { uint32_t line_id = qb_get_zend_line_id(TSRMLS_C); qb_append_exception_variable_name(ivar TSRMLS_CC); qb_set_exception_line_id(line_id TSRMLS_CC); result = FALSE; } if(p_zvalue) { *p_zvalue = zvalue; } else { if(ivar->flags & QB_VARIABLE_GLOBAL) { zend_hash_quick_update(&EG(symbol_table), ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &zvalue, sizeof(zval *), NULL); } else if(ivar->flags & QB_VARIABLE_CLASS_INSTANCE) { zval *container = scope->object; zval *name = qb_string_to_zval(ivar->name, ivar->name_length TSRMLS_CC); Z_OBJ_WRITE_PROP(container, name, zvalue); } } } if(!p_zvalue && zvalue) { // if p_zvalue isn't null, then something else has put a refcount // on the zval (and we didn't increment it earlier) zval_ptr_dtor(&zvalue); } ivar->value_pointer = NULL; ivar->value = NULL; ivar->flags &= ~QB_VARIABLE_IMPORTED; } return result; }
/** * Sharpen the image by a given amount. * * @param int $amount amount to sharpen: 1-100 * @return Phalcon\Image\Adapter */ PHP_METHOD(Phalcon_Image_Adapter, sharpen) { zval **amount; phalcon_fetch_params_ex(1, 0, &amount); PHALCON_MM_GROW(); SEPARATE_ZVAL_IF_NOT_REF(amount); if (Z_TYPE_PP(amount) != IS_LONG) { convert_to_long(*amount); } if (Z_LVAL_PP(amount) > 100) { ZVAL_LONG(*amount, 100); } else if (Z_LVAL_PP(amount) < 1) { ZVAL_LONG(*amount, 1); } PHALCON_CALL_METHOD(NULL, this_ptr, "_sharpen", *amount); RETURN_THIS(); }
U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, HashTable *args, UChar **formatted, int32_t *formatted_len) { int arg_count = zend_hash_num_elements(args); std::vector<Formattable> fargs; std::vector<UnicodeString> farg_names; MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf; HashTable *types; intl_error& err = INTL_DATA_ERROR(mfo); if (U_FAILURE(err.code)) { return; } types = umsg_get_types(mfo, err); umsg_set_timezone(mfo, err); fargs.resize(arg_count); farg_names.resize(arg_count); int argNum = 0; zval *elem; // Key related variables zend_string *str_index; zend_ulong num_index; ZEND_HASH_FOREACH_KEY_VAL(args, num_index, str_index, elem) { Formattable& formattable = fargs[argNum]; UnicodeString& key = farg_names[argNum]; Formattable::Type argType = Formattable::kObject, //unknown *storedArgType = NULL; if (!U_SUCCESS(err.code)) { break; } /* Process key and retrieve type */ if (str_index == NULL) { /* includes case where index < 0 because it's exposed as unsigned */ if (num_index > (zend_ulong)INT32_MAX) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found negative or too large array key", 0); continue; } UChar temp[16]; int32_t len = u_sprintf(temp, "%u", (uint32_t)num_index); key.append(temp, len); storedArgType = (Formattable::Type*)zend_hash_index_find_ptr(types, (zend_ulong)num_index); } else { //string; assumed to be in UTF-8 intl_stringFromChar(key, ZSTR_VAL(str_index), ZSTR_LEN(str_index), &err.code); if (U_FAILURE(err.code)) { char *message; spprintf(&message, 0, "Invalid UTF-8 data in argument key: '%s'", ZSTR_VAL(str_index)); intl_errors_set(&err, err.code, message, 1); efree(message); continue; } storedArgType = (Formattable::Type*)zend_hash_str_find_ptr(types, (char*)key.getBuffer(), key.length()); } if (storedArgType != NULL) { argType = *storedArgType; } /* Convert zval to formattable according to message format type * or (as a fallback) the zval type */ if (argType != Formattable::kObject) { switch (argType) { case Formattable::kString: { string_arg: /* This implicitly converts objects * Note that our vectors will leak if object conversion fails * and PHP ends up with a fatal error and calls longjmp * as a result of that. */ convert_to_string_ex(elem); UnicodeString *text = new UnicodeString(); intl_stringFromChar(*text, Z_STRVAL_P(elem), Z_STRLEN_P(elem), &err.code); if (U_FAILURE(err.code)) { char *message; spprintf(&message, 0, "Invalid UTF-8 data in string argument: " "'%s'", Z_STRVAL_P(elem)); intl_errors_set(&err, err.code, message, 1); efree(message); delete text; continue; } formattable.adoptString(text); break; } case Formattable::kDouble: { double d; if (Z_TYPE_P(elem) == IS_DOUBLE) { d = Z_DVAL_P(elem); } else if (Z_TYPE_P(elem) == IS_LONG) { d = (double)Z_LVAL_P(elem); } else { SEPARATE_ZVAL_IF_NOT_REF(elem); convert_scalar_to_number(elem); d = (Z_TYPE_P(elem) == IS_DOUBLE) ? Z_DVAL_P(elem) : (double)Z_LVAL_P(elem); } formattable.setDouble(d); break; } case Formattable::kLong: { int32_t tInt32 = 0; retry_klong: if (Z_TYPE_P(elem) == IS_DOUBLE) { if (Z_DVAL_P(elem) > (double)INT32_MAX || Z_DVAL_P(elem) < (double)INT32_MIN) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP float with absolute value too large for " "32 bit integer argument", 0); } else { tInt32 = (int32_t)Z_DVAL_P(elem); } } else if (Z_TYPE_P(elem) == IS_LONG) { if (Z_LVAL_P(elem) > INT32_MAX || Z_LVAL_P(elem) < INT32_MIN) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP integer with absolute value too large " "for 32 bit integer argument", 0); } else { tInt32 = (int32_t)Z_LVAL_P(elem); } } else { SEPARATE_ZVAL_IF_NOT_REF(elem); convert_scalar_to_number(elem); goto retry_klong; } formattable.setLong(tInt32); break; } case Formattable::kInt64: { int64_t tInt64 = 0; retry_kint64: if (Z_TYPE_P(elem) == IS_DOUBLE) { if (Z_DVAL_P(elem) > (double)U_INT64_MAX || Z_DVAL_P(elem) < (double)U_INT64_MIN) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP float with absolute value too large for " "64 bit integer argument", 0); } else { tInt64 = (int64_t)Z_DVAL_P(elem); } } else if (Z_TYPE_P(elem) == IS_LONG) { /* assume long is not wider than 64 bits */ tInt64 = (int64_t)Z_LVAL_P(elem); } else { SEPARATE_ZVAL_IF_NOT_REF(elem); convert_scalar_to_number(elem); goto retry_kint64; } formattable.setInt64(tInt64); break; } case Formattable::kDate: { double dd = intl_zval_to_millis(elem, &err, "msgfmt_format"); if (U_FAILURE(err.code)) { char *message; zend_string *u8key; UErrorCode status = UErrorCode(); u8key = intl_charFromString(key, &status); if (u8key) { spprintf(&message, 0, "The argument for key '%s' " "cannot be used as a date or time", ZSTR_VAL(u8key)); intl_errors_set(&err, err.code, message, 1); zend_string_release(u8key); efree(message); } continue; } formattable.setDate(dd); break; } default: intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found unsupported argument type", 0); break; } } else { /* We couldn't find any information about the argument in the pattern, this * means it's an extra argument. So convert it to a number if it's a number or * bool or null and to a string if it's anything else except arrays . */ switch (Z_TYPE_P(elem)) { case IS_DOUBLE: formattable.setDouble(Z_DVAL_P(elem)); break; case IS_TRUE: case IS_FALSE: convert_to_long_ex(elem); /* Intentional fallthrough */ case IS_LONG: formattable.setInt64((int64_t)Z_LVAL_P(elem)); break; case IS_NULL: formattable.setInt64((int64_t)0); break; case IS_STRING: case IS_OBJECT: goto string_arg; default: { char *message; zend_string *u8key; UErrorCode status = UErrorCode(); u8key = intl_charFromString(key, &status); if (u8key) { spprintf(&message, 0, "No strategy to convert the " "value given for the argument with key '%s' " "is available", ZSTR_VAL(u8key)); intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, message, 1); zend_string_release(u8key); efree(message); } } } } argNum++; } ZEND_HASH_FOREACH_END(); // visiting each argument
/** * Crop an image to the given size. Either the width or the height can be * omitted and the current width or height will be used. * * @param int $width new width * @param int $height new height * @param int $offset_x offset from the left, if it's true then will center * @param int $offset_y offset from the top, if it's true then will middle * @return Phalcon\Image\Adapter */ PHP_METHOD(Phalcon_Image_Adapter, crop) { zval **w, **h, **ofs_x = NULL, **ofs_y = NULL; zval *image_width, *image_height; zval *width, *height, *offset_x, *offset_y; long tmp_max_width, tmp_max_height, tmp_width, tmp_height, tmp_image_width, tmp_image_height, tmp_offset_x, tmp_offset_y; phalcon_fetch_params_ex(2, 2, &w, &h, &ofs_x, &ofs_y); PHALCON_ENSURE_IS_LONG(w); PHALCON_ENSURE_IS_LONG(h); PHALCON_MM_GROW(); image_width = phalcon_fetch_nproperty_this(this_ptr, SL("_width"), PH_NOISY TSRMLS_CC); image_height = phalcon_fetch_nproperty_this(this_ptr, SL("_height"), PH_NOISY TSRMLS_CC); SEPARATE_ZVAL_IF_NOT_REF(w); if (Z_TYPE_PP(w) != IS_LONG) { convert_to_long(*w); } SEPARATE_ZVAL_IF_NOT_REF(h); if (Z_TYPE_PP(h) != IS_LONG) { convert_to_long(*h); } if (ofs_x && Z_TYPE_PP(ofs_x) != IS_NULL && Z_TYPE_PP(ofs_x) != IS_BOOL && Z_TYPE_PP(ofs_x) != IS_LONG) { SEPARATE_ZVAL_IF_NOT_REF(ofs_x); convert_to_long(*ofs_x); } if (ofs_y && Z_TYPE_PP(ofs_y) != IS_NULL && Z_TYPE_PP(ofs_y) != IS_BOOL && Z_TYPE_PP(ofs_x) != IS_LONG) { SEPARATE_ZVAL_IF_NOT_REF(ofs_y); convert_to_long(*ofs_y); } tmp_width = Z_LVAL_PP(w); tmp_height = Z_LVAL_PP(h); tmp_image_width = phalcon_get_intval(image_width); tmp_image_height = phalcon_get_intval(image_height); if (tmp_width > tmp_image_width) { tmp_width = tmp_image_width; } if (tmp_height > tmp_image_height) { tmp_height = tmp_image_height; } if (!ofs_x) { tmp_offset_x = (int)(((tmp_image_width - tmp_width) / 2) + 0.5); } else if (Z_TYPE_PP(ofs_x) == IS_BOOL && PHALCON_IS_TRUE(*ofs_x)) { tmp_offset_x = tmp_image_width - tmp_width; } else if (Z_TYPE_PP(ofs_x) == IS_LONG) { if (Z_LVAL_PP(ofs_x) < 0) { tmp_offset_x = (int)(tmp_image_width - tmp_width + Z_LVAL_PP(ofs_x) + 0.5); } else { tmp_offset_x = Z_LVAL_PP(ofs_x); } } else { tmp_offset_x = (int)(((tmp_image_width - tmp_width) / 2) + 0.5); } if (!ofs_y) { tmp_offset_y = (int)(((tmp_image_height - tmp_height) / 2) + 0.5); } else if (Z_TYPE_PP(ofs_x) == IS_BOOL && PHALCON_IS_TRUE(*ofs_y)) { tmp_offset_y = tmp_image_height - tmp_height; } else if (Z_TYPE_PP(ofs_y) == IS_LONG) { if (Z_LVAL_PP(ofs_y) < 0) { tmp_offset_y = tmp_image_height - tmp_height + Z_LVAL_PP(ofs_y); } else { tmp_offset_y = Z_LVAL_PP(ofs_y); } } else { tmp_offset_y = (int)(((tmp_image_height - tmp_height) / 2) + 0.5); } tmp_max_width = tmp_image_width - tmp_offset_x; tmp_max_height = tmp_image_height - tmp_offset_y; if (tmp_width > tmp_max_width) { tmp_width = tmp_max_width; } if (tmp_height > tmp_max_height) { tmp_height = tmp_max_height; } PHALCON_ALLOC_GHOST_ZVAL(width); PHALCON_ALLOC_GHOST_ZVAL(height); PHALCON_ALLOC_GHOST_ZVAL(offset_x); PHALCON_ALLOC_GHOST_ZVAL(offset_y); ZVAL_LONG(width, tmp_width); ZVAL_LONG(height, tmp_height); ZVAL_LONG(offset_x, tmp_offset_x); ZVAL_LONG(offset_y, tmp_offset_y); PHALCON_CALL_METHOD(NULL, this_ptr, "_crop", width, height, offset_x, offset_y); RETURN_THIS(); }
/* the core of COM */ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *f, WORD flags, VARIANT *v, int nargs, zval *args) { DISPID dispid, altdispid; DISPPARAMS disp_params; HRESULT hr; VARIANT *vargs = NULL, *byref_vals = NULL; int i, byref_count = 0, j; /* assumption: that the active function (f) is the function we generated for the engine */ if (!f) { return FAILURE; } hr = php_com_get_id_of_name(obj, f->function_name->val, f->function_name->len, &dispid); if (FAILED(hr)) { char *winerr = NULL; char *msg = NULL; winerr = php_win32_error_to_msg(hr); spprintf(&msg, 0, "Unable to lookup `%s': %s", f->function_name->val, winerr); LocalFree(winerr); php_com_throw_exception(hr, msg); efree(msg); return FAILURE; } if (nargs) { vargs = (VARIANT*)safe_emalloc(sizeof(VARIANT), nargs, 0); } if (f->arg_info) { for (i = 0; i < nargs; i++) { if (f->arg_info[nargs - i - 1].pass_by_reference) { byref_count++; } } } if (byref_count) { byref_vals = (VARIANT*)safe_emalloc(sizeof(VARIANT), byref_count, 0); for (j = 0, i = 0; i < nargs; i++) { if (f->arg_info[nargs - i - 1].pass_by_reference) { /* put the value into byref_vals instead */ php_com_variant_from_zval(&byref_vals[j], &args[nargs - i - 1], obj->code_page); /* if it is already byref, "move" it into the vargs array, otherwise * make vargs a reference to this value */ if (V_VT(&byref_vals[j]) & VT_BYREF) { memcpy(&vargs[i], &byref_vals[j], sizeof(vargs[i])); VariantInit(&byref_vals[j]); /* leave the variant slot empty to simplify cleanup */ } else { VariantInit(&vargs[i]); V_VT(&vargs[i]) = V_VT(&byref_vals[j]) | VT_BYREF; /* union magic ensures that this works out */ vargs[i].byref = &V_UINT(&byref_vals[j]); } j++; } else { php_com_variant_from_zval(&vargs[i], &args[nargs - i - 1], obj->code_page); } } } else { /* Invoke'd args are in reverse order */ for (i = 0; i < nargs; i++) { php_com_variant_from_zval(&vargs[i], &args[nargs - i - 1], obj->code_page); } } disp_params.cArgs = nargs; disp_params.cNamedArgs = 0; disp_params.rgvarg = vargs; disp_params.rgdispidNamedArgs = NULL; if (flags & DISPATCH_PROPERTYPUT) { altdispid = DISPID_PROPERTYPUT; disp_params.rgdispidNamedArgs = &altdispid; disp_params.cNamedArgs = 1; } /* this will create an exception if needed */ hr = php_com_invoke_helper(obj, dispid, flags, &disp_params, v, 0, 0); /* release variants */ if (vargs) { if (f && f->arg_info) { for (i = 0, j = 0; i < nargs; i++) { /* if this was byref, update the zval */ if (f->arg_info[nargs - i - 1].pass_by_reference) { SEPARATE_ZVAL_IF_NOT_REF(&args[nargs - i - 1]); /* if the variant is pointing at the byref_vals, we need to map * the pointee value as a zval; otherwise, the value is pointing * into an existing PHP variant record */ if (V_VT(&vargs[i]) & VT_BYREF) { if (vargs[i].byref == &V_UINT(&byref_vals[j])) { /* copy that value */ php_com_zval_from_variant(&args[nargs - i - 1], &byref_vals[j], obj->code_page); } } else { /* not sure if this can ever happen; the variant we marked as BYREF * is no longer BYREF - copy its value */ php_com_zval_from_variant(&args[nargs - i - 1], &vargs[i], obj->code_page); } VariantClear(&byref_vals[j]); j++; } VariantClear(&vargs[i]); } } else { for (i = 0, j = 0; i < nargs; i++) { VariantClear(&vargs[i]); } } efree(vargs); } return SUCCEEDED(hr) ? SUCCESS : FAILURE; }