2010-04-05 00:10:28 +09:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "php.h"
|
|
|
|
#include "php_ini.h"
|
|
|
|
#include "ext/standard/info.h"
|
|
|
|
#include "ext/standard/php_smart_str.h"
|
2010-07-17 18:46:28 +09:00
|
|
|
#include "ext/standard/php_incomplete_class.h"
|
|
|
|
#include "ext/standard/php_var.h"
|
|
|
|
#include "ext/session/php_session.h"
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
#include "php_msgpack.h"
|
|
|
|
#include "msgpack_pack.h"
|
|
|
|
#include "msgpack_unpack.h"
|
|
|
|
#include "msgpack_class.h"
|
2010-09-29 08:47:06 +09:00
|
|
|
#include "msgpack/version.h"
|
2010-07-17 18:46:28 +09:00
|
|
|
|
|
|
|
static ZEND_FUNCTION(msgpack_serialize);
|
|
|
|
static ZEND_FUNCTION(msgpack_unserialize);
|
|
|
|
|
|
|
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_serialize, 0, 0, 1)
|
|
|
|
ZEND_ARG_INFO(0, value)
|
|
|
|
ZEND_END_ARG_INFO()
|
|
|
|
|
|
|
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unserialize, 0, 0, 1)
|
|
|
|
ZEND_ARG_INFO(0, str)
|
|
|
|
ZEND_END_ARG_INFO()
|
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
PHP_INI_BEGIN()
|
|
|
|
STD_PHP_INI_BOOLEAN(
|
|
|
|
"msgpack.error_display", "1", PHP_INI_ALL, OnUpdateBool,
|
|
|
|
error_display, zend_msgpack_globals, msgpack_globals)
|
|
|
|
STD_PHP_INI_BOOLEAN(
|
|
|
|
"msgpack.php_only", "1", PHP_INI_ALL, OnUpdateBool,
|
|
|
|
php_only, zend_msgpack_globals, msgpack_globals)
|
|
|
|
PHP_INI_END()
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
PS_SERIALIZER_FUNCS(msgpack);
|
|
|
|
|
|
|
|
static const zend_function_entry msgpack_functions[] = {
|
|
|
|
ZEND_FE(msgpack_serialize, arginfo_msgpack_serialize)
|
|
|
|
ZEND_FE(msgpack_unserialize, arginfo_msgpack_unserialize)
|
|
|
|
ZEND_FALIAS(msgpack_pack, msgpack_serialize, arginfo_msgpack_serialize)
|
2010-09-29 08:47:06 +09:00
|
|
|
ZEND_FALIAS(msgpack_unpack, msgpack_unserialize, arginfo_msgpack_unserialize)
|
2010-07-17 18:46:28 +09:00
|
|
|
{NULL, NULL, NULL}
|
|
|
|
};
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
static void msgpack_init_globals(zend_msgpack_globals *msgpack_globals)
|
|
|
|
{
|
|
|
|
TSRMLS_FETCH();
|
|
|
|
|
|
|
|
if (PG(display_errors))
|
|
|
|
{
|
|
|
|
msgpack_globals->error_display = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
msgpack_globals->error_display = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
msgpack_globals->php_only = 1;
|
|
|
|
}
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
static ZEND_MINIT_FUNCTION(msgpack)
|
2010-04-05 00:10:28 +09:00
|
|
|
{
|
2010-09-29 08:47:06 +09:00
|
|
|
ZEND_INIT_MODULE_GLOBALS(msgpack, msgpack_init_globals, NULL);
|
|
|
|
|
|
|
|
REGISTER_INI_ENTRIES();
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
#if HAVE_PHP_SESSION
|
|
|
|
php_session_register_serializer("msgpack",
|
|
|
|
PS_SERIALIZER_ENCODE_NAME(msgpack),
|
|
|
|
PS_SERIALIZER_DECODE_NAME(msgpack));
|
|
|
|
#endif
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
msgpack_init_class();
|
|
|
|
|
2010-12-27 11:09:14 +09:00
|
|
|
#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 1)
|
|
|
|
REGISTER_LONG_CONSTANT(
|
|
|
|
"MESSAGEPACK_OPT_PHPONLY", MSGPACK_CLASS_OPT_PHPONLY,
|
|
|
|
CONST_CS | CONST_PERSISTENT);
|
|
|
|
#endif
|
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ZEND_MSHUTDOWN_FUNCTION(msgpack)
|
|
|
|
{
|
|
|
|
UNREGISTER_INI_ENTRIES();
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
return SUCCESS;
|
2010-04-05 00:10:28 +09:00
|
|
|
}
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
static ZEND_MINFO_FUNCTION(msgpack)
|
2010-04-05 00:10:28 +09:00
|
|
|
{
|
2010-07-17 18:46:28 +09:00
|
|
|
php_info_print_table_start();
|
2010-09-29 08:47:06 +09:00
|
|
|
php_info_print_table_row(2, "MessagePack Support", "enabled");
|
2010-07-17 18:46:28 +09:00
|
|
|
#if HAVE_PHP_SESSION
|
2010-09-29 08:47:06 +09:00
|
|
|
php_info_print_table_row(2, "Session Support", "enabled" );
|
2010-07-17 18:46:28 +09:00
|
|
|
#endif
|
2010-09-29 08:47:06 +09:00
|
|
|
php_info_print_table_row(2, "extension Version", MSGPACK_EXTENSION_VERSION);
|
|
|
|
php_info_print_table_row(2, "header Version", MSGPACK_VERSION);
|
2010-07-17 18:46:28 +09:00
|
|
|
php_info_print_table_end();
|
2010-09-29 08:47:06 +09:00
|
|
|
|
|
|
|
DISPLAY_INI_ENTRIES();
|
2010-04-05 00:10:28 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
zend_module_entry msgpack_module_entry = {
|
|
|
|
#if ZEND_MODULE_API_NO >= 20010901
|
2010-07-17 18:46:28 +09:00
|
|
|
STANDARD_MODULE_HEADER,
|
2010-04-05 00:10:28 +09:00
|
|
|
#endif
|
2010-07-17 18:46:28 +09:00
|
|
|
"msgpack",
|
|
|
|
msgpack_functions,
|
|
|
|
ZEND_MINIT(msgpack),
|
2010-09-29 08:47:06 +09:00
|
|
|
ZEND_MSHUTDOWN(msgpack),
|
2010-07-17 18:46:28 +09:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
ZEND_MINFO(msgpack),
|
2010-04-05 00:10:28 +09:00
|
|
|
#if ZEND_MODULE_API_NO >= 20010901
|
2010-10-30 16:06:50 +09:00
|
|
|
MSGPACK_EXTENSION_VERSION,
|
2010-04-05 00:10:28 +09:00
|
|
|
#endif
|
2010-07-17 18:46:28 +09:00
|
|
|
STANDARD_MODULE_PROPERTIES
|
2010-04-05 00:10:28 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef COMPILE_DL_MSGPACK
|
|
|
|
ZEND_GET_MODULE(msgpack)
|
|
|
|
#endif
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
PS_SERIALIZER_ENCODE_FUNC(msgpack)
|
2010-04-05 00:10:28 +09:00
|
|
|
{
|
2010-07-17 18:46:28 +09:00
|
|
|
smart_str buf = {0};
|
|
|
|
php_serialize_data_t var_hash;
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
PHP_VAR_SERIALIZE_INIT(var_hash);
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
msgpack_serialize_zval(&buf, PS(http_session_vars), &var_hash TSRMLS_CC);
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
if (newlen)
|
|
|
|
{
|
|
|
|
*newlen = buf.len;
|
|
|
|
}
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
smart_str_0(&buf);
|
|
|
|
*newstr = buf.c;
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
PHP_VAR_SERIALIZE_DESTROY(var_hash);
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
return SUCCESS;
|
2010-04-05 00:10:28 +09:00
|
|
|
}
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
PS_SERIALIZER_DECODE_FUNC(msgpack)
|
2010-04-05 00:10:28 +09:00
|
|
|
{
|
2010-07-17 18:46:28 +09:00
|
|
|
int ret;
|
|
|
|
HashTable *tmp_hash;
|
|
|
|
HashPosition tmp_hash_pos;
|
|
|
|
char *key_str;
|
|
|
|
ulong key_long;
|
|
|
|
uint key_len;
|
|
|
|
zval *tmp;
|
2010-09-29 08:47:06 +09:00
|
|
|
zval **value;
|
|
|
|
size_t off = 0;
|
|
|
|
msgpack_unpack_t mp;
|
|
|
|
php_unserialize_data_t var_hash;
|
2010-07-17 18:46:28 +09:00
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
ALLOC_INIT_ZVAL(tmp);
|
2010-07-17 18:46:28 +09:00
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
template_init(&mp);
|
2010-07-17 18:46:28 +09:00
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
msgpack_unserialize_var_init(&var_hash);
|
2010-07-17 18:46:28 +09:00
|
|
|
|
2010-12-27 11:09:14 +09:00
|
|
|
mp.user.retval = (zval *)tmp;
|
|
|
|
mp.user.var_hash = (php_unserialize_data_t *)&var_hash;
|
2010-07-17 18:46:28 +09:00
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
ret = template_execute(&mp, (char *)val, (size_t)vallen, &off);
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-12-27 11:09:14 +09:00
|
|
|
if (ret == MSGPACK_UNPACK_EXTRA_BYTES || ret == MSGPACK_UNPACK_SUCCESS)
|
|
|
|
{
|
|
|
|
msgpack_unserialize_var_destroy(&var_hash, 0);
|
2010-07-17 18:46:28 +09:00
|
|
|
|
2010-12-27 11:09:14 +09:00
|
|
|
tmp_hash = HASH_OF(tmp);
|
2010-07-17 18:46:28 +09:00
|
|
|
|
2010-12-27 11:09:14 +09:00
|
|
|
zend_hash_internal_pointer_reset_ex(tmp_hash, &tmp_hash_pos);
|
|
|
|
|
|
|
|
while (zend_hash_get_current_data_ex(
|
|
|
|
tmp_hash, (void *)&value, &tmp_hash_pos) == SUCCESS)
|
2010-07-17 18:46:28 +09:00
|
|
|
{
|
2010-12-27 11:09:14 +09:00
|
|
|
ret = zend_hash_get_current_key_ex(
|
|
|
|
tmp_hash, &key_str, &key_len, &key_long, 0, &tmp_hash_pos);
|
|
|
|
switch (ret)
|
|
|
|
{
|
|
|
|
case HASH_KEY_IS_LONG:
|
|
|
|
/* ??? */
|
|
|
|
break;
|
|
|
|
case HASH_KEY_IS_STRING:
|
|
|
|
php_set_session_var(
|
|
|
|
key_str, key_len - 1, *value, NULL TSRMLS_CC);
|
|
|
|
php_add_session_var(key_str, key_len - 1 TSRMLS_CC);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
zend_hash_move_forward_ex(tmp_hash, &tmp_hash_pos);
|
2010-07-17 18:46:28 +09:00
|
|
|
}
|
2010-12-27 11:09:14 +09:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
msgpack_unserialize_var_destroy(&var_hash, 1);
|
2010-07-17 18:46:28 +09:00
|
|
|
}
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
zval_ptr_dtor(&tmp);
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
return SUCCESS;
|
2010-04-05 00:10:28 +09:00
|
|
|
}
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
PHP_MSGPACK_API void php_msgpack_serialize(smart_str *buf, zval *val TSRMLS_DC)
|
2010-04-05 00:10:28 +09:00
|
|
|
{
|
2010-07-17 18:46:28 +09:00
|
|
|
php_serialize_data_t var_hash;
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
PHP_VAR_SERIALIZE_INIT(var_hash);
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
msgpack_serialize_zval(buf, val, &var_hash TSRMLS_CC);
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
PHP_VAR_SERIALIZE_DESTROY(var_hash);
|
2010-04-05 00:10:28 +09:00
|
|
|
}
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
PHP_MSGPACK_API void php_msgpack_unserialize(
|
|
|
|
zval *return_value, char *str, size_t str_len TSRMLS_DC)
|
2010-04-05 00:10:28 +09:00
|
|
|
{
|
2010-07-17 18:46:28 +09:00
|
|
|
int ret;
|
2010-09-29 08:47:06 +09:00
|
|
|
size_t off = 0;
|
|
|
|
msgpack_unpack_t mp;
|
2010-07-17 18:46:28 +09:00
|
|
|
php_unserialize_data_t var_hash;
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
if (str_len <= 0)
|
|
|
|
{
|
|
|
|
RETURN_NULL();
|
2010-04-05 00:10:28 +09:00
|
|
|
}
|
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
template_init(&mp);
|
2010-07-17 18:46:28 +09:00
|
|
|
|
2010-09-29 08:47:06 +09:00
|
|
|
msgpack_unserialize_var_init(&var_hash);
|
2010-07-17 18:46:28 +09:00
|
|
|
|
2010-12-27 11:09:14 +09:00
|
|
|
mp.user.retval = (zval *)return_value;
|
|
|
|
mp.user.var_hash = (php_unserialize_data_t *)&var_hash;
|
2010-09-29 08:47:06 +09:00
|
|
|
|
|
|
|
ret = template_execute(&mp, str, (size_t)str_len, &off);
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
switch (ret)
|
|
|
|
{
|
|
|
|
case MSGPACK_UNPACK_PARSE_ERROR:
|
2010-12-27 11:09:14 +09:00
|
|
|
{
|
|
|
|
msgpack_unserialize_var_destroy(&var_hash, 1);
|
2010-09-29 08:47:06 +09:00
|
|
|
if (MSGPACK_G(error_display))
|
|
|
|
{
|
|
|
|
zend_error(E_WARNING,
|
2010-12-27 11:09:14 +09:00
|
|
|
"[msgpack] (%s) Parse error", __FUNCTION__);
|
2010-09-29 08:47:06 +09:00
|
|
|
}
|
2010-07-17 18:46:28 +09:00
|
|
|
break;
|
2010-12-27 11:09:14 +09:00
|
|
|
}
|
2010-07-17 18:46:28 +09:00
|
|
|
case MSGPACK_UNPACK_CONTINUE:
|
2010-12-27 11:09:14 +09:00
|
|
|
{
|
|
|
|
msgpack_unserialize_var_destroy(&var_hash, 1);
|
2010-09-29 08:47:06 +09:00
|
|
|
if (MSGPACK_G(error_display))
|
|
|
|
{
|
|
|
|
zend_error(E_WARNING,
|
2010-12-27 11:09:14 +09:00
|
|
|
"[msgpack] (%s) Insufficient data for unserializing",
|
|
|
|
__FUNCTION__);
|
2010-09-29 08:47:06 +09:00
|
|
|
}
|
2010-07-17 18:46:28 +09:00
|
|
|
break;
|
2010-12-27 11:09:14 +09:00
|
|
|
}
|
2010-07-17 18:46:28 +09:00
|
|
|
case MSGPACK_UNPACK_EXTRA_BYTES:
|
|
|
|
case MSGPACK_UNPACK_SUCCESS:
|
2010-12-27 11:09:14 +09:00
|
|
|
msgpack_unserialize_var_destroy(&var_hash, 0);
|
2010-09-29 08:47:06 +09:00
|
|
|
if (off < (size_t)str_len && MSGPACK_G(error_display))
|
|
|
|
{
|
|
|
|
zend_error(E_WARNING,
|
2010-12-27 11:09:14 +09:00
|
|
|
"[msgpack] (%s) Extra bytes", __FUNCTION__);
|
2010-09-29 08:47:06 +09:00
|
|
|
}
|
2010-07-17 18:46:28 +09:00
|
|
|
break;
|
|
|
|
default:
|
2010-12-27 11:09:14 +09:00
|
|
|
msgpack_unserialize_var_destroy(&var_hash, 0);
|
2010-09-29 08:47:06 +09:00
|
|
|
if (MSGPACK_G(error_display))
|
|
|
|
{
|
|
|
|
zend_error(E_WARNING,
|
2010-12-27 11:09:14 +09:00
|
|
|
"[msgpack] (%s) Unknown result", __FUNCTION__);
|
2010-09-29 08:47:06 +09:00
|
|
|
}
|
2010-07-17 18:46:28 +09:00
|
|
|
break;
|
|
|
|
}
|
2010-04-05 00:10:28 +09:00
|
|
|
}
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
static ZEND_FUNCTION(msgpack_serialize)
|
2010-04-05 00:10:28 +09:00
|
|
|
{
|
2010-07-17 18:46:28 +09:00
|
|
|
zval *parameter;
|
|
|
|
smart_str buf = {0};
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
if (zend_parse_parameters(
|
|
|
|
ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == FAILURE)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
php_msgpack_serialize(&buf, parameter TSRMLS_CC);
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
smart_str_free(&buf);
|
2010-04-05 00:10:28 +09:00
|
|
|
}
|
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
static ZEND_FUNCTION(msgpack_unserialize)
|
2010-04-05 00:10:28 +09:00
|
|
|
{
|
2010-07-17 18:46:28 +09:00
|
|
|
char *str;
|
|
|
|
int str_len;
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
if (zend_parse_parameters(
|
|
|
|
ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
if (!str_len)
|
|
|
|
{
|
|
|
|
RETURN_NULL();
|
|
|
|
}
|
2010-04-05 00:10:28 +09:00
|
|
|
|
2010-07-17 18:46:28 +09:00
|
|
|
php_msgpack_unserialize(return_value, str, str_len TSRMLS_CC);
|
|
|
|
}
|