Update PHP Extension

This commit is contained in:
advect 2010-07-17 18:46:28 +09:00
parent a97f9081a3
commit 78f542f6c0
71 changed files with 7345 additions and 2108 deletions

40
php/ChangeLog Normal file
View File

@ -0,0 +1,40 @@
msgpack extension changelog
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.

26
php/LICENSE Normal file
View File

@ -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.

View File

@ -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/)

248
php/benchmark.php Normal file
View File

@ -0,0 +1,248 @@
<?php
require_once 'Benchmark/Timer.php';
$loop = 10000;
$retry = 10;
$value_display = false;
$types = array(
1, //integer
2, //float
3, //string
4, //array
5, //hash
6, //object
);
foreach ($types as $type)
{
switch ($type)
{
case 1:
//integer
$value = rand();
break;
case 2:
//float
$value = log(rand());
break;
case 3:
//string
$value = md5(rand());
break;
case 4:
//array
$value = array(md5(rand()),
md5(rand()),
md5(rand()),
md5(rand()),
md5(rand()));
break;
case 5:
//hash
$value = array(md5(rand()) => 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;
}
}

View File

@ -1,14 +1,73 @@
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])
dnl PHP_ARG_ENABLE(msgpack, whether to enable msgpack support,
dnl Make sure that the comment is aligned:
dnl [ --enable-msgpack Enable msgpack support])
if test "$PHP_MSGPACK" != "no"; then
dnl AC_DEFINE([HAVE_MSGPACK],1 ,[whether to enable MessagePack support])
dnl AC_HEADER_STDC
dnl Write more examples of tests here...
PHP_NEW_EXTENSION(msgpack, msgpack.c, $ext_shared)
dnl PHP_SUBST(MSGPACK_SHARED_LIBADD)
dnl --with-msgpack -> check with-path
SEARCH_PATH="/usr/local /usr" # you might want to change this
SEARCH_FOR="/include/msgpack.h" # you most likely want to change this
if test -r $PHP_MSGPACK/$SEARCH_FOR; then # path given as parameter
MSGPACK_DIR=$PHP_MSGPACK
else # search default path list
AC_MSG_CHECKING([for msgpack files in default path])
for i in $SEARCH_PATH ; do
if test -r $i/$SEARCH_FOR; then
MSGPACK_DIR=$i
AC_MSG_RESULT(found in $i)
fi
done
fi
if test -z "$MSGPACK_DIR"; then
AC_MSG_RESULT([not found])
AC_MSG_ERROR([Please reinstall the msgpack distribution])
fi
dnl --with-msgpack -> add include path
PHP_ADD_INCLUDE($MSGPACK_DIR/include)
dnl --with-msgpack -> check for lib and symbol presence
LIBNAME=msgpack # you may want to change this
LIBSYMBOL=msgpack_pack_object # you most likely want to change this
PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
[
PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $MSGPACK_DIR/lib, MSGPACK_SHARED_LIBADD)
AC_DEFINE(HAVE_MSGPACKLIB,1,[ ])
],[
AC_MSG_ERROR([wrong msgpack lib version or lib not found])
],[
-L$MSGPACK_DIR/lib -lm
])
PHP_SUBST(MSGPACK_SHARED_LIBADD)
PHP_NEW_EXTENSION(msgpack, msgpack.c msgpack_pack.c msgpack_unpack.c msgpack_class.c, $ext_shared)
PHP_INSTALL_HEADERS([ext/msgpack], [php_msgpack.h])
fi

View File

@ -8,6 +8,5 @@
// 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");
}

View File

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

View File

@ -2,7 +2,7 @@
$br = (php_sapi_name() == "cli")? "":"<br>";
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";
?>

View File

@ -1,26 +0,0 @@
/*
* MessagePack unpacking routine template
*
* 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_PACK_DEFINE_H__
#define MSGPACK_PACK_DEFINE_H__
#include <stddef.h>
#include <stdint.h>
#include <limits.h>
#endif /* msgpack/pack_define.h */

View File

