diff options
| author | advect <advect@gmail.com> | 2010-07-17 18:46:28 +0900 |
|---|---|---|
| committer | advect <advect@gmail.com> | 2010-07-17 18:46:28 +0900 |
| commit | 78f542f6c0205a7771f273175518db02f461f8e5 (patch) | |
| tree | 8150e3e55e0eeef4ac87a6cb9d691ffd35313a7e /php/msgpack.c | |
| parent | a97f9081a3a41180cf1e08f9fd8b41e5b17924eb (diff) | |
| download | msgpack-python-78f542f6c0205a7771f273175518db02f461f8e5.tar.gz | |
Update PHP Extension
Diffstat (limited to 'php/msgpack.c')
| -rw-r--r-- | php/msgpack.c | 781 |
1 files changed, 195 insertions, 586 deletions
diff --git a/php/msgpack.c b/php/msgpack.c index b38eb18..62fb68d 100644 --- a/php/msgpack.c +++ b/php/msgpack.c @@ -1,22 +1,3 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2007 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Hideyuki TAKEI | - +----------------------------------------------------------------------+ -*/ - -/* $Id: header 226204 2007-01-01 19:32:10Z iliaa $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -26,631 +7,259 @@ #include "php_ini.h" #include "ext/standard/info.h" #include "ext/standard/php_smart_str.h" -#include "php_msgpack.h" - -#define PHP_EXT_VERSION "0.01" - -#ifndef TRUE -# define TRUE 1 -# define FALSE 0 -#endif - - -/* pack */ -#include "msgpack/pack_define.h" - -#define msgpack_pack_inline_func(name) \ - static inline void msgpack_pack ## name - -#define msgpack_pack_inline_func_cint(name) \ - static inline void msgpack_pack ## name - -#define msgpack_pack_user smart_str* - -#define msgpack_pack_append_buffer(user, buf, len) \ - smart_str_appendl(user, (const void*)buf, len) - -#include "msgpack/pack_template.h" - - -/* unpack */ -#include "msgpack/unpack_define.h" - -typedef struct { - int finished; - char* source; -} unpack_user; - -#define msgpack_unpack_struct(name) \ - struct template ## name - -#define msgpack_unpack_func(ret, name) \ - ret template ## name - -#define msgpack_unpack_callback(name) \ - template_callback ## name - -#define msgpack_unpack_object zval* - -#define msgpack_unpack_user unpack_user - -struct template_context; -typedef struct template_context msgpack_unpack_t; - -static void template_init(msgpack_unpack_t* u); -static msgpack_unpack_object template_data(msgpack_unpack_t* u); -static int template_execute(msgpack_unpack_t* u, - const char* data, size_t len, size_t* off); - -ZEND_BEGIN_MODULE_GLOBALS(msgpack) - msgpack_unpack_t *global_mp; -ZEND_END_MODULE_GLOBALS(msgpack) +#include "ext/standard/php_incomplete_class.h" +#include "ext/standard/php_var.h" +#include "ext/session/php_session.h" -#ifdef ZTS -#define MSGPACK_G(v) TSRMG(msgpack_globals_id, zend_msgpack_globals *, v) -#else -#define MSGPACK_G(v) (msgpack_globals.v) -#endif +#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} +}; -static inline msgpack_unpack_object template_callback_root(unpack_user* u) +static ZEND_MINIT_FUNCTION(msgpack) { - msgpack_unpack_object data; - ALLOC_INIT_ZVAL(data); - ZVAL_NULL(data); - return data; -} - -static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; } - -static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; } - -static inline int template_callback_uint32(unpack_user* u, uint32_t d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; } - -static inline int template_callback_uint64(unpack_user* u, uint64_t d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; } - -static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, (long)d); return 0; } - -static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, (long)d); return 0; } - -static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, (long)d); return 0; } + MSGPACK_G(error_display) = 1; -static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; } - -static inline int template_callback_float(unpack_user* u, float d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_DOUBLE(*o, d); return 0; } - -static inline int template_callback_double(unpack_user* u, double d, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_DOUBLE(*o, d); return 0; } - -static inline int template_callback_nil(unpack_user* u, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_NULL(*o); return 0; } - -static inline int template_callback_true(unpack_user* u, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_BOOL(*o, 1); return 0; } - -static inline int template_callback_false(unpack_user* u, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); ZVAL_BOOL(*o, 0); return 0;} - -static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); array_init(*o); return 0; } - -static inline int template_callback_array_item(unpack_user* u, msgpack_unpack_object* c, msgpack_unpack_object o) -{ add_next_index_zval(*c, o); return 0; } +#if HAVE_PHP_SESSION + php_session_register_serializer("msgpack", + PS_SERIALIZER_ENCODE_NAME(msgpack), + PS_SERIALIZER_DECODE_NAME(msgpack)); +#endif -static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_unpack_object* o) -{ ALLOC_INIT_ZVAL(*o); array_init(*o); return 0; } + msgpack_init_class(TSRMLS_CC); -static inline int template_callback_map_item(unpack_user* u, msgpack_unpack_object* c, msgpack_unpack_object k, msgpack_unpack_object v) -{ - switch(k->type) { - case IS_LONG: - add_index_zval(*c, Z_LVAL(*k), v); - break; - case IS_STRING: - add_assoc_zval_ex(*c, Z_STRVAL(*k), Z_STRLEN(*k)+1, v); - break; - default: - zend_error(E_WARNING, "[msgpack] (php_msgpack_decode) illegal offset type, skip this decoding"); - break; - } - return 0; + return SUCCESS; } - -static inline int template_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_unpack_object* o) +static ZEND_MINFO_FUNCTION(msgpack) { - ALLOC_INIT_ZVAL(*o); - if (l == 0) { - ZVAL_STRINGL(*o, "", 0, 1); - } else { - ZVAL_STRINGL(*o, p, l, 1); - } - return 0; + 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(); } -#include "msgpack/unpack_template.h" - -static PHP_GINIT_FUNCTION(msgpack); - -ZEND_DECLARE_MODULE_GLOBALS(msgpack) - -/* True global resources - no need for thread safety here */ -static int le_msgpack; - -/* {{{ msgpack_functions[] - * - * Every user visible function must have an entry in msgpack_functions[]. - */ -zend_function_entry msgpack_functions[] = { - PHP_FE(msgpack_pack, NULL) - PHP_FE(msgpack_unpack, NULL) - PHP_FE(msgpack_unpack_limit, NULL) - PHP_ME(msgpack, initialize, NULL, 0) - PHP_ME(msgpack, execute, NULL, 0) - PHP_ME(msgpack, execute_limit, NULL, 0) - PHP_ME(msgpack, finished, NULL, 0) - PHP_ME(msgpack, data, NULL, 0) - {NULL, NULL, NULL} /* Must be the last line in msgpack_functions[] */ -}; -/* }}} */ - -/* {{{ msgpack_module_entry - */ zend_module_entry msgpack_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER, #endif - "msgpack", - msgpack_functions, - PHP_MINIT(msgpack), - PHP_MSHUTDOWN(msgpack), - PHP_RINIT(msgpack), /* Replace with NULL if there's nothing to do at request start */ - PHP_RSHUTDOWN(msgpack), /* Replace with NULL if there's nothing to do at request end */ - PHP_MINFO(msgpack), + "msgpack", + msgpack_functions, + ZEND_MINIT(msgpack), + NULL, + NULL, + NULL, + ZEND_MINFO(msgpack), #if ZEND_MODULE_API_NO >= 20010901 - "0.1", /* Replace with version number for your extension */ + MSGPACK_VERSION, #endif - PHP_MODULE_GLOBALS(msgpack), - PHP_GINIT(msgpack), - NULL, - NULL, - STANDARD_MODULE_PROPERTIES_EX + STANDARD_MODULE_PROPERTIES }; -/* }}} */ #ifdef COMPILE_DL_MSGPACK ZEND_GET_MODULE(msgpack) #endif -/* {{{ PHP_GINIT_FUNCTION */ -static PHP_GINIT_FUNCTION(msgpack) -{ - msgpack_globals->global_mp = NULL; -} -/* }}} */ - -/* {{{ PHP_MINIT_FUNCTION - */ -PHP_MINIT_FUNCTION(msgpack) +PS_SERIALIZER_ENCODE_FUNC(msgpack) { - zend_class_entry ce; - INIT_CLASS_ENTRY(ce, "MessagePack", msgpack_functions); - msgpack_ce = zend_register_internal_class(&ce TSRMLS_CC); - - return SUCCESS; -} -/* }}} */ + smart_str buf = {0}; + php_serialize_data_t var_hash; -/* {{{ PHP_MSHUTDOWN_FUNCTION - */ -PHP_MSHUTDOWN_FUNCTION(msgpack) -{ - /* uncomment this line if you have INI entries - UNREGISTER_INI_ENTRIES(); - */ - if (MSGPACK_G(global_mp)) { - efree(MSGPACK_G(global_mp)); - MSGPACK_G(global_mp) = NULL; - } - - return SUCCESS; -} -/* }}} */ - -/* Remove if there's nothing to do at request start */ -/* {{{ PHP_RINIT_FUNCTION - */ -PHP_RINIT_FUNCTION(msgpack) -{ - return SUCCESS; -} -/* }}} */ + PHP_VAR_SERIALIZE_INIT(var_hash); -/* Remove if there's nothing to do at request end */ -/* {{{ PHP_RSHUTDOWN_FUNCTION - */ -PHP_RSHUTDOWN_FUNCTION(msgpack) -{ - return SUCCESS; -} -/* }}} */ + msgpack_serialize_zval(&buf, PS(http_session_vars), &var_hash TSRMLS_CC); -/* {{{ PHP_MINFO_FUNCTION - */ -PHP_MINFO_FUNCTION(msgpack) -{ - php_info_print_table_start(); - php_info_print_table_header(2, "msgpack support", "enabled"); - php_info_print_table_row(2, "php extension version", PHP_EXT_VERSION); - php_info_print_table_row(2, "author", "Hideyuki TAKEI"); - php_info_print_table_row(2, "homepage", "http://msgpack.sourceforge.net"); - php_info_print_table_row(2, "open sourced by", "KLab inc."); - php_info_print_table_end(); -} -/* }}} */ + if (newlen) + { + *newlen = buf.len; + } -PHP_MSGPACK_API int msgpack_determine_array_type(zval **val TSRMLS_DC) /* {{{ */ -{ - int i; - HashTable *myht = HASH_OF(*val); - - i = myht ? zend_hash_num_elements(myht) : 0; - if (i > 0) { - char *key; - ulong index, idx; - uint key_len; - HashPosition pos; - - zend_hash_internal_pointer_reset_ex(myht, &pos); - idx = 0; - for (;; zend_hash_move_forward_ex(myht, &pos)) { - i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos); - if (i == HASH_KEY_NON_EXISTANT) - break; - if (i == HASH_KEY_IS_STRING) { - return 1; - } else { - if (index != idx) { - return 1; - } - } - idx++; - } - } - return 0; -} -/* }}} */ + smart_str_0(&buf); + *newstr = buf.c; -PHP_MSGPACK_API void msgpack_pack_array_hash(smart_str *pk, zval **val TSRMLS_DC) /* {{{ */ -{ - int i, r; - HashTable *myht; - - if(Z_TYPE_PP(val) == IS_ARRAY){ - myht = HASH_OF(*val); - r = msgpack_determine_array_type(val TSRMLS_CC); - } - else{ - myht = Z_OBJPROP_PP(val); - r = 1; - } - - i = myht ? zend_hash_num_elements(myht) : 0; - - if(r == 0){ - msgpack_pack_array(pk, i); - } - else{ - msgpack_pack_map(pk, i); - } - - if(i>0){ - char *key; - zval **data; - ulong index; - uint key_len; - HashPosition pos; - HashTable *tmp_ht; - int need_comma = 0; - - zend_hash_internal_pointer_reset_ex(myht, &pos); - for(;; zend_hash_move_forward_ex(myht, &pos)){ - i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos); - if(i==HASH_KEY_NON_EXISTANT) - break; - if(zend_hash_get_current_data_ex(myht, (void **) &data, &pos) == SUCCESS){ - tmp_ht = HASH_OF(*data); - if (tmp_ht) - tmp_ht->nApplyCount++; - - if(r==0) - php_msgpack_pack(pk, *data TSRMLS_CC); - else if(r==1){ - if(i==HASH_KEY_IS_STRING){ - if(key[0]=='\0' && Z_TYPE_PP(val)==IS_OBJECT){ - // Skip protected and private members. - if(tmp_ht) - tmp_ht->nApplyCount--; - continue; - } - msgpack_pack_raw(pk, key_len-1); - msgpack_pack_raw_body(pk, key, key_len-1); - php_msgpack_pack(pk, *data TSRMLS_CC); - } - else{ - msgpack_pack_long(pk, index); - php_msgpack_pack(pk, *data TSRMLS_CC); - } - } - - if(tmp_ht){ - tmp_ht->nApplyCount--; - } - } - } - - } -} -/* }}} */ + PHP_VAR_SERIALIZE_DESTROY(var_hash); -PHP_MSGPACK_API void php_msgpack_pack(smart_str *pk, zval *val TSRMLS_DC) /* {{{ */ -{ - switch(Z_TYPE_P(val)){ - case IS_NULL: - msgpack_pack_nil(pk); - break; - case IS_BOOL: - if (Z_BVAL_P(val)) - msgpack_pack_true(pk); - else - msgpack_pack_false(pk); - break; - case IS_LONG: - msgpack_pack_long(pk, Z_LVAL_P(val)); - break; - case IS_DOUBLE: - { - double dbl = Z_DVAL_P(val); - if (zend_isinf(dbl) || zend_isnan(dbl)) { - zend_error(E_WARNING, "[msgpack] (php_msgpack_pack) double %.9g does not conform to the MSGPACK spec, encoded as 0", dbl); - ZVAL_LONG(val, 0); - } - msgpack_pack_double(pk, Z_DVAL_P(val)); - } - break; - case IS_STRING: - msgpack_pack_raw(pk, Z_STRLEN_P(val)); - msgpack_pack_raw_body(pk, Z_STRVAL_P(val), Z_STRLEN_P(val)); - break; - case IS_ARRAY: - case IS_OBJECT: - msgpack_pack_array_hash(pk, &val TSRMLS_CC); - break; - defalut: - zend_error(E_WARNING, "[msgpack] (php_msgpack_pack) type is unsupported, encoded as null"); - msgpack_pack_nil(pk); - break; - } - - return; + return SUCCESS; } -/* }}} */ -PHP_MSGPACK_API void php_msgpack_unpack_limit(zval *return_value, const char *buf, int len, zend_bool assoc TSRMLS_DC) /* {{{ */ -{ - if (len<=0) { - RETURN_NUL(); - } - - msgpack_unpack_t mp; - template_init(&mp); - unpack_user u = {0, ""}; - - size_t from = 0; - char* dptr = (char*)buf; - long dlen = len; - int ret; - - (&mp)->user.source = (char*)buf; - ret = template_execute(&mp, dptr, (size_t)dlen, &from); - (&mp)->user.source = ""; - - if(ret < 0) { - zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) parse error"); - } else if(ret == 0) { - zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) insufficient bytes"); - } else { - if(from < dlen) { - zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) extra bytes"); - } - - *return_value = *template_data(&mp); - FREE_ZVAL(template_data(&mp)); - } -} -/* }}} */ - - -PHP_FUNCTION(msgpack_pack) +PS_SERIALIZER_DECODE_FUNC(msgpack) { - zval *parameter; - smart_str buf = {0}; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == FAILURE) { - return; - } + 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; + } - php_msgpack_pack(&buf, parameter TSRMLS_CC); + 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); + } - ZVAL_STRINGL(return_value, buf.c, buf.len, 1); + zval_ptr_dtor(&tmp); - smart_str_free(&buf); + return SUCCESS; } -PHP_FUNCTION(msgpack_unpack) +PHP_MSGPACK_API void php_msgpack_serialize(smart_str *buf, zval *val TSRMLS_DC) { - char *parameter; - int parameter_len; - zend_bool assoc = 0; + php_serialize_data_t var_hash; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", - ¶meter, ¶meter_len, &assoc) == FAILURE) { - return; - } + PHP_VAR_SERIALIZE_INIT(var_hash); - if (!parameter_len) { - RETURN_NULL(); - } + msgpack_serialize_zval(buf, val, &var_hash TSRMLS_CC); - php_msgpack_unpack_limit(return_value, parameter, parameter_len, assoc TSRMLS_CC); + PHP_VAR_SERIALIZE_DESTROY(var_hash); } -PHP_FUNCTION(msgpack_unpack_limit) +PHP_MSGPACK_API void php_msgpack_unserialize( + zval *return_value, char *str, size_t str_len TSRMLS_DC) { - char *parameter; - int parameter_len; - int limit; - zend_bool assoc = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|b", - ¶meter, ¶meter_len, &limit, &assoc) == FAILURE) { - return; - } - - if (!parameter_len) { - RETURN_NULL(); - } - else if (parameter_len < limit) { - zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) limit greater than data_len"); - limit = parameter_len; - } - - php_msgpack_unpack_limit(return_value, parameter, limit, assoc TSRMLS_CC); -} - + int ret; + php_unserialize_data_t var_hash; + msgpack_unserialize_data mpsd; -PHP_MSGPACK_API void php_msgpack_unpacker_execute_limit(zval *return_value, const char *buf, int off, int len, zend_bool assoc TSRMLS_DC) /* {{{ */ -{ - if (len<=0) { - RETURN_NUL(); - } - - size_t from = off; - char* dptr = (char*)buf; - long dlen = len; - int ret; - - if(from >= dlen) { - zend_error(E_WARNING, "[msgpack] (php_msgpack_unpacker_execute_limit) offset is bigger than data buffer size"); + if (str_len <= 0) + { + RETURN_NULL(); } - MSGPACK_G(global_mp)->user.source = (char*)buf; - ret = template_execute(MSGPACK_G(global_mp), dptr, (size_t)dlen, &from); - MSGPACK_G(global_mp)->user.source = ""; - - if(ret < 0) { - zend_error(E_WARNING, "[msgpack] (php_msgpack_unpacker_execute_limit) parse error"); - } else if(ret > 0) { - MSGPACK_G(global_mp)->user.finished = 1; - RETVAL_LONG(from); - } else { - MSGPACK_G(global_mp)->user.finished = 0; - RETVAL_LONG(from); - } -} -/* }}} */ + 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; + } -PHP_MSGPACK_API void php_msgpack_unpacker_reset(TSRMLS_D) /* {{{ */ -{ - if(MSGPACK_G(global_mp)) { - efree(MSGPACK_G(global_mp)); - MSGPACK_G(global_mp) = NULL; - } - MSGPACK_G(global_mp) = safe_emalloc(sizeof(msgpack_unpack_t), 1, 0); - - template_init(MSGPACK_G(global_mp)); - unpack_user u = {0, ""}; - MSGPACK_G(global_mp)->user = u; - return; + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); } -/* }}} */ -PHP_METHOD(msgpack, initialize) +static ZEND_FUNCTION(msgpack_serialize) { - php_msgpack_unpacker_reset(TSRMLS_C); - return; -} + zval *parameter; + smart_str buf = {0}; -PHP_METHOD(msgpack, execute) -{ - char *data; - int off; - int data_len; - zend_bool assoc = 0; + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == FAILURE) + { + return; + } - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|b", - &data, &data_len, &off, &assoc) == FAILURE) { - return; - } + php_msgpack_serialize(&buf, parameter TSRMLS_CC); - if (!data_len) { - RETURN_NULL(); - } + ZVAL_STRINGL(return_value, buf.c, buf.len, 1); - php_msgpack_unpacker_execute_limit(return_value, data, off, data_len, assoc TSRMLS_CC); + smart_str_free(&buf); } -PHP_METHOD(msgpack, execute_limit) +static ZEND_FUNCTION(msgpack_unserialize) { - char *data; - int off; - int data_len; - int limit; - zend_bool assoc = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|b", - &data, &data_len, &off, &limit, &assoc) == FAILURE) { - return; - } - - if (!data_len) { - RETURN_NULL(); - } - else if (data_len < limit) { - zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) limit greater than (data+off)_len"); - limit = data_len; - } - - php_msgpack_unpacker_execute_limit(return_value, data, off, limit, assoc TSRMLS_CC); -} + char *str; + int str_len; -PHP_METHOD(msgpack, finished) -{ - if(MSGPACK_G(global_mp)->user.finished == 1) { - RETURN_TRUE; - } - RETURN_FALSE; -} + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) + { + return; + } -PHP_METHOD(msgpack, data) -{ - *return_value = *template_data(MSGPACK_G(global_mp)); - return; -} + if (!str_len) + { + RETURN_NULL(); + } -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ + php_msgpack_unserialize(return_value, str, str_len TSRMLS_CC); +} |
