mirror of
https://github.com/php-win-ext/pecl-memcache.git
synced 2026-03-24 00:52:07 +01:00
Scalar data types (int, bool, double) are preserved by get/set using the flag field
This commit is contained in:
@@ -315,28 +315,35 @@ static int mmc_uncompress(const char *data, unsigned long data_len, char **resul
|
||||
int mmc_pack_value(mmc_pool_t *pool, mmc_buffer_t *buffer, zval *value, unsigned int *flags TSRMLS_DC) /*
|
||||
does serialization and compression to pack a zval into the buffer {{{ */
|
||||
{
|
||||
if (*flags & 0xffff & ~MMC_COMPRESSED) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The lowest two bytes of the flags array is reserved for pecl/memcache internal use");
|
||||
return MMC_REQUEST_FAILURE;
|
||||
}
|
||||
|
||||
*flags &= ~MMC_SERIALIZED;
|
||||
switch (Z_TYPE_P(value)) {
|
||||
case IS_STRING:
|
||||
*flags &= ~MMC_SERIALIZED;
|
||||
*flags |= MMC_TYPE_STRING;
|
||||
mmc_compress(pool, buffer, Z_STRVAL_P(value), Z_STRLEN_P(value), flags, 0 TSRMLS_CC);
|
||||
break;
|
||||
|
||||
case IS_LONG:
|
||||
case IS_DOUBLE:
|
||||
case IS_BOOL: {
|
||||
zval value_copy;
|
||||
*flags &= ~MMC_SERIALIZED;
|
||||
|
||||
/* FIXME: we should be using 'Z' instead of this, but unfortunately it's PHP5-only */
|
||||
value_copy = *value;
|
||||
zval_copy_ctor(&value_copy);
|
||||
convert_to_string(&value_copy);
|
||||
|
||||
mmc_compress(pool, buffer, Z_STRVAL(value_copy), Z_STRLEN(value_copy), flags, 0 TSRMLS_CC);
|
||||
|
||||
zval_dtor(&value_copy);
|
||||
*flags |= MMC_TYPE_LONG;
|
||||
smart_str_append_long(&(buffer->value), Z_LVAL_P(value));
|
||||
break;
|
||||
|
||||
case IS_DOUBLE: {
|
||||
char buf[256];
|
||||
int len = snprintf(buf, 256, "%.14g", Z_DVAL_P(value));
|
||||
*flags |= MMC_TYPE_DOUBLE;
|
||||
smart_str_appendl(&(buffer->value), buf, len);
|
||||
break;
|
||||
}
|
||||
|
||||
case IS_BOOL:
|
||||
*flags |= MMC_TYPE_BOOL;
|
||||
smart_str_appendc(&(buffer->value), Z_BVAL_P(value) ? '1' : '0');
|
||||
break;
|
||||
|
||||
default: {
|
||||
php_serialize_data_t value_hash;
|
||||
@@ -446,13 +453,37 @@ int mmc_unpack_value(
|
||||
return value_handler(key_tmp, key_len, object, flags, cas, value_handler_param TSRMLS_CC);
|
||||
}
|
||||
else {
|
||||
data[data_len] = '\0';
|
||||
ZVAL_STRINGL(&value, data, data_len, 0);
|
||||
|
||||
if (!(flags & MMC_COMPRESSED)) {
|
||||
mmc_buffer_release(buffer);
|
||||
}
|
||||
switch (flags & 0x0f00) {
|
||||
case MMC_TYPE_LONG: {
|
||||
long val;
|
||||
data[data_len] = '\0';
|
||||
val = strtol(data, NULL, 10);
|
||||
ZVAL_LONG(&value, val);
|
||||
break;
|
||||
}
|
||||
|
||||
case MMC_TYPE_DOUBLE: {
|
||||
double val = 0;
|
||||
data[data_len] = '\0';
|
||||
sscanf(data, "%lg", &val);
|
||||
ZVAL_DOUBLE(&value, val);
|
||||
break;
|
||||
}
|
||||
|
||||
case MMC_TYPE_BOOL:
|
||||
ZVAL_BOOL(&value, data_len == 1 && data[0] == '1');
|
||||
break;
|
||||
|
||||
default:
|
||||
data[data_len] = '\0';
|
||||
ZVAL_STRINGL(&value, data, data_len, 0);
|
||||
|
||||
if (!(flags & MMC_COMPRESSED)) {
|
||||
/* release buffer because it's now owned by the zval */
|
||||
mmc_buffer_release(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* delegate to value handler */
|
||||
return request->value_handler(key, key_len, &value, flags, cas, request->value_handler_param TSRMLS_CC);
|
||||
}
|
||||
|
||||
@@ -41,8 +41,20 @@
|
||||
#define ZSTR_VAL(v) (v).s
|
||||
#endif
|
||||
|
||||
#define MMC_SERIALIZED 1
|
||||
#define MMC_COMPRESSED 2
|
||||
/* use lowest byte for flags */
|
||||
#define MMC_SERIALIZED 0x0001
|
||||
#define MMC_COMPRESSED 0x0002
|
||||
|
||||
/* use second lowest byte to indicate data type */
|
||||
#define MMC_TYPE_STRING 0x0000
|
||||
#define MMC_TYPE_BOOL 0x0100
|
||||
/*#define MMC_TYPE_INT 0x0200*/
|
||||
#define MMC_TYPE_LONG 0x0300
|
||||
/*#define MMC_TYPE_DATE 0x0400*/
|
||||
/*#define MMC_TYPE_BYTE 0x0500*/
|
||||
/*#define MMC_TYPE_FLOAT 0x0600*/
|
||||
#define MMC_TYPE_DOUBLE 0x0700
|
||||
/*#define MMC_TYPE_BLOB 0x0800*/
|
||||
|
||||
#define MMC_BUFFER_SIZE 4096
|
||||
#define MMC_MAX_UDP_LEN 1400
|
||||
|
||||
@@ -37,10 +37,13 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<license uri="http://www.php.net/license">PHP License</license>
|
||||
<notes>
|
||||
- Enabled compression by default for values larger than 20kb
|
||||
- Scalar data types (int, bool, double) are preserved by get/set
|
||||
- Reserved the lowest 2 bytes of the flags for internal use
|
||||
- Fixed PECL bug #14157 (Segmentation fault with errorcallback handler)
|
||||
- Fixed PECL bug #15342 (memcache keys whitespaces replace issue)
|
||||
- Fixed PECL bug #15447 (Persistent Connections Cause Segfaults if One Server Drops)
|
||||
- Fixed PECL bug #15529 (memcache object loses port information)
|
||||
- Fixed PECL bug #14730 (Types lost during get/set)
|
||||
- Fixed PECL request #14801 (Session handler and large sessions)
|
||||
- Added REPORT_ERRORS to php stream open
|
||||
- New INI directive
|
||||
|
||||
@@ -21,4 +21,4 @@ var_dump($result3);
|
||||
--EXPECT--
|
||||
int(6)
|
||||
int(5)
|
||||
string(1) "5"
|
||||
int(5)
|
||||
|
||||
@@ -21,4 +21,4 @@ var_dump($result3);
|
||||
--EXPECT--
|
||||
int(6)
|
||||
int(5)
|
||||
string(1) "5"
|
||||
int(5)
|
||||
|
||||
@@ -49,6 +49,6 @@ bool(true)
|
||||
int(11)
|
||||
int(21)
|
||||
string(0) ""
|
||||
string(2) "21"
|
||||
string(2) "11"
|
||||
int(21)
|
||||
int(11)
|
||||
string(0) ""
|
||||
|
||||
@@ -36,8 +36,8 @@ array(2) {
|
||||
["%s"]=>
|
||||
int(3)
|
||||
}
|
||||
string(1) "2"
|
||||
string(1) "3"
|
||||
int(2)
|
||||
int(3)
|
||||
array(2) {
|
||||
["%s"]=>
|
||||
int(1)
|
||||
|
||||
@@ -7,8 +7,8 @@ memcache->get() with flags
|
||||
|
||||
include 'connect.inc';
|
||||
|
||||
$flag1 = 0x100;
|
||||
$flag2 = 0x200;
|
||||
$flag1 = 0x10000;
|
||||
$flag2 = 0x20000;
|
||||
|
||||
$memcache->set('test_key1', 'test1', $flag1);
|
||||
$memcache->set('test_key2', 'test2', $flag2);
|
||||
@@ -57,13 +57,13 @@ var_dump($result5);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(256)
|
||||
int(65536)
|
||||
string(5) "test1"
|
||||
array(2) {
|
||||
["test_key1"]=>
|
||||
int(256)
|
||||
int(65536)
|
||||
["test_key2"]=>
|
||||
int(512)
|
||||
int(131072)
|
||||
}
|
||||
array(2) {
|
||||
["test_key1"]=>
|
||||
@@ -72,13 +72,13 @@ array(2) {
|
||||
string(5) "test2"
|
||||
}
|
||||
string(5) "test1"
|
||||
int(256)
|
||||
int(65536)
|
||||
string(5) "test1"
|
||||
array(2) {
|
||||
["test_key1"]=>
|
||||
int(256)
|
||||
int(65536)
|
||||
["test_key2"]=>
|
||||
int(512)
|
||||
int(131072)
|
||||
}
|
||||
array(2) {
|
||||
["test_key1"]=>
|
||||
|
||||
40
tests/055.phpt
Normal file
40
tests/055.phpt
Normal file
@@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
memcache->set()/get() datatype preservation
|
||||
--SKIPIF--
|
||||
<?php include 'connect.inc'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include 'connect.inc';
|
||||
|
||||
$memcache->set('test_key', '1');
|
||||
$result = $memcache->get('test_key');
|
||||
var_dump($result);
|
||||
|
||||
$memcache->set('test_key', 1);
|
||||
$result = $memcache->get('test_key');
|
||||
var_dump($result);
|
||||
|
||||
$memcache->set('test_key', true);
|
||||
$result = $memcache->get('test_key');
|
||||
var_dump($result);
|
||||
|
||||
$memcache->set('test_key', false);
|
||||
$result = $memcache->get('test_key');
|
||||
var_dump($result);
|
||||
|
||||
$memcache->set('test_key', 1.1);
|
||||
$result = $memcache->get('test_key');
|
||||
var_dump($result);
|
||||
|
||||
$memcache->set('test_key', '1', 0x10);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(1) "1"
|
||||
int(1)
|
||||
bool(true)
|
||||
bool(false)
|
||||
float(1.1)
|
||||
|
||||
Warning: MemcachePool::set(): The lowest two bytes of the flags %s
|
||||
Reference in New Issue
Block a user