diff --git a/php/CREDITS b/php/CREDITS index 3aae276b..b3ae8a01 100644 --- a/php/CREDITS +++ b/php/CREDITS @@ -1 +1 @@ -msgpack +msgpack \ No newline at end of file diff --git a/php/ChangeLog b/php/ChangeLog new file mode 100644 index 00000000..3cee3b60 --- /dev/null +++ b/php/ChangeLog @@ -0,0 +1,47 @@ +msgpack extension changelog + +Version 0.3.0 +------------- + * Change msgpack_unpack.c (used template) + * Add php_only ini option (true / false) + * Change class MessagePack and MessagePackUnpacker __construct option. + * Add class MessagePack and MessagePackUnpacker setOption method. + +Version 0.2.1 +------------- + * Fix stream deserializer. + +Version 0.2.0 +------------- + * Add stream deserializer / class MessagePackUnpacker interface. + * Add alias functions. + * Add class MessagePack interface. + +Version 0.1.5 +------------- + * Add msgpack_pack.c + * Add msgpack_unpack.c + * Update msgpack.c + +Version 0.1.4 +------------- + * Change broken random data. + * Support PHP 5.2.x version. + +Version 0.1.3 +------------- + * Fix broken random data. + * Change arrays and objects. + +Version 0.1.2 +------------- + * Add Serializable class support. + * Fix arrays and objects reference. + +Version 0.1.1 +------------- + * Add session support. + +Version 0.1.0 +------------- + * Initial release. diff --git a/php/LICENSE b/php/LICENSE new file mode 100644 index 00000000..c0688fcf --- /dev/null +++ b/php/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2010, advect +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the advect nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. diff --git a/php/README b/php/README index e69de29b..ac8e4857 100644 --- a/php/README +++ b/php/README @@ -0,0 +1,11 @@ +Description +----------- +This extension provide API for communicating with MessagePack serialization. + +MessagePack is a binary-based efficient object serialization library. +It enables to exchange structured objects between many languages like JSON. +But unlike JSON, it is very fast and small. + +Resources +--------- + * [msgpack](http://msgpack.sourceforge.net/) diff --git a/php/benchmark.php b/php/benchmark.php new file mode 100644 index 00000000..559801cb --- /dev/null +++ b/php/benchmark.php @@ -0,0 +1,248 @@ + md5(rand()), + md5(rand()) => md5(rand()), + md5(rand()) => md5(rand()), + md5(rand()) => md5(rand()), + md5(rand()) => md5(rand())); + break; + case 6: + //object + $value = new stdClass; + $value->param1 = rand(); + $value->param2 = md5(uniqid()); + $value->param3 = array(md5(uniqid())); + $value->param4 = array(md5(uniqid()) => md5(uniqid())); + $value->param5 = null; + break; + default: + //null + $value = null; + } + + if (!is_numeric($retry) || empty($retry)) + { + $retry = 1; + } + + $serialize_pack = 0; + $serialize_unpack = 0; + $serialize_size = 0; + $serialize_status = '*NG*'; + $json_pack = 0; + $json_unpack = 0; + $json_size = 0; + $json_status = '*NG*'; + $igbinary_pack = 0; + $igbinary_unpack = 0; + $igbinary_size = 0; + $igbinary_status = '*NG*'; + $msgpack_pack = 0; + $msgpack_unpack = 0; + $msgpack_size = 0; + $msgpack_status = '*NG*'; + + for ($c = 0; $c < $retry; $c++) + { + //default (serialize) + $pack = null; + $unpack = null; + $t = new Benchmark_Timer; + $t->start(); + for ($i = 0; $i < $loop; $i++) + { + $pack = serialize($value); + } + $t->setMarker('serialize'); + for ($i = 0; $i < $loop; $i++) + { + $unpack = unserialize($pack); + } + $t->stop(); + //$t->display(); + $profiling = $t->getProfiling(); + unset($t); + + $serialize_pack += $profiling[1]['diff']; + $serialize_unpack += $profiling[2]['diff']; + $serialize_size += strlen($pack); + if ($unpack === $value || + (is_object($value) && $unpack == $value)) + { + $serialize_status = 'OK'; + } + + //json + $pack = null; + $unpack = null; + $opt = false; + if (is_array($value)) + { + $opt = true; + } + $t = new Benchmark_Timer; + $t->start(); + for ($i = 0; $i < $loop; $i++) + { + $pack = json_encode($value); + } + $t->setMarker('json_encode'); + for ($i = 0; $i < $loop; $i++) + { + $unpack = json_decode($pack, $opt); + } + $t->stop(); + //$t->display(); + $profiling = $t->getProfiling(); + unset($t); + + $json_pack += $profiling[1]['diff']; + $json_unpack += $profiling[2]['diff']; + $json_size += strlen($pack); + if ($unpack === $value || + (is_object($value) && $unpack == $value) || + (is_float($value) && + number_format($value, 10, '.', '') === + number_format($unpack, 10, '.', ''))) + { + $json_status = 'OK'; + } + + //igbinary + if (extension_loaded('igbinary')) + { + $pack = null; + $unpack = null; + $t = new Benchmark_Timer; + $t->start(); + for ($i = 0; $i < $loop; $i++) + { + $pack = igbinary_serialize($value); + } + $t->setMarker('igbinary_serialize'); + for ($i = 0; $i < $loop; $i++) + { + $unpack = igbinary_unserialize($pack); + } + $t->stop(); + //$t->display(); + $profiling = $t->getProfiling(); + unset($t); + + $igbinary_pack += $profiling[1]['diff']; + $igbinary_unpack += $profiling[2]['diff']; + $igbinary_size += strlen($pack); + if ($unpack === $value || + (is_object($value) && $unpack == $value)) + { + $igbinary_status = 'OK'; + } + } + + //msgpack + $pack = null; + $unpack = null; + $t = new Benchmark_Timer; + $t->start(); + for ($i = 0; $i < $loop; $i++) + { + $pack = msgpack_serialize($value); + } + $t->setMarker('msgpack_serialize'); + for ($i = 0; $i < $loop; $i++) + { + $unpack = msgpack_unserialize($pack); + } + $t->stop(); + //$t->display(); + $profiling = $t->getProfiling(); + unset($t); + + $msgpack_pack += $profiling[1]['diff']; + $msgpack_unpack += $profiling[2]['diff']; + $msgpack_size += strlen($pack); + if ($unpack === $value || + (is_object($value) && $unpack == $value)) + { + $msgpack_status = 'OK'; + } + } + + $serialize_pack /= $retry; + $serialize_unpack /= $retry; + $serialize_size /= $retry; + $json_pack /= $retry; + $json_unpack /= $retry; + $json_size /= $retry; + $igbinary_pack /= $retry; + $igbinary_unpack /= $retry; + $igbinary_size /= $retry; + $msgpack_pack /= $retry; + $msgpack_unpack /= $retry; + $msgpack_size /= $retry; + + printf("[%-10s] %13s %13s %13s %13s\n", + gettype($value), 'default', 'json', 'igbinary', 'msgpack'); + printf("status : %12s %12s %12s %12s\n", + $serialize_status, $json_status, $igbinary_status, $msgpack_status); + printf("serialize : %.4f (100%%) %.4f (%3d%%) %.4f (%3d%%) %.4f (%3d%%)\n", + $serialize_pack, + $json_pack, ($json_pack / $serialize_pack * 100), + $igbinary_pack, ($igbinary_pack / $serialize_pack * 100), + $msgpack_pack, ($msgpack_pack / $serialize_pack * 100)); + printf("unserialize: %.4f (100%%) %.4f (%3d%%) %.4f (%3d%%) %.4f (%3d%%)\n", + $serialize_unpack, + $json_unpack, ($json_unpack / $serialize_unpack * 100), + $igbinary_unpack, ($igbinary_unpack / $serialize_unpack * 100), + $msgpack_unpack, ($msgpack_unpack / $serialize_unpack * 100)); + printf("size : %6d (100%%) %6d (%3d%%) %6d (%3d%%) %6d (%3d%%)\n\n", + $serialize_size, + $json_size, ($json_size / $serialize_size * 100), + $igbinary_size, ($igbinary_size / $serialize_size * 100), + $msgpack_size, ($msgpack_size / $serialize_size * 100)); + if ($value_display === true) + { + var_dump($value); + echo PHP_EOL; + } +} diff --git a/php/config.m4 b/php/config.m4 index 751b4712..a78e1f32 100644 --- a/php/config.m4 +++ b/php/config.m4 @@ -1,14 +1,28 @@ -dnl $Id$ dnl config.m4 for extension msgpack -PHP_ARG_ENABLE(msgpack, whether to enable MessagePack support, +dnl Comments in this file start with the string 'dnl'. +dnl Remove where necessary. This file will not work +dnl without editing. + +dnl Check PHP version: + +AC_MSG_CHECKING(PHP version) +AC_TRY_COMPILE([#include "php/main/php_version.h"], [ +#if PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 2) +#error this extension requires at least PHP version 5.2.0 +#endif +], +[AC_MSG_RESULT(ok)], +[AC_MSG_ERROR([need at least PHP 5.2.0])]) + +dnl If your extension references something external, use with: + +PHP_ARG_WITH(msgpack, for msgpack support, Make sure that the comment is aligned: -[ --enable-msgpack Enable MessagePack support]) +[ --with-msgpack Include msgpack support]) if test "$PHP_MSGPACK" != "no"; then - dnl AC_DEFINE([HAVE_MSGPACK],1 ,[whether to enable MessagePack support]) - dnl AC_HEADER_STDC + PHP_NEW_EXTENSION(msgpack, msgpack.c msgpack_pack.c msgpack_unpack.c msgpack_class.c, $ext_shared) - PHP_NEW_EXTENSION(msgpack, msgpack.c, $ext_shared) - dnl PHP_SUBST(MSGPACK_SHARED_LIBADD) + PHP_INSTALL_HEADERS([ext/msgpack], [php_msgpack.h]) fi diff --git a/php/config.w32 b/php/config.w32 index 50e9bec2..726b75f2 100644 --- a/php/config.w32 +++ b/php/config.w32 @@ -4,10 +4,6 @@ // If your extension references something external, use ARG_WITH // ARG_WITH("msgpack", "for msgpack support", "no"); -// Otherwise, use ARG_ENABLE -// ARG_ENABLE("msgpack", "enable msgpack support", "no"); - if (PHP_MSGPACK != "no") { - EXTENSION("msgpack", "msgpack.c"); + EXTENSION("msgpack", "msgpack.c msgpack_pack.c msgpack_unpack.c msgpack_class.c"); } - diff --git a/php/msgpack.c b/php/msgpack.c index b38eb18c..5d4f9264 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,300 @@ #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" +#include "msgpack/version.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" +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() -#define msgpack_pack_inline_func(name) \ - static inline void msgpack_pack ## name +PS_SERIALIZER_FUNCS(msgpack); -#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 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; +} + +static ZEND_MINIT_FUNCTION(msgpack) +{ + ZEND_INIT_MODULE_GLOBALS(msgpack, msgpack_init_globals, NULL); + + REGISTER_INI_ENTRIES(); + +#if HAVE_PHP_SESSION + php_session_register_serializer("msgpack", + PS_SERIALIZER_ENCODE_NAME(msgpack), + PS_SERIALIZER_DECODE_NAME(msgpack)); +#endif + + msgpack_init_class(); + + return SUCCESS; +} + +static ZEND_MSHUTDOWN_FUNCTION(msgpack) +{ + UNREGISTER_INI_ENTRIES(); + + return SUCCESS; +} + +static ZEND_MINFO_FUNCTION(msgpack) +{ + php_info_print_table_start(); + php_info_print_table_row(2, "MessagePack Support", "enabled"); +#if HAVE_PHP_SESSION + php_info_print_table_row(2, "Session Support", "enabled" ); +#endif + php_info_print_table_row(2, "extension Version", MSGPACK_EXTENSION_VERSION); + php_info_print_table_row(2, "header Version", MSGPACK_VERSION); + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); +} + 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), + ZEND_MSHUTDOWN(msgpack), + 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); + int ret; + HashTable *tmp_hash; + HashPosition tmp_hash_pos; + char *key_str; + ulong key_long; + uint key_len; + zval *tmp; + zval **value; + size_t off = 0; + msgpack_unpack_t mp; + php_unserialize_data_t var_hash; - template_init(MSGPACK_G(global_mp)); - unpack_user u = {0, ""}; - MSGPACK_G(global_mp)->user = u; - return; + ALLOC_INIT_ZVAL(tmp); + + template_init(&mp); + + msgpack_unserialize_var_init(&var_hash); + + (&mp)->user.retval = (zval *)tmp; + (&mp)->user.var_hash = (php_unserialize_data_t *)&var_hash; + + ret = template_execute(&mp, (char *)val, (size_t)vallen, &off); + + msgpack_unserialize_var_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 *)&value, &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, *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); + } + + 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; + size_t off = 0; + msgpack_unpack_t mp; + php_unserialize_data_t var_hash; - 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(); - } + template_init(&mp); - php_msgpack_unpacker_execute_limit(return_value, data, off, data_len, assoc TSRMLS_CC); + msgpack_unserialize_var_init(&var_hash); + + (&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); + + switch (ret) + { + case MSGPACK_UNPACK_PARSE_ERROR: + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (php_msgpack_unserialize) Parse error"); + } + break; + case MSGPACK_UNPACK_CONTINUE: + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (php_msgpack_unserialize) " + "Insufficient data for unserializing"); + } + break; + case MSGPACK_UNPACK_EXTRA_BYTES: + case MSGPACK_UNPACK_SUCCESS: + if (off < (size_t)str_len && MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (php_msgpack_unserialize) Extra bytes"); + } + break; + default: + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (php_msgpack_unserialize) Unknown result"); + } + break; + } } -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); +} diff --git a/php/msgpack.php b/php/msgpack.php index c2498dda..51547818 100644 --- a/php/msgpack.php +++ b/php/msgpack.php @@ -2,7 +2,7 @@ $br = (php_sapi_name() == "cli")? "":"
"; if(!extension_loaded('msgpack')) { - dl('msgpack.' . PHP_SHLIB_SUFFIX); + dl('msgpack.' . PHP_SHLIB_SUFFIX); } $module = 'msgpack'; $functions = get_extension_funcs($module); @@ -11,11 +11,11 @@ foreach($functions as $func) { echo $func."$br\n"; } echo "$br\n"; -$function = 'confirm_' . $module . '_compiled'; +$function = $module . '_serialize'; if (extension_loaded($module)) { - $str = $function($module); + $str = $function($module); } else { - $str = "Module $module is not compiled into PHP"; + $str = "Module $module is not compiled into PHP"; } echo "$str\n"; ?> diff --git a/php/msgpack/pack_define.h b/php/msgpack/pack_define.h index 33408e58..4845d52e 100644 --- a/php/msgpack/pack_define.h +++ b/php/msgpack/pack_define.h @@ -1,7 +1,7 @@ /* * MessagePack unpacking routine template * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki + * Copyright (C) 2008-2010 FURUHASHI Sadayuki * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ #ifndef MSGPACK_PACK_DEFINE_H__ #define MSGPACK_PACK_DEFINE_H__ -#include -#include +#include "msgpack/sysdep.h" #include +#include #endif /* msgpack/pack_define.h */ diff --git a/php/msgpack/pack_template.h b/php/msgpack/pack_template.h index aa620f53..b636967f 100644 --- a/php/msgpack/pack_template.h +++ b/php/msgpack/pack_template.h @@ -1,7 +1,7 @@ /* * MessagePack packing routine template * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki + * Copyright (C) 2008-2010 FURUHASHI Sadayuki * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,88 +16,16 @@ * limitations under the License. */ -#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define __LITTLE_ENDIAN__ -#elif __BYTE_ORDER == __BIG_ENDIAN -#define __BIG_ENDIAN__ -#endif -#endif - - -#ifdef __LITTLE_ENDIAN__ - -#define STORE8_BE8(d) \ - ((uint8_t*)&d)[0] - - -#define STORE16_BE8(d) \ - ((uint8_t*)&d)[0] - -#define STORE16_BE16(d) \ - ((uint8_t*)&d)[1], ((uint8_t*)&d)[0] - - -#define STORE32_BE8(d) \ - ((uint8_t*)&d)[0] - -#define STORE32_BE16(d) \ - ((uint8_t*)&d)[1], ((uint8_t*)&d)[0] - -#define STORE32_BE32(d) \ - ((uint8_t*)&d)[3], ((uint8_t*)&d)[2], ((uint8_t*)&d)[1], ((uint8_t*)&d)[0] - - -#define STORE64_BE8(d) \ - ((uint8_t*)&d)[0] - -#define STORE64_BE16(d) \ - ((uint8_t*)&d)[1], ((uint8_t*)&d)[0] - -#define STORE64_BE32(d) \ - ((uint8_t*)&d)[3], ((uint8_t*)&d)[2], ((uint8_t*)&d)[1], ((uint8_t*)&d)[0] - -#define STORE64_BE64(d) \ - ((uint8_t*)&d)[7], ((uint8_t*)&d)[6], ((uint8_t*)&d)[5], ((uint8_t*)&d)[4], \ - ((uint8_t*)&d)[3], ((uint8_t*)&d)[2], ((uint8_t*)&d)[1], ((uint8_t*)&d)[0] - - -#elif __BIG_ENDIAN__ - -#define STORE8_BE8(d) \ - ((uint8_t*)&d)[0] - - -#define STORE16_BE8(d) \ - ((uint8_t*)&d)[1] - -#define STORE16_BE16(d) \ - ((uint8_t*)&d)[0], ((uint8_t*)&d)[1] - - -#define STORE32_BE8(d) \ - ((uint8_t*)&d)[3] - -#define STORE32_BE16(d) \ - ((uint8_t*)&d)[2], ((uint8_t*)&d)[3] - -#define STORE32_BE32(d) \ - ((uint8_t*)&d)[0], ((uint8_t*)&d)[1], ((uint8_t*)&d)[2], ((uint8_t*)&d)[3] - - -#define STORE64_BE8(d) \ - ((uint8_t*)&d)[7] - -#define STORE64_BE16(d) \ - ((uint8_t*)&d)[6], ((uint8_t*)&d)[7] - -#define STORE64_BE32(d) \ - ((uint8_t*)&d)[4], ((uint8_t*)&d)[5], ((uint8_t*)&d)[6], ((uint8_t*)&d)[7] - -#define STORE64_BE64(d) \ - ((uint8_t*)&d)[0], ((uint8_t*)&d)[1], ((uint8_t*)&d)[2], ((uint8_t*)&d)[3], \ - ((uint8_t*)&d)[4], ((uint8_t*)&d)[5], ((uint8_t*)&d)[6], ((uint8_t*)&d)[7] - +#if defined(__LITTLE_ENDIAN__) +#define TAKE8_8(d) ((uint8_t*)&d)[0] +#define TAKE8_16(d) ((uint8_t*)&d)[0] +#define TAKE8_32(d) ((uint8_t*)&d)[0] +#define TAKE8_64(d) ((uint8_t*)&d)[0] +#elif defined(__BIG_ENDIAN__) +#define TAKE8_8(d) ((uint8_t*)&d)[0] +#define TAKE8_16(d) ((uint8_t*)&d)[1] +#define TAKE8_32(d) ((uint8_t*)&d)[3] +#define TAKE8_64(d) ((uint8_t*)&d)[7] #endif #ifndef msgpack_pack_inline_func @@ -121,10 +49,10 @@ do { \ if(d < (1<<7)) { \ /* fixnum */ \ - msgpack_pack_append_buffer(x, &STORE8_BE8(d), 1); \ + msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); \ } else { \ /* unsigned 8 */ \ - const unsigned char buf[2] = {0xcc, STORE8_BE8(d)}; \ + unsigned char buf[2] = {0xcc, TAKE8_8(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } \ } while(0) @@ -133,14 +61,15 @@ do { \ do { \ if(d < (1<<7)) { \ /* fixnum */ \ - msgpack_pack_append_buffer(x, &STORE16_BE8(d), 1); \ + msgpack_pack_append_buffer(x, &TAKE8_16(d), 1); \ } else if(d < (1<<8)) { \ /* unsigned 8 */ \ - const unsigned char buf[2] = {0xcc, STORE16_BE8(d)}; \ + unsigned char buf[2] = {0xcc, TAKE8_16(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } else { \ /* unsigned 16 */ \ - const unsigned char buf[3] = {0xcd, STORE16_BE16(d)}; \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 3); \ } \ } while(0) @@ -150,20 +79,22 @@ do { \ if(d < (1<<8)) { \ if(d < (1<<7)) { \ /* fixnum */ \ - msgpack_pack_append_buffer(x, &STORE32_BE8(d), 1); \ + msgpack_pack_append_buffer(x, &TAKE8_32(d), 1); \ } else { \ /* unsigned 8 */ \ - const unsigned char buf[2] = {0xcc, STORE32_BE8(d)}; \ + unsigned char buf[2] = {0xcc, TAKE8_32(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } \ } else { \ if(d < (1<<16)) { \ /* unsigned 16 */ \ - const unsigned char buf[3] = {0xcd, STORE32_BE16(d)}; \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* unsigned 32 */ \ - const unsigned char buf[5] = {0xce, STORE32_BE32(d)}; \ + unsigned char buf[5]; \ + buf[0] = 0xce; _msgpack_store32(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 5); \ } \ } \ @@ -174,24 +105,27 @@ do { \ if(d < (1ULL<<8)) { \ if(d < (1<<7)) { \ /* fixnum */ \ - msgpack_pack_append_buffer(x, &STORE64_BE8(d), 1); \ + msgpack_pack_append_buffer(x, &TAKE8_64(d), 1); \ } else { \ /* unsigned 8 */ \ - const unsigned char buf[2] = {0xcc, STORE64_BE8(d)}; \ + unsigned char buf[2] = {0xcc, TAKE8_64(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } \ } else { \ if(d < (1ULL<<16)) { \ - /* signed 16 */ \ - const unsigned char buf[3] = {0xcd, STORE64_BE16(d)}; \ + /* unsigned 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else if(d < (1ULL<<32)) { \ - /* signed 32 */ \ - const unsigned char buf[5] = {0xce, STORE64_BE32(d)}; \ + /* unsigned 32 */ \ + unsigned char buf[5]; \ + buf[0] = 0xce; _msgpack_store32(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 5); \ } else { \ - /* signed 64 */ \ - const unsigned char buf[9] = {0xcf, STORE64_BE64(d)}; \ + /* unsigned 64 */ \ + unsigned char buf[9]; \ + buf[0] = 0xcf; _msgpack_store64(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 9); \ } \ } \ @@ -201,11 +135,11 @@ do { \ do { \ if(d < -(1<<5)) { \ /* signed 8 */ \ - const unsigned char buf[2] = {0xd0, STORE8_BE8(d)}; \ + unsigned char buf[2] = {0xd0, TAKE8_8(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } else { \ /* fixnum */ \ - msgpack_pack_append_buffer(x, &STORE8_BE8(d), 1); \ + msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); \ } \ } while(0) @@ -214,24 +148,26 @@ do { \ if(d < -(1<<5)) { \ if(d < -(1<<7)) { \ /* signed 16 */ \ - const unsigned char buf[3] = {0xd1, STORE16_BE16(d)}; \ + unsigned char buf[3]; \ + buf[0] = 0xd1; _msgpack_store16(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* signed 8 */ \ - const unsigned char buf[2] = {0xd0, STORE16_BE8(d)}; \ + unsigned char buf[2] = {0xd0, TAKE8_16(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } \ } else if(d < (1<<7)) { \ /* fixnum */ \ - msgpack_pack_append_buffer(x, &STORE16_BE8(d), 1); \ + msgpack_pack_append_buffer(x, &TAKE8_16(d), 1); \ } else { \ if(d < (1<<8)) { \ /* unsigned 8 */ \ - const unsigned char buf[2] = {0xcc, STORE16_BE8(d)}; \ + unsigned char buf[2] = {0xcc, TAKE8_16(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } else { \ /* unsigned 16 */ \ - const unsigned char buf[3] = {0xcd, STORE16_BE16(d)}; \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 3); \ } \ } \ @@ -242,32 +178,36 @@ do { \ if(d < -(1<<5)) { \ if(d < -(1<<15)) { \ /* signed 32 */ \ - const unsigned char buf[5] = {0xd2, STORE32_BE32(d)}; \ + unsigned char buf[5]; \ + buf[0] = 0xd2; _msgpack_store32(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 5); \ } else if(d < -(1<<7)) { \ /* signed 16 */ \ - const unsigned char buf[3] = {0xd1, STORE32_BE16(d)}; \ + unsigned char buf[3]; \ + buf[0] = 0xd1; _msgpack_store16(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* signed 8 */ \ - const unsigned char buf[2] = {0xd0, STORE32_BE8(d)}; \ + unsigned char buf[2] = {0xd0, TAKE8_32(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } \ } else if(d < (1<<7)) { \ /* fixnum */ \ - msgpack_pack_append_buffer(x, &STORE32_BE8(d), 1); \ + msgpack_pack_append_buffer(x, &TAKE8_32(d), 1); \ } else { \ if(d < (1<<8)) { \ /* unsigned 8 */ \ - const unsigned char buf[2] = {0xcc, STORE32_BE8(d)}; \ + unsigned char buf[2] = {0xcc, TAKE8_32(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } else if(d < (1<<16)) { \ /* unsigned 16 */ \ - const unsigned char buf[3] = {0xcd, STORE32_BE16(d)}; \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* unsigned 32 */ \ - const unsigned char buf[5] = {0xce, STORE32_BE32(d)}; \ + unsigned char buf[5]; \ + buf[0] = 0xce; _msgpack_store32(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 5); \ } \ } \ @@ -279,46 +219,52 @@ do { \ if(d < -(1LL<<15)) { \ if(d < -(1LL<<31)) { \ /* signed 64 */ \ - const unsigned char buf[9] = {0xd3, STORE64_BE64(d)}; \ + unsigned char buf[9]; \ + buf[0] = 0xd3; _msgpack_store64(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 9); \ } else { \ /* signed 32 */ \ - const unsigned char buf[5] = {0xd2, STORE64_BE32(d)}; \ + unsigned char buf[5]; \ + buf[0] = 0xd2; _msgpack_store32(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 5); \ } \ } else { \ if(d < -(1<<7)) { \ /* signed 16 */ \ - const unsigned char buf[3] = {0xd1, STORE64_BE16(d)}; \ + unsigned char buf[3]; \ + buf[0] = 0xd1; _msgpack_store16(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* signed 8 */ \ - const unsigned char buf[2] = {0xd0, STORE64_BE8(d)}; \ + unsigned char buf[2] = {0xd0, TAKE8_64(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } \ } \ } else if(d < (1<<7)) { \ /* fixnum */ \ - msgpack_pack_append_buffer(x, &STORE64_BE8(d), 1); \ + msgpack_pack_append_buffer(x, &TAKE8_64(d), 1); \ } else { \ if(d < (1LL<<16)) { \ if(d < (1<<8)) { \ /* unsigned 8 */ \ - const unsigned char buf[2] = {0xcc, STORE64_BE8(d)}; \ + unsigned char buf[2] = {0xcc, TAKE8_64(d)}; \ msgpack_pack_append_buffer(x, buf, 2); \ } else { \ /* unsigned 16 */ \ - const unsigned char buf[3] = {0xcd, STORE64_BE16(d)}; \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 3); \ } \ } else { \ if(d < (1LL<<32)) { \ /* unsigned 32 */ \ - const unsigned char buf[5] = {0xce, STORE64_BE32(d)}; \ + unsigned char buf[5]; \ + buf[0] = 0xce; _msgpack_store32(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 5); \ } else { \ /* unsigned 64 */ \ - const unsigned char buf[9] = {0xcf, STORE64_BE64(d)}; \ + unsigned char buf[9]; \ + buf[0] = 0xcf; _msgpack_store64(&buf[1], d); \ msgpack_pack_append_buffer(x, buf, 9); \ } \ } \ @@ -326,57 +272,63 @@ do { \ } while(0) -#ifdef msgpack_pack_inline_func_fastint +#ifdef msgpack_pack_inline_func_fixint -msgpack_pack_inline_func_fastint(_uint8)(msgpack_pack_user x, uint8_t d) +msgpack_pack_inline_func_fixint(_uint8)(msgpack_pack_user x, uint8_t d) { - const unsigned char buf[2] = {0xcc, STORE8_BE8(d)}; + unsigned char buf[2] = {0xcc, TAKE8_8(d)}; msgpack_pack_append_buffer(x, buf, 2); } -msgpack_pack_inline_func_fastint(_uint16)(msgpack_pack_user x, uint16_t d) +msgpack_pack_inline_func_fixint(_uint16)(msgpack_pack_user x, uint16_t d) { - const unsigned char buf[3] = {0xcd, STORE16_BE16(d)}; + unsigned char buf[3]; + buf[0] = 0xcd; _msgpack_store16(&buf[1], d); msgpack_pack_append_buffer(x, buf, 3); } -msgpack_pack_inline_func_fastint(_uint32)(msgpack_pack_user x, uint32_t d) +msgpack_pack_inline_func_fixint(_uint32)(msgpack_pack_user x, uint32_t d) { - const unsigned char buf[5] = {0xce, STORE32_BE32(d)}; + unsigned char buf[5]; + buf[0] = 0xce; _msgpack_store32(&buf[1], d); msgpack_pack_append_buffer(x, buf, 5); } -msgpack_pack_inline_func_fastint(_uint64)(msgpack_pack_user x, uint64_t d) +msgpack_pack_inline_func_fixint(_uint64)(msgpack_pack_user x, uint64_t d) { - const unsigned char buf[9] = {0xcf, STORE64_BE64(d)}; + unsigned char buf[9]; + buf[0] = 0xcf; _msgpack_store64(&buf[1], d); msgpack_pack_append_buffer(x, buf, 9); } -msgpack_pack_inline_func_fastint(_int8)(msgpack_pack_user x, int8_t d) +msgpack_pack_inline_func_fixint(_int8)(msgpack_pack_user x, int8_t d) { - const unsigned char buf[2] = {0xd0, STORE8_BE8(d)}; + unsigned char buf[2] = {0xd0, TAKE8_8(d)}; msgpack_pack_append_buffer(x, buf, 2); } -msgpack_pack_inline_func_fastint(_int16)(msgpack_pack_user x, int16_t d) +msgpack_pack_inline_func_fixint(_int16)(msgpack_pack_user x, int16_t d) { - const unsigned char buf[3] = {0xd1, STORE16_BE16(d)}; + unsigned char buf[3]; + buf[0] = 0xd1; _msgpack_store16(&buf[1], d); msgpack_pack_append_buffer(x, buf, 3); } -msgpack_pack_inline_func_fastint(_int32)(msgpack_pack_user x, int32_t d) +msgpack_pack_inline_func_fixint(_int32)(msgpack_pack_user x, int32_t d) { - const unsigned char buf[5] = {0xd2, STORE32_BE32(d)}; + unsigned char buf[5]; + buf[0] = 0xd2; _msgpack_store32(&buf[1], d); msgpack_pack_append_buffer(x, buf, 5); } -msgpack_pack_inline_func_fastint(_int64)(msgpack_pack_user x, int64_t d) +msgpack_pack_inline_func_fixint(_int64)(msgpack_pack_user x, int64_t d) { - const unsigned char buf[9] = {0xd3, STORE64_BE64(d)}; + unsigned char buf[9]; + buf[0] = 0xd3; _msgpack_store64(&buf[1], d); msgpack_pack_append_buffer(x, buf, 9); } -#undef msgpack_pack_inline_func_fastint +#undef msgpack_pack_inline_func_fixint #endif @@ -425,14 +377,24 @@ msgpack_pack_inline_func(_int64)(msgpack_pack_user x, int64_t d) msgpack_pack_inline_func_cint(_short)(msgpack_pack_user x, short d) { -#if defined(SIZEOF_SHORT) || defined(SHRT_MAX) -#if SIZEOF_SHORT == 2 || SHRT_MAX == 0x7fff +#if defined(SIZEOF_SHORT) +#if SIZEOF_SHORT == 2 msgpack_pack_real_int16(x, d); -#elif SIZEOF_SHORT == 4 || SHRT_MAX == 0x7fffffff +#elif SIZEOF_SHORT == 4 msgpack_pack_real_int32(x, d); #else msgpack_pack_real_int64(x, d); #endif + +#elif defined(SHRT_MAX) +#if SHRT_MAX == 0x7fff + msgpack_pack_real_int16(x, d); +#elif SHRT_MAX == 0x7fffffff + msgpack_pack_real_int32(x, d); +#else + msgpack_pack_real_int64(x, d); +#endif + #else if(sizeof(short) == 2) { msgpack_pack_real_int16(x, d); @@ -446,14 +408,24 @@ if(sizeof(short) == 2) { msgpack_pack_inline_func_cint(_int)(msgpack_pack_user x, int d) { -#if defined(SIZEOF_INT) || defined(INT_MAX) -#if SIZEOF_INT == 2 || INT_MAX == 0x7fff +#if defined(SIZEOF_INT) +#if SIZEOF_INT == 2 msgpack_pack_real_int16(x, d); -#elif SIZEOF_INT == 4 || INT_MAX == 0x7fffffff +#elif SIZEOF_INT == 4 msgpack_pack_real_int32(x, d); #else msgpack_pack_real_int64(x, d); #endif + +#elif defined(INT_MAX) +#if INT_MAX == 0x7fff + msgpack_pack_real_int16(x, d); +#elif INT_MAX == 0x7fffffff + msgpack_pack_real_int32(x, d); +#else + msgpack_pack_real_int64(x, d); +#endif + #else if(sizeof(int) == 2) { msgpack_pack_real_int16(x, d); @@ -467,14 +439,24 @@ if(sizeof(int) == 2) { msgpack_pack_inline_func_cint(_long)(msgpack_pack_user x, long d) { -#if defined(SIZEOF_LONG) || defined(LONG_MAX) -#if SIZEOF_LONG == 2 || LONG_MAX == 0x7fffL +#if defined(SIZEOF_LONG) +#if SIZEOF_LONG == 2 msgpack_pack_real_int16(x, d); -#elif SIZEOF_LONG == 4 || LONG_MAX == 0x7fffffffL +#elif SIZEOF_LONG == 4 msgpack_pack_real_int32(x, d); #else msgpack_pack_real_int64(x, d); #endif + +#elif defined(LONG_MAX) +#if LONG_MAX == 0x7fffL + msgpack_pack_real_int16(x, d); +#elif LONG_MAX == 0x7fffffffL + msgpack_pack_real_int32(x, d); +#else + msgpack_pack_real_int64(x, d); +#endif + #else if(sizeof(long) == 2) { msgpack_pack_real_int16(x, d); @@ -488,14 +470,24 @@ if(sizeof(long) == 2) { msgpack_pack_inline_func_cint(_long_long)(msgpack_pack_user x, long long d) { -#if defined(SIZEOF_LONG_LONG) || defined(LLONG_MAX) -#if SIZEOF_LONG_LONG == 2 || LLONG_MAX == 0x7fffL +#if defined(SIZEOF_LONG_LONG) +#if SIZEOF_LONG_LONG == 2 msgpack_pack_real_int16(x, d); -#elif SIZEOF_LONG_LONG == 4 || LLONG_MAX == 0x7fffffffL +#elif SIZEOF_LONG_LONG == 4 msgpack_pack_real_int32(x, d); #else msgpack_pack_real_int64(x, d); #endif + +#elif defined(LLONG_MAX) +#if LLONG_MAX == 0x7fffL + msgpack_pack_real_int16(x, d); +#elif LLONG_MAX == 0x7fffffffL + msgpack_pack_real_int32(x, d); +#else + msgpack_pack_real_int64(x, d); +#endif + #else if(sizeof(long long) == 2) { msgpack_pack_real_int16(x, d); @@ -509,14 +501,24 @@ if(sizeof(long long) == 2) { msgpack_pack_inline_func_cint(_unsigned_short)(msgpack_pack_user x, unsigned short d) { -#if defined(SIZEOF_SHORT) || defined(USHRT_MAX) -#if SIZEOF_SHORT == 2 || USHRT_MAX == 0xffffU +#if defined(SIZEOF_SHORT) +#if SIZEOF_SHORT == 2 msgpack_pack_real_uint16(x, d); -#elif SIZEOF_SHORT == 4 || USHRT_MAX == 0xffffffffU +#elif SIZEOF_SHORT == 4 msgpack_pack_real_uint32(x, d); #else msgpack_pack_real_uint64(x, d); #endif + +#elif defined(USHRT_MAX) +#if USHRT_MAX == 0xffffU + msgpack_pack_real_uint16(x, d); +#elif USHRT_MAX == 0xffffffffU + msgpack_pack_real_uint32(x, d); +#else + msgpack_pack_real_uint64(x, d); +#endif + #else if(sizeof(unsigned short) == 2) { msgpack_pack_real_uint16(x, d); @@ -530,14 +532,24 @@ if(sizeof(unsigned short) == 2) { msgpack_pack_inline_func_cint(_unsigned_int)(msgpack_pack_user x, unsigned int d) { -#if defined(SIZEOF_INT) || defined(UINT_MAX) -#if SIZEOF_INT == 2 || UINT_MAX == 0xffffU +#if defined(SIZEOF_INT) +#if SIZEOF_INT == 2 msgpack_pack_real_uint16(x, d); -#elif SIZEOF_INT == 4 || UINT_MAX == 0xffffffffU +#elif SIZEOF_INT == 4 msgpack_pack_real_uint32(x, d); #else msgpack_pack_real_uint64(x, d); #endif + +#elif defined(UINT_MAX) +#if UINT_MAX == 0xffffU + msgpack_pack_real_uint16(x, d); +#elif UINT_MAX == 0xffffffffU + msgpack_pack_real_uint32(x, d); +#else + msgpack_pack_real_uint64(x, d); +#endif + #else if(sizeof(unsigned int) == 2) { msgpack_pack_real_uint16(x, d); @@ -551,18 +563,28 @@ if(sizeof(unsigned int) == 2) { msgpack_pack_inline_func_cint(_unsigned_long)(msgpack_pack_user x, unsigned long d) { -#if defined(SIZEOF_LONG) || defined(ULONG_MAX) -#if SIZEOF_LONG == 2 || ULONG_MAX == 0xffffUL +#if defined(SIZEOF_LONG) +#if SIZEOF_LONG == 2 msgpack_pack_real_uint16(x, d); -#elif SIZEOF_LONG == 4 || ULONG_MAX == 0xffffffffUL +#elif SIZEOF_LONG == 4 msgpack_pack_real_uint32(x, d); #else msgpack_pack_real_uint64(x, d); #endif -#else -if(sizeof(unsigned int) == 2) { + +#elif defined(ULONG_MAX) +#if ULONG_MAX == 0xffffUL msgpack_pack_real_uint16(x, d); -} else if(sizeof(unsigned int) == 4) { +#elif ULONG_MAX == 0xffffffffUL + msgpack_pack_real_uint32(x, d); +#else + msgpack_pack_real_uint64(x, d); +#endif + +#else +if(sizeof(unsigned long) == 2) { + msgpack_pack_real_uint16(x, d); +} else if(sizeof(unsigned long) == 4) { msgpack_pack_real_uint32(x, d); } else { msgpack_pack_real_uint64(x, d); @@ -572,14 +594,24 @@ if(sizeof(unsigned int) == 2) { msgpack_pack_inline_func_cint(_unsigned_long_long)(msgpack_pack_user x, unsigned long long d) { -#if defined(SIZEOF_LONG_LONG) || defined(ULLONG_MAX) -#if SIZEOF_LONG_LONG == 2 || ULLONG_MAX == 0xffffUL +#if defined(SIZEOF_LONG_LONG) +#if SIZEOF_LONG_LONG == 2 msgpack_pack_real_uint16(x, d); -#elif SIZEOF_LONG_LONG == 4 || ULLONG_MAX == 0xffffffffUL +#elif SIZEOF_LONG_LONG == 4 msgpack_pack_real_uint32(x, d); #else msgpack_pack_real_uint64(x, d); #endif + +#elif defined(ULLONG_MAX) +#if ULLONG_MAX == 0xffffUL + msgpack_pack_real_uint16(x, d); +#elif ULLONG_MAX == 0xffffffffUL + msgpack_pack_real_uint32(x, d); +#else + msgpack_pack_real_uint64(x, d); +#endif + #else if(sizeof(unsigned long long) == 2) { msgpack_pack_real_uint16(x, d); @@ -602,17 +634,19 @@ if(sizeof(unsigned long long) == 2) { msgpack_pack_inline_func(_float)(msgpack_pack_user x, float d) { - union { char buf[4]; uint32_t num; } f; - *((float*)&f.buf) = d; // FIXME - const unsigned char buf[5] = {0xca, STORE32_BE32(f.num)}; + union { float f; uint32_t i; } mem; + mem.f = d; + unsigned char buf[5]; + buf[0] = 0xca; _msgpack_store32(&buf[1], mem.i); msgpack_pack_append_buffer(x, buf, 5); } msgpack_pack_inline_func(_double)(msgpack_pack_user x, double d) { - union { char buf[8]; uint64_t num; } f; - *((double*)&f.buf) = d; // FIXME - const unsigned char buf[9] = {0xcb, STORE64_BE64(f.num)}; + union { double f; uint64_t i; } mem; + mem.f = d; + unsigned char buf[9]; + buf[0] = 0xcb; _msgpack_store64(&buf[1], mem.i); msgpack_pack_append_buffer(x, buf, 9); } @@ -655,12 +689,12 @@ msgpack_pack_inline_func(_array)(msgpack_pack_user x, unsigned int n) unsigned char d = 0x90 | n; msgpack_pack_append_buffer(x, &d, 1); } else if(n < 65536) { - uint16_t d = (uint16_t)n; - unsigned char buf[3] = {0xdc, STORE16_BE16(d)}; + unsigned char buf[3]; + buf[0] = 0xdc; _msgpack_store16(&buf[1], n); msgpack_pack_append_buffer(x, buf, 3); } else { - uint32_t d = (uint32_t)n; - unsigned char buf[5] = {0xdd, STORE32_BE32(d)}; + unsigned char buf[5]; + buf[0] = 0xdd; _msgpack_store32(&buf[1], n); msgpack_pack_append_buffer(x, buf, 5); } } @@ -674,14 +708,14 @@ msgpack_pack_inline_func(_map)(msgpack_pack_user x, unsigned int n) { if(n < 16) { unsigned char d = 0x80 | n; - msgpack_pack_append_buffer(x, &STORE8_BE8(d), 1); + msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); } else if(n < 65536) { - uint16_t d = (uint16_t)n; - unsigned char buf[3] = {0xde, STORE16_BE16(d)}; + unsigned char buf[3]; + buf[0] = 0xde; _msgpack_store16(&buf[1], n); msgpack_pack_append_buffer(x, buf, 3); } else { - uint32_t d = (uint32_t)n; - unsigned char buf[5] = {0xdf, STORE32_BE32(d)}; + unsigned char buf[5]; + buf[0] = 0xdf; _msgpack_store32(&buf[1], n); msgpack_pack_append_buffer(x, buf, 5); } } @@ -695,14 +729,14 @@ msgpack_pack_inline_func(_raw)(msgpack_pack_user x, size_t l) { if(l < 32) { unsigned char d = 0xa0 | l; - msgpack_pack_append_buffer(x, &STORE8_BE8(d), 1); + msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); } else if(l < 65536) { - uint16_t d = (uint16_t)l; - unsigned char buf[3] = {0xda, STORE16_BE16(d)}; + unsigned char buf[3]; + buf[0] = 0xda; _msgpack_store16(&buf[1], l); msgpack_pack_append_buffer(x, buf, 3); } else { - uint32_t d = (uint32_t)l; - unsigned char buf[5] = {0xdb, STORE32_BE32(d)}; + unsigned char buf[5]; + buf[0] = 0xdb; _msgpack_store32(&buf[1], l); msgpack_pack_append_buffer(x, buf, 5); } } @@ -716,19 +750,10 @@ msgpack_pack_inline_func(_raw_body)(msgpack_pack_user x, const void* b, size_t l #undef msgpack_pack_user #undef msgpack_pack_append_buffer -#undef STORE8_BE8 - -#undef STORE16_BE8 -#undef STORE16_BE16 - -#undef STORE32_BE8 -#undef STORE32_BE16 -#undef STORE32_BE32 - -#undef STORE64_BE8 -#undef STORE64_BE16 -#undef STORE64_BE32 -#undef STORE64_BE64 +#undef TAKE8_8 +#undef TAKE8_16 +#undef TAKE8_32 +#undef TAKE8_64 #undef msgpack_pack_real_uint8 #undef msgpack_pack_real_uint16 diff --git a/php/msgpack/sysdep.h b/php/msgpack/sysdep.h new file mode 100644 index 00000000..2bc01c9f --- /dev/null +++ b/php/msgpack/sysdep.h @@ -0,0 +1,118 @@ +/* + * MessagePack system dependencies + * + * Copyright (C) 2008-2010 FURUHASHI Sadayuki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MSGPACK_SYSDEP_H__ +#define MSGPACK_SYSDEP_H__ + + +#ifdef _MSC_VER +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +#include +#include +#include +#endif + + +#ifdef _WIN32 +typedef long _msgpack_atomic_counter_t; +#define _msgpack_sync_decr_and_fetch(ptr) InterlockedDecrement(ptr) +#define _msgpack_sync_incr_and_fetch(ptr) InterlockedIncrement(ptr) +#else +typedef unsigned int _msgpack_atomic_counter_t; +#define _msgpack_sync_decr_and_fetch(ptr) __sync_sub_and_fetch(ptr, 1) +#define _msgpack_sync_incr_and_fetch(ptr) __sync_add_and_fetch(ptr, 1) +#endif + + +#ifdef _WIN32 +#include + +#ifdef __cplusplus +/* numeric_limits::min,max */ +#ifdef max +#undef max +#endif +#ifdef min +#undef min +#endif +#endif + +#else +#include /* __BYTE_ORDER */ +#endif + +#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __LITTLE_ENDIAN__ +#elif __BYTE_ORDER == __BIG_ENDIAN +#define __BIG_ENDIAN__ +#endif +#endif + +#ifdef __LITTLE_ENDIAN__ + +#define _msgpack_be16(x) ntohs(x) +#define _msgpack_be32(x) ntohl(x) + +#if defined(_byteswap_uint64) +# define _msgpack_be64(x) (_byteswap_uint64(x)) +#elif defined(bswap_64) +# define _msgpack_be64(x) bswap_64(x) +#elif defined(__DARWIN_OSSwapInt64) +# define _msgpack_be64(x) __DARWIN_OSSwapInt64(x) +#else +#define _msgpack_be64(x) \ + ( ((((uint64_t)x) << 56) & 0xff00000000000000ULL ) | \ + ((((uint64_t)x) << 40) & 0x00ff000000000000ULL ) | \ + ((((uint64_t)x) << 24) & 0x0000ff0000000000ULL ) | \ + ((((uint64_t)x) << 8) & 0x000000ff00000000ULL ) | \ + ((((uint64_t)x) >> 8) & 0x00000000ff000000ULL ) | \ + ((((uint64_t)x) >> 24) & 0x0000000000ff0000ULL ) | \ + ((((uint64_t)x) >> 40) & 0x000000000000ff00ULL ) | \ + ((((uint64_t)x) >> 56) & 0x00000000000000ffULL ) ) +#endif + +#else +#define _msgpack_be16(x) (x) +#define _msgpack_be32(x) (x) +#define _msgpack_be64(x) (x) +#endif + + +#define _msgpack_store16(to, num) \ + do { uint16_t val = _msgpack_be16(num); memcpy(to, &val, 2); } while(0); +#define _msgpack_store32(to, num) \ + do { uint32_t val = _msgpack_be32(num); memcpy(to, &val, 4); } while(0); +#define _msgpack_store64(to, num) \ + do { uint64_t val = _msgpack_be64(num); memcpy(to, &val, 8); } while(0); + + +#define _msgpack_load16(cast, from) ((cast)_msgpack_be16(*(uint16_t*)from)) +#define _msgpack_load32(cast, from) ((cast)_msgpack_be32(*(uint32_t*)from)) +#define _msgpack_load64(cast, from) ((cast)_msgpack_be64(*(uint64_t*)from)) + + +#endif /* msgpack/sysdep.h */ + diff --git a/php/msgpack/unpack_define.h b/php/msgpack/unpack_define.h index 63668c24..959d3519 100644 --- a/php/msgpack/unpack_define.h +++ b/php/msgpack/unpack_define.h @@ -1,7 +1,7 @@ /* * MessagePack unpacking routine template * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki + * Copyright (C) 2008-2010 FURUHASHI Sadayuki * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,55 +18,19 @@ #ifndef MSGPACK_UNPACK_DEFINE_H__ #define MSGPACK_UNPACK_DEFINE_H__ -#include -#include +#include "msgpack/sysdep.h" +#include #include #include #include -#ifndef __WIN32__ -#include -#endif #ifdef __cplusplus extern "C" { #endif -#ifndef MSGPACK_MAX_STACK_SIZE -#define MSGPACK_MAX_STACK_SIZE 16 -#endif - - -#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define __LITTLE_ENDIAN__ -#elif __BYTE_ORDER == __BIG_ENDIAN -#define __BIG_ENDIAN__ -#endif -#endif - -#define msgpack_betoh16(x) ntohs(x) -#define msgpack_betoh32(x) ntohl(x) - -#ifdef __LITTLE_ENDIAN__ -#if defined(__bswap_64) -# define msgpack_betoh64(x) __bswap_64(x) -#elif defined(__DARWIN_OSSwapInt64) -# define msgpack_betoh64(x) __DARWIN_OSSwapInt64(x) -#else -static inline uint64_t msgpack_betoh64(uint64_t x) { - return ((x << 56) & 0xff00000000000000ULL ) | - ((x << 40) & 0x00ff000000000000ULL ) | - ((x << 24) & 0x0000ff0000000000ULL ) | - ((x << 8) & 0x000000ff00000000ULL ) | - ((x >> 8) & 0x00000000ff000000ULL ) | - ((x >> 24) & 0x0000000000ff0000ULL ) | - ((x >> 40) & 0x000000000000ff00ULL ) | - ((x >> 56) & 0x00000000000000ffULL ) ; -} -#endif -#else -#define msgpack_betoh64(x) (x) +#ifndef MSGPACK_EMBED_STACK_SIZE +#define MSGPACK_EMBED_STACK_SIZE 32 #endif diff --git a/php/msgpack/unpack_template.h b/php/msgpack/unpack_template.h index d67fd1ef..0fbfbb78 100644 --- a/php/msgpack/unpack_template.h +++ b/php/msgpack/unpack_template.h @@ -1,7 +1,7 @@ /* * MessagePack unpacking routine template * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki + * Copyright (C) 2008-2010 FURUHASHI Sadayuki * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,6 +40,11 @@ #error msgpack_unpack_user type is not defined #endif +#ifndef USE_CASE_RANGE +#if !defined(_MSC_VER) +#define USE_CASE_RANGE +#endif +#endif msgpack_unpack_struct_decl(_stack) { msgpack_unpack_object obj; @@ -53,7 +58,12 @@ msgpack_unpack_struct_decl(_context) { unsigned int cs; unsigned int trail; unsigned int top; - msgpack_unpack_struct(_stack) stack[MSGPACK_MAX_STACK_SIZE]; + /* + msgpack_unpack_struct(_stack)* stack; + unsigned int stack_size; + msgpack_unpack_struct(_stack) embed_stack[MSGPACK_EMBED_STACK_SIZE]; + */ + msgpack_unpack_struct(_stack) stack[MSGPACK_EMBED_STACK_SIZE]; }; @@ -62,9 +72,22 @@ msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx) ctx->cs = CS_HEADER; ctx->trail = 0; ctx->top = 0; + /* + ctx->stack = ctx->embed_stack; + ctx->stack_size = MSGPACK_EMBED_STACK_SIZE; + */ ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user); } +/* +msgpack_unpack_func(void, _destroy)(msgpack_unpack_struct(_context)* ctx) +{ + if(ctx->stack_size != MSGPACK_EMBED_STACK_SIZE) { + free(ctx->stack); + } +} +*/ + msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx) { return (ctx)->stack[0].obj; @@ -83,6 +106,9 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c unsigned int cs = ctx->cs; unsigned int top = ctx->top; msgpack_unpack_struct(_stack)* stack = ctx->stack; + /* + unsigned int stack_size = ctx->stack_size; + */ msgpack_unpack_user* user = &ctx->user; msgpack_unpack_object obj; @@ -112,34 +138,60 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c goto _fixed_trail_again #define start_container(func, count_, ct_) \ + if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ \ if(msgpack_unpack_callback(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \ if((count_) == 0) { obj = stack[top].obj; goto _push; } \ - if(top >= MSGPACK_MAX_STACK_SIZE) { goto _failed; } \ stack[top].ct = ct_; \ stack[top].count = count_; \ + ++top; \ /*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \ /*printf("stack push %d\n", top);*/ \ - ++top; \ + /* FIXME \ + if(top >= stack_size) { \ + if(stack_size == MSGPACK_EMBED_STACK_SIZE) { \ + size_t csize = sizeof(msgpack_unpack_struct(_stack)) * MSGPACK_EMBED_STACK_SIZE; \ + size_t nsize = csize * 2; \ + msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)malloc(nsize); \ + if(tmp == NULL) { goto _failed; } \ + memcpy(tmp, ctx->stack, csize); \ + ctx->stack = stack = tmp; \ + ctx->stack_size = stack_size = MSGPACK_EMBED_STACK_SIZE * 2; \ + } else { \ + size_t nsize = sizeof(msgpack_unpack_struct(_stack)) * ctx->stack_size * 2; \ + msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)realloc(ctx->stack, nsize); \ + if(tmp == NULL) { goto _failed; } \ + ctx->stack = stack = tmp; \ + ctx->stack_size = stack_size = stack_size * 2; \ + } \ + } \ + */ \ goto _header_again #define NEXT_CS(p) \ ((unsigned int)*p & 0x1f) -#define PTR_CAST_8(ptr) (*(uint8_t*)ptr) -#define PTR_CAST_16(ptr) msgpack_betoh16(*(uint16_t*)ptr) -#define PTR_CAST_32(ptr) msgpack_betoh32(*(uint32_t*)ptr) -#define PTR_CAST_64(ptr) msgpack_betoh64(*(uint64_t*)ptr) +#ifdef USE_CASE_RANGE +#define SWITCH_RANGE_BEGIN switch(*p) { +#define SWITCH_RANGE(FROM, TO) case FROM ... TO: +#define SWITCH_RANGE_DEFAULT default: +#define SWITCH_RANGE_END } +#else +#define SWITCH_RANGE_BEGIN { if(0) { +#define SWITCH_RANGE(FROM, TO) } else if(FROM <= *p && *p <= TO) { +#define SWITCH_RANGE_DEFAULT } else { +#define SWITCH_RANGE_END } } +#endif if(p == pe) { goto _out; } do { switch(cs) { case CS_HEADER: - switch(*p) { - case 0x00 ... 0x7f: // Positive Fixnum + SWITCH_RANGE_BEGIN + SWITCH_RANGE(0x00, 0x7f) // Positive Fixnum push_fixed_value(_uint8, *(uint8_t*)p); - case 0xe0 ... 0xff: // Negative Fixnum + SWITCH_RANGE(0xe0, 0xff) // Negative Fixnum push_fixed_value(_int8, *(int8_t*)p); - case 0xc0 ... 0xdf: // Variable + SWITCH_RANGE(0xc0, 0xdf) // Variable switch(*p) { case 0xc0: // nil push_simple_value(_nil); @@ -182,16 +234,16 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c default: goto _failed; } - case 0xa0 ... 0xbf: // FixRaw + SWITCH_RANGE(0xa0, 0xbf) // FixRaw again_fixed_trail_if_zero(ACS_RAW_VALUE, ((unsigned int)*p & 0x1f), _raw_zero); - case 0x90 ... 0x9f: // FixArray + SWITCH_RANGE(0x90, 0x9f) // FixArray start_container(_array, ((unsigned int)*p) & 0x0f, CT_ARRAY_ITEM); - case 0x80 ... 0x8f: // FixMap + SWITCH_RANGE(0x80, 0x8f) // FixMap start_container(_map, ((unsigned int)*p) & 0x0f, CT_MAP_KEY); - default: + SWITCH_RANGE_DEFAULT goto _failed; - } + SWITCH_RANGE_END // end CS_HEADER @@ -205,70 +257,70 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c //case CS_ //case CS_ case CS_FLOAT: { - union { uint32_t num; char buf[4]; } f; - f.num = PTR_CAST_32(n); // FIXME - push_fixed_value(_float, *((float*)f.buf)); } + union { uint32_t i; float f; } mem; + mem.i = _msgpack_load32(uint32_t,n); + push_fixed_value(_float, mem.f); } case CS_DOUBLE: { - union { uint64_t num; char buf[8]; } f; - f.num = PTR_CAST_64(n); // FIXME - push_fixed_value(_double, *((double*)f.buf)); } + union { uint64_t i; double f; } mem; + mem.i = _msgpack_load64(uint64_t,n); + push_fixed_value(_double, mem.f); } case CS_UINT_8: - push_fixed_value(_uint8, (uint8_t)PTR_CAST_8(n)); + push_fixed_value(_uint8, *(uint8_t*)n); case CS_UINT_16: - push_fixed_value(_uint16, (uint16_t)PTR_CAST_16(n)); + push_fixed_value(_uint16, _msgpack_load16(uint16_t,n)); case CS_UINT_32: - push_fixed_value(_uint32, (uint32_t)PTR_CAST_32(n)); + push_fixed_value(_uint32, _msgpack_load32(uint32_t,n)); case CS_UINT_64: - push_fixed_value(_uint64, (uint64_t)PTR_CAST_64(n)); + push_fixed_value(_uint64, _msgpack_load64(uint64_t,n)); case CS_INT_8: - push_fixed_value(_int8, (int8_t)PTR_CAST_8(n)); + push_fixed_value(_int8, *(int8_t*)n); case CS_INT_16: - push_fixed_value(_int16, (int16_t)PTR_CAST_16(n)); + push_fixed_value(_int16, _msgpack_load16(int16_t,n)); case CS_INT_32: - push_fixed_value(_int32, (int32_t)PTR_CAST_32(n)); + push_fixed_value(_int32, _msgpack_load32(int32_t,n)); case CS_INT_64: - push_fixed_value(_int64, (int64_t)PTR_CAST_64(n)); + push_fixed_value(_int64, _msgpack_load64(int64_t,n)); //case CS_ //case CS_ //case CS_BIG_INT_16: - // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, (uint16_t)PTR_CAST_16(n), _big_int_zero); + // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load16(uint16_t,n), _big_int_zero); //case CS_BIG_INT_32: - // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, (uint32_t)PTR_CAST_32(n), _big_int_zero); + // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load32(uint32_t,n), _big_int_zero); //case ACS_BIG_INT_VALUE: //_big_int_zero: // // FIXME // push_variable_value(_big_int, data, n, trail); //case CS_BIG_FLOAT_16: - // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, (uint16_t)PTR_CAST_16(n), _big_float_zero); + // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load16(uint16_t,n), _big_float_zero); //case CS_BIG_FLOAT_32: - // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, (uint32_t)PTR_CAST_32(n), _big_float_zero); + // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load32(uint32_t,n), _big_float_zero); //case ACS_BIG_FLOAT_VALUE: //_big_float_zero: // // FIXME // push_variable_value(_big_float, data, n, trail); case CS_RAW_16: - again_fixed_trail_if_zero(ACS_RAW_VALUE, (uint16_t)PTR_CAST_16(n), _raw_zero); + again_fixed_trail_if_zero(ACS_RAW_VALUE, _msgpack_load16(uint16_t,n), _raw_zero); case CS_RAW_32: - again_fixed_trail_if_zero(ACS_RAW_VALUE, (uint32_t)PTR_CAST_32(n), _raw_zero); + again_fixed_trail_if_zero(ACS_RAW_VALUE, _msgpack_load32(uint32_t,n), _raw_zero); case ACS_RAW_VALUE: _raw_zero: push_variable_value(_raw, data, n, trail); case CS_ARRAY_16: - start_container(_array, (uint16_t)PTR_CAST_16(n), CT_ARRAY_ITEM); + start_container(_array, _msgpack_load16(uint16_t,n), CT_ARRAY_ITEM); case CS_ARRAY_32: /* FIXME security guard */ - start_container(_array, (uint32_t)PTR_CAST_32(n), CT_ARRAY_ITEM); + start_container(_array, _msgpack_load32(uint32_t,n), CT_ARRAY_ITEM); case CS_MAP_16: - start_container(_map, (uint16_t)PTR_CAST_16(n), CT_MAP_KEY); + start_container(_map, _msgpack_load16(uint16_t,n), CT_MAP_KEY); case CS_MAP_32: /* FIXME security guard */ - start_container(_map, (uint32_t)PTR_CAST_32(n), CT_MAP_KEY); + start_container(_map, _msgpack_load32(uint32_t,n), CT_MAP_KEY); default: goto _failed; @@ -354,8 +406,4 @@ _end: #undef start_container #undef NEXT_CS -#undef PTR_CAST_8 -#undef PTR_CAST_16 -#undef PTR_CAST_32 -#undef PTR_CAST_64 diff --git a/php/msgpack/version.h b/php/msgpack/version.h new file mode 100644 index 00000000..13671d1a --- /dev/null +++ b/php/msgpack/version.h @@ -0,0 +1,40 @@ +/* + * MessagePack for C version information + * + * Copyright (C) 2008-2009 FURUHASHI Sadayuki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MSGPACK_VERSION_H__ +#define MSGPACK_VERSION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +const char* msgpack_version(void); +int msgpack_version_major(void); +int msgpack_version_minor(void); + +#define MSGPACK_VERSION "0.5.4" +#define MSGPACK_VERSION_MAJOR 0 +#define MSGPACK_VERSION_MINOR 5 + + +#ifdef __cplusplus +} +#endif + +#endif /* msgpack/version.h */ + diff --git a/php/msgpack_class.c b/php/msgpack_class.c new file mode 100644 index 00000000..5cfff8d8 --- /dev/null +++ b/php/msgpack_class.c @@ -0,0 +1,559 @@ + +#include "php.h" + +#include "php_msgpack.h" +#include "msgpack_pack.h" +#include "msgpack_unpack.h" +#include "msgpack_class.h" + +typedef struct { + zend_object object; + long php_only; +} php_msgpack_base_t; + +typedef struct { + zend_object object; + smart_str buffer; + zval *retval; + long offset; + msgpack_unpack_t mp; + php_unserialize_data_t var_hash; + long php_only; +} php_msgpack_unpacker_t; + +#if ZEND_MODULE_API_NO >= 20060613 +# define MSGPACK_METHOD_BASE(classname, name) zim_##classname##_##name +#else +# define MSGPACK_METHOD_BASE(classname, name) zif_##classname##_##name +#endif + +#if ZEND_MODULE_API_NO >= 20090115 +# define PUSH_PARAM(arg) zend_vm_stack_push(arg TSRMLS_CC) +# define POP_PARAM() (void)zend_vm_stack_pop(TSRMLS_C) +# define PUSH_EO_PARAM() +# define POP_EO_PARAM() +#else +# define PUSH_PARAM(arg) zend_ptr_stack_push(&EG(argument_stack), arg) +# define POP_PARAM() (void)zend_ptr_stack_pop(&EG(argument_stack)) +# define PUSH_EO_PARAM() zend_ptr_stack_push(&EG(argument_stack), NULL) +# define POP_EO_PARAM() (void)zend_ptr_stack_pop(&EG(argument_stack)) +#endif + +#define MSGPACK_METHOD_HELPER(classname, name, retval, thisptr, num, param) \ + PUSH_PARAM(param); PUSH_PARAM((void*)num); \ + PUSH_EO_PARAM(); \ + MSGPACK_METHOD_BASE(classname, name)(num, retval, NULL, thisptr, 0 TSRMLS_CC); \ + POP_EO_PARAM(); \ + POP_PARAM(); \ + POP_PARAM(); + +#define MSGPACK_METHOD(classname, name, retval, thisptr) \ + MSGPACK_METHOD_BASE(classname, name)(0, retval, NULL, thisptr, 0 TSRMLS_CC) + +#define MSGPACK_METHOD1(classname, name, retval, thisptr, param1) \ + MSGPACK_METHOD_HELPER(classname, name, retval, thisptr, 1, param1); + +#define MSGPACK_BASE_OBJECT \ + php_msgpack_base_t *base; \ + base = (php_msgpack_base_t *)zend_object_store_get_object(getThis() TSRMLS_CC); + +#define MSGPACK_UNPACKER_OBJECT \ + php_msgpack_unpacker_t *unpacker; \ + unpacker = (php_msgpack_unpacker_t *)zend_object_store_get_object(getThis() TSRMLS_CC); + +#define MSGPACK_CLASS_OPT_PHPONLY -1001 + +/* MessagePack */ +static zend_class_entry *msgpack_ce = NULL; + +static ZEND_METHOD(msgpack, __construct); +static ZEND_METHOD(msgpack, setOption); +static ZEND_METHOD(msgpack, pack); +static ZEND_METHOD(msgpack, unpack); +static ZEND_METHOD(msgpack, unpacker); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_base___construct, 0, 0, 0) + ZEND_ARG_INFO(0, opt) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_base_setOption, 0, 0, 2) + ZEND_ARG_INFO(0, option) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_base_pack, 0, 0, 1) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_base_unpack, 0, 0, 1) + ZEND_ARG_INFO(0, str) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_base_unpacker, 0, 0, 0) +ZEND_END_ARG_INFO() + +static const zend_function_entry msgpack_base_methods[] = { + ZEND_ME(msgpack, __construct, + arginfo_msgpack_base___construct, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack, setOption, arginfo_msgpack_base_setOption, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack, pack, arginfo_msgpack_base_pack, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack, unpack, arginfo_msgpack_base_unpack, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack, unpacker, arginfo_msgpack_base_unpacker, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +/* MessagePackUnpacker */ +static zend_class_entry *msgpack_unpacker_ce = NULL; + +static ZEND_METHOD(msgpack_unpacker, __construct); +static ZEND_METHOD(msgpack_unpacker, __destruct); +static ZEND_METHOD(msgpack_unpacker, setOption); +static ZEND_METHOD(msgpack_unpacker, feed); +static ZEND_METHOD(msgpack_unpacker, execute); +static ZEND_METHOD(msgpack_unpacker, data); +static ZEND_METHOD(msgpack_unpacker, reset); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unpacker___construct, 0, 0, 0) + ZEND_ARG_INFO(0, opt) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unpacker___destruct, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unpacker_setOption, 0, 0, 2) + ZEND_ARG_INFO(0, option) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unpacker_feed, 0, 0, 1) + ZEND_ARG_INFO(0, str) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unpacker_execute, 1, 0, 0) + ZEND_ARG_INFO(0, str) + ZEND_ARG_INFO(1, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unpacker_data, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unpacker_reset, 0, 0, 0) +ZEND_END_ARG_INFO() + +static const zend_function_entry msgpack_unpacker_methods[] = { + ZEND_ME(msgpack_unpacker, __construct, + arginfo_msgpack_unpacker___construct, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack_unpacker, __destruct, + arginfo_msgpack_unpacker___destruct, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack_unpacker, setOption, + arginfo_msgpack_unpacker_setOption, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack_unpacker, feed, + arginfo_msgpack_unpacker_feed, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack_unpacker, execute, + arginfo_msgpack_unpacker_execute, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack_unpacker, data, + arginfo_msgpack_unpacker_data, ZEND_ACC_PUBLIC) + ZEND_ME(msgpack_unpacker, reset, + arginfo_msgpack_unpacker_reset, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +static void php_msgpack_base_free(php_msgpack_base_t *base TSRMLS_DC) +{ + zend_object_std_dtor(&base->object TSRMLS_CC); + efree(base); +} + +static zend_object_value php_msgpack_base_new(zend_class_entry *ce TSRMLS_DC) +{ + zend_object_value retval; + zval *tmp; + php_msgpack_base_t *base; + + base = emalloc(sizeof(php_msgpack_base_t)); + + zend_object_std_init(&base->object, ce TSRMLS_CC); + + zend_hash_copy( + base->object.properties, &ce->default_properties, + (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *)); + + retval.handle = zend_objects_store_put( + base, (zend_objects_store_dtor_t)zend_objects_destroy_object, + (zend_objects_free_object_storage_t)php_msgpack_base_free, + NULL TSRMLS_CC); + retval.handlers = zend_get_std_object_handlers(); + + return retval; +} + +static void php_msgpack_unpacker_free( + php_msgpack_unpacker_t *unpacker TSRMLS_DC) +{ + zend_object_std_dtor(&unpacker->object TSRMLS_CC); + efree(unpacker); +} + +static zend_object_value php_msgpack_unpacker_new( + zend_class_entry *ce TSRMLS_DC) +{ + zend_object_value retval; + zval *tmp; + php_msgpack_unpacker_t *unpacker; + + unpacker = emalloc(sizeof(php_msgpack_unpacker_t)); + + zend_object_std_init(&unpacker->object, ce TSRMLS_CC); + + zend_hash_copy( + unpacker->object.properties, &ce->default_properties, + (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *)); + + retval.handle = zend_objects_store_put( + unpacker, (zend_objects_store_dtor_t)zend_objects_destroy_object, + (zend_objects_free_object_storage_t)php_msgpack_unpacker_free, + NULL TSRMLS_CC); + retval.handlers = zend_get_std_object_handlers(); + + return retval; +} + +/* MessagePack */ +static ZEND_METHOD(msgpack, __construct) +{ + bool php_only = MSGPACK_G(php_only); + MSGPACK_BASE_OBJECT; + + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "|b", &php_only) == FAILURE) + { + return; + } + + base->php_only = php_only; +} + +static ZEND_METHOD(msgpack, setOption) +{ + long option; + zval *value; + MSGPACK_BASE_OBJECT; + + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "lz", &option, &value) == FAILURE) + { + return; + } + + switch (option) + { + case MSGPACK_CLASS_OPT_PHPONLY: + convert_to_boolean(value); + base->php_only = Z_BVAL_P(value); + break; + default: + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (MessagePack::setOption) " + "error setting msgpack option"); + } + RETURN_FALSE; + break; + } + + RETURN_TRUE; +} + +static ZEND_METHOD(msgpack, pack) +{ + zval *parameter; + smart_str buf = {0}; + int php_only = MSGPACK_G(php_only); + MSGPACK_BASE_OBJECT; + + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == FAILURE) + { + return; + } + + MSGPACK_G(php_only) = base->php_only; + + php_msgpack_serialize(&buf, parameter TSRMLS_CC); + + MSGPACK_G(php_only) = php_only; + + ZVAL_STRINGL(return_value, buf.c, buf.len, 1); + + smart_str_free(&buf); +} + +static ZEND_METHOD(msgpack, unpack) +{ + char *str; + int str_len; + int php_only = MSGPACK_G(php_only); + MSGPACK_BASE_OBJECT; + + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) + { + return; + } + + if (!str_len) + { + RETURN_NULL(); + } + + MSGPACK_G(php_only) = base->php_only; + + php_msgpack_unserialize(return_value, str, str_len TSRMLS_CC); + + MSGPACK_G(php_only) = php_only; +} + +static ZEND_METHOD(msgpack, unpacker) +{ + zval temp, *opt; + MSGPACK_BASE_OBJECT; + + ALLOC_INIT_ZVAL(opt); + ZVAL_BOOL(opt, base->php_only); + + object_init_ex(return_value, msgpack_unpacker_ce); + + MSGPACK_METHOD1(msgpack_unpacker, __construct, &temp, return_value, opt); + + zval_ptr_dtor(&opt); +} + +/* MessagePackUnpacker */ +static ZEND_METHOD(msgpack_unpacker, __construct) +{ + bool php_only = MSGPACK_G(php_only); + MSGPACK_UNPACKER_OBJECT; + + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "|b", &php_only) == FAILURE) + { + return; + } + + unpacker->php_only = php_only; + + unpacker->buffer.c = NULL; + unpacker->buffer.len = 0; + unpacker->buffer.a = 0; + unpacker->retval = NULL; + unpacker->offset = 0; + + template_init(&unpacker->mp); + + msgpack_unserialize_var_init(&unpacker->var_hash); + + (&unpacker->mp)->user.var_hash = + (php_unserialize_data_t *)&unpacker->var_hash; +} + +static ZEND_METHOD(msgpack_unpacker, __destruct) +{ + MSGPACK_UNPACKER_OBJECT; + + smart_str_free(&unpacker->buffer); + + if (unpacker->retval != NULL) + { + zval_ptr_dtor(&unpacker->retval); + } + + msgpack_unserialize_var_destroy(&unpacker->var_hash); +} + +static ZEND_METHOD(msgpack_unpacker, setOption) +{ + long option; + zval *value; + MSGPACK_UNPACKER_OBJECT; + + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "lz", &option, &value) == FAILURE) + { + return; + } + + switch (option) + { + case MSGPACK_CLASS_OPT_PHPONLY: + convert_to_boolean(value); + unpacker->php_only = Z_BVAL_P(value); + break; + default: + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (MessagePackUnpacker::setOption) " + "error setting msgpack option"); + } + RETURN_FALSE; + break; + } + + RETURN_TRUE; +} + +static ZEND_METHOD(msgpack_unpacker, feed) +{ + char *str; + int str_len; + MSGPACK_UNPACKER_OBJECT; + + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) + { + return; + } + + if (!str_len) + { + RETURN_FALSE; + } + + smart_str_appendl(&unpacker->buffer, str, str_len); + + RETURN_TRUE; +} + +static ZEND_METHOD(msgpack_unpacker, execute) +{ + char *str = NULL, *data; + long str_len = 0; + zval *offset; + int ret; + size_t len, off; + int error_display = MSGPACK_G(error_display); + int php_only = MSGPACK_G(php_only); + MSGPACK_UNPACKER_OBJECT; + + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "|sz/", + &str, &str_len, &offset) == FAILURE) + { + return; + } + + if (str != NULL) + { + data = (char *)str; + len = (size_t)str_len; + off = Z_LVAL_P(offset); + } + else + { + data = (char *)unpacker->buffer.c; + len = unpacker->buffer.len; + off = unpacker->offset; + } + + if (unpacker->retval == NULL) + { + ALLOC_INIT_ZVAL(unpacker->retval); + } + (&unpacker->mp)->user.retval = (zval *)unpacker->retval; + + MSGPACK_G(error_display) = 0; + MSGPACK_G(php_only) = unpacker->php_only; + + ret = template_execute(&unpacker->mp, data, len, &off); + + MSGPACK_G(error_display) = error_display; + MSGPACK_G(php_only) = php_only; + + if (str != NULL) + { + ZVAL_LONG(offset, off); + } + else + { + unpacker->offset = off; + } + + switch (ret) + { + case MSGPACK_UNPACK_EXTRA_BYTES: + case MSGPACK_UNPACK_SUCCESS: + RETURN_TRUE; + default: + RETURN_FALSE; + } +} + +static ZEND_METHOD(msgpack_unpacker, data) +{ + MSGPACK_UNPACKER_OBJECT; + + RETURN_ZVAL(unpacker->retval, 1, 1); +} + +static ZEND_METHOD(msgpack_unpacker, reset) +{ + smart_str buffer = {0}; + MSGPACK_UNPACKER_OBJECT; + + if (unpacker->buffer.len > unpacker->offset) + { + smart_str_appendl(&buffer, unpacker->buffer.c + unpacker->offset, + unpacker->buffer.len - unpacker->offset); + } + + smart_str_free(&unpacker->buffer); + + unpacker->buffer.c = NULL; + unpacker->buffer.len = 0; + unpacker->buffer.a = 0; + unpacker->offset = 0; + + if (buffer.len > 0) + { + smart_str_appendl(&unpacker->buffer, buffer.c, buffer.len); + } + + smart_str_free(&buffer); + + if (unpacker->retval != NULL) + { + zval_ptr_dtor(&unpacker->retval); + unpacker->retval = NULL; + } + + msgpack_unserialize_var_destroy(&unpacker->var_hash); + + + msgpack_unserialize_var_init(&unpacker->var_hash); + + (&unpacker->mp)->user.var_hash = + (php_unserialize_data_t *)&unpacker->var_hash; + + msgpack_unserialize_init(&((&unpacker->mp)->user)); +} + +void msgpack_init_class() +{ + zend_class_entry ce; + TSRMLS_FETCH(); + + /* base */ + INIT_CLASS_ENTRY(ce, "MessagePack", msgpack_base_methods); + msgpack_ce = zend_register_internal_class(&ce TSRMLS_CC); + msgpack_ce->create_object = php_msgpack_base_new; + + zend_declare_class_constant_long( + msgpack_ce, ZEND_STRS("OPT_PHPONLY") - 1, + MSGPACK_CLASS_OPT_PHPONLY TSRMLS_CC); + + /* unpacker */ + INIT_CLASS_ENTRY(ce, "MessagePackUnpacker", msgpack_unpacker_methods); + msgpack_unpacker_ce = zend_register_internal_class(&ce TSRMLS_CC); + msgpack_unpacker_ce->create_object = php_msgpack_unpacker_new; +} diff --git a/php/msgpack_class.h b/php/msgpack_class.h new file mode 100644 index 00000000..fbebaf4d --- /dev/null +++ b/php/msgpack_class.h @@ -0,0 +1,7 @@ + +#ifndef MSGPACK_CLASS_H +#define MSGPACK_CLASS_H + +void msgpack_init_class(); + +#endif diff --git a/php/msgpack_pack.c b/php/msgpack_pack.c new file mode 100644 index 00000000..d2d4ba3b --- /dev/null +++ b/php/msgpack_pack.c @@ -0,0 +1,558 @@ + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/php_smart_str.h" +#include "ext/standard/php_incomplete_class.h" +#include "ext/standard/php_var.h" + +#include "php_msgpack.h" +#include "msgpack_pack.h" + +#include "msgpack/pack_define.h" +#define msgpack_pack_user smart_str* +#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_append_buffer(user, buf, len) \ + smart_str_appendl(user, (const void*)buf, len) +#include "msgpack/pack_template.h" + +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3) +# define Z_ISREF_P(pz) PZVAL_IS_REF(pz) +#endif + +inline static int msgpack_var_add( + HashTable *var_hash, zval *var, void *var_old TSRMLS_DC) +{ + ulong var_no; + char id[32], *p; + int len; + + if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) + { + p = smart_str_print_long( + id + sizeof(id) - 1, + (((size_t)Z_OBJCE_P(var) << 5) + | ((size_t)Z_OBJCE_P(var) >> (sizeof(long) * 8 - 5))) + + (long)Z_OBJ_HANDLE_P(var)); + len = id + sizeof(id) - 1 - p; + } + else + { + p = smart_str_print_long(id + sizeof(id) - 1, (long)var); + len = id + sizeof(id) - 1 - p; + } + + if (var_old && zend_hash_find(var_hash, p, len, var_old) == SUCCESS) + { + if (!Z_ISREF_P(var)) + { + var_no = -1; + zend_hash_next_index_insert( + var_hash, &var_no, sizeof(var_no), NULL); + } + return FAILURE; + } + + var_no = zend_hash_num_elements(var_hash) + 1; + + zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL); + + return SUCCESS; +} + +inline static void msgpack_serialize_string( + smart_str *buf, char *str, size_t len) +{ + msgpack_pack_raw(buf, len); + msgpack_pack_raw_body(buf, str, len); +} + +inline static void msgpack_serialize_class( + smart_str *buf, zval *val, zval *retval_ptr, HashTable *var_hash, + char *class_name, zend_uint name_len, zend_bool incomplete_class TSRMLS_DC) +{ + int count; + HashTable *ht = HASH_OF(retval_ptr); + + count = zend_hash_num_elements(ht); + if (incomplete_class) + { + --count; + } + + if (count > 0) + { + char *key; + zval **data, **name; + ulong key_index; + HashPosition pos; + int n; + zval nval, *nvalp; + + msgpack_pack_map(buf, count + 1); + + msgpack_pack_nil(buf); + msgpack_serialize_string(buf, class_name, name_len); + + ZVAL_NULL(&nval); + nvalp = &nval; + + zend_hash_internal_pointer_reset_ex(ht, &pos); + + for (;; zend_hash_move_forward_ex(ht, &pos)) + { + n = zend_hash_get_current_key_ex( + ht, &key, NULL, &key_index, 0, &pos); + + if (n == HASH_KEY_NON_EXISTANT) + { + break; + } + if (incomplete_class && strcmp(key, MAGIC_MEMBER) == 0) + { + continue; + } + + zend_hash_get_current_data_ex(ht, (void **)&name, &pos); + + if (Z_TYPE_PP(name) != IS_STRING) + { + if (MSGPACK_G(error_display)) + { + zend_error(E_NOTICE, + "[msgpack] (msgpack_serialize_class) " + "__sleep should return an array only " + "containing the names of " + "instance-variables to serialize."); + } + continue; + } + + if (zend_hash_find( + Z_OBJPROP_P(val), Z_STRVAL_PP(name), + Z_STRLEN_PP(name) + 1, (void *)&data) == SUCCESS) + { + msgpack_serialize_string( + buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name)); + msgpack_serialize_zval(buf, *data, var_hash TSRMLS_CC); + } + else + { + zend_class_entry *ce; + ce = zend_get_class_entry(val TSRMLS_CC); + if (ce) + { + char *prot_name, *priv_name; + int prop_name_length; + + do + { + zend_mangle_property_name( + &priv_name, &prop_name_length, ce->name, + ce->name_length, Z_STRVAL_PP(name), + Z_STRLEN_PP(name), + ce->type & ZEND_INTERNAL_CLASS); + if (zend_hash_find( + Z_OBJPROP_P(val), priv_name, + prop_name_length + 1, + (void *)&data) == SUCCESS) + { + msgpack_serialize_string( + buf, priv_name, prop_name_length); + + pefree(priv_name, + ce->type & ZEND_INTERNAL_CLASS); + + msgpack_serialize_zval( + buf, *data, var_hash TSRMLS_CC); + break; + } + + pefree(priv_name, + ce->type & ZEND_INTERNAL_CLASS); + + zend_mangle_property_name( + &prot_name, &prop_name_length, "*", 1, + Z_STRVAL_PP(name), Z_STRLEN_PP(name), + ce->type & ZEND_INTERNAL_CLASS); + + if (zend_hash_find( + Z_OBJPROP_P(val), prot_name, + prop_name_length + 1, + (void *)&data) == SUCCESS) + { + msgpack_serialize_string( + buf, prot_name, prop_name_length); + + pefree(prot_name, + ce->type & ZEND_INTERNAL_CLASS); + + msgpack_serialize_zval( + buf, *data, var_hash TSRMLS_CC); + break; + } + + pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS); + + if (MSGPACK_G(error_display)) + { + zend_error(E_NOTICE, + "[msgpack] (msgpack_serialize_class) " + "\"%s\" returned as member variable from " + "__sleep() but does not exist", + Z_STRVAL_PP(name)); + } + + msgpack_serialize_string( + buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name)); + + msgpack_serialize_zval( + buf, nvalp, var_hash TSRMLS_CC); + } + while (0); + } + else + { + msgpack_serialize_string( + buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name)); + + msgpack_serialize_zval(buf, nvalp, var_hash TSRMLS_CC); + } + } + } + } +} + +inline static void msgpack_serialize_array( + smart_str *buf, zval *val, HashTable *var_hash, bool object, + char* class_name, zend_uint name_len, zend_bool incomplete_class TSRMLS_DC) +{ + HashTable *ht; + size_t n; + bool hash = true; + + if (object) + { + ht = Z_OBJPROP_P(val); + } + else + { + ht = HASH_OF(val); + } + + if (ht) + { + n = zend_hash_num_elements(ht); + } + else + { + n = 0; + } + + if (n > 0 && incomplete_class) + { + --n; + } + + if (object) + { + if (MSGPACK_G(php_only)) + { + if (Z_ISREF_P(val)) + { + msgpack_pack_map(buf, n + 2); + msgpack_pack_nil(buf); + msgpack_pack_long(buf, MSGPACK_SERIALIZE_TYPE_REFERENCE); + } + else + { + msgpack_pack_map(buf, n + 1); + } + + msgpack_pack_nil(buf); + + msgpack_serialize_string(buf, class_name, name_len); + } + else + { + msgpack_pack_array(buf, n); + hash = false; + } + } + else if (n == 0) + { + hash = false; + msgpack_pack_array(buf, n); + } + else + { + if (Z_ISREF_P(val) && MSGPACK_G(php_only)) + { + msgpack_pack_map(buf, n + 1); + msgpack_pack_nil(buf); + msgpack_pack_long(buf, MSGPACK_SERIALIZE_TYPE_REFERENCE); + } + else + { + msgpack_pack_map(buf, n); + } + } + + if (n > 0) + { + char *key; + uint key_len; + int key_type; + ulong key_index; + zval **data; + HashPosition pos; + + zend_hash_internal_pointer_reset_ex(ht, &pos); + for (;; zend_hash_move_forward_ex(ht, &pos)) + { + key_type = zend_hash_get_current_key_ex( + ht, &key, &key_len, &key_index, 0, &pos); + + if (key_type == HASH_KEY_NON_EXISTANT) + { + break; + } + if (incomplete_class && strcmp(key, MAGIC_MEMBER) == 0) + { + continue; + } + + if (hash) + { + switch (key_type) + { + case HASH_KEY_IS_LONG: + msgpack_pack_long(buf, key_index); + break; + case HASH_KEY_IS_STRING: + msgpack_serialize_string(buf, key, key_len - 1); + break; + default: + msgpack_serialize_string(buf, "", sizeof("")); + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (msgpack_serialize_array) " + "key is not string nor array"); + } + break; + } + } + + if (zend_hash_get_current_data_ex( + ht, (void *)&data, &pos) != SUCCESS || + !data || data == &val || + (Z_TYPE_PP(data) == IS_ARRAY && + Z_ARRVAL_PP(data)->nApplyCount > 1)) + { + msgpack_pack_nil(buf); + } + else + { + if (Z_TYPE_PP(data) == IS_ARRAY) + { + Z_ARRVAL_PP(data)->nApplyCount++; + } + + msgpack_serialize_zval(buf, *data, var_hash TSRMLS_CC); + + if (Z_TYPE_PP(data) == IS_ARRAY) + { + Z_ARRVAL_PP(data)->nApplyCount--; + } + } + } + } +} + +inline static void msgpack_serialize_object( + smart_str *buf, zval *val, HashTable *var_hash, + char* class_name, zend_uint name_len, zend_bool incomplete_class TSRMLS_DC) +{ + zval *retval_ptr = NULL; + zval fname; + int res; + zend_class_entry *ce = NULL; + + if (Z_OBJ_HT_P(val)->get_class_entry) + { + ce = Z_OBJCE_P(val); + } + + if (ce && ce->serialize != NULL) + { + unsigned char *serialized_data = NULL; + zend_uint serialized_length; + + if (ce->serialize( + val, &serialized_data, &serialized_length, + (zend_serialize_data *)var_hash TSRMLS_CC) == SUCCESS && + !EG(exception)) + { + /* has custom handler */ + msgpack_pack_map(buf, 2); + + msgpack_pack_nil(buf); + msgpack_pack_long(buf, MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT); + + msgpack_serialize_string(buf, ce->name, ce->name_length); + msgpack_pack_raw(buf, serialized_length); + msgpack_pack_raw_body(buf, serialized_data, serialized_length); + } + else + { + msgpack_pack_nil(buf); + } + + if (serialized_data) + { + efree(serialized_data); + } + + return; + } + + if (ce && ce != PHP_IC_ENTRY && + zend_hash_exists(&ce->function_table, "__sleep", sizeof("__sleep"))) + { + INIT_PZVAL(&fname); + ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 0); + res = call_user_function_ex(CG(function_table), &val, &fname, + &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); + if (res == SUCCESS && !EG(exception)) + { + if (retval_ptr) + { + if (HASH_OF(retval_ptr)) + { + msgpack_serialize_class( + buf, val, retval_ptr, var_hash, + class_name, name_len, incomplete_class TSRMLS_CC); + } + else + { + if (MSGPACK_G(error_display)) + { + zend_error(E_NOTICE, + "[msgpack] (msgpack_serialize_object) " + "__sleep should return an array only " + "containing the names of instance-variables " + "to serialize"); + } + msgpack_pack_nil(buf); + } + zval_ptr_dtor(&retval_ptr); + } + return; + } + } + + if (retval_ptr) + { + zval_ptr_dtor(&retval_ptr); + } + + msgpack_serialize_array( + buf, val, var_hash, true, + class_name, name_len, incomplete_class TSRMLS_CC); +} + +void msgpack_serialize_zval( + smart_str *buf, zval *val, HashTable *var_hash TSRMLS_DC) +{ + ulong *var_already; + + if (MSGPACK_G(php_only) && + var_hash && + msgpack_var_add( + var_hash, val, (void *)&var_already TSRMLS_CC) == FAILURE) + { + if (Z_ISREF_P(val) && Z_TYPE_P(val) == IS_ARRAY) + { + msgpack_pack_map(buf, 2); + + msgpack_pack_nil(buf); + msgpack_pack_long(buf, MSGPACK_SERIALIZE_TYPE_RECURSIVE); + + msgpack_pack_long(buf, 0); + msgpack_pack_long(buf, *var_already); + + return; + } + else if (Z_TYPE_P(val) == IS_OBJECT) + { + msgpack_pack_map(buf, 2); + + msgpack_pack_nil(buf); + msgpack_pack_long(buf, MSGPACK_SERIALIZE_TYPE_RECURSIVE); + + msgpack_pack_long(buf, 0); + msgpack_pack_long(buf, *var_already); + + return; + } + } + + switch (Z_TYPE_P(val)) + { + case IS_NULL: + msgpack_pack_nil(buf); + break; + case IS_BOOL: + if (Z_BVAL_P(val)) + { + msgpack_pack_true(buf); + } + else + { + msgpack_pack_false(buf); + } + break; + case IS_LONG: + msgpack_pack_long(buf, Z_LVAL_P(val)); + break; + case IS_DOUBLE: + { + double dbl = Z_DVAL_P(val); + msgpack_pack_double(buf, dbl); + } + break; + case IS_STRING: + msgpack_serialize_string( + buf, Z_STRVAL_P(val), Z_STRLEN_P(val)); + break; + case IS_ARRAY: + msgpack_serialize_array( + buf, val, var_hash, false, NULL, 0, 0 TSRMLS_CC); + break; + case IS_OBJECT: + { + PHP_CLASS_ATTRIBUTES; + PHP_SET_CLASS_ATTRIBUTES(val); + + msgpack_serialize_object( + buf, val, var_hash, class_name, name_len, + incomplete_class TSRMLS_CC); + + PHP_CLEANUP_CLASS_ATTRIBUTES(); + } + break; + default: + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (php_msgpack_serialize) " + "type is unsupported, encoded as null"); + } + msgpack_pack_nil(buf); + break; + } + return; +} diff --git a/php/msgpack_pack.h b/php/msgpack_pack.h new file mode 100644 index 00000000..16f3e7bc --- /dev/null +++ b/php/msgpack_pack.h @@ -0,0 +1,18 @@ + +#ifndef MSGPACK_PACK_H +#define MSGPACK_PACK_H + +#include "ext/standard/php_smart_str.h" + +enum msgpack_serialize_type +{ + MSGPACK_SERIALIZE_TYPE_NONE = 0, + MSGPACK_SERIALIZE_TYPE_REFERENCE = 1, + MSGPACK_SERIALIZE_TYPE_RECURSIVE, + MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT, +}; + +void msgpack_serialize_zval( + smart_str *buf, zval *val, HashTable *var_hash TSRMLS_DC); + +#endif diff --git a/php/msgpack_unpack.c b/php/msgpack_unpack.c new file mode 100644 index 00000000..f3b610d2 --- /dev/null +++ b/php/msgpack_unpack.c @@ -0,0 +1,703 @@ + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/php_incomplete_class.h" + +#include "php_msgpack.h" +#include "msgpack_pack.h" +#include "msgpack_unpack.h" + +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3) +# define Z_ADDREF_PP(ppz) ZVAL_ADDREF(*(ppz)) +# define Z_SET_ISREF_PP(ppz) (*(ppz))->is_ref = 1 +# define Z_UNSET_ISREF_PP(ppz) (*(ppz))->is_ref = 0 +#endif + +#define VAR_ENTRIES_MAX 1024 + +typedef struct +{ + zval *data[VAR_ENTRIES_MAX]; + long used_slots; + long value_slots; + long access_slots[VAR_ENTRIES_MAX]; + bool alloc_slots[VAR_ENTRIES_MAX]; + void *next; +} var_entries; + +#define MSGPACK_UNSERIALIZE_ALLOC(_unpack) \ + if (_unpack->deps <= 0) { \ + *obj = _unpack->retval; \ + msgpack_var_push(_unpack->var_hash, obj, true, false); \ + } else { \ + ALLOC_INIT_ZVAL(*obj); \ + msgpack_var_push(_unpack->var_hash, obj, false, true); \ + } + +#define MSGPACK_UNSERIALIZE_ALLOC_VALUE(_unpack) \ + if (_unpack->deps <= 0) { \ + *obj = _unpack->retval; \ + msgpack_var_push(_unpack->var_hash, obj, true, false); \ + } else { \ + ALLOC_INIT_ZVAL(*obj); \ + msgpack_var_push(_unpack->var_hash, obj, true, true); \ + } + +#define MSGPACK_UNSERIALIZE_PUSH_ITEM(_unpack, _count, _val) \ + msgpack_var_alloc(_unpack->var_hash, _count); \ + if (Z_TYPE_P(_val) != IS_ARRAY && Z_TYPE_P(_val) != IS_OBJECT) { \ + msgpack_var_push(_unpack->var_hash, &_val, true, false); \ + } + +#define MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack) \ + long deps = _unpack->deps - 1; \ + _unpack->stack[deps]--; \ + if (_unpack->stack[deps] == 0) { \ + _unpack->deps--; \ + } + +#define MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(_unpack, _key, _val) \ + zval_ptr_dtor(&_key); \ + zval_ptr_dtor(&_val); \ + msgpack_var_alloc(_unpack->var_hash, 2); \ + MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack); + + +inline static void msgpack_var_push( + php_unserialize_data_t *var_hashx, zval **rval, bool value, bool alloc) +{ + var_entries *var_hash, *prev = NULL; + + if (!var_hashx) + { + return; + } + + var_hash = var_hashx->first; + + while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) + { + prev = var_hash; + var_hash = var_hash->next; + } + + if (!var_hash) + { + var_hash = emalloc(sizeof(var_entries)); + var_hash->used_slots = 0; + var_hash->value_slots = 0; + var_hash->next = 0; + + if (!var_hashx->first) + { + var_hashx->first = var_hash; + } + else + { + prev->next = var_hash; + } + } + + var_hash->alloc_slots[var_hash->used_slots] = alloc; + + if (value) + { + var_hash->access_slots[var_hash->value_slots++] = var_hash->used_slots; + } + + var_hash->data[var_hash->used_slots++] = *rval; +} + +inline static void msgpack_var_alloc( + php_unserialize_data_t *var_hashx, long count) +{ + long i; + var_entries *var_hash = var_hashx->first; + + while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) + { + var_hash = var_hash->next; + } + + if (!var_hash || count <= 0) + { + return; + } + + for (i = var_hash->used_slots - 1; i >= 0; i--) + { + if (var_hash->alloc_slots[i]) + { + var_hash->alloc_slots[i] = false; + if (--count <= 0) + { + break; + } + } + } +} + +inline static int msgpack_var_access( + php_unserialize_data_t *var_hashx, long id, zval ***store) +{ + var_entries *var_hash = var_hashx->first; + + while (id >= VAR_ENTRIES_MAX && + var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) + { + var_hash = var_hash->next; + id -= VAR_ENTRIES_MAX; + } + + if (!var_hash) + { + return !SUCCESS; + } + + if (id < 0 || id >= var_hash->value_slots) + { + return !SUCCESS; + } + + id = var_hash->access_slots[id]; + + if (id < 0 || id >= var_hash->used_slots) + { + return !SUCCESS; + } + + *store = &var_hash->data[id]; + + return SUCCESS; +} + +inline static zend_class_entry* msgpack_unserialize_class( + zval **container, char *class_name, size_t name_len) +{ + zend_class_entry *ce, **pce; + bool incomplete_class = false; + zval *user_func, *retval_ptr, **args[1], *arg_func_name; + TSRMLS_FETCH(); + + do + { + /* Try to find class directly */ + if (zend_lookup_class(class_name, name_len, &pce TSRMLS_CC) == SUCCESS) + { + ce = *pce; + break; + } + + /* Check for unserialize callback */ + if ((PG(unserialize_callback_func) == NULL) || + (PG(unserialize_callback_func)[0] == '\0')) + { + incomplete_class = 1; + ce = PHP_IC_ENTRY; + break; + } + + /* Call unserialize callback */ + ALLOC_INIT_ZVAL(user_func); + ZVAL_STRING(user_func, PG(unserialize_callback_func), 1); + args[0] = &arg_func_name; + ALLOC_INIT_ZVAL(arg_func_name); + ZVAL_STRING(arg_func_name, class_name, 1); + if (call_user_function_ex( + CG(function_table), NULL, user_func, &retval_ptr, + 1, args, 0, NULL TSRMLS_CC) != SUCCESS) + { + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (msgpack_unserialize_class) " + "defined (%s) but not found", class_name); + } + + incomplete_class = 1; + ce = PHP_IC_ENTRY; + zval_ptr_dtor(&user_func); + zval_ptr_dtor(&arg_func_name); + break; + } + if (retval_ptr) + { + zval_ptr_dtor(&retval_ptr); + } + + /* The callback function may have defined the class */ + if (zend_lookup_class(class_name, name_len, &pce TSRMLS_CC) == SUCCESS) + { + ce = *pce; + } + else + { + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (msgpack_unserialize_class) " + "Function %s() hasn't defined the class " + "it was called for", class_name); + } + + incomplete_class = true; + ce = PHP_IC_ENTRY; + } + + zval_ptr_dtor(&user_func); + zval_ptr_dtor(&arg_func_name); + } + while(0); + + if (EG(exception)) + { + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (msgpack_unserialize_class) " + "Exception error"); + } + + return NULL; + } + + object_init_ex(*container, ce); + + /* store incomplete class name */ + if (incomplete_class) + { + php_store_class_name(*container, class_name, name_len); + } + + return ce; +} + +void msgpack_unserialize_var_init(php_unserialize_data_t *var_hashx) +{ + var_hashx->first = 0; + var_hashx->first_dtor = 0; +} + +void msgpack_unserialize_var_destroy(php_unserialize_data_t *var_hashx) +{ + void *next; + long i; + var_entries *var_hash = var_hashx->first; + + while (var_hash) + { + for (i = 0; i < var_hash->used_slots; i++) + { + if (var_hash->alloc_slots[i] && var_hash->data[i]) + { + zval_ptr_dtor(&var_hash->data[i]); + } + } + + next = var_hash->next; + efree(var_hash); + var_hash = next; + } + + /* + var_hash = var_hashx->first_dtor; + + while (var_hash) + { + for (i = 0; i < var_hash->used_slots; i++) + { + zval_ptr_dtor(&var_hash->data[i]); + } + next = var_hash->next; + efree(var_hash); + var_hash = next; + } + */ +} + +void msgpack_unserialize_init(msgpack_unserialize_data *unpack) +{ + unpack->deps = 0; + unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; +} + +int msgpack_unserialize_uint8( + msgpack_unserialize_data *unpack, uint8_t data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_LONG(*obj, data); + + return 0; +} + +int msgpack_unserialize_uint16( + msgpack_unserialize_data *unpack, uint16_t data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_LONG(*obj, data); + + return 0; +} + +int msgpack_unserialize_uint32( + msgpack_unserialize_data *unpack, uint32_t data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_LONG(*obj, data); + + return 0; +} + +int msgpack_unserialize_uint64( + msgpack_unserialize_data *unpack, uint64_t data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_LONG(*obj, data); + + return 0; +} + +int msgpack_unserialize_int8( + msgpack_unserialize_data *unpack, int8_t data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_LONG(*obj, data); + + return 0; +} + +int msgpack_unserialize_int16( + msgpack_unserialize_data *unpack, int16_t data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_LONG(*obj, data); + + return 0; +} + +int msgpack_unserialize_int32( + msgpack_unserialize_data *unpack, int32_t data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_LONG(*obj, data); + + return 0; +} + +int msgpack_unserialize_int64( + msgpack_unserialize_data *unpack, int64_t data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_LONG(*obj, data); + + return 0; +} + +int msgpack_unserialize_float( + msgpack_unserialize_data *unpack, float data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_DOUBLE(*obj, data); + + return 0; +} + +int msgpack_unserialize_double( + msgpack_unserialize_data *unpack, double data, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_DOUBLE(*obj, data); + + return 0; +} + +int msgpack_unserialize_nil(msgpack_unserialize_data *unpack, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_NULL(*obj); + + return 0; +} + +int msgpack_unserialize_true(msgpack_unserialize_data *unpack, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_BOOL(*obj, 1); + + return 0; +} + +int msgpack_unserialize_false(msgpack_unserialize_data *unpack, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + ZVAL_BOOL(*obj, 0); + + return 0; +} + +int msgpack_unserialize_raw( + msgpack_unserialize_data *unpack, const char* base, + const char* data, unsigned int len, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC(unpack); + + if (len == 0) + { + ZVAL_STRINGL(*obj, "", 0, 1); + } + else + { + ZVAL_STRINGL(*obj, data, len, 1); + } + + return 0; +} + +int msgpack_unserialize_array( + msgpack_unserialize_data *unpack, unsigned int count, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC_VALUE(unpack); + + array_init(*obj); + + unpack->stack[unpack->deps++] = count; + + return 0; +} + +int msgpack_unserialize_array_item( + msgpack_unserialize_data *unpack, zval **container, zval *obj) +{ + MSGPACK_UNSERIALIZE_PUSH_ITEM(unpack, 1, obj); + + add_next_index_zval(*container, obj); + + MSGPACK_UNSERIALIZE_FINISH_ITEM(unpack); + + return 0; +} + +int msgpack_unserialize_map( + msgpack_unserialize_data *unpack, unsigned int count, zval **obj) +{ + MSGPACK_UNSERIALIZE_ALLOC_VALUE(unpack); + + unpack->stack[unpack->deps++] = count; + + unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; + + return 0; +} + +int msgpack_unserialize_map_item( + msgpack_unserialize_data *unpack, zval **container, zval *key, zval *val) +{ + TSRMLS_FETCH(); + + if (MSGPACK_G(php_only)) + { + if (Z_TYPE_P(key) == IS_NULL) + { + unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; + + if (Z_TYPE_P(val) == IS_LONG) + { + switch (Z_LVAL_P(val)) + { + case MSGPACK_SERIALIZE_TYPE_REFERENCE: + Z_SET_ISREF_PP(container); + break; + case MSGPACK_SERIALIZE_TYPE_RECURSIVE: + unpack->type = MSGPACK_SERIALIZE_TYPE_RECURSIVE; + break; + case MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT: + unpack->type = MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT; + break; + default: + break; + } + } + else if (Z_TYPE_P(val) == IS_STRING) + { + zend_class_entry *ce = msgpack_unserialize_class( + container, Z_STRVAL_P(val), Z_STRLEN_P(val)); + + if (ce == NULL) + { + MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); + + return 0; + } + } + + MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); + + return 0; + } + else if (unpack->type == MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT) + { + unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; + + zend_class_entry *ce = msgpack_unserialize_class( + container, Z_STRVAL_P(key), Z_STRLEN_P(key)); + + if (ce == NULL) + { + MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); + + return 0; + } + + /* implementing Serializable */ + if (ce->unserialize == NULL) + { + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (msgpack_unserialize_map_item) " + "Class %s has no unserializer", ce->name); + } + + MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); + + return 0; + } + + ce->unserialize( + container, ce, + (const unsigned char *)Z_STRVAL_P(val), Z_STRLEN_P(val) + 1, + NULL TSRMLS_CC); + + MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); + + return 0; + } + else if (unpack->type == MSGPACK_SERIALIZE_TYPE_RECURSIVE) + { + zval **rval; + + unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; + + if (msgpack_var_access( + unpack->var_hash, Z_LVAL_P(val) - 1, &rval) != SUCCESS) + { + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (msgpack_unserialize_map_item) " + "Invalid references value: %ld", + Z_LVAL_P(val) - 1); + } + + MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); + + return 0; + } + + if (container != NULL) + { + zval_ptr_dtor(container); + } + + *container = *rval; + + Z_ADDREF_PP(container); + + MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); + + return 0; + } + } + + MSGPACK_UNSERIALIZE_PUSH_ITEM(unpack, 2, val); + + if (Z_TYPE_PP(container) != IS_ARRAY && Z_TYPE_PP(container) != IS_OBJECT) + { + array_init(*container); + } + + switch (Z_TYPE_P(key)) + { + case IS_LONG: + if (zend_hash_index_update( + HASH_OF(*container), Z_LVAL_P(key), &val, + sizeof(val), NULL) == FAILURE) + { + zval_ptr_dtor(&val); + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (msgpack_unserialize_map_item) " + "illegal offset type, skip this decoding"); + } + } + break; + case IS_STRING: + if (zend_symtable_update( + HASH_OF(*container), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, + &val, sizeof(val), NULL) == FAILURE) + { + zval_ptr_dtor(&val); + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (msgpack_unserialize_map_item) " + "illegal offset type, skip this decoding"); + } + } + break; + default: + zval_ptr_dtor(&val); + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (msgpack_unserialize_map_item) " + "illegal offset type, skip this decoding"); + } + break; + } + + zval_ptr_dtor(&key); + + long deps = unpack->deps - 1; + unpack->stack[deps]--; + if (unpack->stack[deps] == 0) + { + unpack->deps--; + + /* wakeup */ + if (MSGPACK_G(php_only) && + Z_TYPE_PP(container) == IS_OBJECT && + Z_OBJCE_PP(container) != PHP_IC_ENTRY && + zend_hash_exists( + &Z_OBJCE_PP(container)->function_table, + "__wakeup", sizeof("__wakeup"))) + { + zval f, *h = NULL; + + INIT_PZVAL(&f); + ZVAL_STRINGL(&f, "__wakeup", sizeof("__wakeup") - 1, 0); + call_user_function_ex( + CG(function_table), container, &f, &h, 0, 0, 1, NULL TSRMLS_CC); + if (h) + { + zval_ptr_dtor(&h); + } + } + } + + return 0; +} diff --git a/php/msgpack_unpack.h b/php/msgpack_unpack.h new file mode 100644 index 00000000..da963ebf --- /dev/null +++ b/php/msgpack_unpack.h @@ -0,0 +1,129 @@ + +#ifndef MSGPACK_UNPACK_H +#define MSGPACK_UNPACK_H + +#include "ext/standard/php_var.h" + +#define MSGPACK_EMBED_STACK_SIZE 1024 + +#include "msgpack/unpack_define.h" + +typedef enum +{ + MSGPACK_UNPACK_SUCCESS = 2, + MSGPACK_UNPACK_EXTRA_BYTES = 1, + MSGPACK_UNPACK_CONTINUE = 0, + MSGPACK_UNPACK_PARSE_ERROR = -1, +} msgpack_unpack_return; + +typedef struct { + zval *retval; + long deps; + php_unserialize_data_t *var_hash; + long stack[MSGPACK_EMBED_STACK_SIZE]; + int type; +} msgpack_unserialize_data; + +void msgpack_unserialize_var_init(php_unserialize_data_t *var_hashx); +void msgpack_unserialize_var_destroy(php_unserialize_data_t *var_hashx); + +void msgpack_unserialize_init(msgpack_unserialize_data *unpack); + +int msgpack_unserialize_uint8( + msgpack_unserialize_data *unpack, uint8_t data, zval **obj); +int msgpack_unserialize_uint16( + msgpack_unserialize_data *unpack, uint16_t data, zval **obj); +int msgpack_unserialize_uint32( + msgpack_unserialize_data *unpack, uint32_t data, zval **obj); +int msgpack_unserialize_uint64( + msgpack_unserialize_data *unpack, uint64_t data, zval **obj); +int msgpack_unserialize_int8( + msgpack_unserialize_data *unpack, int8_t data, zval **obj); +int msgpack_unserialize_int16( + msgpack_unserialize_data *unpack, int16_t data, zval **obj); +int msgpack_unserialize_int32( + msgpack_unserialize_data *unpack, int32_t data, zval **obj); +int msgpack_unserialize_int64( + msgpack_unserialize_data *unpack, int64_t data, zval **obj); +int msgpack_unserialize_float( + msgpack_unserialize_data *unpack, float data, zval **obj); +int msgpack_unserialize_double( + msgpack_unserialize_data *unpack, double data, zval **obj); +int msgpack_unserialize_nil(msgpack_unserialize_data *unpack, zval **obj); +int msgpack_unserialize_true(msgpack_unserialize_data *unpack, zval **obj); +int msgpack_unserialize_false(msgpack_unserialize_data *unpack, zval **obj); +int msgpack_unserialize_raw( + msgpack_unserialize_data *unpack, const char* base, const char* data, + unsigned int len, zval **obj); +int msgpack_unserialize_array( + msgpack_unserialize_data *unpack, unsigned int count, zval **obj); +int msgpack_unserialize_array_item( + msgpack_unserialize_data *unpack, zval **container, zval *obj); +int msgpack_unserialize_map( + msgpack_unserialize_data *unpack, unsigned int count, zval **obj); +int msgpack_unserialize_map_item( + msgpack_unserialize_data *unpack, zval **container, zval *key, zval *val); + +/* template functions */ +#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 unpack_user msgpack_unserialize_data +#define msgpack_unpack_user msgpack_unserialize_data + +struct template_context; +typedef struct template_context msgpack_unpack_t; + +static void template_init(msgpack_unpack_t* unpack); +static msgpack_unpack_object template_data(msgpack_unpack_t* unpack); +static int template_execute( + msgpack_unpack_t* unpack, const char* data, size_t len, size_t* off); + +static inline msgpack_unpack_object template_callback_root(unpack_user* user) +{ + msgpack_unserialize_init(user); + return NULL; +} + +#define template_callback_uint8(user, data, obj) \ + msgpack_unserialize_uint8(user, data, obj) +#define template_callback_uint16(user, data, obj) \ + msgpack_unserialize_uint16(user, data, obj) +#define template_callback_uint32(user, data, obj) \ + msgpack_unserialize_uint32(user, data, obj) +#define template_callback_uint64(user, data, obj) \ + msgpack_unserialize_uint64(user, data, obj) +#define template_callback_int8(user, data, obj) \ + msgpack_unserialize_int8(user, data, obj) +#define template_callback_int16(user, data, obj) \ + msgpack_unserialize_int16(user, data, obj) +#define template_callback_int32(user, data, obj) \ + msgpack_unserialize_int32(user, data, obj) +#define template_callback_int64(user, data, obj) \ + msgpack_unserialize_int64(user, data, obj) +#define template_callback_float(user, data, obj) \ + msgpack_unserialize_float(user, data, obj) +#define template_callback_double(user, data, obj) \ + msgpack_unserialize_double(user, data, obj) +#define template_callback_nil(user, obj) \ + msgpack_unserialize_nil(user, obj) +#define template_callback_true(user, obj) \ + msgpack_unserialize_true(user, obj) +#define template_callback_false(user, obj) \ + msgpack_unserialize_false(user, obj) +#define template_callback_raw(user, base, data, len, obj) \ + msgpack_unserialize_raw(user, base, data, len, obj) +#define template_callback_array(user, count, obj) \ + msgpack_unserialize_array(user, count, obj) +#define template_callback_array_item(user, container, obj) \ + msgpack_unserialize_array_item(user, container, obj) +#define template_callback_map(user, count, obj) \ + msgpack_unserialize_map(user, count, obj) +#define template_callback_map_item(user, container, key, val) \ + msgpack_unserialize_map_item(user, container, key, val) + +#include "msgpack/unpack_template.h" + +#endif diff --git a/php/package.xml b/php/package.xml new file mode 100644 index 00000000..6172a4c5 --- /dev/null +++ b/php/package.xml @@ -0,0 +1,125 @@ + + + msgpack + pecl.php.net + PHP extension for interfacing with MessagePack + This extension provide API for communicating with MessagePack serialization. + + Advect + advect + advect@gmail.com + yes + + 2010-09-28 + + + 0.3.0 + 0.3.0 + + + beta + beta + + New BSD + Initial release. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5.2.0 + + + 1.4.3 + + + + msgpack + + diff --git a/php/php-msgpack.spec b/php/php-msgpack.spec new file mode 100644 index 00000000..6a98288b --- /dev/null +++ b/php/php-msgpack.spec @@ -0,0 +1,59 @@ +%define php_apiver %((echo 0; php -i 2>/dev/null | sed -n 's/^PHP API => //p') | tail -1) +%{!?php_extdir: %{expand: %%define php_extdir %(php-config --extension-dir)}} + +Summary: PHP extension for interfacing with MessagePack +Name: php-msgpack +Version: 0.3.0 +Release: 1%{?dist} +Source: php-msgpack-%{version}.tar.gz +License: New BSD License +Group: Development/Libraries +Packager: advect +Provides: php-pecl-msgpack +BuildRoot: %{_tmppath}/%{name}-%{version}-root +BuildRequires: php-devel +Requires: msgpack +%if 0%{?php_zend_api} +Requires: php(zend-abi) = %{php_zend_api} +Requires: php(api) = %{php_core_api} +%else +Requires: php-api = %{php_apiver} +%endif + +%description +PHP extension for interfacing with MessagePack. + +%prep +%setup -q -n php-msgpack + +%build +phpize +%configure +%{__make} + +%install +%makeinstall INSTALL_ROOT=%{buildroot} + +%{__install} -d %{buildroot}%{_sysconfdir}/php.d +%{__cat} > %{buildroot}%{_sysconfdir}/php.d/msgpack.ini <= 4 +# define PHP_MSGPACK_API __attribute__ ((visibility("default"))) #else -#define PHP_MSGPACK_API +# define PHP_MSGPACK_API #endif #ifdef ZTS #include "TSRM.h" #endif -PHP_MINIT_FUNCTION(msgpack); -PHP_MSHUTDOWN_FUNCTION(msgpack); -PHP_RINIT_FUNCTION(msgpack); -PHP_RSHUTDOWN_FUNCTION(msgpack); -PHP_MINFO_FUNCTION(msgpack); - -PHP_FUNCTION(msgpack_pack); -PHP_FUNCTION(msgpack_unpack); -PHP_FUNCTION(msgpack_unpack_limit); - -PHP_METHOD(msgpack, initialize); -PHP_METHOD(msgpack, execute); -PHP_METHOD(msgpack, execute_limit); -PHP_METHOD(msgpack, finished); -PHP_METHOD(msgpack, data); - -static zend_class_entry *msgpack_ce; - -/* - Declare any global variables you may need between the BEGIN - and END macros here: - ZEND_BEGIN_MODULE_GLOBALS(msgpack) - long global_value; - char *global_string; + zend_bool error_display; + zend_bool php_only; ZEND_END_MODULE_GLOBALS(msgpack) -*/ -/* In every utility function you add that needs to use variables - in php_msgpack_globals, call TSRMLS_FETCH(); after declaring other - variables used by that function, or better yet, pass in TSRMLS_CC - after the last function argument and declare your utility function - with TSRMLS_DC after the last declared argument. Always refer to - the globals in your function as MSGPACK_G(variable). You are - encouraged to rename these macros something shorter, see - examples in any other php module directory. -*/ +ZEND_DECLARE_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 -#endif /* PHP_MSGPACK_H */ +PHP_MSGPACK_API void php_msgpack_serialize( + smart_str *buf, zval *val TSRMLS_DC); +PHP_MSGPACK_API void php_msgpack_unserialize( + zval *return_value, char *str, size_t str_len TSRMLS_DC); - -/* - * 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 - */ +#endif /* PHP_MSGPACK_H */ diff --git a/php/test_normal.php b/php/test_normal.php old mode 100755 new mode 100644 diff --git a/php/test_streaming.php b/php/test_streaming.php old mode 100755 new mode 100644 index 8f89f4c6..f2f470e3 --- a/php/test_streaming.php +++ b/php/test_streaming.php @@ -4,8 +4,7 @@ $msgs = array(pack("C*", 0x93, 0x01, 0x02, 0x03, 0x92), pack("C*", 0x03, 0x09, 0x04)); // streaming deserialize - $unpacker = new MessagePack(); - $unpacker->initialize(); + $unpacker = new MessagePackUnpacker(); $buffer = ""; $nread = 0; @@ -13,13 +12,11 @@ $buffer = $buffer . $msg; while(true){ - $nread = $unpacker->execute($buffer, $nread); - - if($unpacker->finished()){ + if($unpacker->execute($buffer, $nread)){ $msg = $unpacker->data(); var_dump($msg); - $unpacker->initialize(); + $unpacker->reset(); $buffer = substr($buffer, $nread); $nread = 0; diff --git a/php/tests/001.phpt b/php/tests/001.phpt new file mode 100644 index 00000000..840ae461 --- /dev/null +++ b/php/tests/001.phpt @@ -0,0 +1,10 @@ +--TEST-- +Check for msgpack presence +--SKIPIF-- + +--FILE-- + +--EXPECT-- +msgpack extension is available diff --git a/php/tests/002.phpt b/php/tests/002.phpt new file mode 100644 index 00000000..75b9488e --- /dev/null +++ b/php/tests/002.phpt @@ -0,0 +1,26 @@ +--TEST-- +Check for null serialisation +--SKIPIF-- +--FILE-- + +--EXPECT-- +null +c0 +NULL +OK diff --git a/php/tests/003.phpt b/php/tests/003.phpt new file mode 100644 index 00000000..8c85f904 --- /dev/null +++ b/php/tests/003.phpt @@ -0,0 +1,31 @@ +--TEST-- +Check for bool serialisation +--SKIPIF-- +--FILE-- + +--EXPECT-- +bool true +c3 +bool(true) +OK +bool false +c2 +bool(false) +OK diff --git a/php/tests/004.phpt b/php/tests/004.phpt new file mode 100644 index 00000000..8c352eca --- /dev/null +++ b/php/tests/004.phpt @@ -0,0 +1,56 @@ +--TEST-- +Check for integer serialisation +--SKIPIF-- +--FILE-- + +--EXPECT-- +zero: 0 +00 +int(0) +OK +small: 1 +01 +int(1) +OK +small: -1 +ff +int(-1) +OK +medium: 1000 +cd03e8 +int(1000) +OK +medium: -1000 +d1fc18 +int(-1000) +OK +large: 100000 +ce000186a0 +int(100000) +OK +large: -100000 +d2fffe7960 +int(-100000) +OK diff --git a/php/tests/005.phpt b/php/tests/005.phpt new file mode 100644 index 00000000..2156ffad --- /dev/null +++ b/php/tests/005.phpt @@ -0,0 +1,26 @@ +--TEST-- +Check for double serialisation +--SKIPIF-- +--FILE-- + +--EXPECT-- +double: 123.456 +cb405edd2f1a9fbe77 +float(123.456) +OK diff --git a/php/tests/006.phpt b/php/tests/006.phpt new file mode 100644 index 00000000..68323553 --- /dev/null +++ b/php/tests/006.phpt @@ -0,0 +1,31 @@ +--TEST-- +Check for simple string serialization +--SKIPIF-- +--FILE-- + +--EXPECT-- +empty: "" +a0 +string(0) "" +OK +string: "foobar" +a6666f6f626172 +string(6) "foobar" +OK diff --git a/php/tests/007.phpt b/php/tests/007.phpt new file mode 100644 index 00000000..db41185b --- /dev/null +++ b/php/tests/007.phpt @@ -0,0 +1,72 @@ +--TEST-- +Check for simple array serialization +--SKIPIF-- +--FILE-- + +--EXPECT-- +empty array: +90 +array(0) { +} +OK +array(1, 2, 3) +83000101020203 +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(array(1, 2, 3), arr... +83008300010102020301830004010502060283000701080209 +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK diff --git a/php/tests/008.phpt b/php/tests/008.phpt new file mode 100644 index 00000000..661c1cd6 --- /dev/null +++ b/php/tests/008.phpt @@ -0,0 +1,61 @@ +--TEST-- +Check for array+string serialization +--SKIPIF-- +--FILE-- + 1, "two" => 2))', array("one" => 1, "two" => 2)); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek")); +test('array("" => "empty")', array("" => "empty")); +?> +--EXPECT-- +array("foo", "foo", "foo") +8300a3666f6f01a3666f6f02a3666f6f +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array("one" => 1, "two" => 2)) +82a36f6e6501a374776f02 +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array("kek" => "lol", "lol" => "kek") +82a36b656ba36c6f6ca36c6f6ca36b656b +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array("" => "empty") +81a0a5656d707479 +array(1) { + [""]=> + string(5) "empty" +} +OK diff --git a/php/tests/009.phpt b/php/tests/009.phpt new file mode 100644 index 00000000..9992988a --- /dev/null +++ b/php/tests/009.phpt @@ -0,0 +1,119 @@ +--TEST-- +Check for reference serialization +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- + + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(&$a, &$a) +820082c00100a3666f6f0182c0020002 +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +cyclic +810082c0010082c0010082c0020002 +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} diff --git a/php/tests/009b.phpt b/php/tests/009b.phpt new file mode 100644 index 00000000..7765d62a --- /dev/null +++ b/php/tests/009b.phpt @@ -0,0 +1,101 @@ +--TEST-- +Check for reference serialization +--SKIPIF-- + + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(&$a, &$a) +820082c00100a3666f6f0182c0020002 +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +cyclic +810082c0010082c0010082c0020002 +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} diff --git a/php/tests/010.phpt b/php/tests/010.phpt new file mode 100644 index 00000000..9eb77a61 --- /dev/null +++ b/php/tests/010.phpt @@ -0,0 +1,49 @@ +--TEST-- +Array test +--SKIPIF-- +--FILE-- + array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) +); + +test('array', $a, false); +?> +--EXPECT-- +array +82a16182a162a163a164a165a16681a167a168 +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK diff --git a/php/tests/012.phpt b/php/tests/012.phpt new file mode 100644 index 00000000..8121c960 --- /dev/null +++ b/php/tests/012.phpt @@ -0,0 +1,48 @@ +--TEST-- +Object test +--SKIPIF-- +--FILE-- +a = $a; + $this->b = $b; + $this->c = $c; + } +} + +$o = new Obj(1, 2, 3); + + +test('object', $o, false); +?> +--EXPECTF-- +object +84c0a34f626aa16101a4002a006202a6004f626a006303 +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK diff --git a/php/tests/013.phpt b/php/tests/013.phpt new file mode 100644 index 00000000..73f7d335 --- /dev/null +++ b/php/tests/013.phpt @@ -0,0 +1,54 @@ +--TEST-- +Object-Array test +--SKIPIF-- +--FILE-- +a = $a; + $this->b = $b; + } +} + +$o = array(new Obj(1, 2), new Obj(3, 4)); + + +test('object', $o, false); +?> +--EXPECTF-- +object +820083c0a34f626aa16101a162020183c0a34f626aa16103a16204 +array(2) { + [0]=> + object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } + [1]=> + object(Obj)#%d (2) { + ["a"]=> + int(3) + ["b"]=> + int(4) + } +} +OK diff --git a/php/tests/014.phpt b/php/tests/014.phpt new file mode 100644 index 00000000..b9c7c671 --- /dev/null +++ b/php/tests/014.phpt @@ -0,0 +1,54 @@ +--TEST-- +Object-Reference test +--SKIPIF-- +--FILE-- +a = $a; + $this->b = $b; + } +} + +$o = new Obj(1, 2); +$a = array(&$o, &$o); + +test('object', $a, false); +?> +--EXPECTF-- +object +820084c001c0a34f626aa16101a162020182c0020002 +array(2) { + [0]=> + &object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } + [1]=> + &object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} +OK diff --git a/php/tests/015.phpt b/php/tests/015.phpt new file mode 100644 index 00000000..634a8b1a --- /dev/null +++ b/php/tests/015.phpt @@ -0,0 +1,58 @@ +--TEST-- +Check for serialization handler +--SKIPIF-- +--FILE-- + +--EXPECT-- +2 +82c001a3666f6f02 +array(1) { + ["foo"]=> + int(2) +} diff --git a/php/tests/015b.phpt b/php/tests/015b.phpt new file mode 100644 index 00000000..7ced3126 --- /dev/null +++ b/php/tests/015b.phpt @@ -0,0 +1,58 @@ +--TEST-- +Check for serialization handler, ini-directive +--SKIPIF-- +--INI-- +session.serialize_handler=msgpack +--FILE-- + +--EXPECT-- +2 +82c001a3666f6f02 +array(1) { + ["foo"]=> + int(2) +} diff --git a/php/tests/016.phpt b/php/tests/016.phpt new file mode 100644 index 00000000..f8f4779e --- /dev/null +++ b/php/tests/016.phpt @@ -0,0 +1,60 @@ +--TEST-- +Object test, __sleep +--SKIPIF-- +--FILE-- +a = $a; + $this->b = $b; + $this->c = $c; + $this->d = $d; + } + + function __sleep() { + return array('a', 'b', 'c'); + } + +# function __wakeup() { +# $this->d = $this->a + $this->b + $this->c; +# } +} + +$o = new Obj(1, 2, 3, 4); + + +test('object', $o, true); +?> +--EXPECTF-- +object +84c0a34f626aa16101a4002a006202a6004f626a006303 +object(Obj)#%d (4) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + ["d"]=> + NULL +} +OK diff --git a/php/tests/017.phpt b/php/tests/017.phpt new file mode 100644 index 00000000..6fbbd901 --- /dev/null +++ b/php/tests/017.phpt @@ -0,0 +1,48 @@ +--TEST-- +Object test, __wakeup +--SKIPIF-- +--FILE-- +b == 3 ? 'OK' : 'ERROR', PHP_EOL; +} + +class Obj { + var $a; + var $b; + + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + + function __wakeup() { + $this->b = $this->a * 3; + } +} + +$o = new Obj(1, 2); + + +test('object', $o, false); +?> +--EXPECTF-- +object +83c0a34f626aa16101a16202 +object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(3) +} +OK diff --git a/php/tests/018.phpt b/php/tests/018.phpt new file mode 100644 index 00000000..f5ff4b72 --- /dev/null +++ b/php/tests/018.phpt @@ -0,0 +1,84 @@ +--TEST-- +Object test, __sleep error cases +--SKIPIF-- +--FILE-- +a = $a; + $this->b = $b; + } + + function __sleep() { + return array('c'); + } + +# function __wakeup() { +# $this->b = $this->a * 3; +# } +} + +class Opj { + var $a; + var $b; + + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + + function __sleep() { + return array(1); + } + +# function __wakeup() { +# +# } +} + +$o = new Obj(1, 2); +$p = new Opj(1, 2); + +test('nonexisting', $o, true); +test('wrong', $p, true); +?> +--EXPECTF-- +nonexisting +82c0a34f626aa163c0 +object(Obj)#%d (3) { + ["a"]=> + NULL + ["b"]=> + NULL + ["c"]=> + NULL +} +OK +wrong +82c0a34f706a +object(Opj)#%d (2) { + ["a"]=> + NULL + ["b"]=> + NULL +} +OK diff --git a/php/tests/019.phpt b/php/tests/019.phpt new file mode 100644 index 00000000..46cccb3f --- /dev/null +++ b/php/tests/019.phpt @@ -0,0 +1,43 @@ +--TEST-- +Object test, __autoload +--SKIPIF-- +--FILE-- +b == 2 ? 'OK' : 'ERROR', PHP_EOL; +} + +function __autoload($classname) { + class Obj { + var $a; + var $b; + + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + } +} + +test('autoload', '83c0a34f626aa16101a16202', false); +?> +--EXPECTF-- +autoload +83c0a34f626aa16101a16202 +object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +OK diff --git a/php/tests/020.phpt b/php/tests/020.phpt new file mode 100644 index 00000000..4ed30e8b --- /dev/null +++ b/php/tests/020.phpt @@ -0,0 +1,31 @@ +--TEST-- +Object test, incomplete class +--SKIPIF-- +--FILE-- + +--EXPECTF-- +incom +83c0a34f626aa16101a16202 +object(__PHP_Incomplete_Class)#%d (3) { + ["__PHP_Incomplete_Class_Name"]=> + string(3) "Obj" + ["a"]=> + int(1) + ["b"]=> + int(2) +} diff --git a/php/tests/021.phpt b/php/tests/021.phpt new file mode 100644 index 00000000..7960a1f3 --- /dev/null +++ b/php/tests/021.phpt @@ -0,0 +1,52 @@ +--TEST-- +Object Serializable interface +--SKIPIF-- +--FILE-- +a = $a; + $this->b = $b; + } + + public function serialize() { + return pack('NN', $this->a, $this->b); + } + + public function unserialize($serialized) { + $tmp = unpack('N*', $serialized); + $this->__construct($tmp[1], $tmp[2]); + } +} + +$o = new Obj(1, 2); + +test('object', $o, false); +?> +--EXPECTF-- +object +82c003a34f626aa80000000100000002 +object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +OK diff --git a/php/tests/022.phpt b/php/tests/022.phpt new file mode 100644 index 00000000..7eab4b80 --- /dev/null +++ b/php/tests/022.phpt @@ -0,0 +1,45 @@ +--TEST-- +Object test, unserialize_callback_func +--SKIPIF-- +--INI-- +unserialize_callback_func=autoload +--FILE-- +b == 2 ? 'OK' : 'ERROR', PHP_EOL; +} + +function autoload($classname) { + class Obj { + var $a; + var $b; + + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + } +} + +test('autoload', '83c0a34f626aa16101a16202', false); +?> +--EXPECTF-- +autoload +83c0a34f626aa16101a16202 +object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +OK diff --git a/php/tests/023.phpt b/php/tests/023.phpt new file mode 100644 index 00000000..46d9ade4 --- /dev/null +++ b/php/tests/023.phpt @@ -0,0 +1,54 @@ +--TEST-- +Resource +--SKIPIF-- + +--FILE-- +open('db.txt'); +} + +test('resource', $res, false); + +switch ($test) { + case 'curl': + curl_close($res); + break; + case 'sqlite': + if (isset($sqlite)) { + $sqlite->close(); + } + @unlink('db.txt'); + break; +} +?> +--EXPECT-- +resource +c0 +NULL +OK diff --git a/php/tests/024.phpt b/php/tests/024.phpt new file mode 100644 index 00000000..9b185f7c --- /dev/null +++ b/php/tests/024.phpt @@ -0,0 +1,170 @@ +--TEST-- +Recursive objects +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- +a = $a; + $this->b = $b; + $this->c = $c; + } +} + +class Obj2 { + public $aa; + protected $bb; + private $cc; + private $obj; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + + $this->obj = new Obj($a, $b, $c); + } +} + +class Obj3 { + private $objs; + + function __construct($a, $b, $c) { + $this->objs = array(); + + for ($i = $a; $i < $c; $i += $b) { + $this->objs[] = new Obj($a, $i, $c); + } + } +} + +class Obj4 { + private $a; + private $obj; + + function __construct($a) { + $this->a = $a; + } + + public function set($obj) { + $this->obj = $obj; + } +} + +$o2 = new Obj2(1, 2, 3); +test('objectrec', $o2, false); + +$o3 = new Obj3(0, 1, 4); +test('objectrecarr', $o3, false); + +$o4 = new Obj4(100); +$o4->set($o4); +test('objectselfrec', $o4, true); +?> +--EXPECTF-- +objectrec +88c0a44f626a32a26161c0a5002a006262c0a8004f626a32006363c0a9004f626a32006f626a84c0a34f626aa16101a4002a006202a6004f626a006303a16101a16202a16303 +object(Obj2)#%d (7) { + ["aa"]=> + NULL + [%r"?bb"?:protected"?%r]=> + NULL + [%r"?cc"?:("Obj2":)?private"?%r]=> + NULL + [%r"?obj"?:("Obj2":)?private"?%r]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + int(3) +} +OK +objectrecarr +82c0a44f626a33aa004f626a33006f626a73840084c0a34f626aa16100a4002a006200a6004f626a0063040184c0a34f626aa16100a4002a006201a6004f626a0063040284c0a34f626aa16100a4002a006202a6004f626a0063040384c0a34f626aa16100a4002a006203a6004f626a006304 +object(Obj3)#%d (1) { + [%r"?objs"?:("Obj3":)?private"?%r]=> + array(4) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + [%r"?b"?:protected"?%r]=> + int(0) + [%r"?c"?:("Obj":)?private"?%r]=> + int(4) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + [%r"?b"?:protected"?%r]=> + int(1) + [%r"?c"?:("Obj":)?private"?%r]=> + int(4) + } + [2]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(4) + } + [3]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + [%r"?b"?:protected"?%r]=> + int(3) + [%r"?c"?:("Obj":)?private"?%r]=> + int(4) + } + } +} +OK +objectselfrec +83c0a44f626a34a7004f626a34006164a9004f626a34006f626a82c0020001 +object(Obj4)#%d (2) { + [%r"?a"?:("Obj4":)?private"?%r]=> + int(100) + [%r"?obj"?:("Obj4":)?private"?%r]=> + object(Obj4)#%d (2) { + [%r"?a"?:("Obj4":)?private"?%r]=> + int(100) + [%r"?obj"?:("Obj4":)?private"?%r]=> + *RECURSION* + } +} +OK diff --git a/php/tests/024b.phpt b/php/tests/024b.phpt new file mode 100644 index 00000000..7c691bec --- /dev/null +++ b/php/tests/024b.phpt @@ -0,0 +1,165 @@ +--TEST-- +Recursive objects +--SKIPIF-- +a = $a; + $this->b = $b; + $this->c = $c; + } +} + +class Obj2 { + public $aa; + protected $bb; + private $cc; + private $obj; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + + $this->obj = new Obj($a, $b, $c); + } +} + +class Obj3 { + private $objs; + + function __construct($a, $b, $c) { + $this->objs = array(); + + for ($i = $a; $i < $c; $i += $b) { + $this->objs[] = new Obj($a, $i, $c); + } + } +} + +class Obj4 { + private $a; + private $obj; + + function __construct($a) { + $this->a = $a; + } + + public function set($obj) { + $this->obj = $obj; + } +} + +$o2 = new Obj2(1, 2, 3); +test('objectrec', $o2, false); + +$o3 = new Obj3(0, 1, 4); +test('objectrecarr', $o3, false); + +$o4 = new Obj4(100); +$o4->set($o4); +test('objectselfrec', $o4, true); +?> +--EXPECTF-- +objectrec +88c0a44f626a32a26161c0a5002a006262c0a8004f626a32006363c0a9004f626a32006f626a84c0a34f626aa16101a4002a006202a6004f626a006303a16101a16202a16303 +object(Obj2)#%d (7) { + ["aa"]=> + NULL + [%r"?bb"?:protected"?%r]=> + NULL + [%r"?cc"?:("Obj2":)?private"?%r]=> + NULL + [%r"?obj"?:("Obj2":)?private"?%r]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + int(3) +} +OK +objectrecarr +82c0a44f626a33aa004f626a33006f626a73840084c0a34f626aa16100a4002a006200a6004f626a0063040184c0a34f626aa16100a4002a006201a6004f626a0063040284c0a34f626aa16100a4002a006202a6004f626a0063040384c0a34f626aa16100a4002a006203a6004f626a006304 +object(Obj3)#%d (1) { + [%r"?objs"?:("Obj3":)?private"?%r]=> + array(4) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + [%r"?b"?:protected"?%r]=> + int(0) + [%r"?c"?:("Obj":)?private"?%r]=> + int(4) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + [%r"?b"?:protected"?%r]=> + int(1) + [%r"?c"?:("Obj":)?private"?%r]=> + int(4) + } + [2]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(4) + } + [3]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + [%r"?b"?:protected"?%r]=> + int(3) + [%r"?c"?:("Obj":)?private"?%r]=> + int(4) + } + } +} +OK +objectselfrec +83c0a44f626a34a7004f626a34006164a9004f626a34006f626a82c0020001 +object(Obj4)#%d (2) { + [%r"?a"?:("Obj4":)?private"?%r]=> + int(100) + [%r"?obj"?:("Obj4":)?private"?%r]=> + *RECURSION* +} +OK diff --git a/php/tests/025.phpt b/php/tests/025.phpt new file mode 100644 index 00000000..234539d3 --- /dev/null +++ b/php/tests/025.phpt @@ -0,0 +1,119 @@ +--TEST-- +Object test, array of objects with __sleep +--SKIPIF-- +--FILE-- +a = $a; + $this->b = $b; + $this->c = $c; + $this->d = $d; + } + + function __sleep() { + return array('a', 'b', 'c'); + } + +# function __wakeup() { +# $this->d = $this->a + $this->b + $this->c; +# } +} + +$array = array( + new Obj("aa", "bb", "cc", "dd"), + new Obj("ee", "ff", "gg", "hh"), + new Obj(1, 2, 3, 4), +); + + +test('array', $array, true); +?> +--EXPECTF-- +array(3) { + [0]=> + object(Obj)#1 (4) { + ["a"]=> + string(2) "aa" + [%r"?b"?:protected"?%r]=> + string(2) "bb" + [%r"?c"?:("Obj":)?private"?%r]=> + string(2) "cc" + ["d"]=> + string(2) "dd" + } + [1]=> + object(Obj)#2 (4) { + ["a"]=> + string(2) "ee" + [%r"?b"?:protected"?%r]=> + string(2) "ff" + [%r"?c"?:("Obj":)?private"?%r]=> + string(2) "gg" + ["d"]=> + string(2) "hh" + } + [2]=> + object(Obj)#3 (4) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + ["d"]=> + int(4) + } +} +array(3) { + [0]=> + object(Obj)#4 (4) { + ["a"]=> + string(2) "aa" + [%r"?b"?:protected"?%r]=> + string(2) "bb" + [%r"?c"?:("Obj":)?private"?%r]=> + string(2) "cc" + ["d"]=> + NULL + } + [1]=> + object(Obj)#5 (4) { + ["a"]=> + string(2) "ee" + [%r"?b"?:protected"?%r]=> + string(2) "ff" + [%r"?c"?:("Obj":)?private"?%r]=> + string(2) "gg" + ["d"]=> + NULL + } + [2]=> + object(Obj)#6 (4) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + ["d"]=> + NULL + } +} diff --git a/php/tests/026.phpt b/php/tests/026.phpt new file mode 100644 index 00000000..c243ef51 --- /dev/null +++ b/php/tests/026.phpt @@ -0,0 +1,147 @@ +--TEST-- +Cyclic array test +--INI-- +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- + array( + 'b' => 'c', + 'd' => 'e' + ), +); + +$a['f'] = &$a; + +test('array', $a, true); + +$a = array("foo" => &$b); +$b = array(1, 2, $a); +var_dump($a); +var_dump($k = msgpack_unserialize(msgpack_serialize($a))); + +$k["foo"][1] = "b"; +var_dump($k); +?> +--EXPECT-- +array +82a16182a162a163a164a165a16683c001a16182a162a163a164a165a16682c0020005 +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + &array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + &array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + *RECURSION* + } + } +} +OK +array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + *RECURSION* + } + } + } +} +array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + ["foo"]=> + *RECURSION* + } + } + } + } +} +array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + string(1) "b" + [2]=> + array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + string(1) "b" + [2]=> + array(1) { + ["foo"]=> + *RECURSION* + } + } + } + } +} diff --git a/php/tests/026b.phpt b/php/tests/026b.phpt new file mode 100644 index 00000000..f7a3381f --- /dev/null +++ b/php/tests/026b.phpt @@ -0,0 +1,107 @@ +--TEST-- +Cyclic array test +--INI-- +--SKIPIF-- + array( + 'b' => 'c', + 'd' => 'e' + ), +); + +$a['f'] = &$a; + +test('array', $a, true); + +$a = array("foo" => &$b); +$b = array(1, 2, $a); +var_dump($a); +var_dump($k = msgpack_unserialize(msgpack_serialize($a))); + +$k["foo"][1] = "b"; +var_dump($k); +?> +--EXPECT-- +array +82a16182a162a163a164a165a16683c001a16182a162a163a164a165a16682c0020005 +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + &array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + *RECURSION* + } +} +OK +array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + *RECURSION* + } +} +array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + ["foo"]=> + *RECURSION* + } + } +} +array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + string(1) "b" + [2]=> + array(1) { + ["foo"]=> + *RECURSION* + } + } +} diff --git a/php/tests/027.phpt b/php/tests/027.phpt new file mode 100644 index 00000000..c9c7cbd5 --- /dev/null +++ b/php/tests/027.phpt @@ -0,0 +1,73 @@ +--TEST-- +Check for serialization handler +--SKIPIF-- +--FILE-- + +--EXPECT-- +bool(true) +read +wrote: 83c001a3666f6f01a474657374a6666f6f626172 +array(2) { + ["foo"]=> + int(1) + ["test"]=> + string(6) "foobar" +} diff --git a/php/tests/028.phpt b/php/tests/028.phpt new file mode 100644 index 00000000..00db6751 --- /dev/null +++ b/php/tests/028.phpt @@ -0,0 +1,671 @@ +--TEST-- +Serialize object into session, full set +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- +d1 = $foo; + $this->d2 = $foo; + $this->d3 = $foo; + } +} + +class Bar { + private static $s1 = array(); + protected static $s2 = array(); + public static $s3 = array(); + + public $d1; + private $d2; + protected $d3; + + public function __construct() { + } + + public function set($foo) { + $this->d1 = $foo; + $this->d2 = $foo; + $this->d3 = $foo; + } +} + +$output = ''; + +function open($path, $name) { + return true; +} + +function close() { + return true; +} + +function read($id) { + global $output; + $output .= "read" . PHP_EOL; + $a = new Bar(); + $b = new Foo($a); + $a->set($b); + $session = array('old' => $b); + return msgpack_serialize($session); +} + +function write($id, $data) { + global $output; + $output .= "write: "; + $output .= bin2hex($data) . PHP_EOL; + return true; +} + +function destroy($id) { + return true; +} + +function gc($time) { + return true; +} + +ini_set('session.serialize_handler', 'msgpack'); + +session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc'); + +session_start(); + +$_SESSION['test'] = "foobar"; +$a = new Bar(); +$b = new Foo($a); +$a->set($b); +$_SESSION['new'] = $a; + +session_write_close(); + +echo $output; +var_dump($_SESSION); +?> +--EXPECTF-- +read +write: 84c001a36f6c6484c0a3466f6fa700466f6f00643184c0a3426172a2643182c0020002a70042617200643282c0020002a5002a00643382c0020002a5002a00643282c0020003a2643382c0020003a474657374a6666f6f626172a36e657784c0a3426172a2643184c0a3466f6fa700466f6f00643182c002000aa5002a00643282c002000aa2643382c002000aa70042617200643282c002000ba5002a00643382c002000b +array(3) { + ["old"]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + } + } + ["test"]=> + string(6) "foobar" + ["new"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d3"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d3"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d3"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + } + } +} diff --git a/php/tests/028b.phpt b/php/tests/028b.phpt new file mode 100644 index 00000000..7331a576 --- /dev/null +++ b/php/tests/028b.phpt @@ -0,0 +1,167 @@ +--TEST-- +Serialize object into session, full set +--SKIPIF-- +d1 = $foo; + $this->d2 = $foo; + $this->d3 = $foo; + } +} + +class Bar { + private static $s1 = array(); + protected static $s2 = array(); + public static $s3 = array(); + + public $d1; + private $d2; + protected $d3; + + public function __construct() { + } + + public function set($foo) { + $this->d1 = $foo; + $this->d2 = $foo; + $this->d3 = $foo; + } +} + +$output = ''; + +function open($path, $name) { + return true; +} + +function close() { + return true; +} + +function read($id) { + global $output; + $output .= "read" . PHP_EOL; + $a = new Bar(); + $b = new Foo($a); + $a->set($b); + $session = array('old' => $b); + return msgpack_serialize($session); +} + +function write($id, $data) { + global $output; + $output .= "write: "; + $output .= bin2hex($data) . PHP_EOL; + return true; +} + +function destroy($id) { + return true; +} + +function gc($time) { + return true; +} + +ini_set('session.serialize_handler', 'msgpack'); + +session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc'); + +session_start(); + +$_SESSION['test'] = "foobar"; +$a = new Bar(); +$b = new Foo($a); +$a->set($b); +$_SESSION['new'] = $a; + +session_write_close(); + +echo $output; +var_dump($_SESSION); +?> +--EXPECTF-- +read +write: 84c001a36f6c6484c0a3466f6fa700466f6f00643184c0a3426172a2643182c0020002a70042617200643282c0020002a5002a00643382c0020002a5002a00643282c0020003a2643382c0020003a474657374a6666f6f626172a36e657784c0a3426172a2643184c0a3466f6fa700466f6f00643182c002000aa5002a00643282c002000aa2643382c002000aa70042617200643282c002000ba5002a00643382c002000b +array(3) { + ["old"]=> + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } + ["test"]=> + string(6) "foobar" + ["new"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } +} diff --git a/php/tests/029.phpt b/php/tests/029.phpt new file mode 100644 index 00000000..686abb92 --- /dev/null +++ b/php/tests/029.phpt @@ -0,0 +1,47 @@ +--TEST-- +Msgpack module info +--SKIPIF-- + +--FILE-- + $val) +{ + if (strcmp($val, 'msgpack') == 0 || $section) + { + $section = true; + } + else + { + continue; + } + + if (empty($val)) + { + $blank++; + if ($blank == 3) + { + $section = false; + } + } + + echo $val, PHP_EOL; +} +--EXPECTF-- +msgpack + +MessagePack Support => enabled +Session Support => enabled +extension Version => %s +header Version => %s + +Directive => Local Value => Master Value +msgpack.error_display => On => On +msgpack.php_only => On => On diff --git a/php/tests/030.phpt b/php/tests/030.phpt new file mode 100644 index 00000000..3b8d986e --- /dev/null +++ b/php/tests/030.phpt @@ -0,0 +1,230 @@ +--TEST-- +Unserialize invalid data +--SKIPIF-- +--FILE-- + 10, "foo"), + true, + false, + 0.187182, + "dakjdh98389\000", + null, + (object)array(1,2,3), +); + +error_reporting(0); + +foreach ($datas as $data) { + $str = msgpack_serialize($data); + $len = strlen($str); + + // truncated + for ($i = 0; $i < $len - 1; $i++) { + $v = msgpack_unserialize(substr($str, 0, $i)); + + if (is_object($data) || is_array($data)) { + if ($v !== null && $v !== false && $v != $data) { + echo "output at $i:\n"; + var_dump($v); + } + } else if ($v !== null && $v == $data) { + continue; + } else if ($v !== null && $v !== $data) { + echo "output at $i:\n"; + var_dump($v); + echo "vs.\n"; + var_dump($data); + } + } + + // padded + $str .= "98398afa\000y21_ "; + $v = msgpack_unserialize($str); + if ($v !== $data && !(is_object($data) && $v == $data)) { + echo "padded should get original\n"; + var_dump($v); + echo "vs.\n"; + var_dump($data); + } +} +?> +--EXPECTF-- +output at 3: +array(1) { + [0]=> + int(1) +} +output at 4: +array(1) { + [0]=> + int(1) +} +output at 5: +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +output at 6: +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +output at 7: +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +output at 8: +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +output at 9: +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +output at 10: +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +output at 11: +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +output at 12: +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +output at 13: +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +output at 14: +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +output at 15: +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +output at 16: +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + ["testing"]=> + int(10) +} +output at 17: +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + ["testing"]=> + int(10) +} +output at 18: +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + ["testing"]=> + int(10) +} +output at 19: +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + ["testing"]=> + int(10) +} +output at 11: +object(stdClass)#2 (0) { +} +output at 12: +object(stdClass)#3 (0) { +} +output at 13: +object(stdClass)#2 (1) { + [0]=> + int(1) +} +output at 14: +object(stdClass)#3 (1) { + [0]=> + int(1) +} +output at 15: +object(stdClass)#2 (2) { + [0]=> + int(1) + [1]=> + int(2) +} diff --git a/php/tests/031.phpt b/php/tests/031.phpt new file mode 100644 index 00000000..ce3ba49f --- /dev/null +++ b/php/tests/031.phpt @@ -0,0 +1,90 @@ +--TEST-- +Object Serializable interface throws exceptions +--SKIPIF-- +--FILE-- +a = $a; + $this->b = $b; + } + + public function serialize() { + $c = self::$count++; + echo "call serialize, ", ($this->a ? "throw" : "no throw"), PHP_EOL; + if ($this->a) { + throw new Exception("exception in serialize $c"); + } + return pack('NN', $this->a, $this->b); + } + + public function unserialize($serialized) { + $tmp = unpack('N*', $serialized); + $this->__construct($tmp[1], $tmp[2]); + $c = self::$count++; + echo "call unserialize, ", ($this->b ? "throw" : "no throw"), PHP_EOL; + if ($this->b) { + throw new Exception("exception in unserialize $c"); + } + } +} + +$a = new Obj(1, 0); +$a = new Obj(0, 0); +$b = new Obj(0, 0); +$c = new Obj(1, 0); +$d = new Obj(0, 1); + +echo "a, a, c", PHP_EOL; +try { + test(array($a, $a, $c)); +} catch (Exception $e) { + if (version_compare(phpversion(), "5.3.0", ">=")) { + if ($e->getPrevious()) { + $e = $e->getPrevious(); + } + } + + echo $e->getMessage(), PHP_EOL; +} + +echo "b, b, d", PHP_EOL; + +try { + test(array($b, $b, $d)); +} catch (Exception $e) { + if (version_compare(phpversion(), "5.3.0", ">=")) { + if ($e->getPrevious()) { + $e = $e->getPrevious(); + } + } + + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +a, a, c +call serialize, no throw +call serialize, throw +exception in serialize 2 +b, b, d +call serialize, no throw +call serialize, no throw +call unserialize, no throw +call unserialize, throw +exception in unserialize 6 diff --git a/php/tests/032.phpt b/php/tests/032.phpt new file mode 100644 index 00000000..b120ea91 --- /dev/null +++ b/php/tests/032.phpt @@ -0,0 +1,76 @@ +--TEST-- +Object test, __sleep and __wakeup exceptions +--SKIPIF-- +--FILE-- +a = $a; + $this->b = $b; + } + + function __sleep() { + $c = self::$count++; + if ($this->a) { + throw new Exception("exception in __sleep $c"); + } + return array('a', 'b'); + } + + function __wakeup() { + $c = self::$count++; + if ($this->b) { + throw new Exception("exception in __wakeup $c"); + } + $this->b = $this->a * 3; + } +} + + +$a = new Obj(1, 0); +$b = new Obj(0, 1); +$c = new Obj(0, 0); + +try { + test($a); +} catch (Exception $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + test($b); +} catch (Exception $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + test($c); +} catch (Exception $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +exception in __sleep 0 +exception in __wakeup 2 +object(Obj)#%d (2) { + ["a"]=> + int(0) + ["b"]=> + int(0) +} diff --git a/php/tests/033.phpt b/php/tests/033.phpt new file mode 100644 index 00000000..682fd4db --- /dev/null +++ b/php/tests/033.phpt @@ -0,0 +1,55 @@ +--TEST-- +Object test, cyclic references +--SKIPIF-- +--FILE-- +parent = null; + $this->children = array(); + } + + public function addChild(Foo $obj) { + $this->children[] = $obj; + $obj->setParent($this); + } + + public function setParent(Foo $obj) { + $this->parent = $obj; + } +} + +$obj1 = new Foo(); + +for ($i = 0; $i < 10; $i++) { + $obj = new Foo(); + $obj1->addChild($obj); +} + +$o = msgpack_unserialize(msgpack_serialize($obj1->children)); + +foreach ($obj1->children as $k => $v) { + $obj_v = $v; + $o_v = $o[$k]; + + echo gettype($obj_v), " ", gettype($o_v), PHP_EOL; +} +?> +--EXPECT-- +object object +object object +object object +object object +object object +object object +object object +object object +object object +object object diff --git a/php/tests/034.phpt b/php/tests/034.phpt new file mode 100644 index 00000000..6610c7c7 --- /dev/null +++ b/php/tests/034.phpt @@ -0,0 +1,38 @@ +--TEST-- +Unserialize invalid random data +--SKIPIF-- +--FILE-- + 10, "foo"), + true, + false, + 0.187182, + "dakjdh98389\000", + null, + (object)array(1,2,3), +); + +error_reporting(0); + +foreach ($datas as $data) { + $str = msgpack_serialize($data); + $len = strlen($str); + + for ($j = 0; $j < 200; $j++) { + for ($i = 0; $i < $len - 1; $i++) { + $sub = substr($str, 0, $i); + $sub .= mcrypt_create_iv(30, MCRYPT_DEV_URANDOM); + $php_errormsg = null; + $v = msgpack_unserialize($sub); + } + } +} + +--EXPECT-- diff --git a/php/tests/035.phpt b/php/tests/035.phpt new file mode 100644 index 00000000..d680565f --- /dev/null +++ b/php/tests/035.phpt @@ -0,0 +1,34 @@ +--TEST-- +Profiling perf test. +--SKIPIF-- + +--FILE-- + 400 ? "GOOD" : "BAD")); +} +?> +--EXPECTF-- +%d iterations took %f seconds: %d/s (GOOD) diff --git a/php/tests/040.phpt b/php/tests/040.phpt new file mode 100644 index 00000000..9a2d0384 --- /dev/null +++ b/php/tests/040.phpt @@ -0,0 +1,43 @@ +--TEST-- +b0rked random data test +--SKIPIF-- +--FILE-- + +--EXPECT-- diff --git a/php/tests/041.phpt b/php/tests/041.phpt new file mode 100644 index 00000000..6400fd97 --- /dev/null +++ b/php/tests/041.phpt @@ -0,0 +1,47 @@ +--TEST-- +Check for double NaN, Inf, -Inf, 0, and -0 +--FILE-- + +--EXPECT-- +empty array: +90 +array(0) { +} +array(1, 2, 3) +93010203 +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(array(1, 2, 3), arr... +93930102039304050693070809 +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +array("foo", "FOO", "Foo") +93a3666f6fa3464f4fa3466f6f +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "FOO" + [2]=> + string(3) "Foo" +} +array(1, 123.45, true, ... +9701cb405edccccccccccdc3c293010293090807c0a3666f6f +array(7) { + [0]=> + int(1) + [1]=> + float(123.45) + [2]=> + bool(true) + [3]=> + bool(false) + [4]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(3) { + [0]=> + int(9) + [1]=> + int(8) + [2]=> + int(7) + } + } + [5]=> + NULL + [6]=> + string(3) "foo" +} diff --git a/php/tests/060.phpt b/php/tests/060.phpt new file mode 100644 index 00000000..649d7886 --- /dev/null +++ b/php/tests/060.phpt @@ -0,0 +1,319 @@ +--TEST-- +Check for buffered streaming unserialization +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- +feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('bool: true', true); +test('bool: false', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('array', array(), false); +test('array(1, 2, 3)', array(1, 2, 3), false); +test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/060b.phpt b/php/tests/060b.phpt new file mode 100644 index 00000000..0b947c8e --- /dev/null +++ b/php/tests/060b.phpt @@ -0,0 +1,313 @@ +--TEST-- +Check for buffered streaming unserialization +--SKIPIF-- +feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('bool: true', true); +test('bool: false', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('array', array(), false); +test('array(1, 2, 3)', array(1, 2, 3), false); +test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/061.phpt b/php/tests/061.phpt new file mode 100644 index 00000000..7ecc0c9f --- /dev/null +++ b/php/tests/061.phpt @@ -0,0 +1,324 @@ +--TEST-- +Check for unbuffered streaming unserialization +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- +execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/061b.phpt b/php/tests/061b.phpt new file mode 100644 index 00000000..efb3a9bf --- /dev/null +++ b/php/tests/061b.phpt @@ -0,0 +1,318 @@ +--TEST-- +Check for unbuffered streaming unserialization +--SKIPIF-- +execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/062.phpt b/php/tests/062.phpt new file mode 100644 index 00000000..159e00de --- /dev/null +++ b/php/tests/062.phpt @@ -0,0 +1,64 @@ +--TEST-- +Extra bytes buffered streaming unserialization +--SKIPIF-- +--FILE-- +feed($str); + + while (true) { + if ($unpacker->execute()) { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } else { + break; + } + } + $i += $len; + } + } +} + +test('array(1, 2, 3)', array('9301020392')); +test('array(1, 2, 3), array(3, 9), 4', array('9301020392', '030904')); +--EXPECTF-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + [0]=> + int(3) + [1]=> + int(9) +} +int(4) diff --git a/php/tests/063.phpt b/php/tests/063.phpt new file mode 100644 index 00000000..5be7e099 --- /dev/null +++ b/php/tests/063.phpt @@ -0,0 +1,68 @@ +--TEST-- +Extra bytes unbuffered streaming unserialization +--SKIPIF-- +--FILE-- +execute($str, $offset)) { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = substr($str, $offset); + $offset = 0; + } else { + break; + } + } + $i += $len; + } + } +} + +test('array(1, 2, 3)', array('9301020392')); +test('array(1, 2, 3), array(3, 9), 4', array('9301020392', '030904')); +--EXPECTF-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + [0]=> + int(3) + [1]=> + int(9) +} +int(4) diff --git a/php/tests/070.phpt b/php/tests/070.phpt new file mode 100644 index 00000000..893023b5 --- /dev/null +++ b/php/tests/070.phpt @@ -0,0 +1,303 @@ +--TEST-- +Check for alias functions +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- + 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/070b.phpt b/php/tests/070b.phpt new file mode 100644 index 00000000..109ddc1a --- /dev/null +++ b/php/tests/070b.phpt @@ -0,0 +1,297 @@ +--TEST-- +Check for alias functions +--SKIPIF-- + 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/071.phpt b/php/tests/071.phpt new file mode 100644 index 00000000..431303b6 --- /dev/null +++ b/php/tests/071.phpt @@ -0,0 +1,305 @@ +--TEST-- +Check for class methods +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- +pack($variable); + $unserialized = $msgpack->unpack($serialized); + + var_dump($unserialized); + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/071b.phpt b/php/tests/071b.phpt new file mode 100644 index 00000000..770d06ee --- /dev/null +++ b/php/tests/071b.phpt @@ -0,0 +1,299 @@ +--TEST-- +Check for class methods +--SKIPIF-- +pack($variable); + $unserialized = $msgpack->unpack($serialized); + + var_dump($unserialized); + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/072.phpt b/php/tests/072.phpt new file mode 100644 index 00000000..ea79a56d --- /dev/null +++ b/php/tests/072.phpt @@ -0,0 +1,345 @@ +--TEST-- +Check for class methods unpacker +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- +pack($variable); + $unpacker = $msgpack->unpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/072b.phpt b/php/tests/072b.phpt new file mode 100644 index 00000000..c7b0c3ce --- /dev/null +++ b/php/tests/072b.phpt @@ -0,0 +1,339 @@ +--TEST-- +Check for class methods unpacker +--SKIPIF-- +pack($variable); + $unpacker = $msgpack->unpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/073.phpt b/php/tests/073.phpt new file mode 100644 index 00000000..d3a76379 --- /dev/null +++ b/php/tests/073.phpt @@ -0,0 +1,346 @@ +--TEST-- +Check for class unpacker +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 and lower"; +} +--FILE-- +pack($variable); + + $unpacker = new MessagePackUnpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/073b.phpt b/php/tests/073b.phpt new file mode 100644 index 00000000..131a5346 --- /dev/null +++ b/php/tests/073b.phpt @@ -0,0 +1,340 @@ +--TEST-- +Check for class unpacker +--SKIPIF-- +pack($variable); + + $unpacker = new MessagePackUnpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/080.phpt b/php/tests/080.phpt new file mode 100644 index 00000000..aba1cb63 --- /dev/null +++ b/php/tests/080.phpt @@ -0,0 +1,301 @@ +--TEST-- +disabled php only (ini_set) +--SKIPIF-- +--FILE-- + 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/081.phpt b/php/tests/081.phpt new file mode 100644 index 00000000..d22daaa0 --- /dev/null +++ b/php/tests/081.phpt @@ -0,0 +1,303 @@ +--TEST-- +disabled php only for class methods (ini_set) +--SKIPIF-- +--FILE-- +pack($variable); + $unserialized = $msgpack->unpack($serialized); + + var_dump($unserialized); + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/082.phpt b/php/tests/082.phpt new file mode 100644 index 00000000..45a9d938 --- /dev/null +++ b/php/tests/082.phpt @@ -0,0 +1,346 @@ +--TEST-- +disabled php only for class methods unpacker (ini_set) +--SKIPIF-- +--FILE-- +pack($variable); + $unpacker = $msgpack->unpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/083.phpt b/php/tests/083.phpt new file mode 100644 index 00000000..203d8299 --- /dev/null +++ b/php/tests/083.phpt @@ -0,0 +1,347 @@ +--TEST-- +disabled php only for class unpacker (ini_set) +--SKIPIF-- +--FILE-- +pack($variable); + + $unpacker = new MessagePackUnpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/084.phpt b/php/tests/084.phpt new file mode 100644 index 00000000..74d061b5 --- /dev/null +++ b/php/tests/084.phpt @@ -0,0 +1,301 @@ +--TEST-- +disabled php only for class methods (constract) +--SKIPIF-- +--FILE-- +pack($variable); + $unserialized = $msgpack->unpack($serialized); + + var_dump($unserialized); + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/085.phpt b/php/tests/085.phpt new file mode 100644 index 00000000..72aacc8b --- /dev/null +++ b/php/tests/085.phpt @@ -0,0 +1,344 @@ +--TEST-- +disabled php only for class methods unpacker (constract) +--SKIPIF-- +--FILE-- +pack($variable); + $unpacker = $msgpack->unpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/086.phpt b/php/tests/086.phpt new file mode 100644 index 00000000..aeaa3328 --- /dev/null +++ b/php/tests/086.phpt @@ -0,0 +1,345 @@ +--TEST-- +disabled php only for class unpacker (constract) +--SKIPIF-- +--FILE-- +pack($variable); + + $unpacker = new MessagePackUnpacker(false); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/087.phpt b/php/tests/087.phpt new file mode 100644 index 00000000..9bb4e49a --- /dev/null +++ b/php/tests/087.phpt @@ -0,0 +1,302 @@ +--TEST-- +disabled php only for class methods (set option) +--SKIPIF-- +--FILE-- +setOption(MessagePack::OPT_PHPONLY, false); + + $serialized = $msgpack->pack($variable); + $unserialized = $msgpack->unpack($serialized); + + var_dump($unserialized); + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/088.phpt b/php/tests/088.phpt new file mode 100644 index 00000000..7cbabb91 --- /dev/null +++ b/php/tests/088.phpt @@ -0,0 +1,345 @@ +--TEST-- +disabled php only for class methods unpacker (set option) +--SKIPIF-- +--FILE-- +setOption(MessagePack::OPT_PHPONLY, false); + + $serialized = $msgpack->pack($variable); + $unpacker = $msgpack->unpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/089.phpt b/php/tests/089.phpt new file mode 100644 index 00000000..f3a05378 --- /dev/null +++ b/php/tests/089.phpt @@ -0,0 +1,347 @@ +--TEST-- +disabled php only for class unpacker (set option) +--SKIPIF-- +--FILE-- +setOption(MessagePack::OPT_PHPONLY, false); + + $serialized = $msgpack->pack($variable); + + $unpacker = new MessagePackUnpacker(); + $unpacker->setOption(MessagePack::OPT_PHPONLY, false); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/test_pack.phpt b/php/tests/test_pack.phpt deleted file mode 100644 index 595e4d03..00000000 --- a/php/tests/test_pack.phpt +++ /dev/null @@ -1,169 +0,0 @@ ---TEST-- -Test msgpack_pack() function : basic functionality ---SKIPIF-- - ---FILE-- - -===DONE=== ---EXPECT-- -*** Testing msgpack_pack() : basic functionality *** --- Iteration 1 -- -string(4) "0xc0" --- Iteration 2 -- -string(4) "0xc0" --- Iteration 3 -- -string(4) "0xc2" --- Iteration 4 -- -string(4) "0xc2" --- Iteration 5 -- -string(4) "0xc3" --- Iteration 6 -- -string(4) "0xc3" --- Iteration 7 -- -string(4) "0x00" --- Iteration 8 -- -string(4) "0x7f" --- Iteration 9 -- -string(6) "0xcc80" --- Iteration 10 -- -string(8) "0xcd0100" --- Iteration 11 -- -string(4) "0xff" --- Iteration 12 -- -string(6) "0xd0df" --- Iteration 13 -- -string(8) "0xd1ff7f" --- Iteration 14 -- -string(8) "0x810101" --- Iteration 15 -- -string(20) "0xcb3ff0000000000000" --- Iteration 16 -- -string(4) "0x90" --- Iteration 17 -- -string(34) "0x9f000102030405060708090a0b0c0d0e" --- Iteration 18 -- -string(40) "0xdc0010000102030405060708090a0b0c0d0e0f" --- Iteration 19 -- -string(64) "0x8f0100020103020403050406050706080709080a090b0a0c0b0d0c0e0d0f0e" --- Iteration 20 -- -string(72) "0xde00100100020103020403050406050706080709080a090b0a0c0b0d0c0e0d0f0e100f" -===DONE===