diff --git a/msgpack.c b/msgpack.c index 4e3124d..fcda164 100644 --- a/msgpack.c +++ b/msgpack.c @@ -55,6 +55,9 @@ STD_PHP_INI_BOOLEAN( STD_PHP_INI_BOOLEAN( "msgpack.use_str8_serialization", "1", PHP_INI_ALL, OnUpdateBool, use_str8_serialization, zend_msgpack_globals, msgpack_globals) +STD_PHP_INI_BOOLEAN( + "msgpack.force_f32", "0", PHP_INI_ALL, OnUpdateBool, + force_f32, zend_msgpack_globals, msgpack_globals) PHP_INI_END() #if HAVE_PHP_SESSION @@ -115,6 +118,8 @@ static ZEND_MINIT_FUNCTION(msgpack) /* {{{ */ { MSGPACK_CLASS_OPT_PHPONLY, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MESSAGEPACK_OPT_ASSOC", MSGPACK_CLASS_OPT_ASSOC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MESSAGEPACK_OPT_FORCE_F32", + MSGPACK_CLASS_OPT_FORCE_F32, CONST_CS | CONST_PERSISTENT); return SUCCESS; } diff --git a/msgpack_class.c b/msgpack_class.c index 243d5ad..f8d162a 100644 --- a/msgpack_class.c +++ b/msgpack_class.c @@ -11,6 +11,7 @@ typedef struct { long php_only; zend_bool assoc; zend_object object; + zend_bool force_f32; } php_msgpack_base_t; typedef struct { @@ -178,6 +179,7 @@ static void php_msgpack_unpacker_free(zend_object *object) /* {{{ */ { static ZEND_METHOD(msgpack, __construct) /* {{{ */ { zend_bool php_only = MSGPACK_G(php_only); zend_bool assoc = MSGPACK_G(assoc); + zend_bool force_f32 = MSGPACK_G(force_f32); php_msgpack_base_t *base = Z_MSGPACK_BASE_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &php_only) == FAILURE) { @@ -186,6 +188,7 @@ static ZEND_METHOD(msgpack, __construct) /* {{{ */ { base->php_only = php_only; base->assoc = assoc; + base->force_f32 = force_f32; } /* }}} */ @@ -205,6 +208,9 @@ static ZEND_METHOD(msgpack, setOption) /* {{{ */ { case MSGPACK_CLASS_OPT_ASSOC: base->assoc = i_zend_is_true(value); break; + case MSGPACK_CLASS_OPT_FORCE_F32: + base->force_f32 = i_zend_is_true(value); + break; default: MSGPACK_WARNING("[msgpack] (MessagePack::setOption) " "error setting msgpack option"); @@ -221,6 +227,7 @@ static ZEND_METHOD(msgpack, pack) /* {{{ */ { smart_str buf = {0}; int php_only = MSGPACK_G(php_only); zend_bool assoc = MSGPACK_G(assoc); + zend_bool force_f32 = MSGPACK_G(force_f32); php_msgpack_base_t *base = Z_MSGPACK_BASE_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", ¶meter) == FAILURE) { @@ -229,11 +236,13 @@ static ZEND_METHOD(msgpack, pack) /* {{{ */ { MSGPACK_G(php_only) = base->php_only; MSGPACK_G(assoc) = base->assoc; + MSGPACK_G(force_f32) = base->force_f32; php_msgpack_serialize(&buf, parameter); MSGPACK_G(php_only) = php_only; MSGPACK_G(assoc) = assoc; + MSGPACK_G(force_f32) = force_f32; if (buf.s) { smart_str_0(&buf); ZVAL_STR(return_value, buf.s); @@ -512,6 +521,7 @@ void msgpack_init_class() /* {{{ */ { zend_declare_class_constant_long(msgpack_ce, ZEND_STRS("OPT_PHPONLY") - 1, MSGPACK_CLASS_OPT_PHPONLY); zend_declare_class_constant_long(msgpack_ce, ZEND_STRS("OPT_ASSOC") - 1, MSGPACK_CLASS_OPT_ASSOC); + zend_declare_class_constant_long(msgpack_ce, ZEND_STRS("OPT_FORCE_F32") - 1, MSGPACK_CLASS_OPT_FORCE_F32); /* unpacker */ INIT_CLASS_ENTRY(ce, "MessagePackUnpacker", msgpack_unpacker_methods); diff --git a/msgpack_class.h b/msgpack_class.h index 3dcbf40..b86d3ce 100644 --- a/msgpack_class.h +++ b/msgpack_class.h @@ -4,6 +4,7 @@ #define MSGPACK_CLASS_OPT_PHPONLY -1001 #define MSGPACK_CLASS_OPT_ASSOC -1002 +#define MSGPACK_CLASS_OPT_FORCE_F32 -1003 void msgpack_init_class(); diff --git a/msgpack_pack.c b/msgpack_pack.c index cfbea5c..57887c1 100644 --- a/msgpack_pack.c +++ b/msgpack_pack.c @@ -589,7 +589,11 @@ void msgpack_serialize_zval(smart_str *buf, zval *val, HashTable *var_hash) /* { msgpack_pack_long(buf, zval_get_long(val_noref)); break; case IS_DOUBLE: - msgpack_pack_double(buf, Z_DVAL_P(val_noref)); + if (MSGPACK_G(force_f32)) { + msgpack_pack_float(buf, (float) Z_DVAL_P(val_noref)); + } else { + msgpack_pack_double(buf, Z_DVAL_P(val_noref)); + } break; case IS_STRING: msgpack_serialize_string(buf, Z_STRVAL_P(val_noref), Z_STRLEN_P(val_noref)); diff --git a/php_msgpack.h b/php_msgpack.h index 2a6ac82..b164094 100644 --- a/php_msgpack.h +++ b/php_msgpack.h @@ -26,6 +26,7 @@ ZEND_BEGIN_MODULE_GLOBALS(msgpack) zend_bool assoc; zend_bool illegal_key_insert; zend_bool use_str8_serialization; + zend_bool force_f32; struct { void *var_hash; unsigned level; diff --git a/tests/029.phpt b/tests/029.phpt index e1656b2..4635c39 100644 --- a/tests/029.phpt +++ b/tests/029.phpt @@ -51,6 +51,7 @@ header Version => %s Directive => Local Value => Master Value msgpack.assoc => %s => %s msgpack.error_display => %s => %s +msgpack.force_f32 => Off => Off msgpack.illegal_key_insert => %s => %s msgpack.php_only => %s => %s msgpack.use_str8_serialization => %s => %s diff --git a/tests/141.phpt b/tests/141.phpt new file mode 100644 index 0000000..3db3701 --- /dev/null +++ b/tests/141.phpt @@ -0,0 +1,25 @@ +--TEST-- +Check for f32 serialisation +--SKIPIF-- +--FILE-- +setOption(\MessagePack::OPT_FORCE_F32, true); + + $serialized = $packer->pack($variable); + + echo $type, PHP_EOL; + echo bin2hex($serialized), PHP_EOL; +} + +test('double: 123.456', 123.456); +?> +--EXPECT-- +double: 123.456 +ca42f6e979 diff --git a/tests/142.phpt b/tests/142.phpt new file mode 100644 index 0000000..1ed8fee --- /dev/null +++ b/tests/142.phpt @@ -0,0 +1,23 @@ +--TEST-- +Check for f32 serialisation +--SKIPIF-- +--INI-- +msgpack.force_f32 = 1 +--FILE-- + +--EXPECT-- +double: 123.456 +ca42f6e979 diff --git a/tests/143.phpt b/tests/143.phpt new file mode 100644 index 0000000..b231192 --- /dev/null +++ b/tests/143.phpt @@ -0,0 +1,25 @@ +--TEST-- +Check for f32 serialisation +--SKIPIF-- +--INI-- +msgpack.force_f32 = 1 +--FILE-- +pack($variable); + + echo $type, PHP_EOL; + echo bin2hex($serialized), PHP_EOL; +} + +test('double: 123.456', 123.456); +?> +--EXPECT-- +double: 123.456 +ca42f6e979