mirror of
https://github.com/msgpack/msgpack-python.git
synced 2026-02-09 03:10:19 +00:00
Update PHP Extension
This commit is contained in:
parent
a97f9081a3
commit
78f542f6c0
71 changed files with 7345 additions and 2108 deletions
803
php/msgpack.c
803
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 "ext/standard/php_incomplete_class.h"
|
||||
#include "ext/standard/php_var.h"
|
||||
#include "ext/session/php_session.h"
|
||||
|
||||
#include "php_msgpack.h"
|
||||
#include "msgpack_pack.h"
|
||||
#include "msgpack_unpack.h"
|
||||
#include "msgpack_class.h"
|
||||
|
||||
#define PHP_EXT_VERSION "0.01"
|
||||
static ZEND_FUNCTION(msgpack_serialize);
|
||||
static ZEND_FUNCTION(msgpack_unserialize);
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
#endif
|
||||
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()
|
||||
|
||||
/* pack */
|
||||
#include "msgpack/pack_define.h"
|
||||
PS_SERIALIZER_FUNCS(msgpack);
|
||||
|
||||
#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)
|
||||
|
||||
#ifdef ZTS
|
||||
#define MSGPACK_G(v) TSRMG(msgpack_globals_id, zend_msgpack_globals *, v)
|
||||
#else
|
||||
#define MSGPACK_G(v) (msgpack_globals.v)
|
||||
#endif
|
||||
|
||||
static inline msgpack_unpack_object template_callback_root(unpack_user* u)
|
||||
{
|
||||
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; }
|
||||
|
||||
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; }
|
||||
|
||||
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; }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static inline int template_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_unpack_object* o)
|
||||
{
|
||||
ALLOC_INIT_ZVAL(*o);
|
||||
if (l == 0) {
|
||||
ZVAL_STRINGL(*o, "", 0, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(*o, p, l, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#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[] */
|
||||
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}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ msgpack_module_entry
|
||||
*/
|
||||
static ZEND_MINIT_FUNCTION(msgpack)
|
||||
{
|
||||
MSGPACK_G(error_display) = 1;
|
||||
|
||||
#if HAVE_PHP_SESSION
|
||||
php_session_register_serializer("msgpack",
|
||||
PS_SERIALIZER_ENCODE_NAME(msgpack),
|
||||
PS_SERIALIZER_DECODE_NAME(msgpack));
|
||||
#endif
|
||||
|
||||
msgpack_init_class(TSRMLS_CC);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static ZEND_MINFO_FUNCTION(msgpack)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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)
|
||||
PS_SERIALIZER_ENCODE_FUNC(msgpack)
|
||||
{
|
||||
msgpack_globals->global_mp = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
smart_str buf = {0};
|
||||
php_serialize_data_t var_hash;
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(msgpack)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
INIT_CLASS_ENTRY(ce, "MessagePack", msgpack_functions);
|
||||
msgpack_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
PHP_VAR_SERIALIZE_INIT(var_hash);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
msgpack_serialize_zval(&buf, PS(http_session_vars), &var_hash TSRMLS_CC);
|
||||
|
||||
/* {{{ 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;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Remove if there's nothing to do at request end */
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_RSHUTDOWN_FUNCTION(msgpack)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
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;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
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_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;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
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)
|
||||
{
|
||||
zval *parameter;
|
||||
smart_str buf = {0};
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
php_msgpack_pack(&buf, parameter TSRMLS_CC);
|
||||
|
||||
ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
|
||||
|
||||
smart_str_free(&buf);
|
||||
}
|
||||
|
||||
PHP_FUNCTION(msgpack_unpack)
|
||||
{
|
||||
char *parameter;
|
||||
int parameter_len;
|
||||
zend_bool assoc = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",
|
||||
¶meter, ¶meter_len, &assoc) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!parameter_len) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
php_msgpack_unpack_limit(return_value, parameter, parameter_len, assoc TSRMLS_CC);
|
||||
}
|
||||
|
||||
PHP_FUNCTION(msgpack_unpack_limit)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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 (newlen)
|
||||
{
|
||||
*newlen = buf.len;
|
||||
}
|
||||
|
||||
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 = "";
|
||||
smart_str_0(&buf);
|
||||
*newstr = buf.c;
|
||||
|
||||
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_SERIALIZE_DESTROY(var_hash);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_MSGPACK_API void php_msgpack_unpacker_reset(TSRMLS_D) /* {{{ */
|
||||
PS_SERIALIZER_DECODE_FUNC(msgpack)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
|
||||
template_init(MSGPACK_G(global_mp));
|
||||
unpack_user u = {0, ""};
|
||||
MSGPACK_G(global_mp)->user = u;
|
||||
return;
|
||||
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_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_ptr_dtor(&tmp);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_METHOD(msgpack, initialize)
|
||||
PHP_MSGPACK_API void php_msgpack_serialize(smart_str *buf, zval *val TSRMLS_DC)
|
||||
{
|
||||
php_msgpack_unpacker_reset(TSRMLS_C);
|
||||
return;
|
||||
php_serialize_data_t var_hash;
|
||||
|
||||
PHP_VAR_SERIALIZE_INIT(var_hash);
|
||||
|
||||
msgpack_serialize_zval(buf, val, &var_hash TSRMLS_CC);
|
||||
|
||||
PHP_VAR_SERIALIZE_DESTROY(var_hash);
|
||||
}
|
||||
|
||||
PHP_METHOD(msgpack, execute)
|
||||
PHP_MSGPACK_API void php_msgpack_unserialize(
|
||||
zval *return_value, char *str, size_t str_len TSRMLS_DC)
|
||||
{
|
||||
char *data;
|
||||
int off;
|
||||
int data_len;
|
||||
zend_bool assoc = 0;
|
||||
int ret;
|
||||
php_unserialize_data_t var_hash;
|
||||
msgpack_unserialize_data mpsd;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|b",
|
||||
&data, &data_len, &off, &assoc) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
if (str_len <= 0)
|
||||
{
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
if (!data_len) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
PHP_VAR_UNSERIALIZE_INIT(var_hash);
|
||||
|
||||
php_msgpack_unpacker_execute_limit(return_value, data, off, data_len, assoc TSRMLS_CC);
|
||||
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_VAR_UNSERIALIZE_DESTROY(var_hash);
|
||||
}
|
||||
|
||||
PHP_METHOD(msgpack, execute_limit)
|
||||
static ZEND_FUNCTION(msgpack_serialize)
|
||||
{
|
||||
char *data;
|
||||
int off;
|
||||
int data_len;
|
||||
int limit;
|
||||
zend_bool assoc = 0;
|
||||
zval *parameter;
|
||||
smart_str buf = {0};
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|b",
|
||||
&data, &data_len, &off, &limit, &assoc) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
if (zend_parse_parameters(
|
||||
ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == 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_serialize(&buf, parameter TSRMLS_CC);
|
||||
|
||||
php_msgpack_unpacker_execute_limit(return_value, data, off, limit, assoc TSRMLS_CC);
|
||||
ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
|
||||
|
||||
smart_str_free(&buf);
|
||||
}
|
||||
|
||||
PHP_METHOD(msgpack, finished)
|
||||
static ZEND_FUNCTION(msgpack_unserialize)
|
||||
{
|
||||
if(MSGPACK_G(global_mp)->user.finished == 1) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
RETURN_FALSE;
|
||||
}
|
||||
char *str;
|
||||
int str_len;
|
||||
|
||||
PHP_METHOD(msgpack, data)
|
||||
{
|
||||
*return_value = *template_data(MSGPACK_G(global_mp));
|
||||
return;
|
||||
}
|
||||
if (zend_parse_parameters(
|
||||
ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
if (!str_len)
|
||||
{
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
php_msgpack_unserialize(return_value, str, str_len TSRMLS_CC);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue