Exemple #1
0
zval *air_config_get_data(TSRMLS_D){
	zval *data = zend_read_static_property(air_config_ce, ZEND_STRL("_data"), 1 TSRMLS_CC);
	if(Z_TYPE_P(data) == IS_NULL){
		air_config_init_default(TSRMLS_C);
		data = zend_read_static_property(air_config_ce, ZEND_STRL("_data"), 1 TSRMLS_CC);
	}
	return data;
}
Exemple #2
0
/*{{{ zval* get_instance(TSRMLS_D)
 */
zval* fool_loader_instance(TSRMLS_D)
{
	zval* instance;

	instance = zend_read_static_property(fool_loader_ce,ZEND_STRL(FOOL_LOADER_PROPERTY_NAME_INSTANCE),1 TSRMLS_CC);

	if(Z_TYPE_P(instance) == IS_OBJECT){
		//Z_ADDREF_P(instance);  ?????????????????
		return instance;
	}

	object_init_ex(instance,fool_loader_ce);

	zend_update_static_property(fool_loader_ce,ZEND_STRL(FOOL_LOADER_PROPERTY_NAME_INSTANCE),instance TSRMLS_CC);

	char* include_path;// = emalloc(strlen(FOOL_G(class_map)) + strlen(FOOL_G(config_path)) + 2);
	
	spprintf(&include_path,0,"%s/%s",FOOLPHP_G(config_path),FOOLPHP_G(class_map));

	if(instance){
		//include class_map
		fool_loader_include(include_path TSRMLS_CC);
		efree(include_path);

		return instance;
	}
	efree(include_path);
	return NULL;
}
Exemple #3
0
/**{{{ zval* get_instance(TSRMLS_D)
 */
zval* fool_view_instance(TSRMLS_D)
{
	zval* instance;
	zval* var;

	instance = zend_read_static_property(fool_view_ce,ZEND_STRL(FOOL_VIEW_PROPERTY_NAME_INSTANCE),1 TSRMLS_CC);

	if(Z_TYPE_P(instance) == IS_OBJECT){
		//Z_ADDREF_P(instance);  //?????????????????
		return instance;
	}

	object_init_ex(instance,fool_view_ce);

	zend_update_static_property(fool_view_ce,ZEND_STRL(FOOL_VIEW_PROPERTY_NAME_INSTANCE),instance TSRMLS_CC);

	
	if(instance){
		MAKE_STD_ZVAL(var);
		array_init(var);
		zend_update_property(fool_view_ce,instance,ZEND_STRL(FOOL_VIEW_PROPERTY_NAME_VAR),var TSRMLS_CC);
		return instance;
	}
	return NULL;
}
Exemple #4
0
/** {{{ int yaf_application_is_module_name(char *name, int len TSRMLS_DC)
*/
int yaf_application_is_module_name(char *name, int len TSRMLS_DC) {
	zval 			*modules, **ppzval;
	HashTable 		*ht;
	yaf_application_t 	*app;

	app = zend_read_static_property(yaf_application_ce, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), 1 TSRMLS_CC);
	if (Z_TYPE_P(app) != IS_OBJECT) {
		return 0;
	}

	modules = zend_read_property(yaf_application_ce, app, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_MODULES), 1 TSRMLS_CC);
	if (Z_TYPE_P(modules) != IS_ARRAY) {
		return 0;
	}

	ht = Z_ARRVAL_P(modules);
	zend_hash_internal_pointer_reset(ht);
	while (zend_hash_get_current_data(ht, (void **)&ppzval) == SUCCESS) {
		if (Z_STRLEN_PP(ppzval) == len && strncasecmp(Z_STRVAL_PP(ppzval), name, len) == 0) {
			return 1;
		}
		zend_hash_move_forward(ht);
	}
	return 0;
}
/** {{{ int yaf_application_is_module_name(char *name, int len TSRMLS_DC)
 *	判断名称是否是已经注册了的module的名称
*/
int yaf_application_is_module_name(char *name, int len TSRMLS_DC) {
	zval 				*modules, **ppzval;
	HashTable 			*ht;
	yaf_application_t 	*app;
	/* 获取类的实例,$app = self::$_app */
	app = zend_read_static_property(yaf_application_ce, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), 1 TSRMLS_CC);
	if (!app || Z_TYPE_P(app) != IS_OBJECT) {
		return 0;
	}
	/* $modules = $this->_modules */
	modules = zend_read_property(yaf_application_ce, app, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_MODULES), 1 TSRMLS_CC);
	if (!modules || Z_TYPE_P(modules) != IS_ARRAY) {
		return 0;
	}
	/* 检测name是否在$this->_modules数组中,在就返回1,不在返回0 */
	ht = Z_ARRVAL_P(modules);
	zend_hash_internal_pointer_reset(ht);
	while (zend_hash_get_current_data(ht, (void **)&ppzval) == SUCCESS) {
		if (Z_TYPE_PP(ppzval) == IS_STRING && Z_STRLEN_PP(ppzval) == len
				&& strncasecmp(Z_STRVAL_PP(ppzval), name, len) == 0) {
			return 1;
		}
		zend_hash_move_forward(ht);
	}
	return 0;
}
Exemple #6
0
ZEND_METHOD( alinq_class , Single )
{
    zend_fcall_info fci;
    zend_fcall_info_cache fci_cache;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    zval * reVal;

 
    char aReturnType;
    int aReturnTypeLen; 

    // aReturnType = 'bool';

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", &fci, &fci_cache) == FAILURE) {
        return;
    }     
    // zval *arrayValues;
    zval *ALINQ_CLOSURE_RETURN_TYPE_BOOL;

    ALINQ_CLOSURE_RETURN_TYPE_BOOL = zend_read_static_property(ce, "ALINQ_CLOSURE_RETURN_TYPE_BOOL", sizeof("ALINQ_CLOSURE_RETURN_TYPE_BOOL")-1, 0 TSRMLS_DC);
    // walu_call_user_function(&arrayValues, getThis(), "GetApplicables", "fl", fci,1);
    reVal = GetApplicables(getThis(),fci,fci_cache,1,Z_STRVAL_P(ALINQ_CLOSURE_RETURN_TYPE_BOOL),sizeof(Z_STRVAL_P(ALINQ_CLOSURE_RETURN_TYPE_BOOL)));
    RETURN_ZVAL(reVal,1,1);
    // php_printf("fine");  
    // RETURN_ZVAL(arrayValues,1,1);
    // walu_call_anony_function(&arrayValues, NULL, fci, "sz", key, keylen,tmpcopy);

}
void activerecord_model_assign_attributes( zval * model, zval * attributes, zend_bool guard )
{
    zval * accessible 	= zend_read_static_property(activerecord_model_ce, "attr_accessible", 15, 0 TSRMLS_CC);
    zval * protected	= zend_read_static_property(activerecord_model_ce, "attr_protected", 14, 0 TSRMLS_CC);
    zval ** attribute;
    int acc_count = zend_hash_num_elements(Z_ARRVAL_P(accessible));
    int prt_count = zend_hash_num_elements(Z_ARRVAL_P(protected));
    HashPosition pos;
    int index, key_len;
    char * key_name;

    for( zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(attributes), &pos);
            zend_hash_get_current_data_ex(Z_ARRVAL_P(attributes), (void **) &attribute, &pos) == SUCCESS;
            zend_hash_move_forward_ex(Z_ARRVAL_P(attributes), &pos) )
    {
        /*
        			if (array_key_exists($name,$table->columns))
        	{
        		$value = $table->columns[$name]->cast($value,$connection);
        		$name = $table->columns[$name]->inflected_name;
        	}
        */
        zend_hash_get_current_key_ex( Z_ARRVAL_P(attributes), &key_name, &key_len, &index, 0, &pos);
        if( guard )
        {
            if( acc_count > 0 && !activerecord_model_array_search( accessible, key_name ) )
                continue;

            if( prt_count > 0 && activerecord_model_array_search( protected, key_name ) )
                continue;

            activerecord_model_magic_set( model, key_name, key_len, *attribute );
        }
        else if( strcmp(key_name, "ar_rnum__") )
        {
            activerecord_assign_attribute( model, key_name, key_len, *attribute );
        }
    }