@ -1,741 +0,0 @@
/*
* MessagePack packing routine template
*
* 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.
*/
#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]
#endif
#ifndef msgpack_pack_inline_func
#error msgpack_pack_inline_func template is not defined
#endif
#ifndef msgpack_pack_user
#error msgpack_pack_user type is not defined
#endif
#ifndef msgpack_pack_append_buffer
#error msgpack_pack_append_buffer callback is not defined
#endif
/*
* Integer
*/
#define msgpack_pack_real_uint8(x, d) \
do { \
if(d < (1<<7)) { \
/* fixnum */ \
msgpack_pack_append_buffer(x, &STORE8_BE8(d), 1); \
} else { \
/* unsigned 8 */ \
const unsigned char buf[2] = {0xcc, STORE8_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} \
} while(0)
#define msgpack_pack_real_uint16(x, d) \
do { \
if(d < (1<<7)) { \
/* fixnum */ \
msgpack_pack_append_buffer(x, &STORE16_BE8(d), 1); \
} else if(d < (1<<8)) { \
/* unsigned 8 */ \
const unsigned char buf[2] = {0xcc, STORE16_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} else { \
/* unsigned 16 */ \
const unsigned char buf[3] = {0xcd, STORE16_BE16(d)}; \
msgpack_pack_append_buffer(x, buf, 3); \
} \
} while(0)
#define msgpack_pack_real_uint32(x, d) \
do { \
if(d < (1<<8)) { \
if(d < (1<<7)) { \
/* fixnum */ \
msgpack_pack_append_buffer(x, &STORE32_BE8(d), 1); \
} else { \
/* unsigned 8 */ \
const unsigned char buf[2] = {0xcc, STORE32_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} \
} else { \
if(d < (1<<16)) { \
/* unsigned 16 */ \
const unsigned char buf[3] = {0xcd, STORE32_BE16(d)}; \
msgpack_pack_append_buffer(x, buf, 3); \
} else { \
/* unsigned 32 */ \
const unsigned char buf[5] = {0xce, STORE32_BE32(d)}; \
msgpack_pack_append_buffer(x, buf, 5); \
} \
} \
} while(0)
#define msgpack_pack_real_uint64(x, d) \
do { \
if(d < (1ULL<<8)) { \
if(d < (1<<7)) { \
/* fixnum */ \
msgpack_pack_append_buffer(x, &STORE64_BE8(d), 1); \
} else { \
/* unsigned 8 */ \
const unsigned char buf[2] = {0xcc, STORE64_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} \
} else { \
if(d < (1ULL<<16)) { \
/* signed 16 */ \
const unsigned char buf[3] = {0xcd, STORE64_BE16(d)}; \
msgpack_pack_append_buffer(x, buf, 3); \
} else if(d < (1ULL<<32)) { \
/* signed 32 */ \
const unsigned char buf[5] = {0xce, STORE64_BE32(d)}; \
msgpack_pack_append_buffer(x, buf, 5); \
} else { \
/* signed 64 */ \
const unsigned char buf[9] = {0xcf, STORE64_BE64(d)}; \
msgpack_pack_append_buffer(x, buf, 9); \
} \
} \
} while(0)
#define msgpack_pack_real_int8(x, d) \
do { \
if(d < -(1<<5)) { \
/* signed 8 */ \
const unsigned char buf[2] = {0xd0, STORE8_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} else { \
/* fixnum */ \
msgpack_pack_append_buffer(x, &STORE8_BE8(d), 1); \
} \
} while(0)
#define msgpack_pack_real_int16(x, d) \
do { \
if(d < -(1<<5)) { \
if(d < -(1<<7)) { \
/* signed 16 */ \
const unsigned char buf[3] = {0xd1, STORE16_BE16(d)}; \
msgpack_pack_append_buffer(x, buf, 3); \
} else { \
/* signed 8 */ \
const unsigned char buf[2] = {0xd0, STORE16_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} \
} else if(d < (1<<7)) { \
/* fixnum */ \
msgpack_pack_append_buffer(x, &STORE16_BE8(d), 1); \
} else { \
if(d < (1<<8)) { \
/* unsigned 8 */ \
const unsigned char buf[2] = {0xcc, STORE16_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} else { \
/* unsigned 16 */ \
const unsigned char buf[3] = {0xcd, STORE16_BE16(d)}; \
msgpack_pack_append_buffer(x, buf, 3); \
} \
} \
} while(0)
#define msgpack_pack_real_int32(x, d) \
do { \
if(d < -(1<<5)) { \
if(d < -(1<<15)) { \
/* signed 32 */ \
const unsigned char buf[5] = {0xd2, STORE32_BE32(d)}; \
msgpack_pack_append_buffer(x, buf, 5); \
} else if(d < -(1<<7)) { \
/* signed 16 */ \
const unsigned char buf[3] = {0xd1, STORE32_BE16(d)}; \
msgpack_pack_append_buffer(x, buf, 3); \
} else { \
/* signed 8 */ \
const unsigned char buf[2] = {0xd0, STORE32_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} \
} else if(d < (1<<7)) { \
/* fixnum */ \
msgpack_pack_append_buffer(x, &STORE32_BE8(d), 1); \
} else { \
if(d < (1<<8)) { \
/* unsigned 8 */ \
const unsigned char buf[2] = {0xcc, STORE32_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} else if(d < (1<<16)) { \
/* unsigned 16 */ \
const unsigned char buf[3] = {0xcd, STORE32_BE16(d)}; \
msgpack_pack_append_buffer(x, buf, 3); \
} else { \
/* unsigned 32 */ \
const unsigned char buf[5] = {0xce, STORE32_BE32(d)}; \
msgpack_pack_append_buffer(x, buf, 5); \
} \
} \
} while(0)
#define msgpack_pack_real_int64(x, d) \
do { \
if(d < -(1LL<<5)) { \
if(d < -(1LL<<15)) { \
if(d < -(1LL<<31)) { \
/* signed 64 */ \
const unsigned char buf[9] = {0xd3, STORE64_BE64(d)}; \
msgpack_pack_append_buffer(x, buf, 9); \
} else { \
/* signed 32 */ \
const unsigned char buf[5] = {0xd2, STORE64_BE32(d)}; \
msgpack_pack_append_buffer(x, buf, 5); \
} \
} else { \
if(d < -(1<<7)) { \
/* signed 16 */ \
const unsigned char buf[3] = {0xd1, STORE64_BE16(d)}; \
msgpack_pack_append_buffer(x, buf, 3); \
} else { \
/* signed 8 */ \
const unsigned char buf[2] = {0xd0, STORE64_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} \
} \
} else if(d < (1<<7)) { \
/* fixnum */ \
msgpack_pack_append_buffer(x, &STORE64_BE8(d), 1); \
} else { \
if(d < (1LL<<16)) { \
if(d < (1<<8)) { \
/* unsigned 8 */ \
const unsigned char buf[2] = {0xcc, STORE64_BE8(d)}; \
msgpack_pack_append_buffer(x, buf, 2); \
} else { \
/* unsigned 16 */ \
const unsigned char buf[3] = {0xcd, STORE64_BE16(d)}; \
msgpack_pack_append_buffer(x, buf, 3); \
} \
} else { \
if(d < (1LL<<32)) { \
/* unsigned 32 */ \
const unsigned char buf[5] = {0xce, STORE64_BE32(d)}; \
msgpack_pack_append_buffer(x, buf, 5); \
} else { \
/* unsigned 64 */ \
const unsigned char buf[9] = {0xcf, STORE64_BE64(d)}; \
msgpack_pack_append_buffer(x, buf, 9); \
} \
} \
} \
} while(0)
#ifdef msgpack_pack_inline_func_fastint
msgpack_pack_inline_func_fastint(_uint8)(msgpack_pack_user x, uint8_t d)
{
const unsigned char buf[2] = {0xcc, STORE8_BE8(d)};
msgpack_pack_append_buffer(x, buf, 2);
}
msgpack_pack_inline_func_fastint(_uint16)(msgpack_pack_user x, uint16_t d)
{
const unsigned char buf[3] = {0xcd, STORE16_BE16(d)};
msgpack_pack_append_buffer(x, buf, 3);
}
msgpack_pack_inline_func_fastint(_uint32)(msgpack_pack_user x, uint32_t d)
{
const unsigned char buf[5] = {0xce, STORE32_BE32(d)};
msgpack_pack_append_buffer(x, buf, 5);
}
msgpack_pack_inline_func_fastint(_uint64)(msgpack_pack_user x, uint64_t d)
{
const unsigned char buf[9] = {0xcf, STORE64_BE64(d)};
msgpack_pack_append_buffer(x, buf, 9);
}
msgpack_pack_inline_func_fastint(_int8)(msgpack_pack_user x, int8_t d)
{
const unsigned char buf[2] = {0xd0, STORE8_BE8(d)};
msgpack_pack_append_buffer(x, buf, 2);
}
msgpack_pack_inline_func_fastint(_int16)(msgpack_pack_user x, int16_t d)
{
const unsigned char buf[3] = {0xd1, STORE16_BE16(d)};
msgpack_pack_append_buffer(x, buf, 3);
}
msgpack_pack_inline_func_fastint(_int32)(msgpack_pack_user x, int32_t d)
{
const unsigned char buf[5] = {0xd2, STORE32_BE32(d)};
msgpack_pack_append_buffer(x, buf, 5);
}
msgpack_pack_inline_func_fastint(_int64)(msgpack_pack_user x, int64_t d)
{
const unsigned char buf[9] = {0xd3, STORE64_BE64(d)};
msgpack_pack_append_buffer(x, buf, 9);
}
#undef msgpack_pack_inline_func_fastint
#endif
msgpack_pack_inline_func(_uint8)(msgpack_pack_user x, uint8_t d)
{
msgpack_pack_real_uint8(x, d);
}
msgpack_pack_inline_func(_uint16)(msgpack_pack_user x, uint16_t d)
{
msgpack_pack_real_uint16(x, d);
}
msgpack_pack_inline_func(_uint32)(msgpack_pack_user x, uint32_t d)
{
msgpack_pack_real_uint32(x, d);
}
msgpack_pack_inline_func(_uint64)(msgpack_pack_user x, uint64_t d)
{
msgpack_pack_real_uint64(x, d);
}
msgpack_pack_inline_func(_int8)(msgpack_pack_user x, int8_t d)
{
msgpack_pack_real_int8(x, d);
}
msgpack_pack_inline_func(_int16)(msgpack_pack_user x, int16_t d)
{
msgpack_pack_real_int16(x, d);
}
msgpack_pack_inline_func(_int32)(msgpack_pack_user x, int32_t d)
{
msgpack_pack_real_int32(x, d);
}
msgpack_pack_inline_func(_int64)(msgpack_pack_user x, int64_t d)
{
msgpack_pack_real_int64(x, d);
}
#ifdef msgpack_pack_inline_func_cint
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
msgpack_pack_real_int16(x, d);
#elif SIZEOF_SHORT == 4 || 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);
} else if(sizeof(short) == 4) {
msgpack_pack_real_int32(x, d);
} else {
msgpack_pack_real_int64(x, d);
}
#endif
}
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
msgpack_pack_real_int16(x, d);
#elif SIZEOF_INT == 4 || 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);
} else if(sizeof(int) == 4) {
msgpack_pack_real_int32(x, d);
} else {
msgpack_pack_real_int64(x, d);
}
#endif
}
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
msgpack_pack_real_int16(x, d);
#elif SIZEOF_LONG == 4 || 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);
} else if(sizeof(long) == 4) {
msgpack_pack_real_int32(x, d);
} else {
msgpack_pack_real_int64(x, d);
}
#endif
}
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
msgpack_pack_real_int16(x, d);
#elif SIZEOF_LONG_LONG == 4 || 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);
} else if(sizeof(long long) == 4) {
msgpack_pack_real_int32(x, d);
} else {
msgpack_pack_real_int64(x, d);
}
#endif
}
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
msgpack_pack_real_uint16(x, d);
#elif SIZEOF_SHORT == 4 || 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);
} else if(sizeof(unsigned short) == 4) {
msgpack_pack_real_uint32(x, d);
} else {
msgpack_pack_real_uint64(x, d);
}
#endif
}
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
msgpack_pack_real_uint16(x, d);
#elif SIZEOF_INT == 4 || 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);
} else if(sizeof(unsigned int) == 4) {
msgpack_pack_real_uint32(x, d);
} else {
msgpack_pack_real_uint64(x, d);
}
#endif
}
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
msgpack_pack_real_uint16(x, d);
#elif SIZEOF_LONG == 4 || ULONG_MAX == 0xffffffffUL
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);
} else if(sizeof(unsigned int) == 4) {
msgpack_pack_real_uint32(x, d);
} else {
msgpack_pack_real_uint64(x, d);
}
#endif
}
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
msgpack_pack_real_uint16(x, d);
#elif SIZEOF_LONG_LONG == 4 || 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);
} else if(sizeof(unsigned long long) == 4) {
msgpack_pack_real_uint32(x, d);
} else {
msgpack_pack_real_uint64(x, d);
}
#endif
}
#undef msgpack_pack_inline_func_cint
#endif
/*
* Float
*/
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)};
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)};
msgpack_pack_append_buffer(x, buf, 9);
}
/*
* Nil
*/
msgpack_pack_inline_func(_nil)(msgpack_pack_user x)
{
static const unsigned char d = 0xc0;
msgpack_pack_append_buffer(x, &d, 1);
}
/*
* Boolean
*/
msgpack_pack_inline_func(_true)(msgpack_pack_user x)
{
static const unsigned char d = 0xc3;
msgpack_pack_append_buffer(x, &d, 1);
}
msgpack_pack_inline_func(_false)(msgpack_pack_user x)
{
static const unsigned char d = 0xc2;
msgpack_pack_append_buffer(x, &d, 1);
}
/*
* Array
*/
msgpack_pack_inline_func(_array)(msgpack_pack_user x, unsigned int n)
{
if(n < 16) {
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)};
msgpack_pack_append_buffer(x, buf, 3);
} else {
uint32_t d = (uint32_t)n;
unsigned char buf[5] = {0xdd, STORE32_BE32(d)};
msgpack_pack_append_buffer(x, buf, 5);
}
}
/*
* Map
*/
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);
} else if(n < 65536) {
uint16_t d = (uint16_t)n;
unsigned char buf[3] = {0xde, STORE16_BE16(d)};
msgpack_pack_append_buffer(x, buf, 3);
} else {
uint32_t d = (uint32_t)n;
unsigned char buf[5] = {0xdf, STORE32_BE32(d)};
msgpack_pack_append_buffer(x, buf, 5);
}
}
/*
* Raw
*/
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);
} else if(l < 65536) {
uint16_t d = (uint16_t)l;
unsigned char buf[3] = {0xda, STORE16_BE16(d)};
msgpack_pack_append_buffer(x, buf, 3);
} else {
uint32_t d = (uint32_t)l;
unsigned char buf[5] = {0xdb, STORE32_BE32(d)};
msgpack_pack_append_buffer(x, buf, 5);
}
}
msgpack_pack_inline_func(_raw_body)(msgpack_pack_user x, const void* b, size_t l)
{
msgpack_pack_append_buffer(x, (const unsigned char*)b, l);
}
#undef msgpack_pack_inline_func
#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 msgpack_pack_real_uint8
#undef msgpack_pack_real_uint16
#undef msgpack_pack_real_uint32
#undef msgpack_pack_real_uint64
#undef msgpack_pack_real_int8
#undef msgpack_pack_real_int16
#undef msgpack_pack_real_int32
#undef msgpack_pack_real_int64

View File

@ -1,129 +0,0 @@
/*
* MessagePack unpacking routine template
*
* 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_UNPACK_DEFINE_H__
#define MSGPACK_UNPACK_DEFINE_H__
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#ifndef __WIN32__
#include <arpa/inet.h>
#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)
#endif
typedef enum {
CS_HEADER = 0x00, // nil
//CS_ = 0x01,
//CS_ = 0x02, // false
//CS_ = 0x03, // true
//CS_ = 0x04,
//CS_ = 0x05,
//CS_ = 0x06,
//CS_ = 0x07,
//CS_ = 0x08,
//CS_ = 0x09,
CS_FLOAT = 0x0a,
CS_DOUBLE = 0x0b,
CS_UINT_8 = 0x0c,
CS_UINT_16 = 0x0d,
CS_UINT_32 = 0x0e,
CS_UINT_64 = 0x0f,
CS_INT_8 = 0x10,
CS_INT_16 = 0x11,
CS_INT_32 = 0x12,
CS_INT_64 = 0x13,
//CS_ = 0x14,
//CS_ = 0x15,
//CS_BIG_INT_16 = 0x16,
//CS_BIG_INT_32 = 0x17,
//CS_BIG_FLOAT_16 = 0x18,
//CS_BIG_FLOAT_32 = 0x19,
CS_RAW_16 = 0x1a,
CS_RAW_32 = 0x1b,
CS_ARRAY_16 = 0x1c,
CS_ARRAY_32 = 0x1d,
CS_MAP_16 = 0x1e,
CS_MAP_32 = 0x1f,
//ACS_BIG_INT_VALUE,
//ACS_BIG_FLOAT_VALUE,
ACS_RAW_VALUE,
} msgpack_unpack_state;
typedef enum {
CT_ARRAY_ITEM,
CT_MAP_KEY,
CT_MAP_VALUE,
} msgpack_container_type;
#ifdef __cplusplus
}
#endif
#endif /* msgpack/unpack_define.h */

View File

