diff options
Diffstat (limited to 'ext/satellite/struct.c')
-rw-r--r-- | ext/satellite/struct.c | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/ext/satellite/struct.c b/ext/satellite/struct.c new file mode 100644 index 0000000000..9c7e79279d --- /dev/null +++ b/ext/satellite/struct.c @@ -0,0 +1,330 @@ +/* + +----------------------------------------------------------------------+ + | PHP version 4.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.02 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.php.net/license/2_02.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: David Eriksson <eriksson@php.net> | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * OrbitStruct class + * + * There are three ways to create a structure + * + * (1) OrbitStruct_Constructor, for new OrbitStruct(...) in PHP + * (2) OrbitStruct_Create, used when a CORBA method returns a struct + * (3) OrbitStruct_Wakeup, used on "unserialization" + * ----------------------------------------------------------------------- + */ +#include "struct.h" +#include "common.h" +#include "typemanager.h" +#include "hashtable.h" + +/* + * enable/disable incomplete serialization support + */ +#define SERIALIZABLE_STRUCT 0 + +struct _OrbitStruct +{ + HashTable mMembers; + zend_bool mIsException; /* otherwise normal struct */ + union + { + StructType * mpStructType; + ExceptionType * mpExceptionType; + } u; +}; + +#if SERIALIZABLE_STRUCT + +static void OrbitStruct_Wakeup(INTERNAL_FUNCTION_PARAMETERS); +static void OrbitStruct_Sleep(INTERNAL_FUNCTION_PARAMETERS); + +static zend_function_entry OrbitStruct_functions[] = +{ + {"__sleep", OrbitStruct_Sleep}, + {"__wakeup", OrbitStruct_Wakeup}, + {NULL, NULL} +}; + +#define MY_IMPLEMENT_CLASS(name, flags)\ +IMPLEMENT_DECLARATIONS(name, flags) \ +IMPLEMENT_FUNCTION_CALL(name, flags) \ +IMPLEMENT_PUT_PROPERTY(name, flags) \ +IMPLEMENT_GET_PROPERTY(name, flags) \ +IMPLEMENT_INIT_EX(name, flags, ##name##_functions, _##name##_FunctionCall, _##name##_GetProperty, _##name##_PutProperty)\ +IMPLEMENT_DATA_HELPERS(name, flags) + +MY_IMPLEMENT_CLASS(OrbitStruct, NO_FUNCTIONS); + +#else /* !SERIALIZABLE_STRUCT */ + +IMPLEMENT_CLASS(OrbitStruct, NO_FUNCTIONS); + +#endif /* SERIALIZABLE_STRUCT */ + +#if SERIALIZABLE_STRUCT + +/* + * prepare for serialization + */ +static void OrbitStruct_Sleep(INTERNAL_FUNCTION_PARAMETERS) +{ + /* get struct data */ + OrbitStruct * p_struct = OrbitStruct_RetrieveData(this_ptr); + + /* validate data */ + if (p_struct == NULL) + { + goto error; + } + +#if 0 + /* add property to zval */ + add_property_string(this_ptr, IOR_PROPERTY_KEY, p_ior, TRUE); + + /* create array */ + array_init(return_value); + + /* add name of property IOR to array */ + add_next_index_string(return_value, IOR_PROPERTY_KEY, TRUE); +#endif + + return; + +error: + RETURN_NULL(); +} + +static void OrbitStruct_Wakeup(INTERNAL_FUNCTION_PARAMETERS) +{ +} + +#endif /* SERIALIZABLE_STRUCT */ + +char * OrbitStruct_GetRepositoryId(OrbitStruct * pStruct) +{ + if (pStruct->mIsException) + return ExceptionType_GetRepositoryId(pStruct->u.mpExceptionType); + else + return StructType_GetRepositoryId(pStruct->u.mpStructType); +} + +static zend_bool OrbitStruct_InitializeMembers(OrbitStruct * pStruct) +{ + MemberType * p_member = NULL; + + if (pStruct->mIsException) + p_member = ExceptionType_GetFirstMember(pStruct->u.mpExceptionType); + else + p_member = StructType_GetFirstMember(pStruct->u.mpStructType); + + zend_hash_init( + &pStruct->mMembers, /* hash table */ + 0, /* size */ + NULL, /* hash function */ + ZVAL_DESTRUCTOR, /* destructor */ + 0); /* persistent */ + + if (!MemberType_IsValid(p_member)) + return TRUE; /* no members */ + + do + { + zval * p_value = NULL; + char * p_name = MemberType_GetName(p_member); + + ALLOC_ZVAL(p_value); + ZVAL_NULL(p_value); + + zend_hash_add( + &pStruct->mMembers, + p_name, + strlen(p_name)+1, /* important: include terminating zero byte */ + p_value, + sizeof(zval), + NULL + ); + } while (MemberType_GetNext(p_member)); + + return TRUE; +} + +static zend_bool OrbitStruct_Initialize(const char * pId, OrbitStruct * pStruct) +{ + /* find type info */ + pStruct->u.mpStructType = TypeManager_FindStruct(pId); + + if (pStruct->u.mpStructType == NULL) + { + /* not a struct -- maybe an exception? */ + pStruct->u.mpExceptionType = TypeManager_FindException(pId); + if (pStruct->u.mpExceptionType == NULL) + { + zend_error(E_ERROR, "(Satellite) unknown struct or exception '%s'", pId); + + goto error; + } + + pStruct->mIsException = TRUE; + } + + /* initialize members */ + if (!OrbitStruct_InitializeMembers(pStruct)) + goto error; + + return TRUE; + +error: + return FALSE; +} + +/* + * used by orbit_namedvalue_to_zval_struct(...) + */ +zend_bool OrbitStruct_Create(const char * pId, zval * pDestination) +{ + /* allocate buffer */ + OrbitStruct * p_struct = orbit_new(OrbitStruct); + + /* initialize struct */ + if (!OrbitStruct_Initialize(pId, p_struct)) + goto error; + + /* set zval members */ + pDestination->type = IS_OBJECT; + pDestination->is_ref = 1; + pDestination->refcount = 1; + + pDestination->value.obj.ce = &OrbitStruct_class_entry; + pDestination->value.obj.properties = orbit_new(HashTable); + + zend_hash_init( + pDestination->value.obj.properties, /* hash table */ + 0, /* size */ + NULL, /* hash function */ + ZVAL_PTR_DTOR, /* destructor */ + 0); /* persistent */ + + /* save orbit data */ + OrbitStruct_SaveData(pDestination, p_struct); + + return TRUE; + +error: + orbit_delete(p_struct); + return FALSE; +} + +/* + * Constructor + * + * Parameters: Repository ID of struct + */ +zend_bool OrbitStruct_Constructor(OrbitStruct ** ppStruct, + int parameterCount, const zval ** ppParameters) +{ + /* allocate buffer */ + OrbitStruct * p_struct = orbit_new(OrbitStruct); + + /* check parameter count */ + if (parameterCount != 1) + { + wrong_param_count(); + goto error; + } + + /* validate parameter types */ + if (ppParameters[0]->type != IS_STRING) + goto error; + + /* initialize struct */ + if (!OrbitStruct_Initialize(ppParameters[0]->value.str.val, p_struct)) + goto error; + + *ppStruct = p_struct; + return TRUE; + +error: + OrbitStruct_Destructor(p_struct); + *ppStruct = NULL; + return FALSE; +} + +zend_bool OrbitStruct_Destructor(OrbitStruct * pStruct) +{ + if (pStruct->mIsException) + ExceptionType_release(pStruct->u.mpExceptionType); + else + StructType_release(pStruct->u.mpStructType); + + /* will crash on uninitialized members structure :-( */ + zend_hash_destroy(&pStruct->mMembers); + orbit_delete(pStruct); + + return TRUE; +} + +/* not used */ +zend_bool OrbitStruct_CallFunction(OrbitStruct * pStruct, + const char * pFunctionName, int parameterCount, const zval ** ppParameters, zval * pResult) +{ + return FALSE; +} + +zend_bool OrbitStruct_PutProperty(OrbitStruct * pStruct, + const char * pPropertyName, const zval * pValue) +{ + zend_bool result; + + result = orbit_store_by_key(&pStruct->mMembers, pPropertyName, pValue); + + if (!result) + { + zend_error(E_ERROR, "(Satellite) unknown member '%s' in struct '%s'", + pPropertyName, OrbitStruct_GetRepositoryId(pStruct)); + } + + return result; +} + +zend_bool OrbitStruct_GetProperty(OrbitStruct * pStruct, + const char * pPropertyName, zval * pReturnValue) +{ + zval * p_value = orbit_find_by_key(&pStruct->mMembers, pPropertyName); + + if (p_value == NULL) + { + zend_error(E_ERROR, "(Satellite) unknown member '%s' in struct '%s'", + pPropertyName, OrbitStruct_GetRepositoryId(pStruct)); + + ZVAL_NULL(pReturnValue); + return FALSE; + } + else + { + memcpy(pReturnValue, p_value, sizeof(zval)); /* raw data copy */ + zval_copy_ctor(pReturnValue); /* smart data copy */ + INIT_PZVAL(pReturnValue); /* set reference count */ + return TRUE; + } +} + |