Exemple #8
0
/**{{{
*/
zval *_getInstance(void) {
	zval *instance;

	instance = zend_read_static_property(mylogs_ce, ZEND_STRL(MYLOGS_INSTANCE), 0 TSRMLS_CC);
	if(IS_OBJECT == Z_TYPE_P(instance)
		&& instanceof_function(Z_OBJCE_P(instance), mylogs_ce TSRMLS_CC)) {
		return instance;
	}

	MAKE_STD_ZVAL(instance);
	object_init_ex(instance, mylogs_ce);
	zend_update_static_property(mylogs_ce, ZEND_STRL(MYLOGS_INSTANCE), instance TSRMLS_CC);
	return instance;
}
Exemple #9
0
//is used to validate objects before serialization and after deserialization. For now, only required fields are validated.
static
void validate_thrift_object(zval* object) {
    zend_class_entry* object_class_entry = Z_OBJCE_P(object);
    zval* is_validate = zend_read_static_property(object_class_entry, "isValidate", sizeof("isValidate")-1, false);
    zval* spec = zend_read_static_property(object_class_entry, "_TSPEC", sizeof("_TSPEC")-1, false);
    HashPosition key_ptr;
    zval* val_ptr;

    if (Z_TYPE_INFO_P(is_validate) == IS_TRUE) {
        for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(spec), &key_ptr);
           (val_ptr = zend_hash_get_current_data_ex(Z_ARRVAL_P(spec), &key_ptr)) != nullptr;
           zend_hash_move_forward_ex(Z_ARRVAL_P(spec), &key_ptr)) {

            zend_ulong fieldno;
            if (zend_hash_get_current_key_ex(Z_ARRVAL_P(spec), nullptr, &fieldno, &key_ptr) != HASH_KEY_IS_LONG) {
              throw_tprotocolexception("Bad keytype in TSPEC (expected 'long')", INVALID_DATA);
              return;
            }
            HashTable* fieldspec = Z_ARRVAL_P(val_ptr);

            // field name
            zval* zvarname = zend_hash_str_find(fieldspec, "var", sizeof("var")-1);
            char* varname = Z_STRVAL_P(zvarname);

            zval* is_required = zend_hash_str_find(fieldspec, "isRequired", sizeof("isRequired")-1);
            zval rv;
            zval* prop = zend_read_property(object_class_entry, object, varname, strlen(varname), false, &rv);

            if (Z_TYPE_INFO_P(is_required) == IS_TRUE && Z_TYPE_P(prop) == IS_NULL) {
                char errbuf[128];
                snprintf(errbuf, 128, "Required field %s.%s is unset!", ZSTR_VAL(object_class_entry->name), varname);
                throw_tprotocolexception(errbuf, INVALID_DATA);
            }
        }
    }
}
Exemple #10
0
PHP_METHOD(slightphp, setZoneAlias)
{
		char *zone, *alias;
		int zone_len, alias_len;
		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &zone, &zone_len, &alias ,&alias_len) == FAILURE) {
				RETURN_FALSE;
		}
		zval *zoneAlias = zend_read_static_property(slightphp_ce_ptr,"zoneAlias",sizeof("zoneAlias")-1,1 TSRMLS_CC);
		if(!zoneAlias){ RETURN_FALSE; }

		if(Z_TYPE_P(zoneAlias)!=IS_ARRAY){
				array_init(zoneAlias);
		}
		add_assoc_string(zoneAlias,zone,alias,1);
		zend_update_static_property(slightphp_ce_ptr,"zoneAlias",sizeof("zoneAlias")-1,zoneAlias TSRMLS_CC);
		RETURN_TRUE;
}
Exemple #11
0
PHP_METHOD(slightphp, getZoneAlias)
{
	char * zone= NULL;
	size_t zone_len;
	if (zend_parse_parameters(ZEND_NUM_ARGS() , "s", &zone, &zone_len) == FAILURE) {
		RETURN_FALSE;
	}
	zval *zoneAlias = zend_read_static_property(slightphp_ce_ptr,"zoneAlias",sizeof("zoneAlias")-1,1 );
	if(!zoneAlias || Z_TYPE_P(zoneAlias)!=IS_ARRAY){ RETURN_FALSE; }
	zval *token;
	if ((token= zend_hash_str_find(Z_ARRVAL_P(zoneAlias), zone,zone_len)) != NULL){
		*return_value = *token;
		zval_copy_ctor(return_value);
	}else{
		RETURN_FALSE;
	}
}
Exemple #12
0
PHP_METHOD(slightphp, getZoneAlias)
{
		char * zone= NULL;
		int zone_len;
		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &zone, &zone_len) == FAILURE) {
				RETURN_FALSE;
		}
		zval *zoneAlias = zend_read_static_property(slightphp_ce_ptr,"zoneAlias",sizeof("zoneAlias")-1,1 TSRMLS_CC);
		if(!zoneAlias || Z_TYPE_P(zoneAlias)!=IS_ARRAY){ RETURN_FALSE; }
		zval **token;
		if(zend_hash_find(Z_ARRVAL_P(zoneAlias),zone, zone_len+1, (void**)&token) == SUCCESS) {
				*return_value = **token;
				zval_copy_ctor(return_value);
		}else{
				RETURN_FALSE;
		}
}
Exemple #13
0
int zephir_read_static_property_ce(zval *result, zend_class_entry *ce, const char *property, int len, int flags)
{
	zval *tmp = zend_read_static_property(ce, property, len, (zend_bool) ZEND_FETCH_CLASS_SILENT);

	//zval_ptr_dtor(result);
	ZVAL_NULL(result);
	if (tmp)
	{
		if ((flags & PH_READONLY) == PH_READONLY) {
			ZVAL_COPY_VALUE(result, tmp);
		} else {
			ZVAL_COPY(result, tmp);
		}
		return SUCCESS;
	}
	return FAILURE;
}
Exemple #14
0
ZEND_METHOD( alinq_class , All )
{
    zend_fcall_info fci;
    zend_fcall_info_cache fci_cache;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    zval *dataSource, *reObj, *reZvalCount,*new_dataSource;

    HashTable *arrht;
    HashTable *rearrht;

    char aReturnType;
    int aReturnTypeLen; 

    int count,reCount;

    // aReturnType = 'bool';

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", &fci, &fci_cache) == FAILURE) {
        return;
    }     
    zval *ALINQ_CLOSURE_RETURN_TYPE_BOOL;

    ALINQ_CLOSURE_RETURN_TYPE_BOOL = zend_read_static_property(ce, "ALINQ_CLOSURE_RETURN_TYPE_BOOL", sizeof("ALINQ_CLOSURE_RETURN_TYPE_BOOL")-1, 0 TSRMLS_DC);
    reObj = GetApplicables(getThis(),fci,fci_cache,0,Z_STRVAL_P(ALINQ_CLOSURE_RETURN_TYPE_BOOL),sizeof(Z_STRVAL_P(ALINQ_CLOSURE_RETURN_TYPE_BOOL)));
    // RETURN_ZVAL(reArr,1,1);
    //过滤后的元素个数
    new_dataSource = zend_read_property(NULL, reObj, "dataSource", sizeof("dataSource")-1, 0 TSRMLS_DC);
    // walu_call_user_function(&reZvalCount, NULL, "count", "z", reArr);
    // reCount = Z_LVAL_P(reZvalCount);
    rearrht = Z_ARRVAL_P(new_dataSource);
    reCount = rearrht->nNumOfElements;


    //原数组的元素个数
    dataSource = zend_read_property(ce, getThis(), "dataSource", sizeof("dataSource")-1, 0 TSRMLS_DC);
    arrht = Z_ARRVAL_P(dataSource);
    count = arrht->nNumOfElements;

    if(count==reCount){
        RETURN_BOOL(1);
    }
    RETURN_BOOL(0);

}
Exemple #15
0
/* {{{ PHP METHODS */
PHP_METHOD(air_async_service, __construct) {
	AIR_INIT_THIS;

	zval *waiter = NULL;
	zval *request = NULL;
	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &waiter, &request) == FAILURE){
		AIR_NEW_EXCEPTION(1, "invalid __construct params");
	}
	//check if waiter is instance of air\waiter
	if(Z_TYPE_P(waiter) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(waiter), air_async_waiter_ce TSRMLS_CC)) {
		air_throw_exception(1, "param waiter must be a instance of air\\waiter");
	}
	zend_update_property(air_async_service_ce, self, ZEND_STRL("_waiter"), waiter TSRMLS_CC);
	zend_update_property(air_async_service_ce, self, ZEND_STRL("request"), request TSRMLS_CC);
	zval *__id = zend_read_static_property(air_async_service_ce, ZEND_STRL("__id"), 0 TSRMLS_CC);
	(*__id).value.lval++;
	zend_update_property_long(air_async_service_ce, self, ZEND_STRL("_id"), Z_LVAL_P(__id) TSRMLS_CC);
}
Exemple #16
0
/** {{{void yaf_trigger_error(int type TSRMLS_DC, char *format, ...)
 */