@ -1,361 +0,0 @@
/*
* MessagePack unpacking routine template
*
* 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_unpack_func
#error msgpack_unpack_func template is not defined
#endif
#ifndef msgpack_unpack_callback
#error msgpack_unpack_callback template is not defined
#endif
#ifndef msgpack_unpack_struct
#error msgpack_unpack_struct template is not defined
#endif
#ifndef msgpack_unpack_struct_decl
#define msgpack_unpack_struct_decl(name) msgpack_unpack_struct(name)
#endif
#ifndef msgpack_unpack_object
#error msgpack_unpack_object type is not defined
#endif
#ifndef msgpack_unpack_user
#error msgpack_unpack_user type is not defined
#endif
msgpack_unpack_struct_decl(_stack) {
msgpack_unpack_object obj;
size_t count;
unsigned int ct;
msgpack_unpack_object map_key;
};
msgpack_unpack_struct_decl(_context) {
msgpack_unpack_user user;
unsigned int cs;
unsigned int trail;
unsigned int top;
msgpack_unpack_struct(_stack) stack[MSGPACK_MAX_STACK_SIZE];
};
msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx)
{
ctx->cs = CS_HEADER;
ctx->trail = 0;
ctx->top = 0;
ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user);
}
msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx)
{
return (ctx)->stack[0].obj;
}
msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off)
{
assert(len >= *off);
const unsigned char* p = (unsigned char*)data + *off;
const unsigned char* const pe = (unsigned char*)data + len;
const void* n = NULL;
unsigned int trail = ctx->trail;
unsigned int cs = ctx->cs;
unsigned int top = ctx->top;
msgpack_unpack_struct(_stack)* stack = ctx->stack;
msgpack_unpack_user* user = &ctx->user;
msgpack_unpack_object obj;
msgpack_unpack_struct(_stack)* c = NULL;
int ret;
#define push_simple_value(func) \
if(msgpack_unpack_callback(func)(user, &obj) < 0) { goto _failed; } \
goto _push
#define push_fixed_value(func, arg) \
if(msgpack_unpack_callback(func)(user, arg, &obj) < 0) { goto _failed; } \
goto _push
#define push_variable_value(func, base, pos, len) \
if(msgpack_unpack_callback(func)(user, \
(const char*)base, (const char*)pos, len, &obj) < 0) { goto _failed; } \
goto _push
#define again_fixed_trail(_cs, trail_len) \
trail = trail_len; \
cs = _cs; \
goto _fixed_trail_again
#define again_fixed_trail_if_zero(_cs, trail_len, ifzero) \
trail = trail_len; \
if(trail == 0) { goto ifzero; } \
cs = _cs; \
goto _fixed_trail_again
#define start_container(func, count_, ct_) \
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_; \
/*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \
/*printf("stack push %d\n", top);*/ \
++top; \
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)
if(p == pe) { goto _out; }
do {
switch(cs) {
case CS_HEADER:
switch(*p) {
case 0x00 ... 0x7f: // Positive Fixnum
push_fixed_value(_uint8, *(uint8_t*)p);
case 0xe0 ... 0xff: // Negative Fixnum
push_fixed_value(_int8, *(int8_t*)p);
case 0xc0 ... 0xdf: // Variable
switch(*p) {
case 0xc0: // nil
push_simple_value(_nil);
//case 0xc1: // string
// again_terminal_trail(NEXT_CS(p), p+1);
case 0xc2: // false
push_simple_value(_false);
case 0xc3: // true
push_simple_value(_true);
//case 0xc4:
//case 0xc5:
//case 0xc6:
//case 0xc7:
//case 0xc8:
//case 0xc9:
case 0xca: // float
case 0xcb: // double
case 0xcc: // unsigned int 8
case 0xcd: // unsigned int 16
case 0xce: // unsigned int 32
case 0xcf: // unsigned int 64
case 0xd0: // signed int 8
case 0xd1: // signed int 16
case 0xd2: // signed int 32
case 0xd3: // signed int 64
again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03));
//case 0xd4:
//case 0xd5:
//case 0xd6: // big integer 16
//case 0xd7: // big integer 32
//case 0xd8: // big float 16
//case 0xd9: // big float 32
case 0xda: // raw 16
case 0xdb: // raw 32
case 0xdc: // array 16
case 0xdd: // array 32
case 0xde: // map 16
case 0xdf: // map 32
again_fixed_trail(NEXT_CS(p), 2 << (((unsigned int)*p) & 0x01));
default:
goto _failed;
}
case 0xa0 ... 0xbf: // FixRaw
again_fixed_trail_if_zero(ACS_RAW_VALUE, ((unsigned int)*p & 0x1f), _raw_zero);
case 0x90 ... 0x9f: // FixArray
start_container(_array, ((unsigned int)*p) & 0x0f, CT_ARRAY_ITEM);
case 0x80 ... 0x8f: // FixMap
start_container(_map, ((unsigned int)*p) & 0x0f, CT_MAP_KEY);
default:
goto _failed;
}
// end CS_HEADER
_fixed_trail_again:
++p;
default:
if((size_t)(pe - p) < trail) { goto _out; }
n = p; p += trail - 1;
switch(cs) {
//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)); }
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)); }
case CS_UINT_8:
push_fixed_value(_uint8, (uint8_t)PTR_CAST_8(n));
case CS_UINT_16:
push_fixed_value(_uint16, (uint16_t)PTR_CAST_16(n));
case CS_UINT_32:
push_fixed_value(_uint32, (uint32_t)PTR_CAST_32(n));
case CS_UINT_64:
push_fixed_value(_uint64, (uint64_t)PTR_CAST_64(n));
case CS_INT_8:
push_fixed_value(_int8, (int8_t)PTR_CAST_8(n));
case CS_INT_16:
push_fixed_value(_int16, (int16_t)PTR_CAST_16(n));
case CS_INT_32:
push_fixed_value(_int32, (int32_t)PTR_CAST_32(n));
case CS_INT_64:
push_fixed_value(_int64, (int64_t)PTR_CAST_64(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);
//case CS_BIG_INT_32:
// again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, (uint32_t)PTR_CAST_32(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);
//case CS_BIG_FLOAT_32:
// again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, (uint32_t)PTR_CAST_32(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);
case CS_RAW_32:
again_fixed_trail_if_zero(ACS_RAW_VALUE, (uint32_t)PTR_CAST_32(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);
case CS_ARRAY_32:
/* FIXME security guard */
start_container(_array, (uint32_t)PTR_CAST_32(n), CT_ARRAY_ITEM);
case CS_MAP_16:
start_container(_map, (uint16_t)PTR_CAST_16(n), CT_MAP_KEY);
case CS_MAP_32:
/* FIXME security guard */
start_container(_map, (uint32_t)PTR_CAST_32(n), CT_MAP_KEY);
default:
goto _failed;
}
}
_push:
if(top == 0) { goto _finish; }
c = &stack[top-1];
switch(c->ct) {
case CT_ARRAY_ITEM:
if(msgpack_unpack_callback(_array_item)(user, &c->obj, obj) < 0) { goto _failed; }
if(--c->count == 0) {
obj = c->obj;
--top;
/*printf("stack pop %d\n", top);*/
goto _push;
}
goto _header_again;
case CT_MAP_KEY:
c->map_key = obj;
c->ct = CT_MAP_VALUE;
goto _header_again;
case CT_MAP_VALUE:
if(msgpack_unpack_callback(_map_item)(user, &c->obj, c->map_key, obj) < 0) { goto _failed; }
if(--c->count == 0) {
obj = c->obj;
--top;
/*printf("stack pop %d\n", top);*/
goto _push;
}
c->ct = CT_MAP_KEY;
goto _header_again;
default:
goto _failed;
}
_header_again:
cs = CS_HEADER;
++p;
} while(p != pe);
goto _out;
_finish:
stack[0].obj = obj;
++p;
ret = 1;
/*printf("-- finish --\n"); */
goto _end;
_failed:
/*printf("** FAILED **\n"); */
ret = -1;
goto _end;
_out:
ret = 0;
goto _end;
_end:
ctx->cs = cs;
ctx->trail = trail;
ctx->top = top;
*off = p - (const unsigned char*)data;
return ret;
}
#undef msgpack_unpack_func
#undef msgpack_unpack_callback
#undef msgpack_unpack_struct
#undef msgpack_unpack_object
#undef msgpack_unpack_user
#undef push_simple_value
#undef push_fixed_value
#undef push_variable_value
#undef again_fixed_trail
#undef again_fixed_trail_if_zero
#undef start_container
#undef NEXT_CS
#undef PTR_CAST_8
#undef PTR_CAST_16
#undef PTR_CAST_32
#undef PTR_CAST_64

340
php/msgpack_class.c Normal file
View File

