6 Star 11 Fork 2

Hprose/hprose-pecl

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
hprose_common.c 22.96 KB
一键复制 编辑 原始数据 按行查看 历史
Hprose 提交于 2016-06-10 20:16 . Fixed #13
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* hprose_common.c *
* *
* hprose common for pecl source file. *
* *
* LastModified: Jun 10, 2016 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/
#include "hprose_common.h"
#if PHP_API_VERSION >= 20100412
#if PHP_MAJOR_VERSION < 7
HashTable *php_hprose_get_gc(zval *object, zval ***table, int *n TSRMLS_DC) {
*table = NULL;
*n = 0;
return zend_std_get_properties(object TSRMLS_CC);
}
#else
HashTable *php_hprose_get_gc(zval *object, zval **table, int *n) {
*table = NULL;
*n = 0;
return zend_std_get_properties(object);
}
#endif
#endif
zend_fcall_info_cache __get_fcall_info_cache(zval *obj, char *name, int32_t len TSRMLS_DC) {
zend_fcall_info_cache fcc = {0};
char *fname, *lcname = NULL;
zend_function *fptr;
#if PHP_VERSION_ID < 70100
zend_class_entry *scope = EG(scope);
#else
zend_class_entry *scope = EG(fake_scope) ? EG(fake_scope) : zend_get_executed_scope();
#endif
if (obj == NULL && (fname = strstr(name, "::")) == NULL) {
char *nsname;
lcname = zend_str_tolower_dup(name, len);
nsname = lcname;
if (lcname[0] == '\\') {
nsname = &lcname[1];
--len;
}
#if PHP_MAJOR_VERSION < 7
if (zend_hash_find(EG(function_table), nsname, len + 1, (void **)&fptr) == FAILURE) {
#else
if ((fptr = zend_hash_str_find_ptr(EG(function_table), nsname, len)) == NULL) {
#endif
efree(lcname);
zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
"Function %s() does not exist", name);
return fcc;
}
fcc.function_handler = fptr;
fcc.calling_scope = scope;
#if PHP_MAJOR_VERSION < 7
#if PHP_API_VERSION < 20090626
fcc.object_pp = NULL;
#else
fcc.called_scope = NULL;
fcc.object_ptr = NULL;
#endif
#else
fcc.called_scope = NULL;
fcc.object = NULL;
#endif
}
#if PHP_API_VERSION >= 20090626
else if (obj && Z_TYPE_P(obj) == IS_OBJECT &&
instanceof_function(Z_OBJCE_P(obj), zend_ce_closure TSRMLS_CC) &&
(fptr = (zend_function*)zend_get_closure_method_def(obj TSRMLS_CC)) != NULL) {
fcc.function_handler = fptr;
fcc.calling_scope = scope;
#if PHP_MAJOR_VERSION < 7
fcc.called_scope = NULL;
fcc.object_ptr = NULL;
#else
fcc.called_scope = NULL;
fcc.object = NULL;
#endif
}
#endif
else {
int32_t flen, clen;
zend_class_entry *ce;
#if PHP_MAJOR_VERSION < 7
char *cname;
zend_class_entry **pce;
#else
zend_string *cname;
#endif
if (obj == NULL) {
clen = fname - name;
#if PHP_MAJOR_VERSION < 7
cname = estrndup(name, clen);
#else
cname = zend_string_init(name, clen, 0);
#endif
flen = len - (clen + 2);
fname += 2;
}
else if (Z_TYPE_P(obj) == IS_STRING) {
clen = Z_STRLEN_P(obj);
#if PHP_MAJOR_VERSION < 7
cname = estrndup(Z_STRVAL_P(obj), clen);
#else
cname = zend_string_init(Z_STRVAL_P(obj), clen, 0);
#endif
flen = len;
fname = name;
obj = NULL;
}
else if (Z_TYPE_P(obj) != IS_OBJECT) {
zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
"The parameter obj is expected to be either a string or an object");
return fcc;
}
if (obj == NULL) {
#if PHP_MAJOR_VERSION < 7
if (zend_lookup_class(cname, clen, &pce TSRMLS_CC) == FAILURE) {
zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
"Class %s does not exist", cname);
efree(cname);
return fcc;
}
efree(cname);
ce = *pce;
#else
if ((ce = zend_lookup_class(cname)) == NULL) {
zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
"Class %s does not exist", cname->val);
zend_string_release(cname);
return fcc;
}
zend_string_release(cname);
#endif
}
else {
ce = Z_OBJCE_P(obj);
fname = name;
flen = len;
}
lcname = zend_str_tolower_dup(fname, flen);
#if PHP_MAJOR_VERSION < 7
if (zend_hash_find(&ce->function_table, lcname, flen + 1, (void **) &fptr) == FAILURE) {
#else
if ((fptr = zend_hash_str_find_ptr(&ce->function_table, lcname, flen)) == NULL) {
#endif
efree(lcname);
zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
"Method %s::%s() does not exist", ce->name, fname);
return fcc;
}
fcc.function_handler = fptr;
if ((fptr->common.fn_flags & ZEND_ACC_STATIC) || obj == NULL) {
#if PHP_API_VERSION < 20090626
fcc.calling_scope = NULL;
fcc.object_pp = NULL;
#else
fcc.calling_scope = fptr->common.scope;
fcc.called_scope = ce;
#if PHP_MAJOR_VERSION < 7
fcc.object_ptr = NULL;
#else
fcc.object = NULL;
#endif
#endif
}
else {
#if PHP_API_VERSION < 20090626
fcc.calling_scope = Z_OBJCE_P(obj);
fcc.object_pp = &obj;
#else
fcc.calling_scope = Z_OBJCE_P(obj);
fcc.called_scope = ce;
#if PHP_MAJOR_VERSION < 7
fcc.object_ptr = obj;
#else
fcc.object = Z_OBJ_P(obj);
#endif
#endif
}
}
if (lcname) {
efree(lcname);
}
fcc.initialized = 1;
return fcc;
}
void __function_invoke_args(zend_fcall_info_cache fcc, zval *obj, zval *return_value, zval *param_array TSRMLS_DC) {
#if PHP_MAJOR_VERSION < 7
zval *retval_ptr = NULL;
zval ***params = NULL;
#else
zval retval;
zval *params = NULL, *val;
int i;
#endif
int result;
int argc;
zend_fcall_info fci;
argc = (param_array) ? Z_ARRLEN_P(param_array) : 0;
if (argc) {
#if PHP_MAJOR_VERSION < 7
params = safe_emalloc(sizeof(zval **), argc, 0);
zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, &params TSRMLS_CC);
params -= argc;
#else
params = safe_emalloc(sizeof(zval), argc, 0);
argc = 0;
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(param_array), val) {
ZVAL_COPY(&params[argc], val);
argc++;
} ZEND_HASH_FOREACH_END();
#endif
}
fci.size = sizeof(fci);
#if PHP_VERSION_ID < 70100
fci.function_table = NULL;
fci.symbol_table = NULL;
#endif
#if PHP_MAJOR_VERSION < 7
fci.function_name = NULL;
fci.retval_ptr_ptr = &retval_ptr;
#else
ZVAL_UNDEF(&fci.function_name);
fci.retval = &retval;
#endif
fci.param_count = argc;
fci.params = params;
fci.no_separation = 1;
if (obj != NULL && Z_TYPE_P(obj) == IS_OBJECT) {
#if PHP_API_VERSION < 20090626
fci.object_pp = &obj;
fcc.object_pp = &obj;
#elif PHP_MAJOR_VERSION < 7
fci.object_ptr = obj;
fcc.object_ptr = obj;
#else
fci.object = Z_OBJ_P(obj);
fcc.object = Z_OBJ_P(obj);
#endif
fcc.calling_scope = Z_OBJCE_P(obj);
}
else {
#if PHP_API_VERSION < 20090626
fci.object_pp = fcc.object_pp;
#elif PHP_MAJOR_VERSION < 7
fci.object_ptr = fcc.object_ptr;
#else
fci.object = fcc.object;
#endif
}
#if PHP_MAJOR_VERSION < 7
result = zend_call_function(&fci, &fcc TSRMLS_CC);
if (argc) {
efree(params);
}
if (result == FAILURE) {
zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
"Invocation of function %s() failed",
fcc.function_handler->common.function_name);
return;
}
if (retval_ptr) {
if (return_value) {
COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
}
else {
zval_ptr_dtor(&retval_ptr);
}
}
#else
result = zend_call_function(&fci, &fcc);
for (i = 0; i < argc; i++) {
zval_ptr_dtor(&params[i]);
}
if (argc) {
efree(params);
}
if (result == FAILURE) {
zend_throw_exception_ex(NULL, 0,
"Invocation of function %s() failed",
fcc.function_handler->common.function_name->val);
return;
}
if (Z_TYPE(retval) != IS_UNDEF) {
if (return_value) {
ZVAL_COPY_VALUE(return_value, &retval);
}
else {
zval_ptr_dtor(&retval);
}
}
#endif
}
void __function_invoke(zend_fcall_info_cache fcc, zval *obj, zval *return_value, zend_bool dtor TSRMLS_DC, const char *params_format, ...) {
#if PHP_MAJOR_VERSION < 7
zval *retval_ptr = NULL;
zval ***params = NULL;
#else
zval retval;
zval *params = NULL;
#endif
uint32_t i, argc;
int result;
zend_fcall_info fci;
argc = strlen(params_format);
if (argc) {
#if PHP_MAJOR_VERSION < 7
va_list ap;
va_start(ap, params_format);
params = safe_emalloc(sizeof(zval **), argc, 0);
for (i = 0; i < argc; ++i) {
params[i] = emalloc(sizeof(zval *));
switch (params_format[i]) {
case 's': {
char *str = va_arg(ap, char *);
long len = va_arg(ap, long);
MAKE_STD_ZVAL(*params[i]);
ZVAL_STRINGL(*params[i], str, len, 0);
break;
}
case 'l': {
long l = va_arg(ap, long);
MAKE_STD_ZVAL(*params[i]);
ZVAL_LONG(*params[i], l);
break;
}
case 'd': {
double d = va_arg(ap, double);
MAKE_STD_ZVAL(*params[i]);
ZVAL_DOUBLE(*params[i], d);
break;
}
case 'n': {
MAKE_STD_ZVAL(*params[i]);
ZVAL_NULL(*params[i]);
break;
}
case 'b': {
zend_bool b = va_arg(ap, int);
MAKE_STD_ZVAL(*params[i]);
ZVAL_BOOL(*params[i], b);
break;
}
case 'z': {
zval *v = va_arg(ap, zval *);
if (v) {
Z_ADDREF_P(v);
*params[i] = v;
}
else {
MAKE_STD_ZVAL(*params[i]);
ZVAL_NULL(*params[i]);
}
break;
}
default:
zend_throw_exception_ex(
NULL, 0 TSRMLS_CC,
"Unsupported type:%c in function_invoke",
params_format[i]);
return;
}
}
va_end(ap);
#else
va_list ap;
va_start(ap, params_format);
params = safe_emalloc(sizeof(zval), argc, 0);
for (i = 0; i < argc; ++i) {
switch (params_format[i]) {
case 's': {
char *str = va_arg(ap, char *);
long len = va_arg(ap, long);
ZVAL_STRINGL(&params[i], str, len);
break;
}
case 'l': {
long l = va_arg(ap, long);
ZVAL_LONG(&params[i], l);
break;
}
case 'd': {
double d = va_arg(ap, double);
ZVAL_DOUBLE(&params[i], d);
break;
}
case 'n': {
ZVAL_NULL(&params[i]);
break;
}
case 'b': {
zend_bool b = va_arg(ap, int);
ZVAL_BOOL(&params[i], b);
break;
}
case 'z': {
zval *v = va_arg(ap, zval *);
if (v) {
ZVAL_COPY(&params[i], v);
}
else {
ZVAL_NULL(&params[i]);
}
break;
}
default:
zend_throw_exception_ex(
NULL, 0,
"Unsupported type:%c in function_invoke",
params_format[i]);
return;
}
}
va_end(ap);
#endif
}
fci.size = sizeof(fci);
#if PHP_VERSION_ID < 70100
fci.function_table = NULL;
fci.symbol_table = NULL;
#endif
#if PHP_MAJOR_VERSION < 7
fci.function_name = NULL;
fci.retval_ptr_ptr = &retval_ptr;
#else
ZVAL_UNDEF(&fci.function_name);
fci.retval = &retval;
#endif
fci.param_count = argc;
fci.params = params;
fci.no_separation = 1;
if (obj != NULL && Z_TYPE_P(obj) == IS_OBJECT) {
#if PHP_API_VERSION < 20090626
fci.object_pp = &obj;
fcc.object_pp = &obj;
#elif PHP_MAJOR_VERSION < 7
fci.object_ptr = obj;
fcc.object_ptr = obj;
#else
fci.object = Z_OBJ_P(obj);
fcc.object = Z_OBJ_P(obj);
#endif
fcc.calling_scope = Z_OBJCE_P(obj);
}
else {
#if PHP_API_VERSION < 20090626
fci.object_pp = fcc.object_pp;
#elif PHP_MAJOR_VERSION < 7
fci.object_ptr = fcc.object_ptr;
#else
fci.object = fcc.object;
#endif
}
#if PHP_MAJOR_VERSION < 7
result = zend_call_function(&fci, &fcc TSRMLS_CC);
for (i = 0; i < argc; i++) {
if (params_format[i] == 's') {
ZVAL_EMPTY_STRING(*params[i]);
}
zval_ptr_dtor(params[i]);
efree(params[i]);
}
if (argc) {
efree(params);
}
if (result == FAILURE) {
zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
"Invocation of function %s() failed",
fcc.function_handler->common.function_name);
return;
}
if (retval_ptr) {
if (return_value) {
if (return_value != retval_ptr) {
if (dtor) {
zval_dtor(return_value);
}
COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
}
else {
if (dtor) {
zval_ptr_dtor(&retval_ptr);
}
}
}
else {
zval_ptr_dtor(&retval_ptr);
}
}
#else
result = zend_call_function(&fci, &fcc);
for (i = 0; i < argc; i++) {
zval_ptr_dtor(&params[i]);
}
if (argc) {
efree(params);
}
if (result == FAILURE) {
zend_throw_exception_ex(NULL, 0,
"Invocation of function %s() failed",
fcc.function_handler->common.function_name->val);
return;
}
if (Z_TYPE(retval) != IS_UNDEF) {
if (return_value) {
if (dtor) {
zval_ptr_dtor(return_value);
}
ZVAL_COPY_VALUE(return_value, &retval);
}
else {
zval_ptr_dtor(&retval);
}
}
#endif
}
zend_class_entry *__create_php_object(char *class_name, int32_t len, zval *return_value TSRMLS_DC, const char *params_format, ...) {
zend_function *constructor;
zend_class_entry *entry;
#if PHP_MAJOR_VERSION < 7
zval *retval_ptr = NULL;
zval ***params = NULL;
#else
zval retval;
zval *params = NULL;
zend_string *classname;
#endif
uint32_t i, argc;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
#if PHP_VERSION_ID < 70100
zend_class_entry *scope = EG(scope);
#else
zend_class_entry *scope = EG(fake_scope) ? EG(fake_scope) : zend_get_executed_scope();
#endif
argc = strlen(params_format);
if (argc) {
#if PHP_MAJOR_VERSION < 7
va_list ap;
va_start(ap, params_format);
params = safe_emalloc(sizeof(zval **), argc, 0);
for (i = 0; i < argc; ++i) {
params[i] = emalloc(sizeof(zval *));
switch (params_format[i]) {
case 's': {
char *str = va_arg(ap, char *);
long len = va_arg(ap, long);
MAKE_STD_ZVAL(*params[i]);
ZVAL_STRINGL(*params[i], str, len, 0);
break;
}
case 'l': {
long l = va_arg(ap, long);
MAKE_STD_ZVAL(*params[i]);
ZVAL_LONG(*params[i], l);
break;
}
case 'd': {
double d = va_arg(ap, double);
MAKE_STD_ZVAL(*params[i]);
ZVAL_DOUBLE(*params[i], d);
break;
}
case 'n': {
MAKE_STD_ZVAL(*params[i]);
ZVAL_NULL(*params[i]);
break;
}
case 'b': {
zend_bool b = va_arg(ap, int);
MAKE_STD_ZVAL(*params[i]);
ZVAL_BOOL(*params[i], b);
break;
}
case 'z': {
zval *v = va_arg(ap, zval *);
if (v) {
Z_ADDREF_P(v);
*params[i] = v;
}
else {
MAKE_STD_ZVAL(*params[i]);
ZVAL_NULL(*params[i]);
}
break;
}
default:
zend_throw_exception_ex(
NULL, 0 TSRMLS_CC,
"Unsupported type:%c in create_php_object",
params_format[i]);
return NULL;
}
}
va_end(ap);
#else
va_list ap;
va_start(ap, params_format);
params = safe_emalloc(sizeof(zval), argc, 0);
for (i = 0; i < argc; ++i) {
switch (params_format[i]) {
case 's': {
char *str = va_arg(ap, char *);
long len = va_arg(ap, long);
ZVAL_STRINGL(&params[i], str, len);
break;
}
case 'l': {
long l = va_arg(ap, long);
ZVAL_LONG(&params[i], l);
break;
}
case 'd': {
double d = va_arg(ap, double);
ZVAL_DOUBLE(&params[i], d);
break;
}
case 'n': {
ZVAL_NULL(&params[i]);
break;
}
case 'b': {
zend_bool b = va_arg(ap, int);
ZVAL_BOOL(&params[i], b);
break;
}
case 'z': {
zval *v = va_arg(ap, zval *);
if (v) {
ZVAL_COPY(&params[i], v);
}
else {
ZVAL_NULL(&params[i]);
}
break;
}
default:
zend_throw_exception_ex(
NULL, 0,
"Unsupported type:%c in create_php_object",
params_format[i]);
return NULL;
}
}
va_end(ap);
#endif
}
#if PHP_MAJOR_VERSION < 7
entry = zend_fetch_class(class_name, len, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
object_init_ex(return_value, entry);
constructor = Z_OBJ_HT_P(return_value)->get_constructor(return_value TSRMLS_CC);
if (constructor && constructor->common.num_args >= argc &&
argc >= constructor->common.required_num_args) {
fci.size = sizeof(fci);
fci.function_table = EG(function_table);
fci.function_name = NULL;
fci.symbol_table = NULL;
#if PHP_API_VERSION < 20090626
fci.object_pp = &return_value;
#else
fci.object_ptr = return_value;
#endif
fci.retval_ptr_ptr = &retval_ptr;
fci.param_count = argc;
fci.params = params;
fci.no_separation = 1;
fcc.initialized = 1;
fcc.function_handler = constructor;
fcc.calling_scope = EG(scope);
#if PHP_API_VERSION < 20090626
fcc.object_pp = &return_value;
#else
fcc.called_scope = Z_OBJCE_P(return_value);
fcc.object_ptr = return_value;
#endif
zend_call_function(&fci, &fcc TSRMLS_CC);
for (i = 0; i < argc; i++) {
if (params_format[i] == 's') {
ZVAL_EMPTY_STRING(*params[i]);
}
zval_ptr_dtor(params[i]);
efree(params[i]);
}
if (argc) {
efree(params);
}
if (retval_ptr) {
zval_ptr_dtor(&retval_ptr);
}
}
#else
classname = zend_string_init(class_name, len, 0);
entry = zend_lookup_class(classname);
zend_string_release(classname);
object_init_ex(return_value, entry);
constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value));
if (constructor && constructor->common.num_args >= argc &&
argc >= constructor->common.required_num_args) {
fci.size = sizeof(fci);
ZVAL_UNDEF(&fci.function_name);
#if PHP_VERSION_ID < 70100
fci.function_table = EG(function_table);
fci.symbol_table = NULL;
#endif
fci.object = Z_OBJ_P(return_value);
fci.retval = &retval;
fci.param_count = argc;
fci.params = params;
fci.no_separation = 1;
fcc.initialized = 1;
fcc.function_handler = constructor;
fcc.calling_scope = scope;
fcc.called_scope = Z_OBJCE_P(return_value);
fcc.object = Z_OBJ_P(return_value);
zend_call_function(&fci, &fcc);
for (i = 0; i < argc; i++) {
zval_ptr_dtor(&params[i]);
}
if (argc) {
efree(params);
}
if (Z_TYPE(retval) != IS_UNDEF) {
zval_ptr_dtor(&retval);
}
}
#endif
return entry;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/andot/hprose-pecl.git
git@gitee.com:andot/hprose-pecl.git
andot
hprose-pecl
hprose-pecl
master

搜索帮助