void yaf_trigger_error(int type TSRMLS_DC, char *format, ...) {
	va_list args;
	char *message;
	uint msg_len;

	va_start(args, format);
	msg_len = vspprintf(&message, 0, format, args); 
	va_end(args);    

	if (YAF_G(throw_exception)) {
		yaf_throw_exception(type, message TSRMLS_CC);
	} else { 
		yaf_application_t *app = zend_read_static_property(yaf_application_ce, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), 1 TSRMLS_CC);
		zend_update_property_long(yaf_application_ce, app, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ERRNO), type TSRMLS_CC);
		zend_update_property_stringl(yaf_application_ce, app, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ERRMSG), message, msg_len TSRMLS_CC);
		php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, message);
	} 
	efree(message); 
}
Exemple #17
0
/*{{{ zval* fool_application_instance(TSRMLS_D)
 */
zval* fool_application_instance(TSRMLS_D)
{
	zval* instance;
	zval* dispatcher;
	zval* loader;

	instance = zend_read_static_property(fool_application_ce,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_INSTANCE),1 TSRMLS_CC);

	if(Z_TYPE_P(instance) == IS_OBJECT){
		//Z_ADDREF_P(instance);
		return instance;
	}

	object_init_ex(instance,fool_application_ce);

	zend_update_static_property(fool_application_ce,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_INSTANCE),instance TSRMLS_CC);

	
	if(instance){
		//init dispatcher
		dispatcher = fool_dispatcher_instance(TSRMLS_C);
		if(!dispatcher){
			return NULL;
		}
	
		loader = fool_loader_instance(TSRMLS_CC);	
		if(!loader){
			return NULL;
		}
		fool_loader_register_autoload(loader TSRMLS_CC);

		zend_update_property(fool_application_ce,instance,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_DISPATCHER),dispatcher TSRMLS_CC);
		
		//init config
		fool_config_init(TSRMLS_C);
		//init object
		fool_object_instance(TSRMLS_C);

		return instance;
	}
	return NULL;
}
Exemple #18
0
/*{{{LICENSE
  +-----------------------------------------------------------------------+
  | slightphp Framework                                                   |
  +-----------------------------------------------------------------------+
  | This program is free software; you can redistribute it and/or modify  |
  | it under the terms of the GNU General Public License as published by  |
  | the Free Software Foundation. You should have received a copy of the  |
  | GNU General Public License along with this program.  If not, see      |
  | http://www.gnu.org/licenses/.                                         |
  | Copyright (C) 2008-2009. All Rights Reserved.                         |
  +-----------------------------------------------------------------------+
  | Supports: http://www.slightphp.com                                    |
  +-----------------------------------------------------------------------+
  }}}*/