@ -0,0 +1,340 @@
#include "php.h"
#include "php_msgpack.h"
#include "msgpack_pack.h"
#include "msgpack_unpack.h"
#include "msgpack_class.h"
typedef struct {
zend_object object;
smart_str buffer;
zval *retval;
long offset;
} php_msgpack_unpacker_t;
#if ZEND_MODULE_API_NO >= 20060613
#define MAGPACK_METHOD_BASE(classname, name) zim_##classname##_##name
#else
#define MSGPACK_METHOD_BASE(classname, name) zif_##classname##_##name
#endif
#define MSGPACK_METHOD(classname, name, retval, thisptr) \
MAGPACK_METHOD_BASE(classname, name)(0, retval, NULL, thisptr, 0 TSRMLS_CC)
#define MSGPACK_UNPACKER_OBJECT \
php_msgpack_unpacker_t *unpacker; \
unpacker =(php_msgpack_unpacker_t *)zend_object_store_get_object(getThis() TSRMLS_CC);
/* MessagePack */
static zend_class_entry *msgpack_ce = NULL;
static ZEND_METHOD(msgpack, pack);
static ZEND_METHOD(msgpack, unpack);
static ZEND_METHOD(msgpack, unpacker);
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, 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, __construct);
static ZEND_METHOD(msgpack, __destruct);
static ZEND_METHOD(msgpack, feed);
static ZEND_METHOD(msgpack, execute);
static ZEND_METHOD(msgpack, data);
static ZEND_METHOD(msgpack, reset);
ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unpacker___construct, 0, 0, 0)
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_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, __construct,
arginfo_msgpack_unpacker___construct, ZEND_ACC_PUBLIC)
ZEND_ME(msgpack, __destruct,
arginfo_msgpack_unpacker___destruct, ZEND_ACC_PUBLIC)
ZEND_ME(msgpack, feed, arginfo_msgpack_unpacker_feed, ZEND_ACC_PUBLIC)
ZEND_ME(msgpack, execute, arginfo_msgpack_unpacker_execute, ZEND_ACC_PUBLIC)
ZEND_ME(msgpack, data, arginfo_msgpack_unpacker_data, ZEND_ACC_PUBLIC)
ZEND_ME(msgpack, reset, arginfo_msgpack_unpacker_reset, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
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, pack)
{
zval *parameter;
smart_str buf = {0};
if (zend_parse_parameters(
ZEND_NUM_ARGS() TSRMLS_CC, "z", &parameter) == FAILURE)
{
return;
}
php_msgpack_serialize(&buf, parameter TSRMLS_CC);
ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
smart_str_free(&buf);
}
static ZEND_METHOD(msgpack, unpack)
{
char *str;
int str_len;
if (zend_parse_parameters(
ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE)
{
return;
}
if (!str_len)
{
RETURN_NULL();
}
php_msgpack_unserialize(return_value, str, str_len TSRMLS_CC);
}
static ZEND_METHOD(msgpack, unpacker)
{
zval temp;
object_init_ex(return_value, msgpack_unpacker_ce);
MSGPACK_METHOD(msgpack, __construct, &temp, return_value);
}
/* MessagePackUnpacker */
static ZEND_METHOD(msgpack, __construct)
{
MSGPACK_UNPACKER_OBJECT;
unpacker->buffer.c = NULL;
unpacker->buffer.len = 0;
unpacker->buffer.a = 0;
unpacker->retval = NULL;
unpacker->offset = 0;
}
static ZEND_METHOD(msgpack, __destruct)
{
MSGPACK_UNPACKER_OBJECT;
smart_str_free(&unpacker->buffer);
if (unpacker->retval != NULL)
{
zval_ptr_dtor(&unpacker->retval);
}
}
static ZEND_METHOD(msgpack, 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, execute)
{
char *str = NULL;
long str_len = 0;
zval *offset;
int ret;
php_unserialize_data_t var_hash;
msgpack_unserialize_data mpsd;
MSGPACK_UNPACKER_OBJECT;
if (zend_parse_parameters(
ZEND_NUM_ARGS() TSRMLS_CC, "|sz/",
&str, &str_len, &offset) == FAILURE)
{
return;
}
if (str != NULL)
{
mpsd.data = (unsigned char *)str;
mpsd.length = str_len;
mpsd.offset = Z_LVAL_P(offset);
}
else
{
mpsd.data = (unsigned char *)unpacker->buffer.c;
mpsd.length = unpacker->buffer.len;
mpsd.offset = unpacker->offset;
}
if (mpsd.length <= 0 || mpsd.length == mpsd.offset)
{
RETURN_FALSE;
}
PHP_VAR_UNSERIALIZE_INIT(var_hash);
if (unpacker->retval == NULL)
{
ALLOC_INIT_ZVAL(unpacker->retval);
}
MSGPACK_G(error_display) = 0;
ret = msgpack_unserialize_zval(
&unpacker->retval, &mpsd, &var_hash TSRMLS_CC);
MSGPACK_G(error_display) = 1;
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
if (str != NULL)
{
ZVAL_LONG(offset, mpsd.offset);
}
else
{
unpacker->offset = mpsd.offset;
}
switch (ret)
{
case MSGPACK_UNPACK_EXTRA_BYTES:
case MSGPACK_UNPACK_SUCCESS:
RETURN_TRUE;
default:
RETURN_FALSE;
}
}
static ZEND_METHOD(msgpack, data)
{
MSGPACK_UNPACKER_OBJECT;
RETURN_ZVAL(unpacker->retval, 1, 1);
}
static ZEND_METHOD(msgpack, 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;
}
}
void msgpack_init_class(TSRMLS_DC)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "MessagePack", msgpack_base_methods);
msgpack_ce = zend_register_internal_class(&ce TSRMLS_CC);
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;
}

7
php/msgpack_class.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef MSGPACL_CLASS_H
#define MSGPACL_CLASS_H
void msgpack_init_class(TSRMLS_DC);
#endif

514
php/msgpack_pack.c Normal file
View File

@ -0,0 +1,514 @@
#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)
{
zend_error(E_NOTICE,
"[msgpack] (msgpack_serialize_class) "
"__sleep should return an array only "
"containing the names of "
"instance-variables to serialize.");
msgpack_pack_nil(buf);
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);
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;
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)
{
msgpack_pack_map(buf, n + 1);
msgpack_pack_nil(buf);
msgpack_serialize_string(buf, class_name, name_len);
}
else if (n == 0)
{
msgpack_pack_array(buf, n);
}
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;
}
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(""));
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
{
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 (var_hash &&
msgpack_var_add(
var_hash, val, (void *)&var_already TSRMLS_CC) == FAILURE)
{
if (Z_ISREF_P(val))
{
msgpack_pack_map(buf, 2);
msgpack_pack_nil(buf);
msgpack_pack_long(buf, MSGPACK_SERIALIZE_TYPE_REFERENCE);
msgpack_pack_nil(buf);
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_OBJECT);
msgpack_pack_nil(buf);
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:
zend_error(E_WARNING,
"[msgpack] (php_msgpack_serialize) "
"type is unsupported, encoded as null");
msgpack_pack_nil(buf);
break;
}
return;
}

17
php/msgpack_pack.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef MSGPACL_PACK_H
#define MSGPACL_PACK_H
#include "ext/standard/php_smart_str.h"
enum msgpack_serialize_type
{
MSGPACK_SERIALIZE_TYPE_REFERENCE = 1,
MSGPACK_SERIALIZE_TYPE_OBJECT,
MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT,
};
void msgpack_serialize_zval(
smart_str *buf, zval *val, HashTable *var_hash TSRMLS_DC);
#endif

829
php/msgpack_unpack.c Normal file
View File

