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;
}