From 2ad0310fd36de9eeabc65138eae28d39d0dbf55b Mon Sep 17 00:00:00 2001 From: David Eriksson Date: Fri, 1 Sep 2000 22:10:15 +0000 Subject: [PATCH] - Initial submission of CORBA extension for PHP: Satellite --- ext/satellite/Makefile.in | 54 ++ ext/satellite/README | 59 ++ ext/satellite/class.c | 180 ++++++ ext/satellite/class.h | 219 ++++++++ ext/satellite/common.c | 31 ++ ext/satellite/common.h | 70 +++ ext/satellite/config.m4 | 40 ++ ext/satellite/corba.c | 128 +++++ ext/satellite/corba.h | 43 ++ ext/satellite/enum.c | 174 ++++++ ext/satellite/enum.h | 34 ++ ext/satellite/findtype.c | 145 +++++ ext/satellite/findtype.h | 43 ++ ext/satellite/hashtable.c | 101 ++++ ext/satellite/hashtable.h | 35 ++ ext/satellite/namedvalue_to_zval.c | 310 +++++++++++ ext/satellite/namedvalue_to_zval.h | 36 ++ ext/satellite/object.c | 851 +++++++++++++++++++++++++++++ ext/satellite/object.h | 37 ++ ext/satellite/php_orbit.c | 199 +++++++ ext/satellite/php_orbit.h | 42 ++ ext/satellite/struct.c | 330 +++++++++++ ext/satellite/struct.h | 35 ++ ext/satellite/typecode.c | 437 +++++++++++++++ ext/satellite/typecode.h | 34 ++ ext/satellite/typemanager.c | 552 +++++++++++++++++++ ext/satellite/typemanager.h | 112 ++++ ext/satellite/zval_to_namedvalue.c | 480 ++++++++++++++++ ext/satellite/zval_to_namedvalue.h | 33 ++ 29 files changed, 4844 insertions(+) create mode 100644 ext/satellite/Makefile.in create mode 100644 ext/satellite/README create mode 100644 ext/satellite/class.c create mode 100644 ext/satellite/class.h create mode 100644 ext/satellite/common.c create mode 100644 ext/satellite/common.h create mode 100644 ext/satellite/config.m4 create mode 100644 ext/satellite/corba.c create mode 100644 ext/satellite/corba.h create mode 100644 ext/satellite/enum.c create mode 100644 ext/satellite/enum.h create mode 100644 ext/satellite/findtype.c create mode 100644 ext/satellite/findtype.h create mode 100644 ext/satellite/hashtable.c create mode 100644 ext/satellite/hashtable.h create mode 100644 ext/satellite/namedvalue_to_zval.c create mode 100644 ext/satellite/namedvalue_to_zval.h create mode 100644 ext/satellite/object.c create mode 100644 ext/satellite/object.h create mode 100644 ext/satellite/php_orbit.c create mode 100644 ext/satellite/php_orbit.h create mode 100644 ext/satellite/struct.c create mode 100644 ext/satellite/struct.h create mode 100644 ext/satellite/typecode.c create mode 100644 ext/satellite/typecode.h create mode 100644 ext/satellite/typemanager.c create mode 100644 ext/satellite/typemanager.h create mode 100644 ext/satellite/zval_to_namedvalue.c create mode 100644 ext/satellite/zval_to_namedvalue.h diff --git a/ext/satellite/Makefile.in b/ext/satellite/Makefile.in new file mode 100644 index 0000000000..7687986bac --- /dev/null +++ b/ext/satellite/Makefile.in @@ -0,0 +1,54 @@ +# +# +----------------------------------------------------------------------+ +# | 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 | +# +----------------------------------------------------------------------+ +# + +# +# $Id$ +# vim: tabstop=2 shiftwidth=2 +# + +# ----------------------------------------------------------------------- +# +# Makefile for satellite +# +# TODO: specify dependencies properly! +# +# ----------------------------------------------------------------------- + +LTLIBRARY_NAME = libsatellite.la +LTLIBRARY_SOURCES = \ + class.c \ + common.c \ + corba.c \ + enum.c \ + findtype.c \ + hashtable.c \ + namedvalue_to_zval.c \ + object.c \ + php_orbit.c \ + struct.c \ + typecode.c \ + typemanager.c \ + zval_to_namedvalue.c +LTLIBRARY_SHARED_NAME = satellite.la + +#LTLIBRARY_SHARED_LIBADD = `orbit-config --libs client` `libIDL-config --libs` +LTLIBRARY_LDFLAGS=`orbit-config --libs client` `libIDL-config --libs` + +EXTRA_CFLAGS = -Wall -Wunused -Wmissing-prototypes -Wmissing-declarations `orbit-config --cflags client` `libIDL-config --cflags` + +include $(top_srcdir)/build/dynlib.mk diff --git a/ext/satellite/README b/ext/satellite/README new file mode 100644 index 0000000000..1d94864999 --- /dev/null +++ b/ext/satellite/README @@ -0,0 +1,59 @@ +$Id$ + +About Satellite +--------------- +Satellite is CORBA support for PHP using ORBit. + +The original version was made by David Eriksson +during the summer 2000. + + +Installation +------------ +Read below about installing ORBit. + +Then create a directory on your server for your IDL files, and add +an entry to your php.ini like this: + + idl_directory = /var/idl + +Note: If you compile Satellite as a dynamic PHP extension you must have the + above line located before the extension=satellite.so line in php.ini! + +PHP as an Apache static module +------------------------------ +Before linking Apache you must do either of these things: + + a) Before running Apache's configure you set the environment variable + LIBS like this: + + export LIBS="`orbit-config --libs client` `libIDL-config --libs`" + + b) You edit apache/src/modules/php4/libphp4.module and + add `orbit-config --libs client` `libIDL-config --libs` + within the quotes on the line beginning with LIBS= + + +What version of ORBit is required? +---------------------------------- +You need the CVS version of ORBit to use Satellite! + +This does NOT work with ORBit 0.5.3 or earlier. + + +How to install ORBit from CVS +----------------------------- + +(1) Get it from CVS + + CVS root: :pserver:anonymous@anoncvs.gnome.org:/cvs/gnome + Password: Empty string + Directory: ORBit + + More about GNOME:s CVS on http://www.gnome.org/start/source.html + +(2) Set the environment variable CERTIFIED_GNOMIE to whatever you like. + +(3) Run ./autogen.sh, gmake och gmake install + + diff --git a/ext/satellite/class.c b/ext/satellite/class.c new file mode 100644 index 0000000000..2ad1332909 --- /dev/null +++ b/ext/satellite/class.c @@ -0,0 +1,180 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + + +/* + * Helper function for making PHP classes + */ + +#include +#include "common.h" +#include "class.h" + +void orbit_class_function_call( + zend_class_entry * pClass, + int dataType, + zend_property_reference *pPropertyReference, + Class_Constructor pConstructor, + Class_CallFunction pCallFunction, + INTERNAL_FUNCTION_PARAMETERS) +{ + /* get object */ + zval * object = pPropertyReference->object; + + /* get function name */ + zend_overloaded_element * function_name = + (zend_overloaded_element *)pPropertyReference->elements_list->tail->data; + + /* handle parameters */ + zval ** arguments = orbit_new_n(zval *, ZEND_NUM_ARGS()); + /*(zval **)emalloc(sizeof(zval *) * ZEND_NUM_ARGS());*/ + if (getParametersArray(ht, ZEND_NUM_ARGS(), arguments) == FAILURE) + { + /* TODO: handle error */ + } + + /* constructor or normal function? */ + if (zend_llist_count(pPropertyReference->elements_list) == 1 + && !strcasecmp(function_name->element.value.str.val, pClass->name)) + { + /* constructor */ + if (pConstructor) + { + void * p_data = NULL; + zend_bool success = (*pConstructor)(&p_data, ZEND_NUM_ARGS(), arguments); + + if (success) + orbit_save_data(object, dataType, p_data); + } + else + { + zend_error(E_ERROR, "(Satellite) This class has no constructor");\ + } + } + else + { + /* normal function */ + if (pCallFunction) + { + void * p_data = orbit_retrieve_data(object, dataType); + + if (p_data == NULL) + { + /* + * this means that the constructor has failed earlier! + * -- or should NULL be allowed here? + */ + php_error(E_ERROR, "(Satellite) Class has no data!"); + RETVAL_NULL(); + goto orbit_class_function_call_exit; + } + + /* pval * return_value is a part of INTERNAL_FUNCTION_PARAMETERS */ + (*pCallFunction)(p_data, function_name->element.value.str.val, + ZEND_NUM_ARGS(), arguments, return_value); + } + else + { + zend_error(E_ERROR, "(Satellite) Can't call functions in this class");\ + } + } + +orbit_class_function_call_exit: + satellite_delete(arguments); + + /* seems to be required! */ + zval_dtor(&function_name->element); +} + +/* + * save a corba object to a php object + */ +void orbit_save_data(zval * php_object, int type, void * data) +{ + pval * orbit_data_handle = NULL; + long id = zend_list_insert( + data, /* data */ + type /* type */ + ); + + + /* + * do it like they do in php_COM_call_function_handler + * (insert into some magic hash index) + */ + ALLOC_ZVAL(orbit_data_handle); /* allocate memory for value */ + + orbit_data_handle->type = IS_LONG; + orbit_data_handle->value.lval = id; + + pval_copy_constructor(orbit_data_handle); /* why? */ + + INIT_PZVAL(orbit_data_handle); /* set reference count */ + + zend_hash_index_update( + php_object->value.obj.properties, /* hashtable */ + 0, /* hash??? */ + &orbit_data_handle, /* data */ + sizeof(pval *), /* data size */ + NULL /* destination */ + ); +} + +/* + * retrieve a corba object from a php object + */ +void * orbit_retrieve_data(const zval * php_object, int wanted_type) +{ + void * data = NULL; + pval ** orbit_data_handle = NULL; + int type = 0; + + /* get handle to corba data */ + zend_hash_index_find( + php_object->value.obj.properties, /* hash table */ + 0, /* hash??? */ + (void **)&orbit_data_handle /* data */ + ); + + if (orbit_data_handle == NULL || *orbit_data_handle == NULL) + { + return NULL; + } + + /* get corba data */ + data = zend_list_find( + (*orbit_data_handle)->value.lval, /* id */ + &type /* type */ + ); + + /* verify corba object */ + if (!data || (type != wanted_type)) + { + /* TODO: handle error */ + return NULL; + } + + return data; +} + + diff --git a/ext/satellite/class.h b/ext/satellite/class.h new file mode 100644 index 0000000000..1dc429cc8b --- /dev/null +++ b/ext/satellite/class.h @@ -0,0 +1,219 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * Macros and things to simplify making PHP classes + * + * ----------------------------------------------------------------------- + */ +#ifndef __orbit_class_h__ +#define __orbit_class_h__ + +#include +#include + +#define CONSTRUCTOR 1 +#define DESTRUCTOR 2 +#define CALL_FUNCTION 4 +#define PUT_PROPERTY 8 +#define GET_PROPERTY 16 +#define NO_FUNCTIONS (CONSTRUCTOR|DESTRUCTOR|PUT_PROPERTY|GET_PROPERTY) +#define NO_PROPERTIES (CONSTRUCTOR|DESTRUCTOR|CALL_FUNCTION) + +/* + * sorry everyone but the constructor itself has to allocate the data + * structure for member variables! + * + * it also has to deallocate this in the destructor... + */ +typedef zend_bool (*Class_Constructor) + (void ** ppObject, int parameterCount, zval ** ppParameters); +typedef zend_bool (*Class_Destructor) + (void * pObject); +typedef zend_bool (*Class_CallFunction) + (void * pObject, const char * pFunctionName, int parameterCount, zval ** ppParameters, zval * pReturnValue); +typedef zend_bool (*Class_PutProperty) + (void * pObject, const char * pPropertyName, const zval * pValue); +typedef zend_bool (*Class_GetProperty) + (void * pObject, const char * pPropertyName, zval * pReturnValue); + + /* put/get data connected to php object */ +void orbit_save_data(zval * pPhpObject, int type, void * pData); +void * orbit_retrieve_data(const zval * pPhpObject, int type); + +void orbit_class_function_call( + zend_class_entry * pClass, + int dataType, + zend_property_reference *pPropertyReference, + Class_Constructor pConstructor, + Class_CallFunction pCallFunction, + INTERNAL_FUNCTION_PARAMETERS); + +/* + * use this macro in the header file + */ +#define DECLARE_CLASS(name) \ +typedef struct _##name name##; \ +zend_bool name##_Init(int module_number); \ +void name##_SaveData(zval * pPhpObject, ##name * pData);\ +##name * name##_RetrieveData(const zval * pPhpObject);\ +zend_bool name##_PutProperty(##name * pObject, const char * pPropertyName, const zval * pValue);\ +zend_bool name##_GetProperty(##name * pObject, const char * pPropertyName, zval * pReturnValue);\ +/* end small macro */ + +/* + * Wrapper for a function call + */ +#define IMPLEMENT_FUNCTION_CALL(name, flags)\ +static void _##name##_FunctionCall(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference * pPropertyReference) \ +{ \ + orbit_class_function_call( \ + &name##_class_entry, \ + name##_data_type, \ + pPropertyReference, \ + ((flags) & CONSTRUCTOR) ? (Class_Constructor)name##_Constructor : NULL, \ + ((flags) & CALL_FUNCTION) ? (Class_CallFunction)name##_CallFunction : NULL, \ + INTERNAL_FUNCTION_PARAM_PASSTHRU\ + );\ +} + +/* + * wrapper for PutProperty + */ +#define IMPLEMENT_PUT_PROPERTY(name, flags)\ +static int _##name##_PutProperty(zend_property_reference * pPropertyReference, zval * pValue)\ +{\ + int result = 0;\ + if ((flags) & PUT_PROPERTY)\ + {\ + ##name * p_data = (##name *)orbit_retrieve_data(pPropertyReference->object, name##_data_type);\ + /* get variable name element */\ + zend_overloaded_element * p_attribute_element = \ + (zend_overloaded_element *)pPropertyReference->elements_list->tail->data;\ + /* get variable name */\ + char * p_attribute_name = p_attribute_element->element.value.str.val;\ + if (p_data)\ + result = ##name##_PutProperty(p_data, p_attribute_name, pValue) ? SUCCESS : FAILURE;\ + else\ + result = FAILURE;\ + }\ + else\ + {\ + zend_error(E_ERROR, "(Satellite) Can't set members in class");\ + }\ + return result;\ +} + +/* + * wrapper for GetProperty + */ +#define IMPLEMENT_GET_PROPERTY(name, flags)\ +static zval _##name##_GetProperty(zend_property_reference * pPropertyReference)\ +{\ + zval value;\ + ZVAL_NULL(&value);\ + if ((flags) & GET_PROPERTY)\ + {\ + ##name * p_data = (##name *)orbit_retrieve_data(pPropertyReference->object, name##_data_type);\ + /* get variable name element */\ + zend_overloaded_element * p_attribute_element = \ + (zend_overloaded_element *)pPropertyReference->elements_list->tail->data;\ + /* get variable name */\ + char * p_attribute_name = p_attribute_element->element.value.str.val;\ + if (p_data)\ + ##name##_GetProperty(p_data, p_attribute_name, &value);\ + }\ + else\ + {\ + zend_error(E_ERROR, "(Satellite) Can't get members in class");\ + }\ + return value;\ +} + + +#define IMPLEMENT_INIT_EX(name, flags, functions, functioncall, getproperty, putproperty)\ +zend_bool name##_Init(int module_number) \ +{ \ + /* register data type */ \ + name##_data_type = register_list_destructors(name##_Destructor, NULL); \ +\ + /* register class */ \ + INIT_OVERLOADED_CLASS_ENTRY( \ + name##_class_entry, \ + #name, \ + functions, \ + functioncall, \ + getproperty, \ + putproperty \ + ); \ +\ + zend_register_internal_class(&name##_class_entry);\ + return TRUE;\ +} + +/* + * initialize object, must be called from PHP_MINIT_FUNCTION etc + */ +#define IMPLEMENT_INIT(name, flags) \ +IMPLEMENT_INIT_EX(name, flags, NULL, _##name##_FunctionCall, _##name##_GetProperty, _##name##_PutProperty) + + +/* + * functions to save and retrieve data for the object + */ +#define IMPLEMENT_DATA_HELPERS(name, flags)\ +void name##_SaveData(zval * pPhpObject, ##name * pData)\ +{\ + orbit_save_data(pPhpObject, name##_data_type, pData);\ +}\ +##name * name##_RetrieveData(const zval * pPhpObject)\ +{\ + return (##name *)orbit_retrieve_data(pPhpObject, name##_data_type);\ +} + +/* + * static declarations for class + */ +#define IMPLEMENT_DECLARATIONS(name, flags)\ +static zend_bool name##_Constructor(##name ** ppObject, int parameterCount, const zval ** ppParameters);\ +static zend_bool name##_Destructor(##name * pObject);\ +static zend_bool name##_CallFunction(##name * pObject, const char * pFunctionName, int parameterCount, const zval ** ppParameters, zval * pResult); \ +\ +static int name##_data_type = 0; \ +static zend_class_entry name##_class_entry; + +/* + * use this macro in the source file + */ +#define 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(name, flags) \ +IMPLEMENT_DATA_HELPERS(name, flags) + + +#endif /* __orbit_class_h__ */ + diff --git a/ext/satellite/common.c b/ext/satellite/common.c new file mode 100644 index 0000000000..d04df3a85d --- /dev/null +++ b/ext/satellite/common.c @@ -0,0 +1,31 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * Some common stuff, now only memory allocation macros + * + * ----------------------------------------------------------------------- + */ +#include "common.h" + diff --git a/ext/satellite/common.h b/ext/satellite/common.h new file mode 100644 index 0000000000..3e038a530e --- /dev/null +++ b/ext/satellite/common.h @@ -0,0 +1,70 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * Some common stuff, now only memory allocation macros + * + * ----------------------------------------------------------------------- + */ +#ifndef __common_h__ +#define __common_h__ + +#include + +#define DEBUG_MEMORY 0 + +#if DEBUG_MEMORY + +void * satellite_debug_calloc(int count, int length); +void satellite_debug_free(void * pBuffer); +char * satellite_debug_strdup(const char * pString); + +/* default memory allocation */ +#define satellite_new_n(type,n) (type*)satellite_debug_calloc((n), sizeof(type)) +#define satellite_delete(p) satellite_debug_free(p) +#define satellite_strdup(s) satellite_debug_strdup(s) + +#else + +/* default memory allocation */ +#define satellite_new_n(type,n) (type*)ecalloc((n), sizeof(type)) +#define satellite_delete(p) if(p)efree(p) +#define satellite_strdup(s) estrdup(s) + +#endif + +#define satellite_new_1(type) satellite_new_n(type, 1) +#define satellite_new(type) satellite_new_1(type) + + +/* macros for old prefix "orbit_" */ + +#define orbit_new_n(type,n) satellite_new_n(type,n) +#define orbit_delete(p) satellite_delete(p) +#define orbit_strdup(s) satellite_strdup(s) +#define orbit_new_1(type) satellite_new_1(type) +#define orbit_new(type) satellite_new(type) + +#endif /* __common_h__ */ + diff --git a/ext/satellite/config.m4 b/ext/satellite/config.m4 new file mode 100644 index 0000000000..aac087d847 --- /dev/null +++ b/ext/satellite/config.m4 @@ -0,0 +1,40 @@ +dnl $Id$ + +dnl My first config.m4 - be nice to me... :-) + +PHP_ARG_ENABLE(satellite, whether to enable CORBA support via Satellite, +dnl Make sure that the comment is aligned: +[ --enable-satellite Enable CORBA support via Satellite (Requires ORBit)]) + +if test "$PHP_SATELLITE" != "no"; then + + dnl check for orbit-config + AC_PATH_PROG(orbit_config, "orbit-config") + + if test -z "$orbit_config"; then + AC_MSG_ERROR(Cannot find orbit-config, install ORBit!) + fi + + dnl check for symbol giop_skip_atexit in libIIOP + AC_CHECK_LIB(IIOP, giop_skip_atexit, [true], [ + AC_MSG_ERROR([Your version of ORBit is out of date! You need a version newer than August 5, 2000.]) + ], `$orbit_config --libs client`) + + dnl ORBIT_CFLAGS=`$orbit_config --cflags client` + dnl ORBIT_LIBS=`$orbit_config --libs client` + + dnl check for libIDL-config + AC_PATH_PROG(libidl_config, "libIDL-config") + + if test -z "libidl_config"; then + AC_MSG_ERROR(Cannot find libIDL-config, install libIDL!) + fi + + dnl LIBIDL_CFLAGS=`$libidl_config --cflags` + dnl LIBIDL_LIBS=`$libidl_config --libs` + + dnl CFLAGS="$CFLAGS $ORBIT_CFLAGS $LIBIDL_CFLAGS" + + AC_DEFINE(HAVE_SATELLITE, 1, [CORBA support enabled via Satellite]) + PHP_EXTENSION(satellite, $ext_shared) +fi diff --git a/ext/satellite/corba.c b/ext/satellite/corba.c new file mode 100644 index 0000000000..9b1cb77152 --- /dev/null +++ b/ext/satellite/corba.c @@ -0,0 +1,128 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * Control access to CORBA_ORB and CORBA_Environment objects + * Adjust these functions to get thread safety! + * + * ----------------------------------------------------------------------- + */ +#include "corba.h" + +#ifdef HAVE_CONFIG_H +#include "php_config.h" /* for COMPILE_DL_ORBIT */ +#endif + +/* ZTS = thread-safe Zend */ +#ifdef ZTS +#error ORBit support not thread-safe, you should at least modify corba.c +#endif + +static CORBA_ORB corba_orb = NULL; +static CORBA_Environment corba_environment; +static CORBA_boolean corba_initialized = FALSE; + +CORBA_boolean orbit_corba_init() +{ + int argc = 1; + char * argv[2] = { "dummy", NULL }; + + +#if COMPILE_DL_SATELLITE + /* + IIOP normally registers a function with atexit, but that's pretty stupid + when it is called from a dynamic module that is unloaded before exit() + is called... + + "In addition, for David Eriksson (I think), added: + int giop_skip_atexit; + to IIOP. Applications may set this TRUE prior to invoking any + CORBA_ORB_init() calls, and it will not invoke atexit. This is + perhaps an ugly way of doing this, but I'm assuming this feature + will only be used from within specialized sharedlib applications + that know what they are doing... + + Kennard" + */ + + giop_skip_atexit = TRUE; +#endif + + CORBA_exception_init(&corba_environment); + corba_orb = CORBA_ORB_init( + &argc, argv, "orbit-local-orb", &corba_environment); + + /* check return value */ + if (corba_orb == NULL || orbit_caught_exception()) + { +/* printf("orbit_corba_init failed\n");*/ + return FALSE; + } + + corba_initialized = TRUE; + + return TRUE; +} + +CORBA_boolean orbit_corba_shutdown() +{ + if (corba_initialized) + { + /* the orb's reference count is two.. what to do? */ + CORBA_Object_release((CORBA_Object)corba_orb, &corba_environment); + CORBA_Object_release((CORBA_Object)corba_orb, &corba_environment); + /*CORBA_ORB_destroy(corba_orb, &corba_environment); */ + + CORBA_exception_free(orbit_get_environment()); + + corba_initialized = FALSE; + corba_orb = NULL; + return TRUE; + } + else + return FALSE; +} + +CORBA_ORB orbit_get_orb() +{ + return corba_orb; +} + +CORBA_Environment * orbit_get_environment() +{ + return &corba_environment; +} + +CORBA_boolean orbit_caught_exception() +{ +#if 0 /*debug*/ + if (orbit_get_environment()->_major != CORBA_NO_EXCEPTION) + { + printf("Caught exception %s\n", + CORBA_exception_id(orbit_get_environment())); + } +#endif + return orbit_get_environment()->_major != CORBA_NO_EXCEPTION; +} + diff --git a/ext/satellite/corba.h b/ext/satellite/corba.h new file mode 100644 index 0000000000..87e176e5fa --- /dev/null +++ b/ext/satellite/corba.h @@ -0,0 +1,43 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* + * Control access to CORBA_ORB and CORBA_Environment objects + */ +#ifndef __corba_h__ +#define __corba_h__ + +#include + +/* corba handling */ +CORBA_boolean orbit_corba_init(); +CORBA_boolean orbit_corba_shutdown(); +CORBA_ORB orbit_get_orb(); +CORBA_Environment * orbit_get_environment(); + +/* exception handling */ +CORBA_boolean orbit_caught_exception(); +#define orbit_error_test(info) orbit_caught_exception() + +#endif /* __corba_h__ */ + diff --git a/ext/satellite/enum.c b/ext/satellite/enum.c new file mode 100644 index 0000000000..215ccf9d99 --- /dev/null +++ b/ext/satellite/enum.c @@ -0,0 +1,174 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * OrbitEnum class + * + * ----------------------------------------------------------------------- + */ +#include "enum.h" +#include "typemanager.h" +#include "common.h" +#include "hashtable.h" + +struct _OrbitEnum +{ + EnumType * mpEnumType; + HashTable mMembers; +}; + +IMPLEMENT_CLASS(OrbitEnum, CONSTRUCTOR|DESTRUCTOR|GET_PROPERTY) + + +static zend_bool OrbitEnum_InitializeMembers(OrbitEnum * pEnum) +{ + int enum_value = 0; + EnumMemberType * p_member = NULL; + + p_member = EnumType_GetFirstMember(pEnum->mpEnumType); + + zend_hash_init( + &pEnum->mMembers, /* hash table */ + 0, /* size */ + NULL, /* hash function */ + ZVAL_DESTRUCTOR, /* destructor */ + 0); /* persistent */ + + if (!EnumMemberType_IsValid(p_member)) + return TRUE; /* no members */ + + do + { + zval * p_value = NULL; + char * p_name = EnumMemberType_GetName(p_member); + + ALLOC_ZVAL(p_value); + ZVAL_LONG(p_value, enum_value); + + zend_hash_add( + &pEnum->mMembers, + p_name, + strlen(p_name)+1, + p_value, + sizeof(zval), + NULL + ); + + /* set value for next member */ + enum_value++; + + } while (EnumMemberType_GetNext(p_member)); + + return TRUE; +} + +zend_bool OrbitEnum_Constructor(OrbitEnum ** ppEnum, int parameterCount, + const zval ** ppParameters) +{ + OrbitEnum * p_enum = orbit_new(OrbitEnum); + + /* check parameter count */ + if (parameterCount != 1) + { + wrong_param_count(); + goto error; + } + + /* validate parameter types */ + if (ppParameters[0]->type != IS_STRING) + goto error; + + /* find type information */ + p_enum->mpEnumType = TypeManager_FindEnum(ppParameters[0]->value.str.val); + if (p_enum->mpEnumType == NULL) + { + zend_error(E_ERROR, "(Satellite) unknown enum '%s'", ppParameters[0]->value.str.val); + goto error; + } + + /* initialize members */ + if (!OrbitEnum_InitializeMembers(p_enum)) + goto error; + + *ppEnum = p_enum; + return TRUE; + +error: +/* printf("OrbitEnum_Constructor failed\n");*/ + OrbitEnum_Destructor(p_enum); + *ppEnum = NULL; + return FALSE; +} + +zend_bool OrbitEnum_Destructor(OrbitEnum * pEnum) +{ +/* printf("OrbitEnum_Destructor\n");*/ + + if (pEnum != NULL) + { + orbit_delete(pEnum->mpEnumType); + } + + zend_hash_destroy(&pEnum->mMembers); + orbit_delete(pEnum); + + return TRUE; +} + +/* not used */ +zend_bool OrbitEnum_CallFunction(OrbitEnum * pEnum, + const char * pFunctionName, int parameterCount, const zval ** ppParameters, zval * pResult) +{ + return FALSE; +} + +/* not used */ +zend_bool OrbitEnum_PutProperty(OrbitEnum * pEnum, + const char * pPropertyName, const zval * pValue) +{ + return FALSE; +} + +zend_bool OrbitEnum_GetProperty(OrbitEnum * pEnum, + const char * pPropertyName, zval * pReturnValue) +{ + zval * p_value = orbit_find_by_key(&pEnum->mMembers, pPropertyName); + + if (p_value == NULL) + { + zend_error(E_ERROR, "(Satellite) unknown member '%s' in enum '%s'", + pPropertyName, EnumType_GetRepositoryId(pEnum->mpEnumType)); + + 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; + } +} + diff --git a/ext/satellite/enum.h b/ext/satellite/enum.h new file mode 100644 index 0000000000..861d87db49 --- /dev/null +++ b/ext/satellite/enum.h @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* + * OrbitEnum class + */ +#ifndef __enum_h__ +#define __enum_h__ + +#include "class.h" + +DECLARE_CLASS(OrbitEnum); + +#endif /* __enum_h__ */ diff --git a/ext/satellite/findtype.c b/ext/satellite/findtype.c new file mode 100644 index 0000000000..cefb5c2559 --- /dev/null +++ b/ext/satellite/findtype.c @@ -0,0 +1,145 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* + * Used by typemanager.c and typecode.c + */ +#include +#include "findtype.h" + +typedef struct +{ + const char * mpWantedId; + IDL_tree_type mWantedType; + IdlInfo mIdlInfo; + CORBA_boolean mSuccess; +} FindTypeData; + +static CORBA_boolean orbit_find_type_compare( + FindTypeData * pData, IDL_tree ident, IDL_tree type) +{ + if (pData == NULL || ident == NULL || type == NULL) + return TRUE; /* continue */ + + /* compare ids */ + if (strcmp(pData->mpWantedId, IDL_IDENT(ident).repo_id) == 0 || + strcasecmp(pData->mpWantedId, IDL_IDENT(ident).str) == 0) + { + pData->mIdlInfo.mIdent = ident; + pData->mIdlInfo.mType = type; + pData->mSuccess = TRUE; + return FALSE; /* stop */ + } + + return TRUE; +} + +static CORBA_boolean orbit_find_type_helper(IDL_tree_func_data *tnfd, FindTypeData *pData) +{ + IDL_tree tree = tnfd->tree; +/* IDL_tree real_tree = tree; */ + IDL_tree ident = NULL; + + /* must be any type or right type */ + if (pData->mWantedType != IDLN_ANY && pData->mWantedType != IDL_NODE_TYPE(tree)) + { + return TRUE; /* continue */ + } + + switch(IDL_NODE_TYPE(tree)) + { + case IDLN_ATTR_DCL: + /* attributes */ + /* real_tree = IDL_ATTR_DCL(tree).param_type_spec; */ + + /* + * XXX: this will only handle the FIRST + * ident connected to the attribute! + */ + ident = IDL_LIST(IDL_ATTR_DCL(tree).simple_declarations).data; + break; + + case IDLN_EXCEPT_DCL: + ident = IDL_EXCEPT_DCL(tree).ident; + + case IDLN_INTERFACE: + ident = IDL_INTERFACE(tree).ident; + break; + + case IDLN_OP_DCL: + ident = IDL_OP_DCL(tree).ident; + break; + + case IDLN_TYPE_DCL: + /* typedefs */ + /* real_tree = IDL_TYPE_DCL(tree).type_spec; */ + + /* + * XXX: this will only handle the FIRST + * ident connected to the type! + */ + ident = IDL_LIST(IDL_TYPE_DCL(tree).dcls).data; + break; + + case IDLN_TYPE_ENUM: + ident = IDL_TYPE_ENUM(tree).ident; + break; + + case IDLN_TYPE_STRUCT: + ident = IDL_TYPE_STRUCT(tree).ident; + break; + + /* TODO: handle more types! */ + + default: + } + + return orbit_find_type_compare(pData, ident, /*real_*/tree); +} + +CORBA_boolean orbit_find_type( + IDL_tree tree, const char * pWantedId, IDL_tree_type wantedType, IdlInfo * pIdlInfo) +{ + FindTypeData data; + + memset(&data, 0, sizeof(data)); + data.mpWantedId = pWantedId; + data.mWantedType = wantedType; + + IDL_tree_walk_in_order( + tree, + (IDL_tree_func)orbit_find_type_helper, + &data); + + *pIdlInfo = data.mIdlInfo; + + return data.mSuccess; +} + +IDL_tree orbit_find_type_simple(IDL_tree tree, const char * pWantedId) +{ + IdlInfo info; + CORBA_boolean success = orbit_find_type(tree, pWantedId, IDLN_ANY, &info); + return success ? info.mType : NULL; +} + diff --git a/ext/satellite/findtype.h b/ext/satellite/findtype.h new file mode 100644 index 0000000000..8be50cab38 --- /dev/null +++ b/ext/satellite/findtype.h @@ -0,0 +1,43 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* + * Used by typemanager.c and typecode.c + */ +#ifndef __findtype_h__ +#define __findtype_h__ + +#include + +typedef struct +{ + IDL_tree mIdent; + IDL_tree mType; +} IdlInfo; + +CORBA_boolean orbit_find_type( + IDL_tree tree, const char * pWantedId, IDL_tree_type wantedType,IdlInfo * pIdlInfo); +IDL_tree orbit_find_type_simple(IDL_tree tree, const char * pWantedId); + +#endif /* __findtype_h__ */ + diff --git a/ext/satellite/hashtable.c b/ext/satellite/hashtable.c new file mode 100644 index 0000000000..68f801f423 --- /dev/null +++ b/ext/satellite/hashtable.c @@ -0,0 +1,101 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* + * HashTable helpers + */ +#include "hashtable.h" +#include "zend_API.h" + +#ifndef FALSE +#define FALSE 0 +#endif + +/* + * duplicate a zval + */ +static zval * orbit_duplicate_zval(const zval * pValue) +{ + zval * p_new_value = NULL; + + if (pValue == NULL) + return NULL; + + ALLOC_ZVAL(p_new_value); /* allocate */ + memcpy(p_new_value, pValue, sizeof(zval)); /* raw data copy */ + zval_copy_ctor(p_new_value); /* smart data copy */ + INIT_PZVAL(p_new_value); /* set reference count */ + + return p_new_value; +} + +/* + * store a zval in a hashtable with a key + */ +zend_bool orbit_store_by_key(HashTable * pHashTable, const char * pKey, const zval * pValue) +{ + int result = FAILURE; + void * p_destination = NULL; + zval * p_new_value = NULL; + + if (pHashTable == NULL || pKey == NULL || pValue == NULL) + return FALSE; + + p_new_value = orbit_duplicate_zval(pValue); + + result = zend_hash_update( + pHashTable, + (char *)pKey, /* discard const */ + strlen(pKey)+1, + p_new_value, + sizeof(zval), + &p_destination + ); + + return result == SUCCESS; +} + +/* + * find a zval in a hashtable with a key + */ +zval * orbit_find_by_key(HashTable * pHashTable, const char * pKey) +{ + int result = FAILURE; + zval * p_value = NULL; + + result = zend_hash_find( + pHashTable, + (char *)pKey, /* discard const */ + strlen(pKey)+1, + (void**)&p_value + ); + + if (result != SUCCESS) + { + p_value = NULL; + } + + return p_value; +} + + diff --git a/ext/satellite/hashtable.h b/ext/satellite/hashtable.h new file mode 100644 index 0000000000..2e33cd4d76 --- /dev/null +++ b/ext/satellite/hashtable.h @@ -0,0 +1,35 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* + * HashTable helpers + */ +#ifndef __hashtable_h__ +#define __hashtable_h__ + +#include + +zval * orbit_find_by_key(HashTable * pHashTable, const char * pKey); +zend_bool orbit_store_by_key(HashTable * pHashTable, const char * pKey, const zval * pValue); + +#endif /* __hashtable_h__ */ diff --git a/ext/satellite/namedvalue_to_zval.c b/ext/satellite/namedvalue_to_zval.c new file mode 100644 index 0000000000..8249d9f465 --- /dev/null +++ b/ext/satellite/namedvalue_to_zval.c @@ -0,0 +1,310 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * Functions to convert a CORBA_NamedValue to a zval + * + * ----------------------------------------------------------------------- + */ +#include +#include "namedvalue_to_zval.h" +#include "common.h" +#include "object.h" +#include "struct.h" +#include "corba.h" + +#include /* for ALIGN_ADDRESS() */ + +static zend_bool satellite_any_to_zval_boolean( + const CORBA_any * pSource, zval * pDestination) +{ + CORBA_boolean * p_value = (CORBA_boolean *)pSource->_value; + ZVAL_BOOL(pDestination, *p_value != 0); + return TRUE; +} + +static zend_bool satellite_any_to_zval_double( + const CORBA_any * pSource, zval * pDestination) +{ + CORBA_double * p_value = (CORBA_double *)pSource->_value; + ZVAL_DOUBLE(pDestination, *p_value); + return TRUE; +} + +static zend_bool satellite_any_to_zval_long( + const CORBA_any * pSource, zval * pDestination) +{ + CORBA_long * p_value = (CORBA_long *)pSource->_value; + ZVAL_LONG(pDestination, *p_value); + return TRUE; +} + +static zend_bool satellite_any_to_zval_short( + const CORBA_any * pSource, zval * pDestination) +{ + CORBA_short * p_value = (CORBA_short *)pSource->_value; + ZVAL_LONG(pDestination, *p_value); + return TRUE; +} + + +static zend_bool satellite_any_to_zval_objref( + const CORBA_any * pSource, zval * pDestination) +{ + CORBA_Object * p_value = (CORBA_Object *)pSource->_value; + CORBA_Object dup = + CORBA_Object_duplicate(*p_value, orbit_get_environment()); + + return OrbitObject_Create(dup, pDestination); +} + +static zend_bool satellite_any_to_zval_sequence( + const CORBA_any * pSource, zval * pDestination) +{ + int i; + int length = 0; + void ** pp_members = NULL; + zend_bool success = FALSE; + CORBA_NamedValue source_item; + zval * p_destination_item = NULL; + CORBA_TypeCode content_type = NULL; + CORBA_sequence_octet * p_value = + (CORBA_sequence_octet *)pSource->_value; + + /* get array to items */ + pp_members = (void **)p_value->_buffer; + + /* get number of members */ + length = p_value->_length; + + /* get type of items */ + content_type = CORBA_TypeCode_content_type( + pSource->_type, orbit_get_environment()); + if (content_type == NULL) + goto error; + + /* set zval members */ +#if 0 + pDestination->type = IS_ARRAY; + pDestination->refcount = 1; + + pDestination->value.ht = orbit_new(HashTable); + + zend_hash_init( + pDestination->value.ht, /* hash table */ + 0, /* size */ + NULL, /* hash function */ + ZVAL_PTR_DTOR, /* destructor */ + 0); /* persistent */ +#else + array_init(pDestination); +#endif + + for (i = 0; i < length; i++) + { + p_destination_item = NULL; + memset(&source_item, 0, sizeof(CORBA_NamedValue)); + + source_item.argument._type = content_type; + source_item.argument._value = &pp_members[i]; + + ALLOC_ZVAL(p_destination_item); + + /* convert item */ + success = orbit_namedvalue_to_zval( + &source_item, + p_destination_item); + + if (!success) + goto error; + + /* add to hashtable */ + INIT_PZVAL(p_destination_item); /* testing! */ + zend_hash_next_index_insert( + pDestination->value.ht, + &p_destination_item, + sizeof(zval *), + NULL); + +/* FREE_ZVAL(p_destination_item);*/ + } + + return TRUE; + +error: + return FALSE; +} + +static zend_bool satellite_any_to_zval_string( + const CORBA_any * pSource, zval * pDestination) +{ + char ** pp_value = (char **)pSource->_value; + ZVAL_STRING(pDestination, (*pp_value), TRUE); + return TRUE; +} + +static zend_bool satellite_any_to_zval_struct( + const CORBA_any * pSource, zval * pDestination) +{ + int member_count = 0; + CORBA_TypeCode type = NULL; + char * p_repository_id = NULL; + OrbitStruct * p_struct = NULL; + + /* make type a shortcut to the typecode */ + type = pSource->_type; + + /* find out the repository id */ + p_repository_id = CORBA_TypeCode_id(type, orbit_get_environment()); + /* do not check for exception because we may be converting one! */ + if (p_repository_id == NULL) + goto error; + + if (!OrbitStruct_Create(p_repository_id, pDestination)) + goto error; + + p_struct = OrbitStruct_RetrieveData(pDestination); + if (p_struct == NULL) + goto error; + + /* now we know the source and destination matches! */ + member_count = CORBA_TypeCode_member_count(type, orbit_get_environment()); + /* do not check for exception because we may be converting one! */ + + if (member_count > 0) + { + int i; + zend_bool success; + zval destination_item; + CORBA_NamedValue source_item; + char * p_buffer = (char *)pSource->_value; + + for (i = 0; i < member_count; i++) + { + int alignment; + char * p_name = + CORBA_TypeCode_member_name(type, i, orbit_get_environment()); + if (p_name == NULL) + goto error; + + /* prepare destination item */ + ZVAL_NULL(&destination_item); + + /* prepare source item */ + memset(&source_item, 0, sizeof(CORBA_NamedValue)); + source_item.argument._type = + CORBA_TypeCode_member_type(type, i, orbit_get_environment()); + if (source_item.argument._type == NULL) + goto error; + + /* align pointer and set value */ + alignment = ORBit_find_alignment(source_item.argument._type); + p_buffer = ALIGN_ADDRESS(p_buffer, alignment); + source_item.argument._value = p_buffer; + + /* convert item */ + if (!orbit_namedvalue_to_zval(&source_item, &destination_item)) + goto error; + + /* set attribute */ + success = OrbitStruct_PutProperty(p_struct, p_name, &destination_item); + if (!success) goto error; + + /* advance buffer */ + p_buffer += ORBit_gather_alloc_info(source_item.argument._type); + } + } + + +error: + return FALSE; +} + +zend_bool satellite_any_to_zval( + const CORBA_any * pSource, zval * pDestination) +{ + zend_bool success = FALSE; + CORBA_TCKind kind; + + if (pSource->_type == NULL || pDestination == NULL) + return FALSE; + + kind = CORBA_TypeCode_kind( + pSource->_type, + orbit_get_environment()); /* does not throw exceptions */ + + switch (kind) + { + case CORBA_tk_boolean: + success = satellite_any_to_zval_boolean(pSource, pDestination); + break; + + case CORBA_tk_double: + success = satellite_any_to_zval_double(pSource, pDestination); + break; + + case CORBA_tk_enum: + case CORBA_tk_long: + success = satellite_any_to_zval_long(pSource, pDestination); + break; + + case CORBA_tk_objref: + success = satellite_any_to_zval_objref(pSource, pDestination); + break; + + case CORBA_tk_sequence: + success = satellite_any_to_zval_sequence(pSource, pDestination); + break; + + case CORBA_tk_short: + success = satellite_any_to_zval_short(pSource, pDestination); + break; + + case CORBA_tk_string: + success = satellite_any_to_zval_string(pSource, pDestination); + break; + + case CORBA_tk_struct: /* 15 */ + case CORBA_tk_except: /* 22 */ + success = satellite_any_to_zval_struct(pSource, pDestination); + break; + + default: +/* printf("unsupported corba TCKind %i\n", kind);*/ +/* php_error(E_WARNING, "unsupported corba TCKind %i", kind);*/ + } + + return success; +} + +zend_bool orbit_namedvalue_to_zval( + const CORBA_NamedValue * pSource, zval * pDestination) +{ + if (pSource == NULL) + return FALSE; + + return satellite_any_to_zval(&pSource->argument, pDestination); +} + + diff --git a/ext/satellite/namedvalue_to_zval.h b/ext/satellite/namedvalue_to_zval.h new file mode 100644 index 0000000000..570d8497ae --- /dev/null +++ b/ext/satellite/namedvalue_to_zval.h @@ -0,0 +1,36 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +#ifndef __namedvalue_to_zval_h__ +#define __namedvalue_to_zval_h__ + +#include +#include + +zend_bool orbit_namedvalue_to_zval( + const CORBA_NamedValue * pSource, zval * pDestination); + +zend_bool satellite_any_to_zval( + const CORBA_any * pSource, zval * pDestination); + +#endif /* __namedvalue_to_zval_h__ */ diff --git a/ext/satellite/object.c b/ext/satellite/object.c new file mode 100644 index 0000000000..d01272dcb2 --- /dev/null +++ b/ext/satellite/object.c @@ -0,0 +1,851 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * OrbitObject class + * + * There are three ways to create an object + * + * (1) OrbitObject_Constructor, for new OrbitObject(...) in PHP + * (2) OrbitObject_Create, used when a CORBA method returns an object + * (3) OrbitObject_Wakeup, used on "unserialization" + * + * ----------------------------------------------------------------------- + */ +#include "class.h" +#include "corba.h" +#include "common.h" +#include "object.h" +#include "typemanager.h" +#include "namedvalue_to_zval.h" +#include "zval_to_namedvalue.h" +#include "typecode.h" /* for satellite_release_typecode */ + +#define PROFILE 0 + +#if PROFILE +#include +#include +#endif + +struct _OrbitObject +{ + CORBA_Object mCorbaObject; + InterfaceType * mpInterface; +}; + +static void OrbitObject_Wakeup(INTERNAL_FUNCTION_PARAMETERS); +static void OrbitObject_Sleep(INTERNAL_FUNCTION_PARAMETERS); + +static zend_function_entry OrbitObject_functions[] = +{ + {"__sleep", OrbitObject_Sleep}, + {"__wakeup", OrbitObject_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(OrbitObject, ~0); + +CORBA_Object OrbitObject_GetCorbaObject(OrbitObject * pObject) +{ + if (pObject == NULL) + return FALSE; + else + return pObject->mCorbaObject; +} +#define IOR_PROPERTY_KEY "IOR" + +/* + * prepare for serialization + * + * this means creating a property containing the object IOR and returning an + * array containing the names of properties we want serialized + * + * TODO: save environment as property?! + * + */ +static void OrbitObject_Sleep(INTERNAL_FUNCTION_PARAMETERS) +{ + CORBA_char * p_ior = NULL; + /* get object data */ + OrbitObject * p_object = OrbitObject_RetrieveData(this_ptr); + + /* validate data */ + if (p_object == NULL) + { + goto error; + } + + /* get IOR from object */ + p_ior = CORBA_ORB_object_to_string( + orbit_get_orb(), p_object->mCorbaObject, orbit_get_environment()); + if (p_ior == NULL || orbit_caught_exception()) + goto error; + + /* 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); + + return; + +error: + RETURN_NULL(); +} + +/* + * initialize OrbitObject structure + */ +static zend_bool OrbitObject_InitializeData(OrbitObject * pObject, const char * pIor) +{ + /* get object */ + pObject->mCorbaObject = CORBA_ORB_string_to_object( + orbit_get_orb(), + pIor, + orbit_get_environment()); + + if (pObject->mCorbaObject == NULL || orbit_caught_exception()) + { + zend_error(E_ERROR, "(Satellite) Unable to resolve IOR"); + goto error; + } + + /* find type info */ + pObject->mpInterface = + TypeManager_FindInterface(pObject->mCorbaObject->type_id); + + if (pObject->mpInterface == NULL) + { + zend_error(E_ERROR, "(Satellite) unknown interface '%s'", + pObject->mCorbaObject->type_id); + /* TODO: set exception */ + goto error; + } + + return TRUE; + +error: + return FALSE; +} + +/* + * recover from serialization + * + * this means reading the property IOR and reconstructing the object! + * + */ +static void OrbitObject_Wakeup(INTERNAL_FUNCTION_PARAMETERS) +{ + zval ** pp_ior = NULL; + + /* create data object */ + OrbitObject * p_object = orbit_new(OrbitObject); + + /* find IOR property */ + if (zend_hash_find( + this_ptr->value.obj.properties, + IOR_PROPERTY_KEY, + sizeof(IOR_PROPERTY_KEY), + (void**)&pp_ior) != SUCCESS) + { + /* TODO: set exception */ + goto error; + } + + if ((*pp_ior)->type != IS_STRING) + { + /* TODO: set exception */ + goto error; + } + + /* initialize data */ + if (!OrbitObject_InitializeData( + p_object, + (*pp_ior)->value.str.val)) + { + goto error; + } + + /* save data to zval */ + OrbitObject_SaveData(this_ptr, p_object); + + return; + +error: + zend_error(E_ERROR, "(Satellite) Invalid serialized object"); + OrbitObject_Destructor(p_object); +} + + +/* instansiate a class */ +zend_bool OrbitObject_Create(CORBA_Object source, zval * pDestination) +{ + OrbitObject * p_object = NULL; + + /* source might be NULL */ + if (source == NULL) + { + ZVAL_NULL(pDestination); + return TRUE; + } + + /* allocate object */ + p_object = orbit_new(OrbitObject); + + /* save corba object */ + p_object->mCorbaObject = source; + + /* find type info */ + p_object->mpInterface = + TypeManager_FindInterface(p_object->mCorbaObject->type_id); + + if (p_object->mpInterface == NULL) + { + zend_error(E_ERROR, "(Satellite) unknown interface '%s'", + p_object->mCorbaObject->type_id); + goto error; + } + + /* set zval members */ + pDestination->type = IS_OBJECT; + pDestination->is_ref = 1; + pDestination->refcount = 1; + + pDestination->value.obj.ce = &OrbitObject_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 */ + OrbitObject_SaveData(pDestination, p_object); + + return TRUE; + +error: + OrbitObject_Destructor(p_object); + return FALSE; +} + + + +/* + * constructor + * + * parameters: IOR, OrbitEnvironment + */ +zend_bool OrbitObject_Constructor(OrbitObject ** ppObject, + int parameterCount, const zval ** ppParameters) +{ + OrbitObject * p_object = NULL; + + /* allocate object */ + p_object = orbit_new(OrbitObject); + + /* check parameter count */ + if (parameterCount != 1) + { + wrong_param_count(); + goto error; + } + + /* validate parameter types */ + if (ppParameters[0]->type != IS_STRING) + { + zend_error(E_ERROR, "(Satellite) IOR is not a string"); + goto error; + } + + /* initialize data object */ + if ( !OrbitObject_InitializeData( + p_object, + ppParameters[0]->value.str.val) ) + { + goto error; + } + + *ppObject = p_object; + return TRUE; + +error: + OrbitObject_Destructor(p_object); + *ppObject = NULL; + + /* TODO: all errors above should set exceptions! */ + + return FALSE; +} + +/* + * destructor + */ +zend_bool OrbitObject_Destructor(OrbitObject * pObject) +{ + InterfaceType_release(pObject->mpInterface); + + if (pObject->mCorbaObject != NULL) + CORBA_Object_release((CORBA_Object)pObject->mCorbaObject, NULL); + + orbit_delete(pObject); + + return TRUE; +} + +/* + * prepare a function call result + */ +static CORBA_NamedValue * OrbitObject_PrepareResult(OrbitObject * pObject, + OperationType * pOperation) +{ + CORBA_NamedValue * p_result = orbit_new(CORBA_NamedValue); + + p_result->argument._type = OperationType_GetReturnType(pOperation); + + if (p_result->argument._type == NULL) + { + orbit_delete(p_result); + p_result = NULL; + } + else + { + orbit_zval_to_namedvalue(NULL, p_result); + } + + return p_result; +} + +/* + * add an argument to a function call + */ +static zend_bool OrbitObject_AddSingleArgument(OrbitObject * pObject, + CORBA_Request request, ParameterType * pParameter, const zval * pSource, CORBA_NamedValue * pDestination) +{ + pDestination->argument._type = ParameterType_GetType(pParameter); + pDestination->arg_modes = ParameterType_GetPassingMode(pParameter); + + /* if the argument is output only, don't care about input value */ + if (pDestination->arg_modes == CORBA_ARG_OUT) + pSource = NULL; + + if (!orbit_zval_to_namedvalue(pSource, pDestination)) + return FALSE; + + /* add parameter to request */ + CORBA_Request_add_arg( + request, /* request */ + NULL, /* arg_name */ + pDestination->argument._type, /* type */ + pDestination->argument._value, /* value */ + pDestination->len, /* length */ + pDestination->arg_modes, /* flags */ + orbit_get_environment() + ); + + if (orbit_caught_exception()) + return FALSE; + + return TRUE; +} + +/* + * add the function call arguments + */ +static zend_bool OrbitObject_AddArguments(OrbitObject * pObject, + CORBA_Request request, OperationType * pOperation, int argumentCount, + const zval ** ppArguments, CORBA_NamedValue ** ppNamedValue) +{ + ParameterType * p_parameter = OperationType_GetFirstParameter(pOperation); + int i = 0; + zend_bool success; + + if (argumentCount < 1) + return TRUE; /* nothing to do */ + + do + { + ppNamedValue[i] = satellite_new(CORBA_NamedValue); + success = OrbitObject_AddSingleArgument( pObject, + request, p_parameter, ppArguments[i], ppNamedValue[i]); + + if (!success) + return FALSE; + + i++; + } while (i < argumentCount && ParameterType_GetNext(p_parameter)); + + /* i should equal argument count and there should be no more parameters */ + if (i != argumentCount || ParameterType_GetNext(p_parameter)) + { +/* printf("%i, %i, %i\n", i, argumentCount, ParameterType_IsValid(p_parameter));*/ + + /* bad number of arguments */ + wrong_param_count(); + return FALSE; + } + + return TRUE; +} + +/* + * release a namedvalue that we have allocated + * + * (move to another file?) + */ +static void satellite_release_namedvalue(CORBA_NamedValue * pNamedValue) +{ + if (pNamedValue == NULL) + return; + + /* clear value */ + if (pNamedValue->argument._value != NULL) + { + /* allocated with ORBit_alloc_tcval */ + CORBA_free(pNamedValue->argument._value); + } + + /* clear typecode */ + satellite_release_typecode(pNamedValue->argument._type); + + /* allocated with satellite_new */ + satellite_delete(pNamedValue); +} + +static void satellite_release_namedvalue_list( + CORBA_NamedValue ** ppNamedValue, int length) +{ + int i; + + if (ppNamedValue == NULL) + return; + + for (i = 0; i < length; i++) + { + /* release named values */ + satellite_release_namedvalue(ppNamedValue[i]); + ppNamedValue[i] = NULL; + } + + satellite_delete(ppNamedValue); +} + +/* + * post-process arguments (take care of output parameters, release memory) + */ +static zend_bool OrbitObject_ReleaseArguments(OrbitObject * pObject, + CORBA_Request request, OperationType * pOperation, int argumentCount, + const zval ** ppArguments, CORBA_NamedValue ** ppNamedValue) +{ + /* TODO: handle output parameters */ + + return TRUE; +} + + + +/* + * call a function + */ +zend_bool OrbitObject_CallFunction(OrbitObject * pObject, + const char * pFunctionName, int parameterCount, const zval ** ppParameters, zval * pReturnValue) +{ + zend_bool success; + CORBA_Request request = NULL; + OperationType * p_operation = NULL; + CORBA_NamedValue ** pp_arguments = NULL; + CORBA_NamedValue * p_result = NULL; + CORBA_TypeCode * p_exception_list = NULL; + +#if PROFILE + int i; + struct timeval tv[4]; + gettimeofday(&tv[0], NULL); +#endif + + /* clear exception */ + CORBA_exception_free(orbit_get_environment()); + + p_operation = InterfaceType_FindOperation(pObject->mpInterface, pFunctionName); + + if (p_operation == NULL) + { + /* no such operation */ + zend_error(E_ERROR, "(Satellite) unknown operation name '%s' in interface '%s'", + pFunctionName, pObject->mCorbaObject->type_id); + goto error; + } + + p_exception_list = OperationType_GetExceptionList(p_operation); + + /* XXX: it's ok if this returns NULL, because the operation may be void! */ + p_result = OrbitObject_PrepareResult(pObject, p_operation); + + /* create the request */ + CORBA_Object_create_request2( + pObject->mCorbaObject, /* object */ + NULL, /* context */ + OperationType_GetName(p_operation), /* name */ + NULL, /* arg_list */ + p_result, /* result */ + p_exception_list, /* user exception list */ + &request, /* request */ + CORBA_OUT_LIST_MEMORY, /* flags */ + orbit_get_environment() /* environment */ + ); + + /* check for exception */ + if (orbit_caught_exception()) + goto error; + + /* add parameters */ + pp_arguments = satellite_new_n(CORBA_NamedValue*, parameterCount); + success = OrbitObject_AddArguments(pObject, + request, p_operation, parameterCount, ppParameters, pp_arguments); + + if (!success) + { + /* bad arguments */ + goto error; + } + +#if PROFILE + gettimeofday(&tv[1], NULL); +#endif + + /* send request and get response */ + CORBA_Request_invoke(request, 0, orbit_get_environment()); + +#if PROFILE + gettimeofday(&tv[2], NULL); +#endif + + if (orbit_caught_exception()) + goto error; + + /* release arguments */ + success = OrbitObject_ReleaseArguments(pObject, + request, p_operation, parameterCount, ppParameters, pp_arguments); + if (!success) + goto error; + + /* take care of return value */ + if (p_result != NULL) + { + orbit_namedvalue_to_zval(p_result, pReturnValue); + } + +#if PROFILE + gettimeofday(&tv[3], NULL); + printf("%s\n", OperationType_GetName(p_operation)); + for(i = 0; i < 4; i++) + printf("%i:%i\n", tv[i].tv_sec, tv[i].tv_usec); +#endif + + success = TRUE; + goto exit; + +error: + /* TODO: all errors above should set exceptions! */ + success = FALSE; + +exit: + CORBA_Object_release((CORBA_Object)request, orbit_get_environment()); + satellite_release_namedvalue(p_result); + satellite_release_namedvalue_list(pp_arguments, parameterCount); + orbit_delete(p_operation); + TypeCodeList_release(p_exception_list); + + return success; +} + +#define GET_PREFIX "_get_" +#define SET_PREFIX "_set_" +#define GET_PREFIX_LENGTH (sizeof(GET_PREFIX)-1) +#define SET_PREFIX_LENGTH (sizeof(SET_PREFIX)-1) + + +/* + * add an argument to a function call + */ +static zend_bool OrbitObject_AddAttributeArgument(OrbitObject * pObject, + CORBA_Request request, AttributeType * pAttribute, const zval * pSource) +{ + CORBA_NamedValue destination; + memset(&destination, 0, sizeof(CORBA_NamedValue)); + + destination.argument._type = AttributeType_GetType(pAttribute); + destination.arg_modes = CORBA_ARG_IN; + + if (!orbit_zval_to_namedvalue(pSource, &destination)) + return FALSE; + + /* add parameter to request */ + CORBA_Request_add_arg( + request, /* request */ + NULL, /* arg_name */ + destination.argument._type, /* type */ + destination.argument._value, /* value */ + destination.len, /* length */ + destination.arg_modes, /* flags */ + orbit_get_environment() + ); + + if (orbit_caught_exception()) + return FALSE; + + return TRUE; +} + + + +/* + * set a php property, or rather a corba attribute + */ +zend_bool OrbitObject_PutProperty(OrbitObject * pObject, + const char * pPropertyName, const zval * pValue) +{ + zend_bool success; + char * p_name = NULL; + CORBA_Request request = NULL; + AttributeType * p_attribute = NULL; + + /* clear exception */ + CORBA_exception_free(orbit_get_environment()); + + /* find attribute type */ + p_attribute = InterfaceType_FindAttribute(pObject->mpInterface, pPropertyName); + + if (p_attribute == NULL) + { + /*printf("InterfaceType_FindAttribute failed for property %s\n", pPropertyName);*/ + /* no such atttribute */ + zend_error(E_ERROR, "(Satellite) unknown attribute name '%s' in interface '%s'", + pPropertyName, pObject->mCorbaObject->type_id); + goto OrbitObject_PutProperty_error; + } + + if (AttributeType_IsReadonly(p_attribute)) + { + /* can't set a readonly attribute! */ + goto OrbitObject_PutProperty_error; + } + + /* create operation name */ + p_name = orbit_new_n(char, strlen(pPropertyName) + SET_PREFIX_LENGTH + 1); + strcpy(p_name, SET_PREFIX); + strcat(p_name, AttributeType_GetName(p_attribute)); + + /* create the request */ + CORBA_Object_create_request( + pObject->mCorbaObject, /* object */ + NULL, /* context */ + p_name, /* name */ + NULL, /* arg_list */ + NULL, /* result */ + &request, /* request */ + CORBA_OUT_LIST_MEMORY, /* flags */ + orbit_get_environment() /* environment */ + ); + + /* check for exception */ + if (orbit_caught_exception()) + goto OrbitObject_PutProperty_error; + + if (request == NULL) + goto OrbitObject_PutProperty_error; + + success = OrbitObject_AddAttributeArgument( + pObject, request, p_attribute, pValue); + + if (!success) + goto OrbitObject_PutProperty_error; + + /* send request and get response */ + CORBA_Request_invoke(request, 0, orbit_get_environment()); + + if (orbit_caught_exception()) + goto OrbitObject_PutProperty_error; + + success = TRUE; + goto OrbitObject_PutProperty_exit; + +OrbitObject_PutProperty_error: + /* TODO: all errors above should set exceptions! */ + success = FALSE; + +OrbitObject_PutProperty_exit: + CORBA_Object_release((CORBA_Object)request, orbit_get_environment()); + orbit_delete(p_attribute); + orbit_delete(p_name); + + return success; +} + +/* + * prepare a function call result + */ +static CORBA_NamedValue * OrbitObject_PrepareAttributeResult(OrbitObject * pObject, + AttributeType * pAttribute) +{ + CORBA_NamedValue * p_result = orbit_new(CORBA_NamedValue); + + p_result->argument._type = AttributeType_GetType(pAttribute); + + if (p_result->argument._type == NULL) + { +/* printf("AttributeType_GetType failed for attribute %s\n", + AttributeType_GetName(pAttribute));*/ + orbit_delete(p_result); + p_result = NULL; + } + else + { + orbit_zval_to_namedvalue(NULL, p_result); + } + + return p_result; +} + + +/* + * get a php property, equal to a corba attribute + */ +zend_bool OrbitObject_GetProperty(OrbitObject * pObject, + const char * pPropertyName, zval * pReturnValue) +{ + zend_bool success; + char * p_name = NULL; + CORBA_Request request = NULL; + AttributeType * p_attribute = NULL; + CORBA_NamedValue * p_result = NULL; + +#if PROFILE + int i; + struct timeval tv[4]; + gettimeofday(&tv[0], NULL); +#endif + + /* clear exception */ + CORBA_exception_free(orbit_get_environment()); + + /* find attribute type */ + p_attribute = InterfaceType_FindAttribute(pObject->mpInterface, pPropertyName); + + if (p_attribute == NULL) + { + /*printf("InterfaceType_FindAttribute failed for property %s\n", pPropertyName);*/ + /* no such atttribute */ + zend_error(E_ERROR, "(Satellite) unknown attribute name '%s' in interface '%s'", + pPropertyName, pObject->mCorbaObject->type_id); + goto OrbitObject_GetProperty_error; + } + + /* prepare result */ + p_result = OrbitObject_PrepareAttributeResult(pObject, p_attribute); + + if (p_result == NULL) + { + /* probably bad return type */ + goto OrbitObject_GetProperty_error; + } + + /* create operation name */ + p_name = orbit_new_n(char, strlen(pPropertyName) + GET_PREFIX_LENGTH + 1); + strcpy(p_name, GET_PREFIX); + strcat(p_name, AttributeType_GetName(p_attribute)); + + /* create the request */ + CORBA_Object_create_request( + pObject->mCorbaObject, /* object */ + NULL, /* context */ + p_name, /* name */ + NULL, /* arg_list */ + p_result, /* result */ + &request, /* request */ + CORBA_OUT_LIST_MEMORY, /* flags */ + orbit_get_environment() /* environment */ + ); + + /* check for exception */ + if (orbit_caught_exception()) + goto OrbitObject_GetProperty_error; + + if (request == NULL) + goto OrbitObject_GetProperty_error; + +#if PROFILE + gettimeofday(&tv[1], NULL); +#endif + + /* send request and get response */ + CORBA_Request_invoke(request, 0, orbit_get_environment()); + +#if PROFILE + gettimeofday(&tv[2], NULL); +#endif + + if (orbit_caught_exception()) + goto OrbitObject_GetProperty_error; + + /* take care of return value */ + orbit_namedvalue_to_zval(p_result, pReturnValue); + +#if 0 /* PROFILE */ + gettimeofday(&tv[3], NULL); + printf("%s\n", p_name); + for(i = 0; i < 4; i++) + printf("%i:%i\n", tv[i].tv_sec, tv[i].tv_usec); +#endif + + success = TRUE; + goto OrbitObject_GetProperty_exit; + +OrbitObject_GetProperty_error: + /* TODO: all errors above should set exceptions! */ + success = FALSE; + +OrbitObject_GetProperty_exit: + CORBA_Object_release((CORBA_Object)request, orbit_get_environment()); + orbit_delete(p_attribute); + orbit_delete(p_name); + satellite_release_namedvalue(p_result); + + return success; +} + diff --git a/ext/satellite/object.h b/ext/satellite/object.h new file mode 100644 index 0000000000..c1fdba998b --- /dev/null +++ b/ext/satellite/object.h @@ -0,0 +1,37 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +#ifndef __orbit_object_h__ +#define __orbit_object_h__ + +#include +#include "class.h" + +DECLARE_CLASS(OrbitObject); + +CORBA_Object OrbitObject_GetCorbaObject(OrbitObject * pObject); +zend_bool OrbitObject_Create(CORBA_Object source, zval * pDestination); + + +#endif /* __orbit_object_h__ */ + diff --git a/ext/satellite/php_orbit.c b/ext/satellite/php_orbit.c new file mode 100644 index 0000000000..098f0d219d --- /dev/null +++ b/ext/satellite/php_orbit.c @@ -0,0 +1,199 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* + * Interface to PHP + */ +#include +#include /* for DISPLAY_INI_ENTRIES() */ +#include /* for php_info_print_table_*() */ +#include "php_orbit.h" +#include "corba.h" +#include "typemanager.h" +#include "namedvalue_to_zval.h" + +/* classes */ +#include "enum.h" +#include "object.h" +#include "struct.h" + + +#ifdef HAVE_CONFIG_H +#include "php_config.h" /* for COMPILE_DL_ORBIT */ +#endif + +/* see php4/README.SELF-CONTAINED-EXTENSIONS */ +#if COMPILE_DL_SATELLITE +ZEND_GET_MODULE(satellite) +#endif + +PHP_MINFO_FUNCTION(satellite); + +PHP_INI_BEGIN() + PHP_INI_ENTRY1("idl_directory", NULL, 0, NULL, NULL) +PHP_INI_END() + +/* + * functions in module + */ +static function_entry satellite_functions[] = +{ + PHP_FE(satellite_load_idl, NULL) + PHP_FE(satellite_get_repository_id, NULL) + PHP_FE(satellite_caught_exception, NULL) + PHP_FE(satellite_exception_id, NULL) + PHP_FE(satellite_exception_value, NULL) + + /* support the old prefix orbit_ */ + PHP_FALIAS(orbit_load_idl, satellite_load_idl, NULL) + PHP_FALIAS(orbit_get_repository_id, satellite_get_repository_id, NULL) + PHP_FALIAS(orbit_caught_exception, satellite_caught_exception, NULL) + PHP_FALIAS(orbit_exception_id, satellite_exception_id, NULL) + PHP_FALIAS(orbit_exception_value, satellite_exception_value, NULL) + + {NULL, NULL, NULL} +}; + + +/* + * module entry + */ +zend_module_entry satellite_module_entry = { + "satellite", + satellite_functions, + PHP_MINIT(satellite), /* module startup */ + PHP_MSHUTDOWN(satellite), /* module shutdown */ + NULL, /* request startup */ + NULL, /* request shutdown */ + PHP_MINFO(satellite), /* module info */ + STANDARD_MODULE_PROPERTIES +}; + +/* + * module initialization + */ +PHP_MINIT_FUNCTION(satellite) +{ + zend_bool success; + + REGISTER_INI_ENTRIES(); + + success = + orbit_corba_init() && + TypeManager_Init(INI_STR("idl_directory")) && + OrbitEnum_Init(module_number) && + OrbitObject_Init(module_number) && + OrbitStruct_Init(module_number); + + return success ? SUCCESS : FAILURE; +} + +/* + * shutdown module! +*/ +PHP_MSHUTDOWN_FUNCTION(satellite) +{ + TypeManager_Shutdown(); + orbit_corba_shutdown(); + + UNREGISTER_INI_ENTRIES(); + + return SUCCESS; +} + +/* + * some function + */ +PHP_MINFO_FUNCTION(satellite) +{ + + php_info_print_table_start(); + php_info_print_table_header(2, "CORBA support via Satellite", "enabled"); + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); +} + +/* instruct the type manager to load an IDL file if not already loaded */ +PHP_FUNCTION(satellite_load_idl) +{ + zval * p_parameter; + + if (ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + RETURN_NULL(); + } + + getParameters(ht, 1, &p_parameter); + + if (p_parameter->type != IS_STRING) + { + RETURN_NULL(); + } + + RETURN_BOOL(TypeManager_LoadFile(p_parameter->value.str.val)); +} + +/* + * NOT IMPLEMENTED + * + * get the repository id for an Orbit* object (nice for debugging...) + */ +PHP_FUNCTION(satellite_get_repository_id) +{ +} + +PHP_FUNCTION(satellite_caught_exception) +{ + RETURN_BOOL(orbit_caught_exception()); +} + +PHP_FUNCTION(satellite_exception_id) +{ + CORBA_char * p_id = CORBA_exception_id(orbit_get_environment()); + + RETURN_STRING(p_id, TRUE); +} + +/* real name: php_if_orbit_exception_value */ +PHP_FUNCTION(satellite_exception_value) +{ + CORBA_NamedValue source; + ExceptionType * p_exception = NULL; + + memset(&source, 0, sizeof(CORBA_NamedValue)); + + /* get exception type info */ + p_exception = TypeManager_FindException( + CORBA_exception_id(orbit_get_environment())); + + /* get exception typecode */ + source.argument._type = ExceptionType_GetTypeCode(p_exception); + /* get exception value */ + source.argument._value = CORBA_exception_value(orbit_get_environment()); + + /* create structure with exception data */ + orbit_namedvalue_to_zval(&source, return_value); +} + diff --git a/ext/satellite/php_orbit.h b/ext/satellite/php_orbit.h new file mode 100644 index 0000000000..d4561d907c --- /dev/null +++ b/ext/satellite/php_orbit.h @@ -0,0 +1,42 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +#ifndef _PHP_ORBIT_H +#define _PHP_ORBIT_H + +extern PHP_MINIT_FUNCTION(satellite); +extern PHP_MSHUTDOWN_FUNCTION(satellite); +extern zend_module_entry satellite_module_entry; + +#define satellite_module_ptr &satellite_module_entry +#define phpext_satellite_ptr satellite_module_ptr + +extern PHP_FUNCTION(satellite_load_idl); +extern PHP_FUNCTION(satellite_get_repository_id); + +/* exception handling */ +extern PHP_FUNCTION(satellite_caught_exception); +extern PHP_FUNCTION(satellite_exception_id); +extern PHP_FUNCTION(satellite_exception_value); + +#endif /* _PHP_ORBIT_H */ 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $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; + } +} + diff --git a/ext/satellite/struct.h b/ext/satellite/struct.h new file mode 100644 index 0000000000..2025a132c7 --- /dev/null +++ b/ext/satellite/struct.h @@ -0,0 +1,35 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +#ifndef __struct_h__ +#define __struct_h__ + +#include "class.h" + +DECLARE_CLASS(OrbitStruct); + +char * OrbitStruct_GetRepositoryId(OrbitStruct * pStruct); +zend_bool OrbitStruct_Create(const char * pId, zval * pDestination); + + +#endif /* __struct_h__ */ diff --git a/ext/satellite/typecode.c b/ext/satellite/typecode.c new file mode 100644 index 0000000000..1075dbbd84 --- /dev/null +++ b/ext/satellite/typecode.c @@ -0,0 +1,437 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * functions to convert IDL_tree info to CORBA_TypeCodes + * + * ought to be cleaned up... + * + * ----------------------------------------------------------------------- + */ +#include "corba.h" +#include "common.h" +#include "findtype.h" +#include "typecode.h" + +void satellite_release_typecode(CORBA_TypeCode typecode) +{ + CORBA_Object_release((CORBA_Object)typecode, orbit_get_environment()); +} + +static CORBA_TypeCode orbit_idl_tree_type_to_typecode_enum(IDL_tree type) +{ + CORBA_TypeCode type_code; + CORBA_EnumMemberSeq * p_members = NULL; + + p_members = CORBA_EnumMemberSeq__alloc(); + p_members->_maximum = p_members->_length = 1; + p_members->_buffer = CORBA_sequence_CORBA_Identifier_allocbuf(p_members->_length); + + p_members->_buffer[0] = "dummy"; + + /* + * TODO: initialize p_members with members... + * look at orbit_idl_tree_type_to_typecode_struct + */ + + type_code = CORBA_ORB_create_enum_tc( + orbit_get_orb(), + IDL_IDENT(IDL_TYPE_ENUM(type).ident).repo_id, + IDL_IDENT(IDL_TYPE_ENUM(type).ident).str, + p_members, + orbit_get_environment()); + + if (orbit_error_test("CORBA_ORB_create_enum_tc")) + { + goto error; + } + + if (type_code == NULL) + { +/* printf("unable to create enum typecode for type %s\n", + IDL_IDENT(IDL_TYPE_ENUM(type).ident).str);*/ + } + + goto exit; + +error: + type_code = NULL; + +exit: + CORBA_free(p_members); + return type_code; +} + +/* + * create a member sequence for a struct or exception + */ +static CORBA_StructMemberSeq * orbit_create_member_sequence(IDL_tree member_list) +{ + int i = 0; + CORBA_StructMemberSeq * p_members = NULL; + IDL_tree first_member = member_list; + + p_members = CORBA_sequence_CORBA_StructMember__alloc(); + /* this is initially set to false, why? */ + p_members->_release = CORBA_TRUE; + + /* ok with empty list */ + if (member_list == NULL) + return p_members; + + /* first iteration, find out member count */ + do + { + IDL_tree declaration = IDL_MEMBER(IDL_LIST(member_list).data).dcls; + if (declaration == NULL) /* very unlikely! */ + continue; + + do + { + p_members->_length++; + } while ((declaration = IDL_LIST(declaration).next)); + } while ((member_list = IDL_LIST(member_list).next)); + + p_members->_maximum = p_members->_length; + p_members->_buffer = + CORBA_sequence_CORBA_StructMember_allocbuf(p_members->_length); + + /* second iteration, set member data */ + member_list = first_member; + do + { + IDL_tree declaration = IDL_MEMBER(IDL_LIST(member_list).data).dcls; + CORBA_TypeCode type_code = NULL; + + if (declaration == NULL) /* very unlikely! */ + continue; + + type_code = orbit_idl_tree_type_to_typecode( + IDL_MEMBER(IDL_LIST(member_list).data).type_spec); + + if (type_code == NULL) + { +/* printf("unknown type for member %s\n", + IDL_IDENT(IDL_LIST(declaration).data).str);*/ + goto error; + } + + do + { + char * p_name = IDL_IDENT(IDL_LIST(declaration).data).str; + + p_members->_buffer[i].name = CORBA_string_dup(p_name); + p_members->_buffer[i].type = (CORBA_TypeCode) + CORBA_Object_duplicate((CORBA_Object)type_code, orbit_get_environment()); + p_members->_buffer[i].type_def = NULL; /* XXX */ + + i++; + } while ((declaration = IDL_LIST(declaration).next)); + + satellite_release_typecode(type_code); + + } while ((member_list = IDL_LIST(member_list).next)); + + goto exit; + +error: + /* TODO: error clean up */ + CORBA_free(p_members); + p_members = NULL; + +exit: + return p_members; +} + +/* + * create a CORBA_TypeCode for a struct + */ +static CORBA_TypeCode orbit_idl_tree_type_to_typecode_struct(IDL_tree type) +{ + CORBA_TypeCode type_code = NULL; + CORBA_StructMemberSeq * p_members = NULL; + +#if 0 + if (IDL_TYPE_STRUCT(type).member_list == NULL) + { + printf("no struct members\n"); + goto error; + } +#endif + + p_members = orbit_create_member_sequence(IDL_TYPE_STRUCT(type).member_list); + if (p_members == NULL) + goto error; + + type_code = CORBA_ORB_create_struct_tc( + orbit_get_orb(), + IDL_IDENT(IDL_TYPE_STRUCT(type).ident).repo_id, + IDL_IDENT(IDL_TYPE_STRUCT(type).ident).str, + p_members, + orbit_get_environment()); + + if (type_code == NULL) + goto error; + + goto exit; + +error: + satellite_release_typecode(type_code); + +exit: + CORBA_free(p_members); + return type_code; +} + + +static CORBA_TypeCode orbit_idl_tree_type_to_typecode_float(IDL_tree type) +{ + enum IDL_float_type float_type = IDL_TYPE_FLOAT(type).f_type; + + switch (float_type) + { + case IDL_FLOAT_TYPE_DOUBLE: return TC_CORBA_double; + + default: + /* php_error(E_WARNING, "only double floats supported at the moment at the moment");*/ + return NULL; + } +} + + +static CORBA_TypeCode orbit_idl_tree_type_to_typecode_integer(IDL_tree type) +{ + enum IDL_integer_type integer_type = IDL_TYPE_INTEGER(type).f_type; + + switch (integer_type) + { + case IDL_INTEGER_TYPE_SHORT: return TC_CORBA_short; + case IDL_INTEGER_TYPE_LONG: return TC_CORBA_long; + + default: +/* php_error(E_WARNING, "unsupported integer type %i", integer_type);*/ + return NULL; + } +} + +static CORBA_TypeCode orbit_idl_tree_type_to_typecode_sequence(IDL_tree type) +{ + CORBA_TypeCode simple_typecode = orbit_idl_tree_type_to_typecode( + IDL_TYPE_SEQUENCE(type).simple_type_spec); + + CORBA_TypeCode typecode = CORBA_ORB_create_sequence_tc( + orbit_get_orb(), + 0, /* bound */ + simple_typecode, + orbit_get_environment() ); + +#if 0 + if (typecode != NULL) + { + typecode->parent.interface = 0; + typecode->parent.refs = ORBIT_REFCNT_STATIC; /* correct? */ + } +#endif + + satellite_release_typecode(simple_typecode); + + return typecode; +} + +/* + * get real type when we have an object/structure/union/enum ident + */ +static CORBA_TypeCode orbit_idl_tree_type_to_typecode_ident(IDL_tree type) +{ + IDL_tree real_type = NULL; + IDL_tree whole_tree = type; + + /* go back to to top of tree (ugly code of the day!) */ + while (whole_tree->up) + whole_tree = whole_tree->up; + + /* find the real type! */ + real_type = orbit_find_type_simple(whole_tree, IDL_IDENT_REPO_ID(type)); + + /* check return value */ + if (real_type == NULL) + { +/* php_error(E_WARNING, + "unknown repository id %s", + IDL_IDENT_REPO_ID(type));*/ + return FALSE; + } + + /* call our generic function again... (hehehe) */ + return orbit_idl_tree_type_to_typecode(real_type); +} + +/* + * make exception typecode + */ +static CORBA_TypeCode orbit_idl_tree_type_to_typecode_exception(IDL_tree type) +{ + CORBA_TypeCode type_code = NULL; + CORBA_StructMemberSeq * p_members = NULL; + +#if 0 + if (IDL_EXCEPT_DCL(type).members == NULL) + { + printf("no members\n"); + goto error; + } +#endif + + p_members = orbit_create_member_sequence(IDL_EXCEPT_DCL(type).members); + if (p_members == NULL) + goto error; + + type_code = CORBA_ORB_create_exception_tc( + orbit_get_orb(), + IDL_IDENT(IDL_EXCEPT_DCL(type).ident).repo_id, + IDL_IDENT(IDL_EXCEPT_DCL(type).ident).str, + p_members, + orbit_get_environment()); + + goto exit; + +error: + satellite_release_typecode(type_code); + +exit: + CORBA_free(p_members); + return type_code; + +} + +static CORBA_TypeCode orbit_idl_tree_type_to_typecode_interface(IDL_tree type) +{ + CORBA_TypeCode typecode = CORBA_ORB_create_interface_tc( + orbit_get_orb(), + IDL_IDENT(IDL_INTERFACE(type).ident).repo_id, + IDL_IDENT(IDL_INTERFACE(type).ident).str, + orbit_get_environment()); + +#if 0 + if (typecode != NULL) + { + typecode->parent.interface = 0; + typecode->parent.refs = ORBIT_REFCNT_STATIC; /* correct? */ + } +#endif + + return typecode; +} + +static CORBA_TypeCode orbit_idl_tree_type_to_typecode_string(IDL_tree type) +{ + CORBA_TypeCode typecode = CORBA_ORB_create_string_tc( + orbit_get_orb(), + 0, /* bound */ + orbit_get_environment()); + +#if 0 + if (typecode != NULL) + { + typecode->parent.interface = 0; + typecode->parent.refs = ORBIT_REFCNT_STATIC; /* correct? */ + } +#endif + + return typecode; +} + +/* + * get a CORBA_TypeCode from a IDL_tree node type + */ +CORBA_TypeCode orbit_idl_tree_type_to_typecode(IDL_tree type) +{ + CORBA_TypeCode type_code = NULL; + + if (type == NULL) + { + /* not good! */ + return FALSE; + } + + switch (IDL_NODE_TYPE(type)) + { + case IDLN_EXCEPT_DCL: + type_code = orbit_idl_tree_type_to_typecode_exception(type); + break; + + case IDLN_IDENT: + type_code = orbit_idl_tree_type_to_typecode_ident(type); + break; + + case IDLN_INTERFACE: + /*type_code = TC_CORBA_Object; */ + type_code = orbit_idl_tree_type_to_typecode_interface(type); + break; + + case IDLN_TYPE_BOOLEAN: + type_code = TC_CORBA_boolean; + break; + + case IDLN_TYPE_DCL: + type_code = + orbit_idl_tree_type_to_typecode(IDL_TYPE_DCL(type).type_spec); + break; + + case IDLN_TYPE_ENUM: + type_code = orbit_idl_tree_type_to_typecode_enum(type); + break; + + case IDLN_TYPE_FLOAT: + type_code = orbit_idl_tree_type_to_typecode_float(type); + break; + + case IDLN_TYPE_INTEGER: + type_code = orbit_idl_tree_type_to_typecode_integer(type); + break; + + case IDLN_TYPE_SEQUENCE: + type_code = orbit_idl_tree_type_to_typecode_sequence(type); + break; + + case IDLN_TYPE_STRING: + /*type_code = TC_CORBA_string; */ + type_code = orbit_idl_tree_type_to_typecode_string(type); + break; + + case IDLN_TYPE_STRUCT: + type_code = orbit_idl_tree_type_to_typecode_struct(type); + break; + + /* TODO: handle more types */ + + default: +/* printf("orbit_idl_tree_type_to_typecode can't handle type %s\n", + IDL_NODE_TYPE_NAME(type));*/ + } + + return type_code; +} + + diff --git a/ext/satellite/typecode.h b/ext/satellite/typecode.h new file mode 100644 index 0000000000..a191e8176c --- /dev/null +++ b/ext/satellite/typecode.h @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +#ifndef __typecode_h__ +#define __typecode_h__ + +#include +#include +CORBA_TypeCode orbit_idl_tree_type_to_typecode(IDL_tree type); + +void satellite_release_typecode(CORBA_TypeCode typecode); + +#endif /* __typecode_h__ */ + diff --git a/ext/satellite/typemanager.c b/ext/satellite/typemanager.c new file mode 100644 index 0000000000..454fd1e5c8 --- /dev/null +++ b/ext/satellite/typemanager.c @@ -0,0 +1,552 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* + * Type manager + */ +#include +#include +#include "common.h" +#include "typemanager.h" +#include "typecode.h" +#include "findtype.h" +#include + +struct _TypeManager +{ +/* IDL_ns mNamespace;*/ + IDL_tree mRoot; +}; + +static TypeManager gTypeManager; + +struct _InterfaceType +{ + IdlInfo mIdlInfo; +}; + +struct _StructType +{ + IdlInfo mIdlInfo; +}; + +struct _EnumType +{ + IdlInfo mIdlInfo; +}; + +struct _ExceptionType +{ + IdlInfo mIdlInfo; +}; + +struct _OperationType +{ + IdlInfo mIdlInfo; +}; + +struct _AttributeType +{ + IdlInfo mIdlInfo; +}; + +struct _MemberType +{ + IDL_tree mOuterList; + IDL_tree mInnerList; +}; + +struct _ParameterType +{ + IDL_tree mList; +}; + +struct _EnumMemberType +{ + IDL_tree mList; +}; + +#define PATTERN "/*.idl" +#define PATTERN_LENGTH (sizeof(PATTERN)-1) + +CORBA_boolean TypeManager_Init(const char * pIdlDirectory) +{ + if (pIdlDirectory != NULL) + { + glob_t result; + char * p_pattern = + orbit_new_n(char, strlen(pIdlDirectory) + PATTERN_LENGTH + 1); + strcpy(p_pattern, pIdlDirectory); + strcat(p_pattern, PATTERN); + + if (glob(p_pattern, 0, NULL, &result) == 0) + { + /* success... */ + int i; + for (i = 0; i < result.gl_pathc; i++) + { + TypeManager_LoadFile(result.gl_pathv[i]); + } + + globfree(&result); + } + + orbit_delete(p_pattern); + } + + return TRUE; +} + +CORBA_boolean TypeManager_Shutdown() +{ + IDL_tree_free(gTypeManager.mRoot); + return TRUE; +} + +CORBA_boolean TypeManager_LoadFile(const char * pFilename) +{ + int x; + IDL_tree root; + IDL_ns namespace; + IDL_tree list; + + x = IDL_parse_filename( + pFilename, + "", + NULL, + &root, &namespace, + IDLF_TYPECODES|IDLF_CODEFRAGS, + IDL_WARNING1); + + if(IDL_SUCCESS != x) + { +/* php_error(E_WARNING, "IDL_parse_filename returned %i");*/ + return FALSE; + } + + list = IDL_list_new(root); + + if (gTypeManager.mRoot == NULL) + gTypeManager.mRoot = list; + else + IDL_list_concat(gTypeManager.mRoot,list); + + /* get rid of this immediatly? */ + IDL_ns_free(namespace); + + return TRUE; +} + + +/* type manager functions */ +InterfaceType * TypeManager_FindInterface(/*TypeManager * pTypeManager, */ + const char * pRepositoryId) +{ + InterfaceType * pInterface = orbit_new(InterfaceType); + CORBA_boolean success = orbit_find_type( + gTypeManager.mRoot, pRepositoryId, IDLN_INTERFACE, &pInterface->mIdlInfo); + + if (!success) + { + orbit_delete(pInterface); + return NULL; + } + + return pInterface; +} + +StructType * TypeManager_FindStruct(/*TypeManager * pTypeManager, */ + const char * pRepositoryId) +{ + StructType * pStruct = orbit_new(StructType); + CORBA_boolean success = orbit_find_type( + gTypeManager.mRoot, pRepositoryId, IDLN_TYPE_STRUCT, &pStruct->mIdlInfo); + + if (!success) + { + orbit_delete(pStruct); + pStruct = NULL; + } + + return pStruct; +} + +EnumType * TypeManager_FindEnum(/*TypeManager * pTypeManager, */ + const char * pRepositoryId) +{ + EnumType * pEnum = orbit_new(EnumType); + CORBA_boolean success = orbit_find_type( + gTypeManager.mRoot, pRepositoryId, IDLN_TYPE_ENUM, &pEnum->mIdlInfo); + if (!success) + { + orbit_delete(pEnum); + pEnum = NULL; + } + return pEnum; +} + +ExceptionType * TypeManager_FindException(/*TypeManager * pTypeManager, */ + const char * pRepositoryId) +{ + ExceptionType * pException = orbit_new(ExceptionType); + CORBA_boolean success = orbit_find_type( + gTypeManager.mRoot, pRepositoryId, IDLN_EXCEPT_DCL, &pException->mIdlInfo); + if (!success) + { + orbit_delete(pException); + pException = NULL; + } + return pException; +} + +/* find an operation in an interface based on case-insensitive name */ +OperationType * InterfaceType_FindOperation(InterfaceType * pInterface, + const char * name) +{ + OperationType * pOperation = orbit_new(OperationType); + CORBA_boolean success = orbit_find_type( + pInterface->mIdlInfo.mType, name, IDLN_OP_DCL, &pOperation->mIdlInfo); + if (!success) + { + orbit_delete(pOperation); + pOperation = NULL; + } + return pOperation; +} + +/* find an attribute in an interface based on case-insensitive name */ +AttributeType * InterfaceType_FindAttribute(InterfaceType * pInterface, + const char * name) +{ + AttributeType * pAttribute = orbit_new(AttributeType); + CORBA_boolean success = orbit_find_type( + pInterface->mIdlInfo.mType, name, IDLN_ATTR_DCL, &pAttribute->mIdlInfo); + if (!success) + { + orbit_delete(pAttribute); + pAttribute = NULL; + } + return pAttribute; +} + +/* return type */ +CORBA_TypeCode OperationType_GetReturnType(OperationType * pOperation) +{ + return orbit_idl_tree_type_to_typecode( + IDL_OP_DCL(pOperation->mIdlInfo.mType).op_type_spec); +} + +/* walk parameter list */ +ParameterType * OperationType_GetFirstParameter(OperationType * pOperation) +{ + ParameterType * pParameter = orbit_new(ParameterType); + pParameter->mList = + IDL_OP_DCL(pOperation->mIdlInfo.mType).parameter_dcls; + return pParameter; +} + +char * OperationType_GetName(OperationType * pOperation) +{ + if (pOperation && pOperation->mIdlInfo.mIdent) + return IDL_IDENT(pOperation->mIdlInfo.mIdent).str; + else + return NULL; +} + +void TypeCodeList_release(CORBA_TypeCode * p_typecodes) +{ + CORBA_TypeCode * p_item = p_typecodes; + + if (p_typecodes == NULL) + return; + + /* delete each typecode */ + while (*p_item) + { + satellite_release_typecode(*p_item); + p_item++; + } + + satellite_delete(p_typecodes); +} + +/* + * the caller is responsible for calling TypeCodeList_release() + * on the return value! + */ +CORBA_TypeCode * OperationType_GetExceptionList(OperationType * pOperation) +{ + int i; + IDL_tree exception_list = IDL_OP_DCL(pOperation->mIdlInfo.mType).raises_expr; + CORBA_TypeCode * p_typecodes = NULL; + + p_typecodes = orbit_new_n(CORBA_TypeCode, + IDL_list_length(exception_list) + 1); + + /* the list data is of type IDL_IDENT */ + for (i = 0; exception_list != NULL; i++) + { + /* get typecode for exception */ + p_typecodes[i] = + orbit_idl_tree_type_to_typecode(IDL_LIST(exception_list).data); + + exception_list = IDL_LIST(exception_list).next; + } + + /* set typecode for last element */ + p_typecodes[i] = CORBA_OBJECT_NIL; + + return p_typecodes; + +#if 0 +error: + TypeCodeList_release(p_typecodes); + return NULL; +#endif +} + + + +CORBA_boolean ParameterType_GetNext(ParameterType * pParameter) +{ + if (ParameterType_IsValid(pParameter)) + { + pParameter->mList = IDL_LIST(pParameter->mList).next; + return pParameter->mList != NULL; + } + else + return FALSE; +} + +CORBA_boolean ParameterType_IsValid(ParameterType * pParameter) +{ + return pParameter && pParameter->mList; +} + +/* get typecode for parameter */ +CORBA_TypeCode ParameterType_GetType(ParameterType * pParameter) +{ + return orbit_idl_tree_type_to_typecode( + IDL_PARAM_DCL(IDL_LIST(pParameter->mList).data).param_type_spec); +} + +/* return CORBA_ARG_IN, CORBA_ARG_OUT or CORBA_ARG_INOUT */ +int ParameterType_GetPassingMode(ParameterType * pParameter) +{ + int flags = 0; + enum IDL_param_attr attr; + + if (pParameter == NULL || pParameter->mList == NULL) + return flags; + + attr = IDL_PARAM_DCL(IDL_LIST(pParameter->mList).data).attr; + + /* check parameter passing mode */ + switch (attr) + { + case IDL_PARAM_IN: flags = CORBA_ARG_IN; break; + case IDL_PARAM_OUT: flags = CORBA_ARG_OUT; break; + case IDL_PARAM_INOUT: flags = CORBA_ARG_INOUT; break; + default: + /* should not get here! */ + } + + return flags; + +} + +CORBA_boolean AttributeType_IsValid(AttributeType * pAttribute) +{ + return + pAttribute != NULL && + pAttribute->mIdlInfo.mType != NULL && + pAttribute->mIdlInfo.mIdent != NULL; +} + +/* is readonly? */ +CORBA_boolean AttributeType_IsReadonly(AttributeType * pAttribute) +{ + if (AttributeType_IsValid(pAttribute)) + return IDL_ATTR_DCL(pAttribute->mIdlInfo.mType).f_readonly; + else + return FALSE; +} + + +/* get typecode for attribute */ +CORBA_TypeCode AttributeType_GetType(AttributeType * pAttribute) +{ + if (AttributeType_IsValid(pAttribute)) + return orbit_idl_tree_type_to_typecode( + IDL_ATTR_DCL(pAttribute->mIdlInfo.mType).param_type_spec); + else + return NULL; +} + +/* get name of Attribute in true case */ +char * AttributeType_GetName(AttributeType * pAttribute) +{ + if (AttributeType_IsValid(pAttribute)) + return IDL_IDENT(pAttribute->mIdlInfo.mIdent).str; + else + return NULL; +} + +/* structure handling */ +MemberType * StructType_GetFirstMember(StructType * pStruct) +{ + /* very similar to ExceptionType_GetFirstMember */ + MemberType * pMember = orbit_new(MemberType); + pMember->mOuterList = + IDL_TYPE_STRUCT(pStruct->mIdlInfo.mType).member_list; + pMember->mInnerList = + IDL_MEMBER(IDL_LIST(pMember->mOuterList).data).dcls; + return pMember; +} + +char * StructType_GetRepositoryId(StructType * pStruct) +{ + return IDL_IDENT(IDL_TYPE_STRUCT(pStruct->mIdlInfo.mType).ident).repo_id; +} + +/* exception handling */ +MemberType * ExceptionType_GetFirstMember(ExceptionType * pException) +{ + /* very similar to StructType_GetFirstMember */ + MemberType * pMember = orbit_new(MemberType); + pMember->mOuterList = + IDL_EXCEPT_DCL(pException->mIdlInfo.mType).members; + pMember->mInnerList = + IDL_MEMBER(IDL_LIST(pMember->mOuterList).data).dcls; + return pMember; +} + +char * ExceptionType_GetRepositoryId(ExceptionType * pException) +{ + return IDL_IDENT(IDL_EXCEPT_DCL(pException->mIdlInfo.mType).ident).repo_id; +} + +/* get a typecode for this exception (used by orbit_exception_value) */ +CORBA_TypeCode ExceptionType_GetTypeCode(ExceptionType * pException) +{ + return orbit_idl_tree_type_to_typecode(pException->mIdlInfo.mType); +} + +/* + * Structure and exception members + */ +CORBA_boolean MemberType_IsValid(MemberType * pMember) +{ + return pMember && pMember->mOuterList && pMember->mInnerList; +} + +CORBA_boolean MemberType_GetNext(MemberType * pMember) +{ + if (pMember == NULL || pMember->mOuterList == NULL || pMember->mInnerList == NULL) + return FALSE; + + pMember->mInnerList = IDL_LIST(pMember->mInnerList).next; + + /* if we're at the end of the inner list, advance the outer list */ + if (pMember->mInnerList == NULL) + { + pMember->mOuterList = IDL_LIST(pMember->mOuterList).next; + if (pMember->mOuterList == NULL) + return FALSE; + + /* initialize inner list */ + pMember->mInnerList = + IDL_MEMBER(IDL_LIST(pMember->mOuterList).data).dcls; + } + + return TRUE; +} + +char * MemberType_GetName(MemberType * pMember) +{ + if (pMember == NULL || pMember->mInnerList == NULL) + return NULL; + else + return IDL_IDENT(IDL_LIST(pMember->mInnerList).data).str; +} + +/* for struct/exception */ +CORBA_TypeCode MemberType_GetType(MemberType * pMember); +/* not used because this is only cared for in typecode.c */ + + +/* + * Enumeration + */ + +char * EnumType_GetRepositoryId(EnumType * pEnum) +{ + return IDL_IDENT(IDL_TYPE_ENUM(pEnum->mIdlInfo.mType).ident).repo_id; +} + + +EnumMemberType * EnumType_GetFirstMember(EnumType * pEnum) +{ + if (pEnum != NULL) + { + EnumMemberType * pEnumMember = orbit_new(EnumMemberType); + + pEnumMember->mList = + IDL_TYPE_ENUM(pEnum->mIdlInfo.mType).enumerator_list; + + return pEnumMember; + } + else + return NULL; +} + +CORBA_boolean EnumMemberType_IsValid(EnumMemberType * pEnumMember) +{ + return pEnumMember && pEnumMember->mList; +} + +CORBA_boolean EnumMemberType_GetNext(EnumMemberType * pEnumMember) +{ + /* reuse object! */ + pEnumMember->mList = IDL_LIST(pEnumMember->mList).next; + + return pEnumMember->mList != NULL; +} + +char * EnumMemberType_GetName(EnumMemberType * pEnumMember) +{ + return IDL_IDENT(IDL_LIST(pEnumMember->mList).data).str; +} + + +/* release types */ +void AttributeType_release(AttributeType * pMember) { orbit_delete(pMember); } +void EnumMemberType_release(EnumMemberType * pMember) { orbit_delete(pMember); } +void ExceptionType_release(ExceptionType * pException) { orbit_delete(pException); } +void InterfaceType_release(InterfaceType * pInterface) { orbit_delete(pInterface); } +void MemberType_release(MemberType * pMember) { orbit_delete(pMember); } +void OperationType_release(OperationType * pOperation) { orbit_delete(pOperation); } +void ParameterType_release(ParameterType * pParameter) { orbit_delete(pParameter); } +void StructType_release(StructType * pStruct) { orbit_delete(pStruct); } + + diff --git a/ext/satellite/typemanager.h b/ext/satellite/typemanager.h new file mode 100644 index 0000000000..18fb9410df --- /dev/null +++ b/ext/satellite/typemanager.h @@ -0,0 +1,112 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +#ifndef __typemanager_h__ +#define __typemanager_h__ + +#include + +typedef struct _TypeManager TypeManager; +typedef struct _InterfaceType InterfaceType; +typedef struct _StructType StructType; +typedef struct _EnumType EnumType; +typedef struct _ExceptionType ExceptionType; +typedef struct _OperationType OperationType; +typedef struct _AttributeType AttributeType; +typedef struct _MemberType MemberType; +typedef struct _ParameterType ParameterType; +typedef struct _EnumMemberType EnumMemberType; + +/* type manager */ +CORBA_boolean TypeManager_Init(const char * pIdlDirectory); +CORBA_boolean TypeManager_Shutdown(); + +CORBA_boolean TypeManager_LoadFile(const char * pFilename); +InterfaceType * TypeManager_FindInterface(/*TypeManager * pTypeManager, */ + const char * pRepositoryId); +StructType * TypeManager_FindStruct(/*TypeManager * pTypeManager, */ + const char * pRepositoryId); +EnumType * TypeManager_FindEnum(/*TypeManager * pTypeManager, */ + const char * pRepositoryId); +ExceptionType * TypeManager_FindException(/*TypeManager * pTypeManager, */ + const char * pRepositoryId); + +/* interface */ +OperationType * InterfaceType_FindOperation(InterfaceType * pInterface, + const char * name); +AttributeType * InterfaceType_FindAttribute(InterfaceType * pInterface, + const char * name); + +/* operation */ +ParameterType * OperationType_GetFirstParameter(OperationType * pOperation); +CORBA_TypeCode OperationType_GetReturnType(OperationType * pOperation); +char * OperationType_GetName(OperationType * pOperation); +CORBA_TypeCode * OperationType_GetExceptionList(OperationType * pOperation); + +/* parameter */ +CORBA_boolean ParameterType_GetNext(ParameterType * pParameter); +int ParameterType_GetPassingMode(ParameterType * pParameter); +CORBA_TypeCode ParameterType_GetType(ParameterType * pParameter); +CORBA_boolean ParameterType_IsValid(ParameterType * pParameter); + +/* attribute */ +char * AttributeType_GetName(AttributeType * pAttribute); +CORBA_TypeCode AttributeType_GetType(AttributeType * pAttribute); +CORBA_boolean AttributeType_IsReadonly(AttributeType * pAttribute); +CORBA_boolean AttributeType_IsValid(AttributeType * pAttribute); + +/* struct */ +MemberType * StructType_GetFirstMember(StructType * pStruct); +char * StructType_GetRepositoryId(StructType * pStruct); + +/* exception */ +MemberType * ExceptionType_GetFirstMember(ExceptionType * pException); +char * ExceptionType_GetRepositoryId(ExceptionType * pException); +CORBA_TypeCode ExceptionType_GetTypeCode(ExceptionType * pException); + +/* member */ +CORBA_boolean MemberType_GetNext(MemberType * pMember); +char * MemberType_GetName(MemberType * pMember); +CORBA_TypeCode MemberType_GetType(MemberType * pMember); +CORBA_boolean MemberType_IsValid(MemberType * pMember); + +/* enum */ +EnumMemberType * EnumType_GetFirstMember(EnumType * pEnum); +CORBA_boolean EnumMemberType_GetNext(EnumMemberType * pEnumMember); +CORBA_boolean EnumMemberType_IsValid(EnumMemberType * pEnumMember); +char * EnumMemberType_GetName(EnumMemberType * pEnumMember); +char * EnumType_GetRepositoryId(EnumType * pEnum); + +/* release types */ +void AttributeType_release(AttributeType * pMember); +void EnumMemberType_release(EnumMemberType * pMember); +void ExceptionType_release(ExceptionType * pException); +void InterfaceType_release(InterfaceType * pInterface); +void MemberType_release(MemberType * pMember); +void OperationType_release(OperationType * pOperation); +void ParameterType_release(ParameterType * pParameter); +void StructType_release(StructType * pStruct); +void TypeCodeList_release(CORBA_TypeCode * p_typecodes); + +#endif /* __typemanager_h__ */ + diff --git a/ext/satellite/zval_to_namedvalue.c b/ext/satellite/zval_to_namedvalue.c new file mode 100644 index 0000000000..a1de33297c --- /dev/null +++ b/ext/satellite/zval_to_namedvalue.c @@ -0,0 +1,480 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +/* ----------------------------------------------------------------------- + * + * Functions to convert a zval to a CORBA_NamedValue + * + * ----------------------------------------------------------------------- + */ +#include +#include "zval_to_namedvalue.h" +#include "object.h" +#include "struct.h" +#include "common.h" +#include "corba.h" + +#include /* for ALIGN_ADDRESS() */ + +/* + * value should be a CORBA_boolean * + */ +static zend_bool satellite_zval_to_namedvalue_boolean(const zval * pSource, + CORBA_NamedValue * pDestination) +{ + CORBA_boolean * p_value = (CORBA_boolean *)pDestination->argument._value; + + pDestination->len = sizeof(CORBA_boolean); + + if (pSource == NULL) + return TRUE; + + if (pSource->type != IS_BOOL && pSource->type != IS_LONG) + return FALSE; + + *p_value = pSource->value.lval != 0; + + return TRUE; +} + + +/* + * value should be a double * + */ +static zend_bool satellite_zval_to_namedvalue_double(const zval * pSource, + CORBA_NamedValue * pDestination) +{ + CORBA_double * p_value = (CORBA_double *)pDestination->argument._value; + + pDestination->len = sizeof(CORBA_double); + + if (pSource == NULL) + return TRUE; + + /*convert_to_double(pSource);*/ + if (pSource->type != IS_DOUBLE) + return FALSE; + + *p_value = pSource->value.dval; + + return TRUE; +} + +/* + * value should be a long * + */ +static zend_bool satellite_zval_to_namedvalue_long(const zval * pSource, + CORBA_NamedValue * pDestination) +{ + CORBA_long * p_value = (CORBA_long *)pDestination->argument._value; + pDestination->len = sizeof(CORBA_long); + + if (pSource == NULL) + return TRUE; + + /*convert_to_long(pSource);*/ + if (pSource->type != IS_LONG) + return FALSE; + + *p_value = pSource->value.lval; + + return TRUE; +} + +/* + * value should be a short * + */ +static zend_bool satellite_zval_to_namedvalue_short(const zval * pSource, + CORBA_NamedValue * pDestination) +{ + CORBA_short * p_value = (CORBA_short *)pDestination->argument._value; + pDestination->len = sizeof(CORBA_short); + + if (pSource == NULL) + return TRUE; + +/* convert_to_long((zval *)pSource);*/ /* discard const */; + if (pSource->type != IS_LONG) + { +/* printf("source value type is %i in satellite_zval_to_namedvalue_short\n", pSource->type);*/ + return FALSE; + } + + *p_value = pSource->value.lval; + + return TRUE; +} + +/* + * convert an OrbitObject to a CORBA object + * + * value should just be a CORBA_Object + */ +static zend_bool satellite_zval_to_namedvalue_objref(const zval * pSource, + CORBA_NamedValue * pDestination) +{ + OrbitObject * pObject = NULL; + CORBA_Object * p_value = (CORBA_Object*)&pDestination->argument._value; + + pDestination->len = 1; + + if (pSource == NULL) + return TRUE; /* nothing else to do */ + + if (pSource->type != IS_OBJECT) + goto error; + + /* see that it's a corba object */ + if (strcmp(pSource->value.obj.ce->name, "OrbitObject") != 0) + goto error; /* bad class type */ + + pObject = OrbitObject_RetrieveData(pSource); + if (pObject == NULL) + goto error; /* unexpected error */ + + *p_value = OrbitObject_GetCorbaObject(pObject); + + /* debug */ +/* (CORBA_Object)pDestination->argument._value = OrbitObject_GetCorbaObject(pObject);*/ + + if (*p_value == NULL) + { +/* printf("NULL object in satellite_zval_to_namedvalue_objref\n");*/ + goto error; + } + +/* printf("satellite_zval_to_namedvalue_objref: %s\n", (*p_value)->type_id);*/ + + return TRUE; + +error: + return FALSE; +} + +/* + * convert a PHP array to a CORBA sequence + * + * value should be a CORBA_sequence_octet * + */ +static zend_bool satellite_zval_to_namedvalue_sequence(const zval * pSource, + CORBA_NamedValue * pDestination) +{ + CORBA_sequence_octet * p_sequence_octet = + (CORBA_sequence_octet *)pDestination->argument._value; + HashTable * p_hashtable = NULL; + int member_count = 0; + + if (pSource == NULL) + return TRUE; /* nothing to do */ + + if (pSource->type != IS_ARRAY) + goto error; /* bad source type */ + + p_hashtable = pSource->value.ht; + member_count = zend_hash_num_elements(p_hashtable); + + /* prepare sequence octet */ + ORBit_sequence_octet_init(p_sequence_octet, member_count); + + /* + * XXX: potential bug nest follows + */ + if (member_count > 0) + { + CORBA_NamedValue destination_value; + zval * p_source_value; + HashPosition position = NULL; + int i; + void ** p_members = (void **)p_sequence_octet->_buffer; + + /* prepare to start walking the hash table */ + zend_hash_internal_pointer_reset_ex(p_hashtable, &position); + + for(i = 0; i < member_count; i++) + { + if (position == NULL) + goto error; + +#if 0 + /* the function call gets messed up */ + if (zend_hash_get_current_data_ex( + p_hashtable, /* XXX */, &position) == FAILURE) + goto error; +#else + p_source_value = *(zval**)position->pData; +#endif + + memset(&destination_value, 0, sizeof(destination_value)); + + destination_value.argument._type = CORBA_TypeCode_content_type( + pDestination->argument._type, orbit_get_environment()); + + if (orbit_caught_exception()) + goto error; + + /* now get a NamedValue for this element */ + if (!orbit_zval_to_namedvalue(p_source_value, &destination_value)) + goto error; + + /* put values in our value */ + p_members[i] = *(void**)destination_value.argument._value; + + /* get next in hashtable */ + if (zend_hash_move_forward_ex(p_hashtable, &position) == FAILURE) + goto error; + } + } + +/* pDestination->argument._value = p_sequence_octet;*/ + return TRUE; + +error: + ORBit_sequence_octet_fini(p_sequence_octet); /* appropriate destruction? */ + return FALSE; +} + +/* + * convert a PHP string to a CORBA string + * + * value should be a char ** + */ +static zend_bool satellite_zval_to_namedvalue_string(const zval * pSource, + CORBA_NamedValue * pDestination) +{ + char ** p_value = (char **)pDestination->argument._value; + + if (pSource == NULL) + return TRUE; /* do nothing */ + +#if 0 + convert_to_string((zval *)pSource); /* discard const */ + if (pSource->type == IS_NULL) + return TRUE; /* do nothing */ +#endif + + if (pSource->type != IS_STRING) + goto error; + + *p_value = CORBA_string_dup(pSource->value.str.val); + pDestination->len = strlen(*p_value); + + return TRUE; + +error: + return FALSE; +} + +/* + * convert an OrbitStruct object to a CORBA structure + * + * XXX: this is trouble! + * + */ +static zend_bool satellite_zval_to_namedvalue_struct(const zval * pSource, + CORBA_NamedValue * pDestination) +{ + OrbitStruct * p_struct = NULL; + int member_count = 0; + CORBA_TypeCode type = NULL; + + pDestination->len = 1; + + /* nothing else to do if we have no source object */ + if (pSource == NULL) + return TRUE; + + /* see that it's an object */ + if (pSource->type != IS_OBJECT) + goto error; /* bad source type */ + + /* see that it's a structure object */ + if (strcmp(pSource->value.obj.ce->name, "OrbitStruct") != 0) + goto error; /* bad class type */ + + /* get struct info */ + p_struct = OrbitStruct_RetrieveData(pSource); + if (p_struct == NULL) + goto error; /* unexpected error */ + + /* make type a shortcut to the typecode */ + type = pDestination->argument._type; + + /* check respository ids */ + { + char * p_source_repository_id = OrbitStruct_GetRepositoryId(p_struct); + char * p_destination_repository_id = CORBA_TypeCode_id(type, orbit_get_environment()); + + if (orbit_caught_exception()) + goto error; + + if (strcmp(p_destination_repository_id, p_source_repository_id) != 0) + goto error; /* bad struct */ + } + + /* now we know the source and destination matches! */ + member_count = CORBA_TypeCode_member_count(type, orbit_get_environment()); + if (orbit_caught_exception()) + goto error; + + if (member_count > 0) + { + int i; + CORBA_NamedValue destination_value; + zval source_value; + zend_bool success; + char * p_buffer = (char *)pDestination->argument._value; + int element_size = 0; + + for (i = 0; i < member_count; i++) + { + int alignment; + /* get member name */ + char * p_name = + CORBA_TypeCode_member_name(type, i, orbit_get_environment()); + if (orbit_caught_exception()) + goto error; + + /* get source value */ + success = OrbitStruct_GetProperty(p_struct, p_name, &source_value); + if (!success) + { + goto error; + } + + /* prepare destination value */ + memset(&destination_value, 0, sizeof(CORBA_NamedValue)); + destination_value.argument._type = + CORBA_TypeCode_member_type(type, i, orbit_get_environment()); + if (destination_value.argument._type == NULL) + goto error; + + /* convert member */ + success = orbit_zval_to_namedvalue(&source_value, &destination_value); + if (!success) + goto error; + + element_size = ORBit_gather_alloc_info(destination_value.argument._type); + + /* align pointer and set value */ + alignment = ORBit_find_alignment(destination_value.argument._type); + p_buffer = ALIGN_ADDRESS(p_buffer, alignment); + + /* copy value to struct */ + memcpy(p_buffer, destination_value.argument._value, element_size); + p_buffer += element_size; + } + } + + return TRUE; + +error: + return FALSE; +} + +/* + * public function to convert form a zval to CORBA_NamedValue + * + * The data type specific functions does not own + * pDestination->argument._value!!! + */ +zend_bool orbit_zval_to_namedvalue(const zval * pSource, + CORBA_NamedValue * pDestination) +{ + zend_bool success = FALSE; + CORBA_TCKind kind; + + if (pDestination->argument._type == NULL) + { +/* printf("pDestination->argument._type is NULL in orbit_zval_to_namedvalue\n");*/ + return FALSE; + } + + kind = CORBA_TypeCode_kind( + pDestination->argument._type, + orbit_get_environment()); + + if (orbit_caught_exception()) + return FALSE; + + /* allocate memory for value */ + if (pSource != NULL) + { + /* use special function to allocate value -- good or bad idea? */ + pDestination->argument._value = + ORBit_alloc_tcval(pDestination->argument._type, 1); + } + + switch (kind) + { + case CORBA_tk_boolean: + success = satellite_zval_to_namedvalue_boolean(pSource, pDestination); + break; + + case CORBA_tk_double: + success = satellite_zval_to_namedvalue_double(pSource, pDestination); + break; + + case CORBA_tk_enum: + case CORBA_tk_long: + success = satellite_zval_to_namedvalue_long(pSource, pDestination); + break; + + case CORBA_tk_objref: + success = satellite_zval_to_namedvalue_objref(pSource, pDestination); + break; + + case CORBA_tk_sequence: + success = satellite_zval_to_namedvalue_sequence(pSource, pDestination); + break; + + case CORBA_tk_short: + success = satellite_zval_to_namedvalue_short(pSource, pDestination); + break; + + case CORBA_tk_string: /* 18 */ + success = satellite_zval_to_namedvalue_string(pSource, pDestination); + break; + + case CORBA_tk_struct: /* 15 */ + success = satellite_zval_to_namedvalue_struct(pSource, pDestination); + break; + + default: +/* printf("unsupported corba TCKind %i\n", kind);*/ +/* php_error(E_WARNING, "unsupported corba TCKind %i", kind);*/ + } + + if (!success) + { +/* printf("orbit_zval_to_namedvalue failed for TCKind %i\n", kind);*/ + /* + * does this always crash? then we better look for another way of + * freeing the data! + */ +/* CORBA_free(pDestination->argument._value); */ + pDestination->argument._value = NULL; + } + + return success; +} + diff --git a/ext/satellite/zval_to_namedvalue.h b/ext/satellite/zval_to_namedvalue.h new file mode 100644 index 0000000000..debc4675ee --- /dev/null +++ b/ext/satellite/zval_to_namedvalue.h @@ -0,0 +1,33 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* + * $Id$ + * vim: syntax=c tabstop=2 shiftwidth=2 + */ + +#ifndef __zval_to_namedvalue_h__ +#define __zval_to_namedvalue_h__ + +#include +#include + +zend_bool orbit_zval_to_namedvalue(const zval * pSource, CORBA_NamedValue * pDestination); + +#endif /* __zval_to_namedvalue_h__ */ + -- 2.40.0