@ -0,0 +1,829 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/php_incomplete_class.h"
#include "ext/standard/php_var.h"
#include "php_msgpack.h"
#include "msgpack_pack.h"
#include "msgpack_unpack.h"
#include "msgpack/unpack_define.h"
#define VAR_ENTRIES_MAX 1024
#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
typedef struct
{
zval *data[VAR_ENTRIES_MAX];
long used_slots;
void *next;
} var_entries;
inline static void msgpack_var_push(
php_unserialize_data_t *var_hashx, zval **rval)
{
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->next = 0;
if (!var_hashx->first)
{
var_hashx->first = var_hash;
}
else
{
prev->next = var_hash;
}
}
var_hash->data[var_hash->used_slots++] = *rval;
}
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->used_slots)
{
return !SUCCESS;
}
*store = &var_hash->data[id];
return SUCCESS;
}
inline static int msgpack_unserialize_array(
zval **return_value, msgpack_unserialize_data *mpsd,
ulong ct, php_unserialize_data_t *var_hash TSRMLS_DC)
{
ulong i;
HashTable *ht;
msgpack_var_push(var_hash, return_value);
if (Z_TYPE_PP(return_value) != IS_ARRAY)
{
array_init(*return_value);
}
ht = HASH_OF(*return_value);
for (i = 0; i < ct; i++)
{
zval *val;
/* value */
ALLOC_INIT_ZVAL(val);
if (msgpack_unserialize_zval(&val, mpsd, var_hash TSRMLS_CC) <= 0)
{
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (msgpack_unserialize_array) "
"Invalid value");
}
zval_ptr_dtor(&val);
return MSGPACK_UNPACK_PARSE_ERROR;
}
/* update */
zend_hash_index_update(ht, i, &val, sizeof(zval *), NULL);
}
return MSGPACK_UNPACK_SUCCESS;
}
inline static int msgpack_unserialize_object_type(
zval **return_value, msgpack_unserialize_data *mpsd,
php_unserialize_data_t *var_hash, zend_bool is_ref TSRMLS_DC)
{
int ret = MSGPACK_UNPACK_SUCCESS;
zval *key, *val, **rval;
ALLOC_INIT_ZVAL(key);
if (msgpack_unserialize_zval(&key, mpsd, NULL TSRMLS_CC) <= 0)
{
zval_ptr_dtor(&key);
ZVAL_BOOL(*return_value, 0);
return MSGPACK_UNPACK_PARSE_ERROR;
}
ALLOC_INIT_ZVAL(val);
if (is_ref)
{
ret = msgpack_unserialize_zval(&val, mpsd, NULL TSRMLS_CC);
}
else
{
ret = msgpack_unserialize_zval(&val, mpsd, var_hash TSRMLS_CC);
}
if (ret <= 0)
{
zval_ptr_dtor(&val);
zval_ptr_dtor(&key);
ZVAL_BOOL(*return_value, 0);
return MSGPACK_UNPACK_PARSE_ERROR;
}
if (!var_hash ||
msgpack_var_access(var_hash, Z_LVAL_P(val) - 1, &rval) != SUCCESS)
{
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (msgpack_unserialize_object_key) "
"Invalid references value: %ld",
Z_LVAL_P(val) - 1);
}
ret = MSGPACK_UNPACK_CONTINUE;
}
else
{
if (*return_value != NULL)
{
zval_ptr_dtor(return_value);
}
*return_value = *rval;
Z_ADDREF_PP(return_value);
if (is_ref)
{
Z_SET_ISREF_PP(return_value);
}
else
{
Z_UNSET_ISREF_PP(return_value);
}
}
zval_ptr_dtor(&key);
zval_ptr_dtor(&val);
return ret;
}
inline static int msgpack_unserialize_object(
zval **return_value, msgpack_unserialize_data *mpsd,
ulong ct, php_unserialize_data_t *var_hash TSRMLS_DC)
{
int ret = MSGPACK_UNPACK_SUCCESS;
zend_class_entry *ce, **pce;
bool incomplete_class = false;
zval *user_func, *retval_ptr, **args[1], *arg_func_name;
HashTable *ht;
zval *key, *val;
int object = 1;
int custom_object = 0;
/* Get class */
ALLOC_INIT_ZVAL(key);
if (msgpack_unserialize_zval(&key, mpsd, NULL TSRMLS_CC) <= 0)
{
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (msgpack_unserialize_object) "
"Invalid sign key");
}
zval_ptr_dtor(&key);
ZVAL_BOOL(*return_value, 0);
return MSGPACK_UNPACK_PARSE_ERROR;
}
ct--;
if (Z_TYPE_P(key) == IS_NULL)
{
ALLOC_INIT_ZVAL(val);
if (msgpack_unserialize_zval(&val, mpsd, NULL TSRMLS_CC) <= 0)
{
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (msgpack_unserialize_object) "
"Invalid sign value");
}
zval_ptr_dtor(&val);
zval_ptr_dtor(&key);
ZVAL_BOOL(*return_value, 0);
return MSGPACK_UNPACK_PARSE_ERROR;
}
if (Z_TYPE_P(val) == IS_LONG)
{
switch (Z_LVAL_P(val))
{
case MSGPACK_SERIALIZE_TYPE_REFERENCE:
ret = msgpack_unserialize_object_type(
return_value, mpsd, var_hash, 1 TSRMLS_CC);
zval_ptr_dtor(&key);
zval_ptr_dtor(&val);
return ret;
case MSGPACK_SERIALIZE_TYPE_OBJECT:
ret = msgpack_unserialize_object_type(
return_value, mpsd, var_hash, 0 TSRMLS_CC);
zval_ptr_dtor(&key);
zval_ptr_dtor(&val);
return ret;
case MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT:
custom_object = 1;
zval_ptr_dtor(&val);
ALLOC_INIT_ZVAL(val);
if (msgpack_unserialize_zval(
&val, mpsd, NULL TSRMLS_CC) <= 0)
{
zval_ptr_dtor(&key);
zval_ptr_dtor(&val);
ZVAL_BOOL(*return_value, 0);
return MSGPACK_UNPACK_PARSE_ERROR;
}
break;
default:
zval_ptr_dtor(&key);
zval_ptr_dtor(&val);
ZVAL_BOOL(*return_value, 0);
return MSGPACK_UNPACK_PARSE_ERROR;
}
}
}
else
{
object = 0;
msgpack_var_push(var_hash, return_value);
if (Z_TYPE_PP(return_value) != IS_ARRAY)
{
array_init(*return_value);
}
ht = HASH_OF(*return_value);
ALLOC_INIT_ZVAL(val);
if (msgpack_unserialize_zval(&val, mpsd, var_hash TSRMLS_CC) <= 0)
{
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (msgpack_unserialize_object) "
"Invalid sign value");
}
zval_ptr_dtor(&val);
zval_ptr_dtor(&key);
return MSGPACK_UNPACK_PARSE_ERROR;
}
/* update */
switch (Z_TYPE_P(key))
{
case IS_LONG:
zend_hash_index_update(
ht, Z_LVAL_P(key), &val, sizeof(zval *), NULL);
break;
case IS_STRING:
zend_symtable_update(
ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1,
&val, sizeof(zval *), NULL);
break;
default:
zval_ptr_dtor(&key);
zval_ptr_dtor(&val);
return MSGPACK_UNPACK_PARSE_ERROR;
}
}
zval_ptr_dtor(&key);
if (object)
{
convert_to_string(val);
do {
/* Try to find class directly */
if (zend_lookup_class(
Z_STRVAL_P(val), Z_STRLEN_P(val), &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, Z_STRVAL_P(val), 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_object) "
"defined (%s) but not found", Z_STRVAL_P(val));
}
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(
Z_STRVAL_P(val), Z_STRLEN_P(val), &pce TSRMLS_CC) == SUCCESS)
{
ce = *pce;
}
else
{
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (msgpack_unserialize_object) "
"Function %s() hasn't defined the class"
"it was called for", Z_STRVAL_P(val));
}
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_object) "
"Exception error");
}
zval_ptr_dtor(&val);
ZVAL_BOOL(*return_value, 0);
return MSGPACK_UNPACK_PARSE_ERROR;
}
msgpack_var_push(var_hash, return_value);
object_init_ex(*return_value, ce);
/* store incomplete class name */
if (incomplete_class)
{
php_store_class_name(
*return_value, Z_STRVAL_P(val), Z_STRLEN_P(val));
}
zval_ptr_dtor(&val);
/* implementing Serializable */
if (custom_object)
{
zval *rval;
if (ce->unserialize == NULL)
{
if (MSGPACK_G(error_display))
{
zend_error(E_WARNING,
"[msgpack] (msgpack_unserialize_object) "
"Class %s has no unserializer", ce->name);
}
return MSGPACK_UNPACK_PARSE_ERROR;
}
/* value */
ALLOC_INIT_ZVAL(rval);
if (msgpack_unserialize_zval(&rval, mpsd, var_hash TSRMLS_CC) <= 0)
{
zval_ptr_dtor(&rval);
return MSGPACK_UNPACK_PARSE_ERROR;
}
ce->unserialize(
return_value, ce,
(const unsigned char *)Z_STRVAL_P(rval), Z_STRLEN_P(rval) + 1,
(zend_unserialize_data *)var_hash TSRMLS_CC);
zval_ptr_dtor(&key);
zval_ptr_dtor(&rval);
return ret;
}
ht = HASH_OF(*return_value);
}
/* object property */
while (ct-- > 0)
{
zval *rval;
/* key */
ALLOC_INIT_ZVAL(key);
if (msgpack_unserialize_zval(&key, mpsd, NULL TSRMLS_CC) <= 0)
{
zval_ptr_dtor(&key);
return MSGPACK_UNPACK_PARSE_ERROR;
}
/* value */
ALLOC_INIT_ZVAL(rval);
if (msgpack_unserialize_zval(&rval, mpsd, var_hash TSRMLS_CC) <= 0)
{
zval_ptr_dtor(&rval);
zval_ptr_dtor(&key);
return MSGPACK_UNPACK_PARSE_ERROR;
}
/* update */
switch (Z_TYPE_P(key))
{
case IS_LONG:
zend_hash_index_update(
ht, Z_LVAL_P(key), &rval, sizeof(zval *), NULL);
break;
case IS_STRING:
zend_symtable_update(
ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1,
&rval, sizeof(zval *), NULL);
break;
default:
zval_ptr_dtor(&key);
zval_ptr_dtor(&rval);
return MSGPACK_UNPACK_PARSE_ERROR;
}
zval_ptr_dtor(&key);
}
/* wakeup */
if (object && Z_OBJCE_PP(return_value) != PHP_IC_ENTRY &&
zend_hash_exists(&Z_OBJCE_PP(return_value)->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), return_value, &f, &h, 0, 0, 1, NULL TSRMLS_CC);
if (h)
{
zval_ptr_dtor(&h);
}
if (EG(exception))
{
ret = MSGPACK_UNPACK_PARSE_ERROR;
}
}
return ret;
}
int msgpack_unserialize_zval(
zval **return_value, msgpack_unserialize_data *mpsd,
php_unserialize_data_t *var_hash TSRMLS_DC)
{
const unsigned char* data = mpsd->data;
const unsigned char* const pe = mpsd->data + mpsd->length;
const void* n = NULL;
unsigned int trail = 0;
unsigned int cs = CS_HEADER;
int ret;
unsigned int ct;
#define next_cs(p) ((unsigned int)*p & 0x1f)
#define finish_zval_long(val_) \
msgpack_var_push(var_hash, return_value); \
ZVAL_LONG(*return_value, val_); \
goto _finish
#define finish_zval_null() \
msgpack_var_push(var_hash, return_value); \
ZVAL_NULL(*return_value); \
goto _finish
#define finish_zval_bool(val_) \
msgpack_var_push(var_hash, return_value); \
ZVAL_BOOL(*return_value, val_); \
goto _finish
#define finish_zval_double(val_) \
msgpack_var_push(var_hash, return_value); \
ZVAL_DOUBLE(*return_value, val_); \
goto _finish
#define finish_zval_string(val_, len_) \
msgpack_var_push(var_hash, return_value); \
if (len_ == 0) { ZVAL_STRINGL(*return_value, "", 0, 1); } \
else { ZVAL_STRINGL(*return_value, val_, len_, 1); } \
goto _finish
#define finish_zval_array(count_) \
ct = count_; \
cs = CS_HEADER; \
++(mpsd->data); \
mpsd->length = (pe - mpsd->data); \
if (msgpack_unserialize_array(return_value, mpsd, ct, var_hash TSRMLS_CC) <= 0) { goto _failed; } \
goto _finish_end
#define finish_zval_object(count_) \
ct = count_; \
cs = CS_HEADER; \
++(mpsd->data); \
mpsd->length = (pe - mpsd->data); \
if (msgpack_unserialize_object(return_value, mpsd, ct, var_hash TSRMLS_CC) <= 0) { goto _failed; } \
goto _finish_end
#define again_fixed_trail(_cs, trail_len) \
trail = trail_len; \
cs = _cs; \
goto _fixed_trail_again
#define again_fixed_trail_if_zero(_cs, trail_len, ifzero) \
trail = trail_len; \
if(trail == 0) { goto ifzero; } \
cs = _cs; \
goto _fixed_trail_again
if (mpsd->length <= 0)
{
goto _failed;
}
if (mpsd->data == pe)
{
goto _out;
}
do
{
switch (cs)
{
case CS_HEADER:
switch (*(mpsd->data))
{
case 0x00 ... 0x7f: /* Positive Fixnum */
finish_zval_long(*(uint8_t*)mpsd->data);
case 0xe0 ... 0xff: /* Negative Fixnum */
finish_zval_long(*(int8_t*)mpsd->data);
case 0xc0 ... 0xdf: /* Variable */
switch (*(mpsd->data))
{
case 0xc0: /* nil */
finish_zval_null();
case 0xc2: /* false */
finish_zval_bool(0);
case 0xc3: /* true */
finish_zval_bool(1);
case 0xca: /* float */
case 0xcb: /* double */
case 0xcc: /* unsigned int 8 */
case 0xcd: /* unsigned int 16 */
case 0xce: /* unsigned int 32 */
case 0xcf: /* unsigned int 64 */
case 0xd0: /* signed int 8 */
case 0xd1: /* signed int 16 */
case 0xd2: /* signed int 32 */
case 0xd3: /* signed int 64 */
again_fixed_trail(
next_cs(mpsd->data),
1 << (((unsigned int)*(mpsd->data)) & 0x03));
case 0xda: /* raw 16 */
case 0xdb: /* raw 32 */
case 0xdc: /* array 16 */
case 0xdd: /* array 32 */
case 0xde: /* map 16 */
case 0xdf: /* map 32 */
again_fixed_trail(
next_cs(mpsd->data),
2 << (((unsigned int)*(mpsd->data)) & 0x01));
default:
goto _failed;
}
case 0xa0 ... 0xbf: /* FixRaw */
again_fixed_trail_if_zero(
ACS_RAW_VALUE, (unsigned int)*(mpsd->data) & 0x1f,
_raw_zero);
case 0x90 ... 0x9f: /* FixArray */
finish_zval_array(((unsigned int)*(mpsd->data)) & 0x0f);
case 0x80 ... 0x8f: /* FixMap */
finish_zval_object(((unsigned int)*(mpsd->data)) & 0x0f);
default:
goto _failed;
}
_fixed_trail_again:
++(mpsd->data);
default:
if ((size_t)(pe - (mpsd->data)) < trail)
{
goto _out;
}
n = (mpsd->data);
mpsd->data += trail - 1;
switch (cs)
{
case CS_FLOAT:
{
union { uint32_t i; float f; } mem;
mem.i = _msgpack_load32(uint32_t, n);
finish_zval_double(mem.f);
}
case CS_DOUBLE:
{
union { uint64_t i; double f; } mem;
mem.i = _msgpack_load64(uint64_t, n);
finish_zval_double(mem.f);
}
case CS_UINT_8:
finish_zval_long(*(uint8_t*)n);
case CS_UINT_16:
finish_zval_long(_msgpack_load16(uint16_t, n));
case CS_UINT_32:
finish_zval_long(_msgpack_load32(uint32_t, n));
case CS_UINT_64:
finish_zval_long(_msgpack_load64(uint64_t, n));
case CS_INT_8:
finish_zval_long(*(int8_t*)n);
case CS_INT_16:
finish_zval_long(_msgpack_load16(int16_t, n));
case CS_INT_32:
finish_zval_long(_msgpack_load32(int32_t, n));
case CS_INT_64:
finish_zval_long(_msgpack_load64(int64_t, n));
case CS_RAW_16:
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, _msgpack_load32(uint32_t, n),
_raw_zero);
case ACS_RAW_VALUE:
_raw_zero:
finish_zval_string(n, trail);
case CS_ARRAY_16:
finish_zval_array(_msgpack_load16(uint16_t, n));
case CS_ARRAY_32:
finish_zval_array(_msgpack_load32(uint32_t, n));
/* FIXME security guard */
case CS_MAP_16:
finish_zval_object(_msgpack_load16(uint16_t, n));
case CS_MAP_32:
finish_zval_object(_msgpack_load32(uint32_t, n));
/* FIXME security guard */
default:
goto _failed;
}
}
cs = CS_HEADER;
++(mpsd->data);
}
while (mpsd->data != pe);
goto _out;
_finish:
++(mpsd->data);
_finish_end:
ret = MSGPACK_UNPACK_EXTRA_BYTES;
goto _end;
_failed:
ret = MSGPACK_UNPACK_PARSE_ERROR;
goto _end;
_out:
ret = MSGPACK_UNPACK_CONTINUE;
goto _end;
_end:
mpsd->offset = mpsd->data - data;
mpsd->length = pe - mpsd->data;
if (ret == MSGPACK_UNPACK_EXTRA_BYTES && mpsd->length == 0)
{
ret = MSGPACK_UNPACK_SUCCESS;
}
return ret;
}
#undef finish_zval_long
#undef finish_zval_null
#undef finish_zval_bool
#undef finish_zval_double
#undef finish_zval_string
#undef finish_zval_array
#undef finish_zval_object
#undef again_fixed_trail
#undef again_fixed_trail_if_zero
#undef next_cs