int debug(char*format,...){
	TSRMLS_FETCH();
	zval *_debug_flag = zend_read_static_property(slightphp_ce_ptr,"_debug",sizeof("_debug")-1,1 );
	convert_to_long(_debug_flag);
	if(Z_LVAL_P(_debug_flag))
	{
		va_list args;
		char *buffer;
		int size;
		TSRMLS_FETCH();

		va_start(args, format);
		size = vspprintf(&buffer, 0, format, args);
		_php_error_log(0,buffer,NULL,NULL );
		zend_printf("<!--slightphp debug:%s-->",buffer);
		efree(buffer);
		va_end(args);
	}
	zval_dtor(_debug_flag);
}
Exemple #19
0
ZEND_METHOD(myclass_child, __construct)
{
	zval *prop1, *prop2;
	zend_class_entry *ce;
	ce = Z_OBJCE_P(getThis());
	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &prop1, &prop2) == FAILURE) {
		php_printf("Parameter Error\n");
		RETURN_NULL();
	}

	zend_update_property(ce, getThis(), "prop1", sizeof("prop1") - 1, prop1 TSRMLS_CC); //更新对象属性
	zend_update_static_property(ce, "prop2", sizeof("prop2") - 1, prop2 TSRMLS_CC); //更新类静态属性(与具体对象无关)

	prop1 = NULL;
	prop2 = NULL;

	prop1 = zend_read_property(ce, getThis(), "prop1", sizeof("prop1") - 1, 0 TSRMLS_DC);
	php_var_dump(&prop1, 1 TSRMLS_CC);

	prop2 = zend_read_static_property(ce, "prop2", sizeof("prop2") - 1, 0 TSRMLS_DC);
	php_var_dump(&prop2, 1 TSRMLS_CC);
}
PHP_METHOD(midgard_connection, get_instance)
{
	zval *instance;

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

	instance = zend_read_static_property(php_midgard_connection_class, "instance", sizeof("instance")-1, 1 TSRMLS_CC);

	if (instance == NULL || ZVAL_IS_NULL(instance)) {
		/* instance is not found. we need to create it */
		zval_ptr_dtor(&instance);
		MAKE_STD_ZVAL(instance);

		object_init_ex(instance, php_midgard_connection_class);
		zend_call_method_with_0_params(&instance, php_midgard_connection_class, &php_midgard_connection_class->constructor, "__construct", NULL);

		MGDG(connection_established) = TRUE;
	}

	zval_add_ref(&instance);
	RETURN_ZVAL(instance, 1, 1);
}
Exemple #21
0
ZEND_METHOD( alinq_class , Where )
{
    zend_fcall_info fci;
    zend_fcall_info_cache fci_cache;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    zval * reVal;

 
    char aReturnType;
    int aReturnTypeLen; 

    // aReturnType = 'bool';

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", &fci, &fci_cache) == FAILURE) {
        return;
    }     
    zval *ALINQ_CLOSURE_RETURN_TYPE_BOOL;

    ALINQ_CLOSURE_RETURN_TYPE_BOOL = zend_read_static_property(ce, "ALINQ_CLOSURE_RETURN_TYPE_BOOL", sizeof("ALINQ_CLOSURE_RETURN_TYPE_BOOL")-1, 0 TSRMLS_DC);
    reVal = GetApplicables(getThis(),fci,fci_cache,0,Z_STRVAL_P(ALINQ_CLOSURE_RETURN_TYPE_BOOL),sizeof(Z_STRVAL_P(ALINQ_CLOSURE_RETURN_TYPE_BOOL)));
    RETURN_ZVAL(reVal,1,1);

}
Exemple #22
0
yaf_dispatcher_t *yaf_dispatcher_instance(yaf_dispatcher_t *this_ptr) /* {{{ */ {
	zval plugins;
	yaf_router_t *router, rv = {{0}};
	yaf_dispatcher_t *instance;

	instance = zend_read_static_property(yaf_dispatcher_ce, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_INSTANCE), 1);

	if (IS_OBJECT == Z_TYPE_P(instance)
			&& instanceof_function(Z_OBJCE_P(instance), yaf_dispatcher_ce)) {
		return instance;
	}

	if (Z_ISUNDEF_P(this_ptr)) {
		object_init_ex(this_ptr, yaf_dispatcher_ce);
	} else {
		return this_ptr;
	}

	array_init(&plugins);
	zend_update_property(yaf_dispatcher_ce, this_ptr, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_PLUGINS), &plugins);
	zval_ptr_dtor(&plugins);

	router = yaf_router_instance(&rv);
	zend_update_property(yaf_dispatcher_ce, this_ptr, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_ROUTER), router);
	zval_ptr_dtor(router);

	zend_update_property_str(yaf_dispatcher_ce,
			this_ptr, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_MODULE), YAF_G(default_module));
	zend_update_property_str(yaf_dispatcher_ce,
			this_ptr, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_CONTROLLER), YAF_G(default_controller));
	zend_update_property_str(yaf_dispatcher_ce,
			this_ptr, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_ACTION), YAF_G(default_action));
	zend_update_static_property(yaf_dispatcher_ce, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_INSTANCE), this_ptr);

	return this_ptr;
}
zval * activerecord_model_magic_set( zval * model, char * name, int name_len, zval * value )
{
    zval ** alias, * retval = NULL;

    if( zend_hash_find( Z_ARRVAL_P(zend_read_static_property(activerecord_model_ce, "alias_attribute", 15, 0 TSRMLS_CC)), name, name_len, (void**)&alias ) == SUCCESS )
    {
        efree( name );
        emalloc( name, sizeof( Z_STRVAL_PP(alias) ) );
        strncpy( name, Z_STRVAL_PP(alias), Z_STRLEN_PP(alias) );
        name_len = Z_STRLEN_PP(alias);
    }
    else
    {
        char *method_name;
        emalloc( method_name, sizeof(name)+4 );
        strcpy( method_name, "set_" );
        strcat( method_name, name );
        if( activerecord_model_array_search( zend_read_property( activerecord_model_ce, this_ptr, "setters", 7, 0 TSRMLS_CC ), method_name) )
        {
            zend_call_method( &this_ptr, activerecord_model_ce, NULL, method_name, sizeof(method_name), &retval, 0, NULL, NULL TSRMLS_CC );
            efree( name );
            RETURN_ZVAL( retval, 0, 0 );
        }
    }

    if( zend_hash_find( Z_ARRVAL_P(zend_read_property(activerecord_model_ce, model, "attributes", 10, 0 TSRMLS_CC)), name, name_len ) == SUCCESS )
    {
        retval = activerecord_model_assign_attribute( model, name, name_len, value );
    }

    efree( name );
    if( retval == NULL );
    // throw new exception

    RETURN_ZVAL( retval, 0, 0 );
}
Exemple #24
0
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_setaction_arginfo, 0, 0, 1)
    ZEND_ARG_INFO(0, action)
ZEND_END_ARG_INFO()

/* }}} */

/** {{{ yaf_dispatcher_t * yaf_dispatcher_instance(zval *this_ptr TSRMLS_DC)
*/
yaf_dispatcher_t * yaf_dispatcher_instance(yaf_dispatcher_t *this_ptr TSRMLS_DC) {
	zval			*plugins;
	yaf_router_t	 	*router;
	yaf_dispatcher_t 	*instance;

	instance = zend_read_static_property(yaf_dispatcher_ce, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_INSTANCE), 1 TSRMLS_CC);

	if (IS_OBJECT == Z_TYPE_P(instance)
			&& instanceof_function(Z_OBJCE_P(instance), yaf_dispatcher_ce TSRMLS_CC)) {
		return instance;
	}

	if (this_ptr) {
		instance = this_ptr;
		return this_ptr;
	} else {
		instance = NULL;
		MAKE_STD_ZVAL(instance);
		object_init_ex(instance, yaf_dispatcher_ce);
	}
