msgpack/php/msgpack.c

266 lines
6.2 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"
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()
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)
ZEND_FALIAS(msgpack_unpack, msgpack_unserialize,
arginfo_msgpack_unserialize)
{NULL, NULL, NULL}
};
2010-04-05 00:10:28 +09:00
2010-07-17 18:46:28 +09:00
static ZEND_MINIT_FUNCTION(msgpack)
2010-04-05 00:10:28 +09:00
{
2010-07-17 18:46:28 +09:00
MSGPACK_G(error_display) = 1;
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-07-17 18:46:28 +09:00
msgpack_init_class(TSRMLS_CC);
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();
php_info_print_table_row(2, "msgpack support", "enabled");
php_info_print_table_row(2, "msgpack version", MSGPACK_VERSION);
#if HAVE_PHP_SESSION
php_info_print_table_row(2, "msgpack Session Support", "enabled" );
#endif
php_info_print_table_end();
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),
NULL,
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
php_unserialize_data_t var_hash;
int ret;
HashTable *tmp_hash;
HashPosition tmp_hash_pos;
char *key_str;
ulong key_long;
uint key_len;
zval *tmp;
zval **data;
msgpack_unserialize_data mpsd;
PHP_VAR_UNSERIALIZE_INIT(var_hash);
MAKE_STD_ZVAL(tmp);
mpsd.data = (unsigned char *)val;;
mpsd.length = vallen;
mpsd.offset = 0;
ret = msgpack_unserialize_zval(&tmp, &mpsd, &var_hash TSRMLS_CC);
switch (ret)
{
case MSGPACK_UNPACK_EXTRA_BYTES:
case MSGPACK_UNPACK_SUCCESS:
break;
case MSGPACK_UNPACK_PARSE_ERROR:
case MSGPACK_UNPACK_CONTINUE:
default:
zval_ptr_dtor(&tmp);
return FAILURE;
}
2010-04-05 00:10:28 +09:00
2010-07-17 18:46:28 +09:00
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
tmp_hash = HASH_OF(tmp);
zend_hash_internal_pointer_reset_ex(tmp_hash, &tmp_hash_pos);
while (zend_hash_get_current_data_ex(
tmp_hash, (void *)&data, &tmp_hash_pos) == SUCCESS)
{
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, *data, 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-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;
php_unserialize_data_t var_hash;
msgpack_unserialize_data mpsd;
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-07-17 18:46:28 +09:00
PHP_VAR_UNSERIALIZE_INIT(var_hash);
mpsd.data = (unsigned char *)str;
mpsd.length = str_len;
mpsd.offset = 0;
ret = msgpack_unserialize_zval(&return_value, &mpsd, &var_hash TSRMLS_CC);
switch (ret)
{
case MSGPACK_UNPACK_PARSE_ERROR:
zend_error(E_WARNING,
"[msgpack] (php_msgpack_unserialize) Parse error");
break;
case MSGPACK_UNPACK_CONTINUE:
zend_error(E_WARNING,
"[msgpack] (php_msgpack_unserialize) "
"Insufficient data for unserializeng");
break;
case MSGPACK_UNPACK_EXTRA_BYTES:
zend_error(E_WARNING,
"[msgpack] (php_msgpack_unserialize) Extra bytes");
break;
case MSGPACK_UNPACK_SUCCESS:
break;
default:
zend_error(E_WARNING,
"[msgpack] (php_msgpack_unserialize) Unknown result");
break;
}
2010-04-05 00:10:28 +09:00
2010-07-17 18:46:28 +09:00
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
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);
}