26
php/msgpack_unpack.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef MSGPACL_UNPACK_H
#define MSGPACL_UNPACK_H
#include "ext/standard/php_var.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
{
unsigned char *data;
size_t length;
size_t offset;
} msgpack_unserialize_data;
int msgpack_unserialize_zval(
zval **return_value, msgpack_unserialize_data *mpsd,
php_unserialize_data_t *var_hash TSRMLS_DC);
#endif

98
php/package.xml Normal file
View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<package version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<name>msgpack</name>
<channel>pecl.php.net</channel>
<summary>PHP extension for interfacing with MessagePack</summary>
<description>This extension provide API for communicating with MessagePack serialization.</description>
<lead>
<name>Advect</name>
<user>advect</user>
<email>advect@gmail.com</email>
<active>yes</active>
</lead>
<date>2010-07-17</date>
<time>18:38:51</time>
<version>
<release>0.2.1</release>
<api>0.2.1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license filesource="LICENSE">New BSD</license>
<notes>Initial release.</notes>
<contents>
<dir name="/">
<file md5sum="12b9d8867e5fde4af426c134283e2082" name="LICENSE" role="doc" />
<file md5sum="8daeb22744f11b57da9d0966608e2fc1" name="README" role="doc" />
<file md5sum="ba9ebe7c9dcae2ac053d9f789827f6f5" name="config.m4" role="src" />
<file md5sum="4223c6e2438bc363b6e13998c1e545b3" name="msgpack.c" role="src" />
<file md5sum="4c1dfbe6537a9189ee798c2647b0bc1d" name="msgpack_class.c" role="src" />
<file md5sum="3f2ae07a305b8353b4a574a4f1cea1c5" name="msgpack_class.h" role="src" />
<file md5sum="2b1a8e1a3e9e7a9893c4a0b3e4ac774f" name="msgpack_pack.c" role="src" />
<file md5sum="aedc1294b727bc8c06048104a7788f01" name="msgpack_pack.h" role="src" />
<file md5sum="0ef4bc4b5178fbf3099a5f53c06da861" name="msgpack_unpack.c" role="src" />
<file md5sum="99d4fa550181a3ba1267e473a4ad727b" name="msgpack_unpack.h" role="src" />
<file md5sum="8886e0071a2387c52ac6f2eff5b0045c" name="php_msgpack.h" role="src" />
<file md5sum="237eda031928a5546bdb92a34815830f" name="tests/001.phpt" role="test" />
<file md5sum="11d3a17e404ec4938eff1d0b0e724e5f" name="tests/002.phpt" role="test" />
<file md5sum="1006ba0ae8b22e3d090a200f3eefea82" name="tests/003.phpt" role="test" />
<file md5sum="21c14487ba126c00d5d42d2dd03c76c3" name="tests/004.phpt" role="test" />
<file md5sum="99b8bb5df5c98b6e27541245b39bb13f" name="tests/005.phpt" role="test" />
<file md5sum="e0488f07f26c74d1c918634c39555d6e" name="tests/006.phpt" role="test" />
<file md5sum="9574605f18eef124b55ede353d255511" name="tests/007.phpt" role="test" />
<file md5sum="dc3584b04311da2a627c6a271a782d2c" name="tests/008.phpt" role="test" />
<file md5sum="84cd4eda863350bf148d9517451c440c" name="tests/009.phpt" role="test" />
<file md5sum="ddb421cd083baaca3ce3a5263f731dcd" name="tests/010.phpt" role="test" />
<file md5sum="6a24b3b12778e2935722c97c95c9e393" name="tests/012.phpt" role="test" />
<file md5sum="377f261d48b4f7fc78689aae481ac952" name="tests/013.phpt" role="test" />
<file md5sum="4407921d4b5c2a5aba21eb78dc651a5f" name="tests/014.phpt" role="test" />
<file md5sum="171194418824d91c9d52c511662cffa7" name="tests/015.phpt" role="test" />
<file md5sum="39693db7f0aafe07ed06b6569c2885b0" name="tests/015b.phpt" role="test" />
<file md5sum="f35a9f6ce6c68c9ce06276fcb5aeb177" name="tests/016.phpt" role="test" />
<file md5sum="c143aa78b84c8d7a7189d754592613e0" name="tests/017.phpt" role="test" />
<file md5sum="0f2600e66084af7989a5facbbf5de990" name="tests/018.phpt" role="test" />
<file md5sum="375d39f1da5efb3067c326a636fa1d88" name="tests/019.phpt" role="test" />
<file md5sum="3d9e08a86a9c1f53af0a86cce5c42d6d" name="tests/020.phpt" role="test" />
<file md5sum="40e429c52cbff763df7a7cdc27c2df2c" name="tests/021.phpt" role="test" />
<file md5sum="23a30dd1eca67eaaf5b640d2153c8c5f" name="tests/022.phpt" role="test" />
<file md5sum="2ccb3302060dbd9395879e215c9b2072" name="tests/023.phpt" role="test" />
<file md5sum="4ce5630191f968701c4e845fdf5ad365" name="tests/024.phpt" role="test" />
<file md5sum="5c2921e615f38d922cff04689aa61b7d" name="tests/025.phpt" role="test" />
<file md5sum="a61a627b3847788dab2072c1eb3600f5" name="tests/026.phpt" role="test" />
<file md5sum="170f20b9a3a9638817f01095fea241dc" name="tests/027.phpt" role="test" />
<file md5sum="0abf41b966db58c72b3b96286ea07b01" name="tests/028.phpt" role="test" />
<file md5sum="e77b91dc9e8ba3d9a49752afed44a99c" name="tests/029.phpt" role="test" />
<file md5sum="731d1a7bec6e3827f50d55df5d1e3ebf" name="tests/030.phpt" role="test" />
<file md5sum="7ca67b854f69837658cc741ce42b8ed8" name="tests/031.phpt" role="test" />
<file md5sum="170dfcb82fd1e097fffc6b57a7e9764a" name="tests/032.phpt" role="test" />
<file md5sum="0e96b2ebf8c37c1c4c13de4d2d5dae95" name="tests/033.phpt" role="test" />
<file md5sum="38a296986d384118800b03bb1a4f24a9" name="tests/034.phpt" role="test" />
<file md5sum="661553a8ccd9b83c95772dd9ad68d82b" name="tests/035.phpt" role="test" />
<file md5sum="2418498403672bfce1087c4b4d277d1d" name="tests/040.phpt" role="test" />
<file md5sum="011672f35987ed8e52b7c9afde98bb8d" name="tests/041.phpt" role="test" />
<file md5sum="ac28799e22762ff27e331aa060a792ad" name="tests/042.phpt" role="test" />
<file md5sum="57478f4e95bd000bf73a8331e9e19cba" name="tests/050.phpt" role="test" />
<file md5sum="7f4047750c52009c7ef369150d2907d6" name="tests/060.phpt" role="test" />
<file md5sum="9ce6adb0492b97c8d7803090b4a08711" name="tests/061.phpt" role="test" />
<file md5sum="187689f3d1d8fe3636ea7d6188e7e559" name="tests/062.phpt" role="test" />
<file md5sum="9c91266595d01080b813fb2a056fca82" name="tests/063.phpt" role="test" />
<file md5sum="29d00ba15f7017c35d08ba83187aaa69" name="tests/070.phpt" role="test" />
<file md5sum="d3759148a10c87bdb5e7377ae7af5211" name="tests/071.phpt" role="test" />
<file md5sum="9a3908df5a67606814dfa6651dfddcc8" name="tests/072.phpt" role="test" />
</dir>
</contents>
<dependencies>
<required>
<php>
<min>5.2.0</min>
</php>
<pearinstaller>
<min>1.4.3</min>
</pearinstaller>
</required>
</dependencies>
<providesextension>msgpack</providesextension>
<extsrcrelease />
</package>

59
php/php-msgpack.spec Normal file
View File

@ -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.2.1
Release: 1%{?dist}
Source: php-msgpack-%{version}.tar.gz
License: New BSD License
Group: Development/Libraries
Packager: advect <advect@gmail.com>
Provides: php-pecl-msgpack
BuildRoot: %{_tmppath}/%{name}-%{version}-root
BuildRequires: php-devel, msgpack-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 <<EOF
; Enable msgpack extension module
extension=msgpack.so
EOF
%check
export NO_INTERACTION=1 REPORT_EXIT_STATUS=1
%{__make} test
unset NO_INTERACTION REPORT_EXIT_STATUS
if [ -n "`find tests -name \*.diff -type f -print`" ]; then
exit 1
fi
%clean
%{__rm} -rf %{buildroot}
%files
%attr(-, root, root)
%{_includedir}/php/ext/msgpack/php_msgpack.h
%{php_extdir}/msgpack.so
%config(noreplace) %{_sysconfdir}/php.d/msgpack.ini

View File

@ -1,86 +1,41 @@
/*
+----------------------------------------------------------------------+
| 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: |
+----------------------------------------------------------------------+
*/
/* $Id: header 226204 2007-01-01 19:32:10Z iliaa $ */
#ifndef PHP_MSGPACK_H
#define PHP_MSGPACK_H
#define MSGPACK_VERSION "0.2.1"
#include "ext/standard/php_smart_str.h"
extern zend_module_entry msgpack_module_entry;
#define phpext_msgpack_ptr &msgpack_module_entry
#ifdef PHP_WIN32
#define PHP_MSGPACK_API __declspec(dllexport)
# define PHP_MSGPACK_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 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_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 */

