int php_memc_set_option()

in php_memcached.c [2981:3128]


int php_memc_set_option(php_memc_object_t *intern, long option, zval *value)
{
	zend_long lval;
	memcached_return rc = MEMCACHED_FAILURE;
	memcached_behavior flag;
	php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc);

	switch (option) {
		case MEMC_OPT_COMPRESSION:
			memc_user_data->compression_enabled = zval_get_long(value) ? 1 : 0;
			break;

		case MEMC_OPT_COMPRESSION_TYPE:
			lval = zval_get_long(value);
			if (lval == COMPRESSION_TYPE_FASTLZ ||
				lval == COMPRESSION_TYPE_ZLIB) {
				memc_user_data->compression_type = lval;
			} else {
				/* invalid compression type */
				intern->rescode = MEMCACHED_INVALID_ARGUMENTS;
				return 0;
			}
			break;

		case MEMC_OPT_PREFIX_KEY:
		{
			zend_string *str;
			char *key;
			str = zval_get_string(value);
			if (ZSTR_LEN(str) == 0) {
				key = NULL;
			} else {
				key = ZSTR_VAL(str);
			}
			if (memcached_callback_set(intern->memc, MEMCACHED_CALLBACK_PREFIX_KEY, key) == MEMCACHED_BAD_KEY_PROVIDED) {
				zend_string_release(str);
				intern->rescode = MEMCACHED_INVALID_ARGUMENTS;
				php_error_docref(NULL, E_WARNING, "bad key provided");
				return 0;
			}
			zend_string_release(str);
		}
			break;

		case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED:
			flag = (memcached_behavior) option;

			lval = zval_get_long(value);
			rc = memcached_behavior_set(intern->memc, flag, (uint64_t)lval);

			if (s_memc_status_handle_result_code(intern, rc) == FAILURE) {
				php_error_docref(NULL, E_WARNING, "error setting memcached option: %s", memcached_strerror (intern->memc, rc));
				return 0;
			}

			/*
			 * This is necessary because libmemcached does not reset hash/distribution
			 * options on false case, like it does for MEMCACHED_BEHAVIOR_KETAMA
			 * (non-weighted) case. We have to clean up ourselves.
			 */
			if (!lval) {
				(void)memcached_behavior_set_key_hash(intern->memc, MEMCACHED_HASH_DEFAULT);
				(void)memcached_behavior_set_distribution_hash(intern->memc, MEMCACHED_HASH_DEFAULT);
				(void)memcached_behavior_set_distribution(intern->memc, MEMCACHED_DISTRIBUTION_MODULA);
			}
			break;

		case MEMC_OPT_SERIALIZER:
		{
			lval = zval_get_long(value);
			/* igbinary serializer */
#ifdef HAVE_MEMCACHED_IGBINARY
			if (lval == SERIALIZER_IGBINARY) {
				memc_user_data->serializer = SERIALIZER_IGBINARY;
			} else
#endif
#ifdef HAVE_JSON_API
			if (lval == SERIALIZER_JSON) {
				memc_user_data->serializer = SERIALIZER_JSON;
			} else if (lval == SERIALIZER_JSON_ARRAY) {
				memc_user_data->serializer = SERIALIZER_JSON_ARRAY;
			} else
#endif
			/* msgpack serializer */
#ifdef HAVE_MEMCACHED_MSGPACK
			if (lval == SERIALIZER_MSGPACK) {
				memc_user_data->serializer = SERIALIZER_MSGPACK;
			} else
#endif
			/* php serializer */
			if (lval == SERIALIZER_PHP) {
				memc_user_data->serializer = SERIALIZER_PHP;
			} else {
				memc_user_data->serializer = SERIALIZER_PHP;
				intern->rescode = MEMCACHED_INVALID_ARGUMENTS;
				php_error_docref(NULL, E_WARNING, "invalid serializer provided");
				return 0;
			}
			break;
		}

		case MEMC_OPT_USER_FLAGS:
			lval = zval_get_long(value);

			if (lval < 0) {
				memc_user_data->set_udf_flags = -1;
				return 1;
			}

			if (lval > MEMC_VAL_USER_FLAGS_MAX) {
				php_error_docref(NULL, E_WARNING, "MEMC_OPT_USER_FLAGS must be < %u", MEMC_VAL_USER_FLAGS_MAX);
				return 0;
			}
			memc_user_data->set_udf_flags = lval;
			break;

		case MEMC_OPT_STORE_RETRY_COUNT:
			lval = zval_get_long(value);
			memc_user_data->store_retry_count = lval;
			break;

		default:
			/*
			 * Assume that it's a libmemcached behavior option.
			 */
			if (option < 0) {
				rc = MEMCACHED_INVALID_ARGUMENTS;
			}
			else {
				flag = (memcached_behavior) option;
				lval = zval_get_long(value);

				if (flag < MEMCACHED_BEHAVIOR_MAX) {
					rc = memcached_behavior_set(intern->memc, flag, (uint64_t)lval);
				}
				else {
					rc = MEMCACHED_INVALID_ARGUMENTS;
				}
			}

			if (s_memc_status_handle_result_code(intern, rc) == FAILURE) {
				php_error_docref(NULL, E_WARNING, "error setting memcached option: %s", memcached_strerror (intern->memc, rc));
				return 0;
			}
			break;
	}
	return 1;
}