Exemple #25
0
static
void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval* return_value, HashTable* fieldspec) {
  ZVAL_NULL(return_value);

  switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
      RETURN_NULL();
      return;
    case T_STRUCT: {
      zval* val_ptr = zend_hash_str_find(fieldspec, "class", sizeof("class")-1);
      if (val_ptr == nullptr) {
        throw_tprotocolexception("no class type in spec", INVALID_DATA);
        skip_element(T_STRUCT, transport);
        RETURN_NULL();
      }

      char* structType = Z_STRVAL_P(val_ptr);
      // Create an object in PHP userland based on our spec
      createObject(structType, return_value);
      if (Z_TYPE_P(return_value) == IS_NULL) {
        // unable to create class entry
        skip_element(T_STRUCT, transport);
        RETURN_NULL();
      }

      zval* spec = zend_read_static_property(Z_OBJCE_P(return_value), "_TSPEC", sizeof("_TSPEC")-1, false);
      if (Z_TYPE_P(spec) != IS_ARRAY) {
        char errbuf[128];
        snprintf(errbuf, 128, "spec for %s is wrong type: %d\n", structType, Z_TYPE_P(spec));
        throw_tprotocolexception(errbuf, INVALID_DATA);
        RETURN_NULL();
      }
      binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec));
      return;
    } break;
    case T_BOOL: {
      uint8_t c;
      transport.readBytes(&c, 1);
      RETURN_BOOL(c != 0);
    }
  //case T_I08: // same numeric value as T_BYTE
    case T_BYTE: {
      uint8_t c;
      transport.readBytes(&c, 1);
      RETURN_LONG((int8_t)c);
    }
    case T_I16: {
      uint16_t c;
      transport.readBytes(&c, 2);
      RETURN_LONG((int16_t)ntohs(c));
    }
    case T_I32: {
      uint32_t c;
      transport.readBytes(&c, 4);
      RETURN_LONG((int32_t)ntohl(c));
    }
    case T_U64:
    case T_I64: {
      uint64_t c;
      transport.readBytes(&c, 8);
      RETURN_LONG((int64_t)ntohll(c));
    }
    case T_DOUBLE: {
      union {
        uint64_t c;
        double d;
      } a;
      transport.readBytes(&(a.c), 8);
      a.c = ntohll(a.c);
      RETURN_DOUBLE(a.d);
    }
    //case T_UTF7: // aliases T_STRING
    case T_UTF8:
    case T_UTF16:
    case T_STRING: {
      uint32_t size = transport.readU32();
      if (size) {
        char strbuf[size+1];
        transport.readBytes(strbuf, size);
        strbuf[size] = '\0';
        ZVAL_STRINGL(return_value, strbuf, size);
      } else {
        ZVAL_EMPTY_STRING(return_value);
      }
      return;
    }
    case T_MAP: { // array of key -> value
      uint8_t types[2];
      transport.readBytes(types, 2);
      uint32_t size = transport.readU32();
      array_init(return_value);

      zval *val_ptr;
      val_ptr = zend_hash_str_find(fieldspec, "key", sizeof("key")-1);
      HashTable* keyspec = Z_ARRVAL_P(val_ptr);
      val_ptr = zend_hash_str_find(fieldspec, "val", sizeof("val")-1);
      HashTable* valspec = Z_ARRVAL_P(val_ptr);

      for (uint32_t s = 0; s < size; ++s) {
        zval key, value;

        binary_deserialize(types[0], transport, &key, keyspec);
        binary_deserialize(types[1], transport, &value, valspec);
        if (Z_TYPE(key) == IS_LONG) {
          zend_hash_index_update(Z_ARR_P(return_value), Z_LVAL(key), &value);
        } else {
          if (Z_TYPE(key) != IS_STRING) convert_to_string(&key);
          zend_symtable_update(Z_ARR_P(return_value), Z_STR(key), &value);
        }
        zval_dtor(&key);
      }
      return; // return_value already populated
    }
    case T_LIST: { // array with autogenerated numeric keys
      int8_t type = transport.readI8();
      uint32_t size = transport.readU32();
      zval *val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1);
      HashTable* elemspec = Z_ARRVAL_P(val_ptr);

      array_init(return_value);
      for (uint32_t s = 0; s < size; ++s) {
        zval value;
        binary_deserialize(type, transport, &value, elemspec);
        zend_hash_next_index_insert(Z_ARR_P(return_value), &value);
      }
      return;
    }
    case T_SET: { // array of key -> TRUE
      uint8_t type;
      uint32_t size;
      transport.readBytes(&type, 1);
      transport.readBytes(&size, 4);
      size = ntohl(size);
      zval *val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1);
      HashTable* elemspec = Z_ARRVAL_P(val_ptr);

      array_init(return_value);

      for (uint32_t s = 0; s < size; ++s) {
        zval key, value;
        ZVAL_TRUE(&value);

        binary_deserialize(type, transport, &key, elemspec);

        if (Z_TYPE(key) == IS_LONG) {
          zend_hash_index_update(Z_ARR_P(return_value), Z_LVAL(key), &value);
        } else {
          if (Z_TYPE(key) != IS_STRING) convert_to_string(&key);
          zend_symtable_update(Z_ARR_P(return_value), Z_STR(key), &value);
        }
        zval_dtor(&key);
      }
      return;
    }
  };

  char errbuf[128];
  sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
  throw_tprotocolexception(errbuf, INVALID_DATA);
}
Exemple #26
0
PHP_METHOD(Edge_Controller, model)
{
    char *model_name = NULL;
    char *model_dir = NULL;
    int mnlen=0;
    int mdlen=0;
    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &model_name, &mnlen, &model_dir, &mdlen) == FAILURE)
    {
        RETURN_FALSE;
    }
    
    char *model_class_name;
    int class_name_len;
    class_name_len = spprintf(&model_class_name, 0, "%s%s", model_name, "Model");

    zval **z_obj;
    if(zend_hash_find(Z_ARRVAL_P(EDGE_G(regs)), model_class_name, class_name_len+1, (void **)&z_obj) == SUCCESS)
    {
        efree(model_class_name);
        RETURN_ZVAL(*z_obj, 1, 0);
    }
    
    zval *config;
    zval *config_data;
    config = zend_read_static_property(edge_core_ce, ZEND_STRL("config"), 1 TSRMLS_DC);
    config_data = zend_read_property(edge_config_ce, config, ZEND_STRL("_data"), 1 TSRMLS_DC);

    zval **models_home_pp;
    if(zend_hash_find(Z_ARRVAL_P(config_data), "_models_home", strlen("_models_home")+1, (void **)&models_home_pp) == FAILURE)
    {
        RETURN_FALSE;
    }
    
    zval *z_model_name;
    MAKE_STD_ZVAL(z_model_name);
    ZVAL_STRING(z_model_name, model_class_name, 1);

    zval *loader;
    zval *ret;
    loader = zend_read_static_property(edge_core_ce, ZEND_STRL("loader"), 1 TSRMLS_DC);
    zend_call_method_with_2_params(&loader, Z_OBJCE_P(loader), NULL, "autoload", &ret, z_model_name, *models_home_pp);
    zval_ptr_dtor(&z_model_name);
    if(!Z_BVAL_P(ret))
    {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "model %s%s load fail", Z_STRVAL_PP(models_home_pp), model_class_name);
        zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "model %s%s load fail", Z_STRVAL_PP(models_home_pp), model_class_name);
        zval_ptr_dtor(&ret);
        efree(model_class_name);
        RETURN_FALSE;
    }
    zval_ptr_dtor(&ret);

    zend_class_entry **model_ce;
    if(zend_lookup_class(model_class_name, class_name_len, &model_ce TSRMLS_CC) == FAILURE)
    {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "model class %s not exist", model_class_name);
        zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "model class %s%s  not exist", model_class_name);
        efree(model_class_name);
        RETURN_FALSE;
    }

    zval *model_obj;
    MAKE_STD_ZVAL(model_obj);
    object_init_ex(model_obj, *model_ce);

    zval **cfptr;
    if(zend_hash_find(&((*model_ce)->function_table), "__construct", strlen("__construct")+1, (void **)&cfptr) == SUCCESS)
    {
        zval *cretval;
        zend_call_method(&model_obj, *model_ce, NULL, "__construct", strlen("__construct"), &cretval, 0, NULL, NULL TSRMLS_CC);
        zval_ptr_dtor(&cretval);
    }

    zend_hash_update(Z_ARRVAL_P(EDGE_G(regs)), model_class_name, class_name_len+1, (void **)&model_obj, sizeof(zval *), NULL);

    efree(model_class_name);
    RETURN_ZVAL(model_obj, 1, 0);
}
Exemple #27
0
static
void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport, zval* value, HashTable* fieldspec) {
  // At this point the typeID (and field num, if applicable) should've already been written to the output so all we need to do is write the payload.
  switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
      return;
    case T_STRUCT: {
      if (Z_TYPE_P(value) != IS_OBJECT) {
        throw_tprotocolexception("Attempt to send non-object type as a T_STRUCT", INVALID_DATA);
      }
      zval* spec = zend_read_static_property(Z_OBJCE_P(value), "_TSPEC", sizeof("_TSPEC")-1, false);
      if (Z_TYPE_P(spec) != IS_ARRAY) {
        throw_tprotocolexception("Attempt to send non-Thrift object as a T_STRUCT", INVALID_DATA);
      }
      binary_serialize_spec(value, transport, Z_ARRVAL_P(spec));
    } return;
    case T_BOOL:
      if (!zval_is_bool(value)) convert_to_boolean(value);
      transport.writeI8(Z_TYPE_INFO_P(value) == IS_TRUE ? 1 : 0);
      return;
    case T_BYTE:
      if (Z_TYPE_P(value) != IS_LONG) convert_to_long(value);
      transport.writeI8(Z_LVAL_P(value));
      return;
    case T_I16:
      if (Z_TYPE_P(value) != IS_LONG) convert_to_long(value);
      transport.writeI16(Z_LVAL_P(value));
      return;
    case T_I32:
      if (Z_TYPE_P(value) != IS_LONG) convert_to_long(value);
      transport.writeI32(Z_LVAL_P(value));
      return;
    case T_I64:
    case T_U64: {
      int64_t l_data;
#if defined(_LP64) || defined(_WIN64)
      if (Z_TYPE_P(value) != IS_LONG) convert_to_long(value);
      l_data = Z_LVAL_P(value);
#else
      if (Z_TYPE_P(value) != IS_DOUBLE) convert_to_double(value);
      l_data = (int64_t)Z_DVAL_P(value);
#endif
      transport.writeI64(l_data);
    } return;
    case T_DOUBLE: {
      union {
        int64_t c;
        double d;
      } a;
      if (Z_TYPE_P(value) != IS_DOUBLE) convert_to_double(value);
      a.d = Z_DVAL_P(value);
      transport.writeI64(a.c);
    } return;
    case T_UTF8:
    case T_UTF16:
    case T_STRING:
      if (Z_TYPE_P(value) != IS_STRING) convert_to_string(value);
      transport.writeString(Z_STRVAL_P(value), Z_STRLEN_P(value));
      return;
    case T_MAP: {
      if (Z_TYPE_P(value) != IS_ARRAY) convert_to_array(value);
      if (Z_TYPE_P(value) != IS_ARRAY) {
        throw_tprotocolexception("Attempt to send an incompatible type as an array (T_MAP)", INVALID_DATA);
      }
      HashTable* ht = Z_ARRVAL_P(value);
      zval* val_ptr;

      val_ptr = zend_hash_str_find(fieldspec, "ktype", sizeof("ktype")-1);
      if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr);
      uint8_t keytype = Z_LVAL_P(val_ptr);
      transport.writeI8(keytype);
      val_ptr = zend_hash_str_find(fieldspec, "vtype", sizeof("vtype")-1);
      if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr);
      uint8_t valtype = Z_LVAL_P(val_ptr);
      transport.writeI8(valtype);

      val_ptr = zend_hash_str_find(fieldspec, "val", sizeof("val")-1);
      HashTable* valspec = Z_ARRVAL_P(val_ptr);

      transport.writeI32(zend_hash_num_elements(ht));
      HashPosition key_ptr;
      for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr);
           (val_ptr = zend_hash_get_current_data_ex(ht, &key_ptr)) != nullptr;
           zend_hash_move_forward_ex(ht, &key_ptr)) {
        binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
        binary_serialize(valtype, transport, val_ptr, valspec);
      }
    } return;
    case T_LIST: {
      if (Z_TYPE_P(value) != IS_ARRAY) convert_to_array(value);
      if (Z_TYPE_P(value) != IS_ARRAY) {
        throw_tprotocolexception("Attempt to send an incompatible type as an array (T_LIST)", INVALID_DATA);
      }
      HashTable* ht = Z_ARRVAL_P(value);
      zval* val_ptr;

      val_ptr = zend_hash_str_find(fieldspec, "etype", sizeof("etype")-1);
      if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr);
      uint8_t valtype = Z_LVAL_P(val_ptr);
      transport.writeI8(valtype);

      val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1);
      HashTable* valspec = Z_ARRVAL_P(val_ptr);

      transport.writeI32(zend_hash_num_elements(ht));
      HashPosition key_ptr;
      for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr);
           (val_ptr = zend_hash_get_current_data_ex(ht, &key_ptr)) != nullptr;
           zend_hash_move_forward_ex(ht, &key_ptr)) {
        binary_serialize(valtype, transport, val_ptr, valspec);
      }
    } return;
    case T_SET: {
      if (Z_TYPE_P(value) != IS_ARRAY) convert_to_array(value);
      if (Z_TYPE_P(value) != IS_ARRAY) {
        throw_tprotocolexception("Attempt to send an incompatible type as an array (T_SET)", INVALID_DATA);
      }
      HashTable* ht = Z_ARRVAL_P(value);
      zval* val_ptr;

      val_ptr = zend_hash_str_find(fieldspec, "etype", sizeof("etype")-1);
      if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr);
      uint8_t keytype = Z_LVAL_P(val_ptr);
      transport.writeI8(keytype);

      transport.writeI32(zend_hash_num_elements(ht));
      HashPosition key_ptr;
      for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr);
           (val_ptr = zend_hash_get_current_data_ex(ht, &key_ptr)) != nullptr;
           zend_hash_move_forward_ex(ht, &key_ptr)) {
        binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
      }
    } return;
  };

  char errbuf[128];
  snprintf(errbuf, 128, "Unknown thrift typeID %d", thrift_typeID);
  throw_tprotocolexception(errbuf, INVALID_DATA);
}
/* {{{ MongoCursor->__construct
 */