0
php/test_normal.php Executable file → Normal file
View File

9
php/test_streaming.php Executable file → Normal file
View File

@ -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;

10
php/tests/001.phpt Normal file
View File

@ -0,0 +1,10 @@
--TEST--
Check for msgpack presence
--SKIPIF--
<?php if (!extension_loaded("msgpack")) print "skip"; ?>
--FILE--
<?php
echo "msgpack extension is available";
?>
--EXPECT--
msgpack extension is available

26
php/tests/002.phpt Normal file
View File

@ -0,0 +1,26 @@
--TEST--
Check for null serialisation
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL;
}
test('null', null);
?>
--EXPECT--
null
c0
NULL
OK

31
php/tests/003.phpt Normal file
View File

@ -0,0 +1,31 @@
--TEST--
Check for bool serialisation
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL;
}
test('bool true', true);
test('bool false', false);
?>
--EXPECT--
bool true
c3
bool(true)
OK
bool false
c2
bool(false)
OK

56
php/tests/004.phpt Normal file
View File

@ -0,0 +1,56 @@
--TEST--
Check for integer serialisation
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL;
}
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);
?>
--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

26
php/tests/005.phpt Normal file
View File

@ -0,0 +1,26 @@
--TEST--
Check for double serialisation
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL;
}
test('double: 123.456', 123.456);
?>
--EXPECT--
double: 123.456
cb405edd2f1a9fbe77
float(123.456)
OK

31
php/tests/006.phpt Normal file
View File

@ -0,0 +1,31 @@
--TEST--
Check for simple string serialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL;
}
test('empty: ""', "");
test('string: "foobar"', "foobar");
?>
--EXPECT--
empty: ""
a0
string(0) ""
OK
string: "foobar"
a6666f6f626172
string(6) "foobar"
OK

72
php/tests/007.phpt Normal file
View File

@ -0,0 +1,72 @@
--TEST--
Check for simple array serialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
test('empty array:', array());
test('array(1, 2, 3)', array(1, 2, 3));
test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)));
?>
--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

61
php/tests/008.phpt Normal file
View File

@ -0,0 +1,61 @@
--TEST--
Check for array+string serialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
test('array("foo", "foo", "foo")', array("foo", "foo", "foo"));
test('array("one" => 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

115
php/tests/009.phpt Normal file
View File

@ -0,0 +1,115 @@
--TEST--
Check for reference serialisation
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
$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);
var_dump($a);
var_dump(msgpack_unserialize(msgpack_serialize($a)));
--EXPECT--
array($a, $a)
82008100a3666f6f018100a3666f6f
array(2) {
[0]=>
array(1) {
[0]=>
string(3) "foo"
}
[1]=>
array(1) {
[0]=>
string(3) "foo"
}
}
OK
array(&$a, &$a)
82008100a3666f6f0182c001c002
array(2) {
[0]=>
&array(1) {
[0]=>
string(3) "foo"
}
[1]=>
&array(1) {
[0]=>
string(3) "foo"
}
}
OK
cyclic
81008100810082c001c002
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*
}
}
}
}
}

49
php/tests/010.phpt Normal file
View File

