summaryrefslogtreecommitdiff
path: root/ext/satellite/struct.c
diff options
context:
space:
mode:
authorDavid Eriksson <eriksson@php.net>2000-09-01 22:10:15 +0000
committerDavid Eriksson <eriksson@php.net>2000-09-01 22:10:15 +0000
commit2ad0310fd36de9eeabc65138eae28d39d0dbf55b (patch)
treec1fc8f0ce35fc6f58fc2f99e6868a0e10881b2f0 /ext/satellite/struct.c
parentcd8af6aa446ae69e28415bd68e4928cafe07f8a0 (diff)
downloadphp-git-2ad0310fd36de9eeabc65138eae28d39d0dbf55b.tar.gz
- Initial submission of CORBA extension for PHP: Satellite
Diffstat (limited to 'ext/satellite/struct.c')
-rw-r--r--ext/satellite/struct.c330
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;
+ }
+}
+