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===