@ -0,0 +1,49 @@
--TEST--
Array test
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
$a = array(
'a' => 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

48
php/tests/012.phpt Normal file
View File

@ -0,0 +1,48 @@
--TEST--
Object test
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
class Obj {
public $a;
protected $b;
private $c;
function __construct($a, $b, $c) {
$this->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

54
php/tests/013.phpt Normal file
View File

@ -0,0 +1,54 @@
--TEST--
Object-Array test
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
class Obj {
var $a;
var $b;
function __construct($a, $b) {
$this->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

54
php/tests/014.phpt Normal file
View File

@ -0,0 +1,54 @@
--TEST--
Object-Reference test
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
class Obj {
var $a;
var $b;
function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
}
$o = new Obj(1, 2);
$a = array(&$o, &$o);
test('object', $a, false);
?>
--EXPECTF--
object
820083c0a34f626aa16101a162020182c001c002
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

58
php/tests/015.phpt Normal file
View File

@ -0,0 +1,58 @@
--TEST--
Check for serialization handler
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
$output = '';
function open($path, $name) {
return true;
}
function close() {
return true;
}
function read($id) {
global $output;
return pack('H*', '81a3666f6f01');
}
function write($id, $data) {
global $output;
$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();
echo ++$_SESSION['foo'], PHP_EOL;
session_write_close();
echo $output;
var_dump($_SESSION);
?>
--EXPECT--
2
81a3666f6f02
array(1) {
["foo"]=>
int(2)
}

58
php/tests/015b.phpt Normal file
View File

@ -0,0 +1,58 @@
--TEST--
Check for serialization handler, ini-directive
--SKIPIF--
--INI--
session.serialize_handler=msgpack
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
$output = '';
function open($path, $name) {
return true;
}
function close() {
return true;
}
function read($id) {
global $output;
return pack('H*', '81a3666f6f01');
}
function write($id, $data) {
global $output;
$output .= bin2hex($data) . PHP_EOL;
return true;
}
function destroy($id) {
return true;
}
function gc($time) {
return true;
}
session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');
session_start();
echo ++$_SESSION['foo'], PHP_EOL;
session_write_close();
echo $output;
var_dump($_SESSION);
?>
--EXPECT--
2
81a3666f6f02
array(1) {
["foo"]=>
int(2)
}

60
php/tests/016.phpt Normal file
View File

@ -0,0 +1,60 @@
--TEST--
Object test, __sleep
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
class Obj {
public $a;
protected $b;
private $c;
var $d;
function __construct($a, $b, $c, $d) {
$this->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

48
php/tests/017.phpt Normal file
View File

@ -0,0 +1,48 @@
--TEST--
Object test, __wakeup
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized->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

84
php/tests/018.phpt Normal file
View File

@ -0,0 +1,84 @@
--TEST--
Object test, __sleep error cases
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
error_reporting(0);
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
class Obj {
var $a;
var $b;
function __construct($a, $b) {
$this->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
82c0a34f706ac0
object(Opj)#%d (2) {
["a"]=>
NULL
["b"]=>
NULL
}
OK

43
php/tests/019.phpt Normal file
View File

@ -0,0 +1,43 @@
--TEST--
Object test, __autoload
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = pack('H*', $variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized->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

31
php/tests/020.phpt Normal file
View File

@ -0,0 +1,31 @@
--TEST--
Object test, incomplete class
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = pack('H*', $variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
}
test('incom', '83c0a34f626aa16101a16202', false);
?>
--EXPECTF--
incom
83c0a34f626aa16101a16202
object(__PHP_Incomplete_Class)#%d (3) {
["__PHP_Incomplete_Class_Name"]=>
string(3) "Obj"
["a"]=>
int(1)
["b"]=>
int(2)
}

52
php/tests/021.phpt Normal file
View File

@ -0,0 +1,52 @@
--TEST--
Object Serializable interface
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
class Obj implements Serializable {
var $a;
var $b;
function __construct($a, $b) {
$this->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

45
php/tests/022.phpt Normal file
View File

@ -0,0 +1,45 @@
--TEST--
Object test, unserialize_callback_func
--SKIPIF--
--INI--
unserialize_callback_func=autoload
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = pack('H*', $variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized->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

54
php/tests/023.phpt Normal file
View File

@ -0,0 +1,54 @@
--TEST--
Resource
--SKIPIF--
<?php
if (!function_exists("curl_init") && !class_exists("Sqlite3"))) {
echo "skip";
}
?>
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
error_reporting(0);
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized === null ? 'OK' : 'FAIL', PHP_EOL;
}
if (function_exists('curl_init')) {
$test = 'curl';
$res = curl_init('http://opensource.dynamoid.com');
} else if (class_exists('Sqlite3')) {
$test = 'sqlite';
$sqlite = new Sqlite3();
$res = $sqlite->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

166
php/tests/024.phpt Normal file
View File

@ -0,0 +1,166 @@
--TEST--
Recursive objects
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
class Obj {
public $a;
protected $b;
private $c;
function __construct($a, $b, $c) {
$this->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
83c0a44f626a34a7004f626a34006164a9004f626a34006f626a82c002c001
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

119
php/tests/025.phpt Normal file
View File

@ -0,0 +1,119 @@
--TEST--
Object test, array of objects with __sleep
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
var_dump($variable);
var_dump($unserialized);
}
class Obj {
public $a;
protected $b;
private $c;
var $d;
function __construct($a, $b, $c, $d) {
$this->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
}
}

143
php/tests/026.phpt Normal file
View File

@ -0,0 +1,143 @@
--TEST--
Cyclic array test
--INI--
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
echo bin2hex($serialized), PHP_EOL;
var_dump($unserialized);
echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
}
$a = array(
'a' => 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
82a16182a162a163a164a165a16682a16182a162a163a164a165a16682c001c005
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*
}
}
}
}
}

73
php/tests/027.phpt Normal file
View File

@ -0,0 +1,73 @@
--TEST--
Check for serialization handler
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
$output = '';
function open($path, $name) {
return true;
}
function close() {
return true;
}
function read($id) {
global $output;
$output .= "read" . PHP_EOL;
return pack('H*', '81a3666f6f01');
}
function write($id, $data) {
global $output;
$output .= "wrote: ";
$output .= bin2hex($data). PHP_EOL;
return true;
}
function destroy($id) {
return true;
}
function gc($time) {
return true;
}
class Foo {
}
class Bar {
}
ini_set('session.serialize_handler', 'msgpack');
session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');
$db_object = new Foo();
$session_object = new Bar();
$v = session_start();
var_dump($v);
$_SESSION['test'] = "foobar";
session_write_close();
echo $output;
var_dump($_SESSION);
?>
--EXPECT--
bool(true)
read
wrote: 82a3666f6f01a474657374a6666f6f626172
array(2) {
["foo"]=>
int(1)
["test"]=>
string(6) "foobar"
}

667
php/tests/028.phpt Normal file
View File

@ -0,0 +1,667 @@
--TEST--
Serialize object into session, full set
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
class Foo {
private static $s1 = array();
protected static $s2 = array();
public static $s3 = array();
private $d1;
protected $d2;
public $d3;
public function __construct($foo) {
$this->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: 83a36f6c6484c0a3466f6fa700466f6f00643184c0a3426172a2643182c002c002a70042617200643282c002c002a5002a00643382c002c002a5002a00643282c002c003a2643382c002c003a474657374a6666f6f626172a36e657784c0a3426172a2643184c0a3466f6fa700466f6f00643182c002c00aa5002a00643282c002c00aa2643382c002c00aa70042617200643282c002c00ba5002a00643382c002c00b
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*
}
}
}
}
}

20
php/tests/029.phpt Normal file
View File

@ -0,0 +1,20 @@
--TEST--
Msgpack module info
--SKIPIF--
<?php if (!extension_loaded("msgpack")) print "skip"; ?>
--FILE--
<?php
ob_start();
phpinfo(INFO_MODULES);
$str = ob_get_clean();
$array = explode("\n", $str);
$array = preg_grep('/^msgpack/', $array);
echo implode("\n", $array), PHP_EOL;
--EXPECTF--
msgpack
msgpack support => enabled
msgpack version => %s
msgpack Session Support => enabled

233
php/tests/030.phpt Normal file
View File

@ -0,0 +1,233 @@
--TEST--
Unserialize invalid data
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
$datas = array(
87817,
-1,
array(1,2,3,"testing" => 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 2:
array(0) {
}
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)
}

90
php/tests/031.phpt Normal file
View File

@ -0,0 +1,90 @@
--TEST--
Object Serializable interface throws exceptions
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
var_dump($unserialized);
}
class Obj implements Serializable {
private static $count = 1;
var $a;
var $b;
function __construct($a, $b) {
$this->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

76
php/tests/032.phpt Normal file
View File

@ -0,0 +1,76 @@
--TEST--
Object test, __sleep and __wakeup exceptions
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
error_reporting(0);
function test($variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
var_dump($unserialized);
}
class Obj {
private static $count = 0;
var $a;
var $b;
function __construct($a, $b) {
$this->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)
}

55
php/tests/033.phpt Normal file
View File

@ -0,0 +1,55 @@
--TEST--
Object test, cyclic references
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
class Foo {
public $parent;
public $children;
public function __construct() {
$this->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

38
php/tests/034.phpt Normal file
View File

@ -0,0 +1,38 @@
--TEST--
Unserialize invalid random data
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
$datas = array(
87817,
-1,
array(1,2,3,"testing" => 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--

34
php/tests/035.phpt Normal file
View File

@ -0,0 +1,34 @@
--TEST--
Profiling perf test.
--SKIPIF--
<?php
if (!extension_loaded("msgpack") || !extension_loaded("mcrypt")) {
echo "skip";
}
?>
--FILE--
<?php
$data_array = array();
for ($i = 0; $i < 5000; $i++) {
$data_array[mcrypt_create_iv(10, MCRYPT_DEV_URANDOM)] = mcrypt_create_iv(10, MCRYPT_DEV_URANDOM);
}
$time_start = microtime(true);
for ($i = 0; $i < 4000; $i++) {
$s = msgpack_serialize($data_array);
$array = msgpack_unserialize($s);
unset($array);
unset($s);
}
$time_end = microtime(true);
if ($time_end <= $time_start) {
echo "Strange, $i iterations ran in infinite speed: $time_end <= $time_start", PHP_EOL;
} else {
$speed = $i / ($time_end - $time_start);
printf("%d iterations took %f seconds: %d/s (%s)\n",
$i, $time_end - $time_start, $speed, ($speed > 400 ? "GOOD" : "BAD"));
}
?>
--EXPECTF--
%d iterations took %f seconds: %d/s (GOOD)

43
php/tests/040.phpt Normal file
View File

@ -0,0 +1,43 @@
--TEST--
b0rked random data test
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
error_reporting(E_ERROR | E_PARSE);
function test() {
$serialized = msgpack_serialize(null);
$serialized = substr($serialized, 0, -1);
$length = mt_rand(1, 255);
for ($i = 0; $i < $length; ++$i) {
$serialized .= chr(mt_rand(0, 255));
}
// if returned null everything is OK
if (($unserialized = msgpack_unserialize($serialized)) === null) {
return true;
}
// whole data is read?
if ($serialized !== msgpack_serialize($unserialized)) {
return true;
}
echo bin2hex($serialized), "\n";
var_dump($unserialized);
return false;
}
mt_srand(0x4c05b583);
for ($i = 0; $i < 100; ++$i) {
if (!test()) break;
}
?>
--EXPECT--

47
php/tests/041.phpt Normal file
View File

@ -0,0 +1,47 @@
--TEST--
Check for double NaN, Inf, -Inf, 0, and -0
--FILE--
<?php
function test($type, $variable) {
$serialized = msgpack_serialize($variable);
$unserialized = msgpack_unserialize($serialized);
echo $type, PHP_EOL;
var_dump($variable);
var_dump($unserialized);
echo bin2hex($serialized), PHP_EOL;
echo PHP_EOL;
}
test('double NaN:', NAN);
test('double Inf:', INF);
test('double -Inf:', -INF);
test('double 0.0:', 0.0);
test('double -0.0:', -0.0);
--EXPECTF--
double NaN:
float(NAN)
float(NAN)
cb7ff8000000000000
double Inf:
float(INF)
float(INF)
cb7ff0000000000000
double -Inf:
float(-INF)
float(-INF)
cbfff0000000000000
double 0.0:
float(0)
float(0)
cb0000000000000000
double -0.0:
float(0)
float(0)
cb0000000000000000

40
php/tests/042.phpt Normal file
View File

@ -0,0 +1,40 @@
--TEST--
Closure
--SKIPIF--
<?php
if (version_compare(PHP_VERSION, '5.3.0') < 0) {
echo "skip closures only for PHP 5.3.0+";
}
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
$closure = function ($x) {
return $x + 1;
};
class Foo implements Serializable {
public function serialize() {
echo "Should not be run.\n";
}
public function unserialize($str) {
echo "Should not be run.\n";
}
}
$array = array($closure, new Foo());
try {
$ser = msgpack_serialize($array);
echo "Serialized closure.\n";
$unser = msgpack_unserialize($ser);
echo "Unserialized closure.\n";
var_dump($unser);
} catch (Exception $e) {
echo "Got exception.\n";
}
--EXPECT--
Got exception.

111
php/tests/050.phpt Normal file
View File

@ -0,0 +1,111 @@
--TEST--
Check for array unserialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$unserialized = msgpack_unserialize(pack('H*', $variable));
echo $type, PHP_EOL;
echo $variable, PHP_EOL;
var_dump($unserialized);
}
test('empty array:', '90');
test('array(1, 2, 3)', '93010203');
test('array(array(1, 2, 3), arr...', '93930102039304050693070809');
test('array("foo", "FOO", "Foo")', '93a3666f6fa3464f4fa3466f6f');
test('array(1, 123.45, true, ...', '9701cb405edccccccccccdc3c293010293090807c0a3666f6f');
?>
--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"
}

315
php/tests/060.phpt Normal file
View File

@ -0,0 +1,315 @@
--TEST--
Check for buffered streaming unserialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test = null) {
$serialized = msgpack_serialize($variable);
$unpacker = new MessagePackUnpacker();
$length = strlen($serialized);
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;
}
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

320
php/tests/061.phpt Normal file
View File

@ -0,0 +1,320 @@
--TEST--
Check for unbuffered streaming unserialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test = null) {
$serialized = msgpack_serialize($variable);
$unpacker = new MessagePackUnpacker();
$length = strlen($serialized);
$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

64
php/tests/062.phpt Normal file
View File

@ -0,0 +1,64 @@
--TEST--
Extra bytes buffered streaming unserialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test = null) {
$unpacker = new MessagePackUnpacker();
foreach ($variable as $var)
{
$serialized = pack('H*', $var);
$length = strlen($serialized);
for ($i = 0; $i < $length;) {
$len = rand(1, 10);
$str = substr($serialized, $i, $len);
$unpacker->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)

68
php/tests/063.phpt Normal file
View File

@ -0,0 +1,68 @@
--TEST--
Extra bytes unbuffered streaming unserialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test = null) {
$unpacker = new MessagePackUnpacker();
$str = "";
$offset = 0;
foreach ($variable as $var)
{
$serialized = pack('H*', $var);
$length = strlen($serialized);
for ($i = 0; $i < $length;) {
$len = rand(1, 10);
$str .= substr($serialized, $i, $len);
while (true) {
if ($unpacker->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)

299
php/tests/070.phpt Normal file
View File

@ -0,0 +1,299 @@
--TEST--
Check for alias functions
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test = null) {
$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), 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

301
php/tests/071.phpt Normal file
View File

@ -0,0 +1,301 @@
--TEST--
Check for class methods
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test = null) {
$msgpack = new MessagePack();
$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), 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

341
php/tests/072.phpt Normal file
View File

@ -0,0 +1,341 @@
--TEST--
Check for class methods unpacker
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('msgpack')) {
dl('msgpack.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test = null) {
$msgpack = new MessagePack();
$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), 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

View File

@ -1,169 +0,0 @@
--TEST--
Test msgpack_pack() function : basic functionality
--SKIPIF--
<?php if (!extension_loaded("msgpack")) print "skip"; ?>
--FILE--
<?php
echo "*** Testing msgpack_pack() : basic functionality ***\n";
function create_map($num)
{
$data = array();
for($i=0; $i<=$num; $i++)
$data[$i+1] = $i;
return $data;
}
$inputs = array (
// null
/*1*/ null,
NULL,
// boolean
/*3*/ false,
FALSE,
true,
TRUE,
// zero
/*7*/ 0,
// positive fixnum
/*8*/ 1,
(1<<6),
(1<<7)-1,
// positive int 8
/*11*/ (1<<7),
(1<<8)-1,
// positive int 16
/*13*/ (1<<8),
(1<<16)-1,
// positive int 32
/*15*/ (1<<16),
(1<<32)-1,
// positive int 64
/*17*/ (1<<32),
(1<<64)-1,
// negative fixnum
/*19*/ -1,
-((1<<5)-1),
-(1<<5),
// negative int 8
/*22*/ -((1<<5)+1),
-(1<<7),
// negative int 16
/*24*/ -((1<<7)+1),
-(1<<15),
//negative int 32
/*26*/ -((1<<15)+1),
-(1<<31),
// negative int 64
/*28*/ -((1<<31)+1),
-(1<<63),
// double
/*30*/ 1.0,
0.1,
-0.1,
-1.0,
// fixraw
/*34*/ "",
str_repeat(" ", (1<<5)-1),
// raw 16
/*36*/ str_repeat(" ", (1<<5)),
//str_repeat(" ", (1<<16)-1),
// raw 32
/*38*/ //str_repeat(" ", (1<<16)),
//str_repeat(" ", (1<<32)-1), // memory error
// fixarraw
/*39*/ array(),
range(0, (1<<4)-1),
// array 16
/*41*/ range(0, (1<<4)),
//range(0, (1<<16)-1),
// array 32
/*43*/ //range(0, (1<<16)),
//range(0, (1<<32)-1), // memory error
// fixmap
//array(),
/*44*/ //create_map((1<<4)-1),
// map 16
/*45*/ //create_map((1<<4)),
//create_map((1<<16)-1),
// map 32
/*47*/ //create_map((1<<16))
//create_map((1<<32)-1) // memory error
);
$count = 1;
foreach($inputs as $input) {
echo "-- Iteration $count --\n";
$str = unpack('H*', msgpack_pack($input));
var_dump("0x".$str[1]);
$count ++;
}
?>
===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===