PHP_METHOD(MongoCursor, __construct) {
  zval *zlink = 0, *zns = 0, *zquery = 0, *zfields = 0, *empty, *timeout;
  zval **data;
  mongo_cursor *cursor;
  mongo_link *link;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oz|zz", &zlink,
                            mongo_ce_Mongo, &zns, &zquery, &zfields) == FAILURE) {
    return;
  }
  if ((zquery && IS_SCALAR_P(zquery)) || (zfields && IS_SCALAR_P(zfields))) {
    zend_error(E_WARNING, "MongoCursor::__construct() expects parameters 3 and 4 to be arrays or objects");
    return;
  }

  // if query or fields weren't passed, make them default to an empty array
  MAKE_STD_ZVAL(empty);
  object_init(empty);

  // these are both initialized to the same zval, but that's okay because 
  // there's no way to change them without creating a new cursor
  if (!zquery || (Z_TYPE_P(zquery) == IS_ARRAY && zend_hash_num_elements(HASH_P(zquery)) == 0)) {
    zquery = empty;
  }
  if (!zfields) {
    zfields = empty;
  }

  cursor = (mongo_cursor*)zend_object_store_get_object(getThis() TSRMLS_CC);
 
  // db connection
  cursor->resource = zlink;
  zval_add_ref(&zlink);

  // db connection resource
  PHP_MONGO_GET_LINK(zlink);
  cursor->link = link;

  // change ['x', 'y', 'z'] into {'x' : 1, 'y' : 1, 'z' : 1}
  if (Z_TYPE_P(zfields) == IS_ARRAY) {
    HashPosition pointer;
    zval *fields;

    MAKE_STD_ZVAL(fields);
    array_init(fields);

    // fields to return
    for(zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(zfields), &pointer); 
        zend_hash_get_current_data_ex(Z_ARRVAL_P(zfields), (void**) &data, &pointer) == SUCCESS; 
        zend_hash_move_forward_ex(Z_ARRVAL_P(zfields), &pointer)) {
      int key_type, key_len;
      ulong index;
      char *key;
      
      key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(zfields), &key, (uint*)&key_len, &index, NO_DUP, &pointer);

      if (key_type == HASH_KEY_IS_LONG) {
        if (Z_TYPE_PP(data) == IS_STRING) {
          add_assoc_long(fields, Z_STRVAL_PP(data), 1);
        }
        else {
          zval_ptr_dtor(&empty);
          zval_ptr_dtor(&fields);
          zend_throw_exception(mongo_ce_Exception, "field names must be strings", 0 TSRMLS_CC);
          return;
        }
      }
      else {
        add_assoc_zval(fields, key, *data);
        zval_add_ref(data);
      }
    }
    cursor->fields = fields;
  }
  // if it's already an object, we don't have to worry
  else {
    cursor->fields = zfields;
    zval_add_ref(&zfields);
  }

  // ns
  convert_to_string(zns);
  cursor->ns = estrdup(Z_STRVAL_P(zns));

  // query
  cursor->query = zquery;
  zval_add_ref(&zquery);

  // reset iteration pointer, just in case
  MONGO_METHOD(MongoCursor, reset, return_value, getThis());

  cursor->at = 0;
  cursor->num = 0;
  cursor->special = 0;
  cursor->persist = 0;
  
  timeout = zend_read_static_property(mongo_ce_Cursor, "timeout", strlen("timeout"), NOISY TSRMLS_CC);
  cursor->timeout = Z_LVAL_P(timeout);

  cursor->opts = link->slave_okay ? (1 << 2) : 0;
  
  // get rid of extra ref
  zval_ptr_dtor(&empty);
}
void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport, zval** value, HashTable* fieldspec) {
    // At this point the typeID (and field num, if applicable) should've already been written to the output so all we need to do is write the payload.
    switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
        return;
    case T_STRUCT: {
        TSRMLS_FETCH();
        if (Z_TYPE_PP(value) != IS_OBJECT) {
            throw_tprotocolexception("Attempt to send non-object type as a T_STRUCT", INVALID_DATA);
        }
        zval* spec = zend_read_static_property(zend_get_class_entry(*value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC);
        binary_serialize_spec(*value, transport, Z_ARRVAL_P(spec));
    }
    return;
    case T_BOOL:
        if (Z_TYPE_PP(value) != IS_BOOL) convert_to_boolean(*value);
        transport.writeI8(Z_BVAL_PP(value) ? 1 : 0);
        return;
    case T_BYTE:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI8(Z_LVAL_PP(value));
        return;
    case T_I16:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI16(Z_LVAL_PP(value));
        return;
    case T_I32:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI32(Z_LVAL_PP(value));
        return;
    case T_I64:
    case T_U64:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI64(Z_LVAL_PP(value));
        return;
    case T_DOUBLE: {
        union {
            int64_t c;
            double d;
        } a;
        if (Z_TYPE_PP(value) != IS_DOUBLE) convert_to_double(*value);
        a.d = Z_DVAL_PP(value);
        transport.writeI64(a.c);
    }
    return;
    //case T_UTF7:
    case T_UTF8:
    case T_UTF16:
    case T_STRING:
        if (Z_TYPE_PP(value) != IS_STRING) convert_to_string(*value);
        transport.writeString(Z_STRVAL_PP(value), Z_STRLEN_PP(value));
        return;
    case T_MAP: {
        if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
        if (Z_TYPE_PP(value) != IS_ARRAY) {
            throw_tprotocolexception("Attempt to send an incompatible type as an array (T_MAP)", INVALID_DATA);
        }
        HashTable* ht = Z_ARRVAL_PP(value);
        zval** val_ptr;

        zend_hash_find(fieldspec, "ktype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t keytype = Z_LVAL_PP(val_ptr);
        transport.writeI8(keytype);
        zend_hash_find(fieldspec, "vtype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t valtype = Z_LVAL_PP(val_ptr);
        transport.writeI8(valtype);

        zend_hash_find(fieldspec, "val", 4, (void**)&val_ptr);
        HashTable* valspec = Z_ARRVAL_PP(val_ptr);

        transport.writeI32(zend_hash_num_elements(ht));
        HashPosition key_ptr;
        for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
            binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
            binary_serialize(valtype, transport, val_ptr, valspec);
        }
    }
    return;
    case T_LIST: {
        if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
        if (Z_TYPE_PP(value) != IS_ARRAY) {
            throw_tprotocolexception("Attempt to send an incompatible type as an array (T_LIST)", INVALID_DATA);
        }
        HashTable* ht = Z_ARRVAL_PP(value);
        zval** val_ptr;

        zend_hash_find(fieldspec, "etype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t valtype = Z_LVAL_PP(val_ptr);
        transport.writeI8(valtype);

        zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr);
        HashTable* valspec = Z_ARRVAL_PP(val_ptr);

        transport.writeI32(zend_hash_num_elements(ht));
        HashPosition key_ptr;
        for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
            binary_serialize(valtype, transport, val_ptr, valspec);
        }
    }
    return;
    case T_SET: {
        if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
        if (Z_TYPE_PP(value) != IS_ARRAY) {
            throw_tprotocolexception("Attempt to send an incompatible type as an array (T_SET)", INVALID_DATA);
        }
        HashTable* ht = Z_ARRVAL_PP(value);
        zval** val_ptr;

        zend_hash_find(fieldspec, "etype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t keytype = Z_LVAL_PP(val_ptr);
        transport.writeI8(keytype);

        transport.writeI32(zend_hash_num_elements(ht));
        HashPosition key_ptr;
        for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
            binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
        }
    }
    return;
    };
    char errbuf[128];
    sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
    throw_tprotocolexception(errbuf, INVALID_DATA);
}
void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval* return_value, HashTable* fieldspec) {
    zval** val_ptr;
    Z_TYPE_P(return_value) = IS_NULL; // just in case

    switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
        RETURN_NULL();
        return;
    case T_STRUCT: {
        if (zend_hash_find(fieldspec, "class", 6, (void**)&val_ptr) != SUCCESS) {
            throw_tprotocolexception("no class type in spec", INVALID_DATA);
            skip_element(T_STRUCT, transport);
            RETURN_NULL();
        }
        char* structType = Z_STRVAL_PP(val_ptr);
        createObject(structType, return_value);
        if (Z_TYPE_P(return_value) == IS_NULL) {
            // unable to create class entry
            skip_element(T_STRUCT, transport);
            RETURN_NULL();
        }
        TSRMLS_FETCH();
        zval* spec = zend_read_static_property(zend_get_class_entry(return_value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC);
        if (Z_TYPE_P(spec) != IS_ARRAY) {
            char errbuf[128];
            snprintf(errbuf, 128, "spec for %s is wrong type: %d\n", structType, Z_TYPE_P(spec));
            throw_tprotocolexception(errbuf, INVALID_DATA);
            RETURN_NULL();
        }
        binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec));
        return;
    }
    break;
    case T_BOOL: {
        uint8_t c;
        transport.readBytes(&c, 1);
        RETURN_BOOL(c != 0);
    }
    //case T_I08: // same numeric value as T_BYTE
    case T_BYTE: {
        uint8_t c;
        transport.readBytes(&c, 1);
        RETURN_LONG(c);
    }
    case T_I16: {
        uint16_t c;
        transport.readBytes(&c, 2);
        RETURN_LONG(ntohs(c));
    }
    case T_I32: {
        uint32_t c;
        transport.readBytes(&c, 4);
        RETURN_LONG(ntohl(c));
    }
    case T_U64:
    case T_I64: {
        uint64_t c;
        transport.readBytes(&c, 8);
        RETURN_LONG(ntohll(c));
    }
    case T_DOUBLE: {
        union {
            uint64_t c;
            double d;
        } a;
        transport.readBytes(&(a.c), 8);
        a.c = ntohll(a.c);
        RETURN_DOUBLE(a.d);
    }
    //case T_UTF7: // aliases T_STRING
    case T_UTF8:
    case T_UTF16:
    case T_STRING: {
        uint32_t size = transport.readU32();
        if (size) {
            char* strbuf = (char*) emalloc(size + 1);
            transport.readBytes(strbuf, size);
            strbuf[size] = '\0';
            ZVAL_STRINGL(return_value, strbuf, size, 0);
        } else {
            ZVAL_EMPTY_STRING(return_value);
        }
        return;
    }
    case T_MAP: { // array of key -> value
        uint8_t types[2];
        transport.readBytes(types, 2);
        uint32_t size = transport.readU32();
        array_init(return_value);

        zend_hash_find(fieldspec, "key", 4, (void**)&val_ptr);
        HashTable* keyspec = Z_ARRVAL_PP(val_ptr);
        zend_hash_find(fieldspec, "val", 4, (void**)&val_ptr);
        HashTable* valspec = Z_ARRVAL_PP(val_ptr);

        for (uint32_t s = 0; s < size; ++s) {
            zval *value;
            MAKE_STD_ZVAL(value);

            zval* key;
            MAKE_STD_ZVAL(key);

            binary_deserialize(types[0], transport, key, keyspec);
            binary_deserialize(types[1], transport, value, valspec);
            if (Z_TYPE_P(key) == IS_LONG) {
                zend_hash_index_update(return_value->value.ht, Z_LVAL_P(key), &value, sizeof(zval *), NULL);
            }
            else {
                if (Z_TYPE_P(key) != IS_STRING) convert_to_string(key);
                zend_hash_update(return_value->value.ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL);
            }
            zval_ptr_dtor(&key);
        }
        return; // return_value already populated
    }
    case T_LIST: { // array with autogenerated numeric keys
        int8_t type = transport.readI8();
        uint32_t size = transport.readU32();
        zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr);
        HashTable* elemspec = Z_ARRVAL_PP(val_ptr);

        array_init(return_value);
        for (uint32_t s = 0; s < size; ++s) {
            zval *value;
            MAKE_STD_ZVAL(value);
            binary_deserialize(type, transport, value, elemspec);
            zend_hash_next_index_insert(return_value->value.ht, &value, sizeof(zval *), NULL);
        }
        return;
    }
    case T_SET: { // array of key -> TRUE
        uint8_t type;
        uint32_t size;
        transport.readBytes(&type, 1);
        transport.readBytes(&size, 4);
        size = ntohl(size);
        zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr);
        HashTable* elemspec = Z_ARRVAL_PP(val_ptr);

        array_init(return_value);

        for (uint32_t s = 0; s < size; ++s) {
            zval* key;
            zval* value;
            MAKE_STD_ZVAL(key);
            MAKE_STD_ZVAL(value);
            ZVAL_TRUE(value);

            binary_deserialize(type, transport, key, elemspec);

            if (Z_TYPE_P(key) == IS_LONG) {
                zend_hash_index_update(return_value->value.ht, Z_LVAL_P(key), &value, sizeof(zval *), NULL);
            }
            else {
                if (Z_TYPE_P(key) != IS_STRING) convert_to_string(key);
                zend_hash_update(return_value->value.ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL);
            }
            zval_ptr_dtor(&key);
        }
        return;
    }
    };

    char errbuf[128];
    sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
    throw_tprotocolexception(errbuf, INVALID_DATA);
}