zend_bool s_invoke_cache_callback()

in php_memcached.c [796:856]


zend_bool s_invoke_cache_callback(zval *zobject, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_bool with_cas, zend_string *key, zval *value)
{
	zend_bool status = 0;
	zval params[4];
	zval retval;
	php_memc_object_t *intern = Z_MEMC_OBJ_P(zobject);

	/* Prepare params */
	ZVAL_COPY(&params[0], zobject);
	ZVAL_STR_COPY(&params[1], key);    /* key */
	ZVAL_NEW_REF(&params[2], value);   /* value */

	if (with_cas) {
		fci->param_count = 3;
	} else {
		ZVAL_NEW_EMPTY_REF(&params[3]);    /* expiration */
		ZVAL_NULL(Z_REFVAL(params[3]));
		fci->param_count = 4;
	}

	fci->retval = &retval;
	fci->params = params;

	if (zend_call_function(fci, fcc) == SUCCESS) {
		if (zend_is_true(&retval)) {
			time_t expiration;
			zval *val = Z_REFVAL(params[2]);

			if (with_cas) {
				if (Z_TYPE_P(val) == IS_ARRAY) {
					zval *rv = zend_hash_str_find(Z_ARRVAL_P(val), "value", sizeof("value") - 1);
					if (rv) {
						zval *cas = zend_hash_str_find(Z_ARRVAL_P(val), "cas", sizeof("cas") -1);
						expiration = cas? Z_LVAL_P(cas) : 0;
						status = s_memc_write_zval (intern, MEMC_OP_SET, NULL, key, rv, expiration);
					}
					/* memleak?  zval_ptr_dtor(value); */
					ZVAL_COPY(value, val);
				}
			} else {
				expiration = zval_get_long(Z_REFVAL(params[3]));
				status = s_memc_write_zval (intern, MEMC_OP_SET, NULL, key, val, expiration);
				/* memleak?  zval_ptr_dtor(value); */
				ZVAL_COPY(value, val);
			}
		}
	}
	else {
		s_memc_set_status(intern, MEMCACHED_NOTFOUND, 0);
	}

	zval_ptr_dtor(&params[0]);
	zval_ptr_dtor(&params[1]);
	zval_ptr_dtor(&params[2]);
	if (!with_cas) {
		zval_ptr_dtor(&params[3]);
	}
	zval_ptr_dtor(&retval);

	return status;
}