msgpack/php/msgpack.c

307 lines
7.3 KiB
C
Raw Normal View History

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();
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-07-17 18:46:28 +09:00
MSGPACK_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-09-29 08:47:06 +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-09-29 08:47:06 +09:00
msgpack_unserialize_var_destroy(&var_hash);
2010-07-17 18:46:28 +09:00
tmp_hash = HASH_OF(tmp);
zend_hash_internal_pointer_reset_ex(tmp_hash, &tmp_hash_pos);
while (zend_hash_get_current_data_ex(
2010-09-29 08:47:06 +09:00
tmp_hash, (void *)&value, &tmp_hash_pos) == SUCCESS)
2010-07-17 18:46:28 +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:
2010-09-29 08:47:06 +09:00
php_set_session_var(
key_str, key_len - 1, *value, NULL TSRMLS_CC);
2010-07-17 18:46:28 +09:00
php_add_session_var(key_str, key_len - 1 TSRMLS_CC);
break;
}
zend_hash_move_forward_ex(tmp_hash, &tmp_hash_pos);
}
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-09-29 08:47:06 +09:00
(&mp)->user.retval = (zval *)return_value;
(&mp)->user.var_hash = (php_unserialize_data_t *)&var_hash;
ret = template_execute(&mp, str, (size_t)str_len, &off);
msgpack_unserialize_var_destroy(&var_hash);
2010-07-17 18:46:28 +09:00
switch (ret)
{
case MSGPACK_UNPACK_PARSE_ERROR:
2010-09-29 08:47:06 +09:00
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (php_msgpack_unserialize) Parse error");
}
2010-07-17 18:46:28 +09:00
break;
case MSGPACK_UNPACK_CONTINUE:
2010-09-29 08:47:06 +09:00
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (php_msgpack_unserialize) "
"Insufficient data for unserializing");
}
2010-07-17 18:46:28 +09:00
break;
case MSGPACK_UNPACK_EXTRA_BYTES:
case MSGPACK_UNPACK_SUCCESS:
2010-09-29 08:47:06 +09:00
if (off < (size_t)str_len && MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (php_msgpack_unserialize) Extra bytes");
}
2010-07-17 18:46:28 +09:00
break;
default:
2010-09-29 08:47:06 +09:00
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (php_msgpack_unserialize) Unknown result");
}
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", &parameter) == 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);
}