zend_bool s_compress_value()

in php_memcached.c [863:932]


zend_bool s_compress_value (php_memc_compression_type compression_type, zend_string **payload_in, uint32_t *flags)
{
	/* status */
	zend_bool compress_status = 0;
	zend_string *payload = *payload_in;
	uint32_t compression_type_flag = 0;

	/* Additional 5% for the data */
	size_t buffer_size = (size_t) (((double) ZSTR_LEN(payload) * 1.05) + 1.0);
	char *buffer       = emalloc(buffer_size);

	/* Store compressed size here */
	size_t compressed_size = 0;
	uint32_t original_size = ZSTR_LEN(payload);

	switch (compression_type) {

		case COMPRESSION_TYPE_FASTLZ:
		{
			compressed_size = fastlz_compress(ZSTR_VAL(payload), ZSTR_LEN(payload), buffer);

			if (compressed_size > 0) {
				compress_status = 1;
				compression_type_flag = MEMC_VAL_COMPRESSION_FASTLZ;
			}
		}
			break;

		case COMPRESSION_TYPE_ZLIB:
		{
			compressed_size = buffer_size;
			int status = compress((Bytef *) buffer, &compressed_size, (Bytef *) ZSTR_VAL(payload), ZSTR_LEN(payload));

			if (status == Z_OK) {
				compress_status = 1;
				compression_type_flag = MEMC_VAL_COMPRESSION_ZLIB;
			}
		}
			break;

		default:
			compress_status = 0;
			break;
	}

	/* This means the value was too small to be compressed and ended up larger */
	if (ZSTR_LEN(payload) <= (compressed_size * MEMC_G(compression_factor))) {
		compress_status = 0;
	}

	/* Replace the payload with the compressed copy */
	if (compress_status) {
		MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSED | compression_type_flag);
		payload = zend_string_realloc(payload, compressed_size + sizeof(uint32_t), 0);

		/* Copy the uin32_t at the beginning */
		memcpy(ZSTR_VAL(payload), &original_size, sizeof(uint32_t));
		memcpy(ZSTR_VAL(payload) + sizeof (uint32_t), buffer, compressed_size);
		efree(buffer);

		zend_string_forget_hash_val(payload);
		*payload_in = payload;

		return 1;
	}

	/* Original payload was not modified */
	efree(buffer);
	return 0;
}