mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-03-19 13:02:13 +01:00
Update PHP Extension
This commit is contained in:
parent
a97f9081a3
commit
78f542f6c0
40
php/ChangeLog
Normal file
40
php/ChangeLog
Normal 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
26
php/LICENSE
Normal 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.
|
11
php/README
11
php/README
@ -0,0 +1,11 @@
|
||||
Description
|
||||
-----------
|
||||
This extension provide API for communicating with MessagePack serialization.
|
||||
|
||||
MessagePack is a binary-based efficient object serialization library.
|
||||
It enables to exchange structured objects between many languages like JSON.
|
||||
But unlike JSON, it is very fast and small.
|
||||
|
||||
Resources
|
||||
---------
|
||||
* [msgpack](http://msgpack.sourceforge.net/)
|
248
php/benchmark.php
Normal file
248
php/benchmark.php
Normal 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;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
803
php/msgpack.c
803
php/msgpack.c
@ -1,22 +1,3 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2007 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Hideyuki TAKEI |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id: header 226204 2007-01-01 19:32:10Z iliaa $ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@ -26,631 +7,259 @@
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "ext/standard/php_smart_str.h"
|
||||
#include "ext/standard/php_incomplete_class.h"
|
||||
#include "ext/standard/php_var.h"
|
||||
#include "ext/session/php_session.h"
|
||||
|
||||
#include "php_msgpack.h"
|
||||
#include "msgpack_pack.h"
|
||||
#include "msgpack_unpack.h"
|
||||
#include "msgpack_class.h"
|
||||
|
||||
#define PHP_EXT_VERSION "0.01"
|
||||
static ZEND_FUNCTION(msgpack_serialize);
|
||||
static ZEND_FUNCTION(msgpack_unserialize);
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
#endif
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_serialize, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, value)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_msgpack_unserialize, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, str)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
/* pack */
|
||||
#include "msgpack/pack_define.h"
|
||||
PS_SERIALIZER_FUNCS(msgpack);
|
||||
|
||||
#define msgpack_pack_inline_func(name) \
|
||||
static inline void msgpack_pack ## name
|
||||
|
||||
#define msgpack_pack_inline_func_cint(name) \
|
||||
static inline void msgpack_pack ## name
|
||||
|
||||
#define msgpack_pack_user smart_str*
|
||||
|
||||
#define msgpack_pack_append_buffer(user, buf, len) \
|
||||
smart_str_appendl(user, (const void*)buf, len)
|
||||
|
||||
#include "msgpack/pack_template.h"
|
||||
|
||||
|
||||
/* unpack */
|
||||
#include "msgpack/unpack_define.h"
|
||||
|
||||
typedef struct {
|
||||
int finished;
|
||||
char* source;
|
||||
} unpack_user;
|
||||
|
||||
#define msgpack_unpack_struct(name) \
|
||||
struct template ## name
|
||||
|
||||
#define msgpack_unpack_func(ret, name) \
|
||||
ret template ## name
|
||||
|
||||
#define msgpack_unpack_callback(name) \
|
||||
template_callback ## name
|
||||
|
||||
#define msgpack_unpack_object zval*
|
||||
|
||||
#define msgpack_unpack_user unpack_user
|
||||
|
||||
struct template_context;
|
||||
typedef struct template_context msgpack_unpack_t;
|
||||
|
||||
static void template_init(msgpack_unpack_t* u);
|
||||
static msgpack_unpack_object template_data(msgpack_unpack_t* u);
|
||||
static int template_execute(msgpack_unpack_t* u,
|
||||
const char* data, size_t len, size_t* off);
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(msgpack)
|
||||
msgpack_unpack_t *global_mp;
|
||||
ZEND_END_MODULE_GLOBALS(msgpack)
|
||||
|
||||
#ifdef ZTS
|
||||
#define MSGPACK_G(v) TSRMG(msgpack_globals_id, zend_msgpack_globals *, v)
|
||||
#else
|
||||
#define MSGPACK_G(v) (msgpack_globals.v)
|
||||
#endif
|
||||
|
||||
static inline msgpack_unpack_object template_callback_root(unpack_user* u)
|
||||
{
|
||||
msgpack_unpack_object data;
|
||||
ALLOC_INIT_ZVAL(data);
|
||||
ZVAL_NULL(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; }
|
||||
|
||||
static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; }
|
||||
|
||||
static inline int template_callback_uint32(unpack_user* u, uint32_t d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; }
|
||||
|
||||
static inline int template_callback_uint64(unpack_user* u, uint64_t d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; }
|
||||
|
||||
static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, (long)d); return 0; }
|
||||
|
||||
static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, (long)d); return 0; }
|
||||
|
||||
static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, (long)d); return 0; }
|
||||
|
||||
static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_LONG(*o, d); return 0; }
|
||||
|
||||
static inline int template_callback_float(unpack_user* u, float d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_DOUBLE(*o, d); return 0; }
|
||||
|
||||
static inline int template_callback_double(unpack_user* u, double d, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_DOUBLE(*o, d); return 0; }
|
||||
|
||||
static inline int template_callback_nil(unpack_user* u, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_NULL(*o); return 0; }
|
||||
|
||||
static inline int template_callback_true(unpack_user* u, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_BOOL(*o, 1); return 0; }
|
||||
|
||||
static inline int template_callback_false(unpack_user* u, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); ZVAL_BOOL(*o, 0); return 0;}
|
||||
|
||||
static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); array_init(*o); return 0; }
|
||||
|
||||
static inline int template_callback_array_item(unpack_user* u, msgpack_unpack_object* c, msgpack_unpack_object o)
|
||||
{ add_next_index_zval(*c, o); return 0; }
|
||||
|
||||
static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_unpack_object* o)
|
||||
{ ALLOC_INIT_ZVAL(*o); array_init(*o); return 0; }
|
||||
|
||||
static inline int template_callback_map_item(unpack_user* u, msgpack_unpack_object* c, msgpack_unpack_object k, msgpack_unpack_object v)
|
||||
{
|
||||
switch(k->type) {
|
||||
case IS_LONG:
|
||||
add_index_zval(*c, Z_LVAL(*k), v);
|
||||
break;
|
||||
case IS_STRING:
|
||||
add_assoc_zval_ex(*c, Z_STRVAL(*k), Z_STRLEN(*k)+1, v);
|
||||
break;
|
||||
default:
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_decode) illegal offset type, skip this decoding");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int template_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_unpack_object* o)
|
||||
{
|
||||
ALLOC_INIT_ZVAL(*o);
|
||||
if (l == 0) {
|
||||
ZVAL_STRINGL(*o, "", 0, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(*o, p, l, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "msgpack/unpack_template.h"
|
||||
|
||||
static PHP_GINIT_FUNCTION(msgpack);
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(msgpack)
|
||||
|
||||
/* True global resources - no need for thread safety here */
|
||||
static int le_msgpack;
|
||||
|
||||
/* {{{ msgpack_functions[]
|
||||
*
|
||||
* Every user visible function must have an entry in msgpack_functions[].
|
||||
*/
|
||||
zend_function_entry msgpack_functions[] = {
|
||||
PHP_FE(msgpack_pack, NULL)
|
||||
PHP_FE(msgpack_unpack, NULL)
|
||||
PHP_FE(msgpack_unpack_limit, NULL)
|
||||
PHP_ME(msgpack, initialize, NULL, 0)
|
||||
PHP_ME(msgpack, execute, NULL, 0)
|
||||
PHP_ME(msgpack, execute_limit, NULL, 0)
|
||||
PHP_ME(msgpack, finished, NULL, 0)
|
||||
PHP_ME(msgpack, data, NULL, 0)
|
||||
{NULL, NULL, NULL} /* Must be the last line in msgpack_functions[] */
|
||||
static const zend_function_entry msgpack_functions[] = {
|
||||
ZEND_FE(msgpack_serialize, arginfo_msgpack_serialize)
|
||||
ZEND_FE(msgpack_unserialize, arginfo_msgpack_unserialize)
|
||||
ZEND_FALIAS(msgpack_pack, msgpack_serialize, arginfo_msgpack_serialize)
|
||||
ZEND_FALIAS(msgpack_unpack, msgpack_unserialize,
|
||||
arginfo_msgpack_unserialize)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ msgpack_module_entry
|
||||
*/
|
||||
static ZEND_MINIT_FUNCTION(msgpack)
|
||||
{
|
||||
MSGPACK_G(error_display) = 1;
|
||||
|
||||
#if HAVE_PHP_SESSION
|
||||
php_session_register_serializer("msgpack",
|
||||
PS_SERIALIZER_ENCODE_NAME(msgpack),
|
||||
PS_SERIALIZER_DECODE_NAME(msgpack));
|
||||
#endif
|
||||
|
||||
msgpack_init_class(TSRMLS_CC);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static ZEND_MINFO_FUNCTION(msgpack)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_row(2, "msgpack support", "enabled");
|
||||
php_info_print_table_row(2, "msgpack version", MSGPACK_VERSION);
|
||||
#if HAVE_PHP_SESSION
|
||||
php_info_print_table_row(2, "msgpack Session Support", "enabled" );
|
||||
#endif
|
||||
php_info_print_table_end();
|
||||
}
|
||||
|
||||
zend_module_entry msgpack_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"msgpack",
|
||||
msgpack_functions,
|
||||
PHP_MINIT(msgpack),
|
||||
PHP_MSHUTDOWN(msgpack),
|
||||
PHP_RINIT(msgpack), /* Replace with NULL if there's nothing to do at request start */
|
||||
PHP_RSHUTDOWN(msgpack), /* Replace with NULL if there's nothing to do at request end */
|
||||
PHP_MINFO(msgpack),
|
||||
"msgpack",
|
||||
msgpack_functions,
|
||||
ZEND_MINIT(msgpack),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ZEND_MINFO(msgpack),
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
"0.1", /* Replace with version number for your extension */
|
||||
MSGPACK_VERSION,
|
||||
#endif
|
||||
PHP_MODULE_GLOBALS(msgpack),
|
||||
PHP_GINIT(msgpack),
|
||||
NULL,
|
||||
NULL,
|
||||
STANDARD_MODULE_PROPERTIES_EX
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_MSGPACK
|
||||
ZEND_GET_MODULE(msgpack)
|
||||
#endif
|
||||
|
||||
/* {{{ PHP_GINIT_FUNCTION */
|
||||
static PHP_GINIT_FUNCTION(msgpack)
|
||||
PS_SERIALIZER_ENCODE_FUNC(msgpack)
|
||||
{
|
||||
msgpack_globals->global_mp = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
smart_str buf = {0};
|
||||
php_serialize_data_t var_hash;
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(msgpack)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
INIT_CLASS_ENTRY(ce, "MessagePack", msgpack_functions);
|
||||
msgpack_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
PHP_VAR_SERIALIZE_INIT(var_hash);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
msgpack_serialize_zval(&buf, PS(http_session_vars), &var_hash TSRMLS_CC);
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(msgpack)
|
||||
{
|
||||
/* uncomment this line if you have INI entries
|
||||
UNREGISTER_INI_ENTRIES();
|
||||
*/
|
||||
if (MSGPACK_G(global_mp)) {
|
||||
efree(MSGPACK_G(global_mp));
|
||||
MSGPACK_G(global_mp) = NULL;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Remove if there's nothing to do at request start */
|
||||
/* {{{ PHP_RINIT_FUNCTION
|
||||
*/
|
||||
PHP_RINIT_FUNCTION(msgpack)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Remove if there's nothing to do at request end */
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_RSHUTDOWN_FUNCTION(msgpack)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(msgpack)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "msgpack support", "enabled");
|
||||
php_info_print_table_row(2, "php extension version", PHP_EXT_VERSION);
|
||||
php_info_print_table_row(2, "author", "Hideyuki TAKEI");
|
||||
php_info_print_table_row(2, "homepage", "http://msgpack.sourceforge.net");
|
||||
php_info_print_table_row(2, "open sourced by", "KLab inc.");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_MSGPACK_API int msgpack_determine_array_type(zval **val TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
int i;
|
||||
HashTable *myht = HASH_OF(*val);
|
||||
|
||||
i = myht ? zend_hash_num_elements(myht) : 0;
|
||||
if (i > 0) {
|
||||
char *key;
|
||||
ulong index, idx;
|
||||
uint key_len;
|
||||
HashPosition pos;
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(myht, &pos);
|
||||
idx = 0;
|
||||
for (;; zend_hash_move_forward_ex(myht, &pos)) {
|
||||
i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
|
||||
if (i == HASH_KEY_NON_EXISTANT)
|
||||
break;
|
||||
if (i == HASH_KEY_IS_STRING) {
|
||||
return 1;
|
||||
} else {
|
||||
if (index != idx) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_MSGPACK_API void msgpack_pack_array_hash(smart_str *pk, zval **val TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
int i, r;
|
||||
HashTable *myht;
|
||||
|
||||
if(Z_TYPE_PP(val) == IS_ARRAY){
|
||||
myht = HASH_OF(*val);
|
||||
r = msgpack_determine_array_type(val TSRMLS_CC);
|
||||
}
|
||||
else{
|
||||
myht = Z_OBJPROP_PP(val);
|
||||
r = 1;
|
||||
}
|
||||
|
||||
i = myht ? zend_hash_num_elements(myht) : 0;
|
||||
|
||||
if(r == 0){
|
||||
msgpack_pack_array(pk, i);
|
||||
}
|
||||
else{
|
||||
msgpack_pack_map(pk, i);
|
||||
}
|
||||
|
||||
if(i>0){
|
||||
char *key;
|
||||
zval **data;
|
||||
ulong index;
|
||||
uint key_len;
|
||||
HashPosition pos;
|
||||
HashTable *tmp_ht;
|
||||
int need_comma = 0;
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(myht, &pos);
|
||||
for(;; zend_hash_move_forward_ex(myht, &pos)){
|
||||
i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
|
||||
if(i==HASH_KEY_NON_EXISTANT)
|
||||
break;
|
||||
if(zend_hash_get_current_data_ex(myht, (void **) &data, &pos) == SUCCESS){
|
||||
tmp_ht = HASH_OF(*data);
|
||||
if (tmp_ht)
|
||||
tmp_ht->nApplyCount++;
|
||||
|
||||
if(r==0)
|
||||
php_msgpack_pack(pk, *data TSRMLS_CC);
|
||||
else if(r==1){
|
||||
if(i==HASH_KEY_IS_STRING){
|
||||
if(key[0]=='\0' && Z_TYPE_PP(val)==IS_OBJECT){
|
||||
// Skip protected and private members.
|
||||
if(tmp_ht)
|
||||
tmp_ht->nApplyCount--;
|
||||
continue;
|
||||
}
|
||||
msgpack_pack_raw(pk, key_len-1);
|
||||
msgpack_pack_raw_body(pk, key, key_len-1);
|
||||
php_msgpack_pack(pk, *data TSRMLS_CC);
|
||||
}
|
||||
else{
|
||||
msgpack_pack_long(pk, index);
|
||||
php_msgpack_pack(pk, *data TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
if(tmp_ht){
|
||||
tmp_ht->nApplyCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_MSGPACK_API void php_msgpack_pack(smart_str *pk, zval *val TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
switch(Z_TYPE_P(val)){
|
||||
case IS_NULL:
|
||||
msgpack_pack_nil(pk);
|
||||
break;
|
||||
case IS_BOOL:
|
||||
if (Z_BVAL_P(val))
|
||||
msgpack_pack_true(pk);
|
||||
else
|
||||
msgpack_pack_false(pk);
|
||||
break;
|
||||
case IS_LONG:
|
||||
msgpack_pack_long(pk, Z_LVAL_P(val));
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
{
|
||||
double dbl = Z_DVAL_P(val);
|
||||
if (zend_isinf(dbl) || zend_isnan(dbl)) {
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_pack) double %.9g does not conform to the MSGPACK spec, encoded as 0", dbl);
|
||||
ZVAL_LONG(val, 0);
|
||||
}
|
||||
msgpack_pack_double(pk, Z_DVAL_P(val));
|
||||
}
|
||||
break;
|
||||
case IS_STRING:
|
||||
msgpack_pack_raw(pk, Z_STRLEN_P(val));
|
||||
msgpack_pack_raw_body(pk, Z_STRVAL_P(val), Z_STRLEN_P(val));
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_OBJECT:
|
||||
msgpack_pack_array_hash(pk, &val TSRMLS_CC);
|
||||
break;
|
||||
defalut:
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_pack) type is unsupported, encoded as null");
|
||||
msgpack_pack_nil(pk);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_MSGPACK_API void php_msgpack_unpack_limit(zval *return_value, const char *buf, int len, zend_bool assoc TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (len<=0) {
|
||||
RETURN_NUL();
|
||||
}
|
||||
|
||||
msgpack_unpack_t mp;
|
||||
template_init(&mp);
|
||||
unpack_user u = {0, ""};
|
||||
|
||||
size_t from = 0;
|
||||
char* dptr = (char*)buf;
|
||||
long dlen = len;
|
||||
int ret;
|
||||
|
||||
(&mp)->user.source = (char*)buf;
|
||||
ret = template_execute(&mp, dptr, (size_t)dlen, &from);
|
||||
(&mp)->user.source = "";
|
||||
|
||||
if(ret < 0) {
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) parse error");
|
||||
} else if(ret == 0) {
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) insufficient bytes");
|
||||
} else {
|
||||
if(from < dlen) {
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) extra bytes");
|
||||
}
|
||||
|
||||
*return_value = *template_data(&mp);
|
||||
FREE_ZVAL(template_data(&mp));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
PHP_FUNCTION(msgpack_pack)
|
||||
{
|
||||
zval *parameter;
|
||||
smart_str buf = {0};
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
php_msgpack_pack(&buf, parameter TSRMLS_CC);
|
||||
|
||||
ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
|
||||
|
||||
smart_str_free(&buf);
|
||||
}
|
||||
|
||||
PHP_FUNCTION(msgpack_unpack)
|
||||
{
|
||||
char *parameter;
|
||||
int parameter_len;
|
||||
zend_bool assoc = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",
|
||||
¶meter, ¶meter_len, &assoc) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!parameter_len) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
php_msgpack_unpack_limit(return_value, parameter, parameter_len, assoc TSRMLS_CC);
|
||||
}
|
||||
|
||||
PHP_FUNCTION(msgpack_unpack_limit)
|
||||
{
|
||||
char *parameter;
|
||||
int parameter_len;
|
||||
int limit;
|
||||
zend_bool assoc = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|b",
|
||||
¶meter, ¶meter_len, &limit, &assoc) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!parameter_len) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
else if (parameter_len < limit) {
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) limit greater than data_len");
|
||||
limit = parameter_len;
|
||||
}
|
||||
|
||||
php_msgpack_unpack_limit(return_value, parameter, limit, assoc TSRMLS_CC);
|
||||
}
|
||||
|
||||
|
||||
PHP_MSGPACK_API void php_msgpack_unpacker_execute_limit(zval *return_value, const char *buf, int off, int len, zend_bool assoc TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (len<=0) {
|
||||
RETURN_NUL();
|
||||
}
|
||||
|
||||
size_t from = off;
|
||||
char* dptr = (char*)buf;
|
||||
long dlen = len;
|
||||
int ret;
|
||||
|
||||
if(from >= dlen) {
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_unpacker_execute_limit) offset is bigger than data buffer size");
|
||||
if (newlen)
|
||||
{
|
||||
*newlen = buf.len;
|
||||
}
|
||||
|
||||
MSGPACK_G(global_mp)->user.source = (char*)buf;
|
||||
ret = template_execute(MSGPACK_G(global_mp), dptr, (size_t)dlen, &from);
|
||||
MSGPACK_G(global_mp)->user.source = "";
|
||||
smart_str_0(&buf);
|
||||
*newstr = buf.c;
|
||||
|
||||
if(ret < 0) {
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_unpacker_execute_limit) parse error");
|
||||
} else if(ret > 0) {
|
||||
MSGPACK_G(global_mp)->user.finished = 1;
|
||||
RETVAL_LONG(from);
|
||||
} else {
|
||||
MSGPACK_G(global_mp)->user.finished = 0;
|
||||
RETVAL_LONG(from);
|
||||
}
|
||||
PHP_VAR_SERIALIZE_DESTROY(var_hash);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_MSGPACK_API void php_msgpack_unpacker_reset(TSRMLS_D) /* {{{ */
|
||||
PS_SERIALIZER_DECODE_FUNC(msgpack)
|
||||
{
|
||||
if(MSGPACK_G(global_mp)) {
|
||||
efree(MSGPACK_G(global_mp));
|
||||
MSGPACK_G(global_mp) = NULL;
|
||||
}
|
||||
MSGPACK_G(global_mp) = safe_emalloc(sizeof(msgpack_unpack_t), 1, 0);
|
||||
php_unserialize_data_t var_hash;
|
||||
int ret;
|
||||
HashTable *tmp_hash;
|
||||
HashPosition tmp_hash_pos;
|
||||
char *key_str;
|
||||
ulong key_long;
|
||||
uint key_len;
|
||||
zval *tmp;
|
||||
zval **data;
|
||||
msgpack_unserialize_data mpsd;
|
||||
|
||||
template_init(MSGPACK_G(global_mp));
|
||||
unpack_user u = {0, ""};
|
||||
MSGPACK_G(global_mp)->user = u;
|
||||
return;
|
||||
PHP_VAR_UNSERIALIZE_INIT(var_hash);
|
||||
|
||||
MAKE_STD_ZVAL(tmp);
|
||||
|
||||
mpsd.data = (unsigned char *)val;;
|
||||
mpsd.length = vallen;
|
||||
mpsd.offset = 0;
|
||||
|
||||
ret = msgpack_unserialize_zval(&tmp, &mpsd, &var_hash TSRMLS_CC);
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case MSGPACK_UNPACK_EXTRA_BYTES:
|
||||
case MSGPACK_UNPACK_SUCCESS:
|
||||
break;
|
||||
case MSGPACK_UNPACK_PARSE_ERROR:
|
||||
case MSGPACK_UNPACK_CONTINUE:
|
||||
default:
|
||||
zval_ptr_dtor(&tmp);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
|
||||
|
||||
tmp_hash = HASH_OF(tmp);
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(tmp_hash, &tmp_hash_pos);
|
||||
while (zend_hash_get_current_data_ex(
|
||||
tmp_hash, (void *)&data, &tmp_hash_pos) == SUCCESS)
|
||||
{
|
||||
ret = zend_hash_get_current_key_ex(
|
||||
tmp_hash, &key_str, &key_len, &key_long, 0, &tmp_hash_pos);
|
||||
switch (ret)
|
||||
{
|
||||
case HASH_KEY_IS_LONG:
|
||||
/* ??? */
|
||||
break;
|
||||
case HASH_KEY_IS_STRING:
|
||||
php_set_session_var(key_str, key_len - 1, *data, NULL TSRMLS_CC);
|
||||
php_add_session_var(key_str, key_len - 1 TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
zend_hash_move_forward_ex(tmp_hash, &tmp_hash_pos);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&tmp);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_METHOD(msgpack, initialize)
|
||||
PHP_MSGPACK_API void php_msgpack_serialize(smart_str *buf, zval *val TSRMLS_DC)
|
||||
{
|
||||
php_msgpack_unpacker_reset(TSRMLS_C);
|
||||
return;
|
||||
php_serialize_data_t var_hash;
|
||||
|
||||
PHP_VAR_SERIALIZE_INIT(var_hash);
|
||||
|
||||
msgpack_serialize_zval(buf, val, &var_hash TSRMLS_CC);
|
||||
|
||||
PHP_VAR_SERIALIZE_DESTROY(var_hash);
|
||||
}
|
||||
|
||||
PHP_METHOD(msgpack, execute)
|
||||
PHP_MSGPACK_API void php_msgpack_unserialize(
|
||||
zval *return_value, char *str, size_t str_len TSRMLS_DC)
|
||||
{
|
||||
char *data;
|
||||
int off;
|
||||
int data_len;
|
||||
zend_bool assoc = 0;
|
||||
int ret;
|
||||
php_unserialize_data_t var_hash;
|
||||
msgpack_unserialize_data mpsd;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|b",
|
||||
&data, &data_len, &off, &assoc) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
if (str_len <= 0)
|
||||
{
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
if (!data_len) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
PHP_VAR_UNSERIALIZE_INIT(var_hash);
|
||||
|
||||
php_msgpack_unpacker_execute_limit(return_value, data, off, data_len, assoc TSRMLS_CC);
|
||||
mpsd.data = (unsigned char *)str;
|
||||
mpsd.length = str_len;
|
||||
mpsd.offset = 0;
|
||||
|
||||
ret = msgpack_unserialize_zval(&return_value, &mpsd, &var_hash TSRMLS_CC);
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case MSGPACK_UNPACK_PARSE_ERROR:
|
||||
zend_error(E_WARNING,
|
||||
"[msgpack] (php_msgpack_unserialize) Parse error");
|
||||
break;
|
||||
case MSGPACK_UNPACK_CONTINUE:
|
||||
zend_error(E_WARNING,
|
||||
"[msgpack] (php_msgpack_unserialize) "
|
||||
"Insufficient data for unserializeng");
|
||||
break;
|
||||
case MSGPACK_UNPACK_EXTRA_BYTES:
|
||||
zend_error(E_WARNING,
|
||||
"[msgpack] (php_msgpack_unserialize) Extra bytes");
|
||||
break;
|
||||
case MSGPACK_UNPACK_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
zend_error(E_WARNING,
|
||||
"[msgpack] (php_msgpack_unserialize) Unknown result");
|
||||
break;
|
||||
}
|
||||
|
||||
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
|
||||
}
|
||||
|
||||
PHP_METHOD(msgpack, execute_limit)
|
||||
static ZEND_FUNCTION(msgpack_serialize)
|
||||
{
|
||||
char *data;
|
||||
int off;
|
||||
int data_len;
|
||||
int limit;
|
||||
zend_bool assoc = 0;
|
||||
zval *parameter;
|
||||
smart_str buf = {0};
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|b",
|
||||
&data, &data_len, &off, &limit, &assoc) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
if (zend_parse_parameters(
|
||||
ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶meter) == FAILURE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data_len) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
else if (data_len < limit) {
|
||||
zend_error(E_WARNING, "[msgpack] (php_msgpack_unpack) limit greater than (data+off)_len");
|
||||
limit = data_len;
|
||||
}
|
||||
php_msgpack_serialize(&buf, parameter TSRMLS_CC);
|
||||
|
||||
php_msgpack_unpacker_execute_limit(return_value, data, off, limit, assoc TSRMLS_CC);
|
||||
ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
|
||||
|
||||
smart_str_free(&buf);
|
||||
}
|
||||
|
||||
PHP_METHOD(msgpack, finished)
|
||||
static ZEND_FUNCTION(msgpack_unserialize)
|
||||
{
|
||||
if(MSGPACK_G(global_mp)->user.finished == 1) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
RETURN_FALSE;
|
||||
}
|
||||
char *str;
|
||||
int str_len;
|
||||
|
||||
PHP_METHOD(msgpack, data)
|
||||
{
|
||||
*return_value = *template_data(MSGPACK_G(global_mp));
|
||||
return;
|
||||
}
|
||||
if (zend_parse_parameters(
|
||||
ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
if (!str_len)
|
||||
{
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
php_msgpack_unserialize(return_value, str, str_len TSRMLS_CC);
|
||||
}
|
||||
|
@ -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";
|
||||
?>
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
340
php/msgpack_class.c
Normal 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", ¶meter) == 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
7
php/msgpack_class.h
Normal 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
514
php/msgpack_pack.c
Normal 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
17
php/msgpack_pack.h
Normal 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
829
php/msgpack_unpack.c
Normal 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
26
php/msgpack_unpack.h
Normal 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
98
php/package.xml
Normal 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
59
php/php-msgpack.spec
Normal 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
|
@ -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
0
php/test_normal.php
Executable file → Normal file
9
php/test_streaming.php
Executable file → Normal file
9
php/test_streaming.php
Executable file → Normal 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
10
php/tests/001.phpt
Normal 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
26
php/tests/002.phpt
Normal 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
31
php/tests/003.phpt
Normal 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
56
php/tests/004.phpt
Normal 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
26
php/tests/005.phpt
Normal 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
31
php/tests/006.phpt
Normal 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
72
php/tests/007.phpt
Normal 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
61
php/tests/008.phpt
Normal 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
115
php/tests/009.phpt
Normal 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
49
php/tests/010.phpt
Normal 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
48
php/tests/012.phpt
Normal 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
54
php/tests/013.phpt
Normal 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
54
php/tests/014.phpt
Normal 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
58
php/tests/015.phpt
Normal 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
58
php/tests/015b.phpt
Normal 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
60
php/tests/016.phpt
Normal 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
48
php/tests/017.phpt
Normal 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
84
php/tests/018.phpt
Normal 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
43
php/tests/019.phpt
Normal 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
31
php/tests/020.phpt
Normal 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
52
php/tests/021.phpt
Normal 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
45
php/tests/022.phpt
Normal 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
54
php/tests/023.phpt
Normal 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
166
php/tests/024.phpt
Normal 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
119
php/tests/025.phpt
Normal 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
143
php/tests/026.phpt
Normal 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
73
php/tests/027.phpt
Normal 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
667
php/tests/028.phpt
Normal 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
20
php/tests/029.phpt
Normal 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
233
php/tests/030.phpt
Normal 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
90
php/tests/031.phpt
Normal 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
76
php/tests/032.phpt
Normal 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
55
php/tests/033.phpt
Normal 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
38
php/tests/034.phpt
Normal 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
34
php/tests/035.phpt
Normal 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
43
php/tests/040.phpt
Normal 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
47
php/tests/041.phpt
Normal 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
40
php/tests/042.phpt
Normal 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
111
php/tests/050.phpt
Normal 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
315
php/tests/060.phpt
Normal 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
320
php/tests/061.phpt
Normal 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
64
php/tests/062.phpt
Normal 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
68
php/tests/063.phpt
Normal 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
299
php/tests/070.phpt
Normal 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
301
php/tests/071.phpt
Normal 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
341
php/tests/072.phpt
Normal 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
|
@ -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===
|
Loading…
x
Reference in New Issue
Block a user