]> granicus.if.org Git - php/commitdiff
- Initial submission of CORBA extension for PHP: Satellite
authorDavid Eriksson <eriksson@php.net>
Fri, 1 Sep 2000 22:10:15 +0000 (22:10 +0000)
committerDavid Eriksson <eriksson@php.net>
Fri, 1 Sep 2000 22:10:15 +0000 (22:10 +0000)
29 files changed:
ext/satellite/Makefile.in [new file with mode: 0644]
ext/satellite/README [new file with mode: 0644]
ext/satellite/class.c [new file with mode: 0644]
ext/satellite/class.h [new file with mode: 0644]
ext/satellite/common.c [new file with mode: 0644]
ext/satellite/common.h [new file with mode: 0644]
ext/satellite/config.m4 [new file with mode: 0644]
ext/satellite/corba.c [new file with mode: 0644]
ext/satellite/corba.h [new file with mode: 0644]
ext/satellite/enum.c [new file with mode: 0644]
ext/satellite/enum.h [new file with mode: 0644]
ext/satellite/findtype.c [new file with mode: 0644]
ext/satellite/findtype.h [new file with mode: 0644]
ext/satellite/hashtable.c [new file with mode: 0644]
ext/satellite/hashtable.h [new file with mode: 0644]
ext/satellite/namedvalue_to_zval.c [new file with mode: 0644]
ext/satellite/namedvalue_to_zval.h [new file with mode: 0644]
ext/satellite/object.c [new file with mode: 0644]
ext/satellite/object.h [new file with mode: 0644]
ext/satellite/php_orbit.c [new file with mode: 0644]
ext/satellite/php_orbit.h [new file with mode: 0644]
ext/satellite/struct.c [new file with mode: 0644]
ext/satellite/struct.h [new file with mode: 0644]
ext/satellite/typecode.c [new file with mode: 0644]
ext/satellite/typecode.h [new file with mode: 0644]
ext/satellite/typemanager.c [new file with mode: 0644]
ext/satellite/typemanager.h [new file with mode: 0644]
ext/satellite/zval_to_namedvalue.c [new file with mode: 0644]
ext/satellite/zval_to_namedvalue.h [new file with mode: 0644]

diff --git a/ext/satellite/Makefile.in b/ext/satellite/Makefile.in
new file mode 100644 (file)
index 0000000..7687986
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+#   +----------------------------------------------------------------------+
+#
+
+#
+# $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 (file)
index 0000000..1d94864
--- /dev/null
@@ -0,0 +1,59 @@
+$Id$
+
+About Satellite
+---------------
+Satellite is CORBA support for PHP using ORBit.
+
+The original version was made by David Eriksson <eriksson@php.net> 
+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 (file)
index 0000000..2ad1332
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+
+/*
+ * Helper function for making PHP classes
+ */
+
+#include <php.h>
+#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 (file)
index 0000000..1dc429c
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 <zend.h>
+#include <zend_API.h>
+
+#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 (file)
index 0000000..d04df3a
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 (file)
index 0000000..3e038a5
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/* -----------------------------------------------------------------------
+ * 
+ * Some common stuff, now only memory allocation macros
+ *
+ * -----------------------------------------------------------------------
+ */
+#ifndef __common_h__
+#define __common_h__
+
+#include <zend.h>
+
+#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 (file)
index 0000000..aac087d
--- /dev/null
@@ -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 (file)
index 0000000..9b1cb77
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 (file)
index 0000000..87e176e
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/*
+ * Control access to CORBA_ORB and CORBA_Environment objects
+ */
+#ifndef __corba_h__
+#define __corba_h__
+
+#include <orb/orbit.h>
+
+/* 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 (file)
index 0000000..215ccf9
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 (file)
index 0000000..861d87d
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 (file)
index 0000000..cefb5c2
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/*
+ * Used by typemanager.c and typecode.c
+ */
+#include <orb/orbit.h>
+#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 (file)
index 0000000..8be50ca
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/*
+ * Used by typemanager.c and typecode.c
+ */
+#ifndef __findtype_h__
+#define __findtype_h__
+
+#include <libIDL/IDL.h>
+
+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 (file)
index 0000000..68f801f
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 (file)
index 0000000..2e33cd4
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/*
+ * HashTable helpers
+ */
+#ifndef __hashtable_h__
+#define __hashtable_h__
+
+#include <zend.h>
+
+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 (file)
index 0000000..8249d9f
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/* -----------------------------------------------------------------------
+ * 
+ * Functions to convert a CORBA_NamedValue to a zval
+ *
+ * -----------------------------------------------------------------------
+ */
+#include <zend_API.h>
+#include "namedvalue_to_zval.h"
+#include "common.h"
+#include "object.h"
+#include "struct.h"
+#include "corba.h"
+
+#include <ORBitutil/util.h>            /* 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 (file)
index 0000000..570d849
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+#ifndef __namedvalue_to_zval_h__
+#define __namedvalue_to_zval_h__
+
+#include <zend.h>
+#include <orb/orbit.h>
+
+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 (file)
index 0000000..d01272d
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 <sys/time.h>
+#include <unistd.h>
+#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 (file)
index 0000000..c1fdba9
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+#ifndef __orbit_object_h__
+#define __orbit_object_h__
+
+#include <orb/orbit.h>
+#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 (file)
index 0000000..098f0d2
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/*
+ * Interface to PHP
+ */
+#include <php.h>
+#include <php_ini.h>    /* for DISPLAY_INI_ENTRIES() */
+#include <ext/standard/info.h> /* 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 (file)
index 0000000..d4561d9
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 (file)
index 0000000..9c7e792
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP version 4.0                                                      |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group                   |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: David Eriksson <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/* -----------------------------------------------------------------------
+ * 
+ * OrbitStruct class
+ * 
+ * There are three ways to create a structure
+ *
+ * (1) OrbitStruct_Constructor, for new OrbitStruct(...) in PHP
+ * (2) OrbitStruct_Create, used when a CORBA method returns a struct
+ * (3) OrbitStruct_Wakeup, used on "unserialization"
+ * -----------------------------------------------------------------------
+ */
+#include "struct.h"
+#include "common.h"
+#include "typemanager.h"
+#include "hashtable.h"
+
+/*
+ * enable/disable incomplete serialization support
+ */
+#define SERIALIZABLE_STRUCT            0
+
+struct _OrbitStruct
+{
+       HashTable mMembers;
+       zend_bool mIsException; /* otherwise normal struct */
+       union
+       {
+               StructType * mpStructType;
+               ExceptionType * mpExceptionType;
+       } u;
+};
+
+#if SERIALIZABLE_STRUCT
+
+static void OrbitStruct_Wakeup(INTERNAL_FUNCTION_PARAMETERS);
+static void OrbitStruct_Sleep(INTERNAL_FUNCTION_PARAMETERS);
+
+static zend_function_entry OrbitStruct_functions[] =
+{
+       {"__sleep", OrbitStruct_Sleep},
+       {"__wakeup", OrbitStruct_Wakeup},
+       {NULL, NULL}
+};
+
+#define MY_IMPLEMENT_CLASS(name, flags)\
+IMPLEMENT_DECLARATIONS(name, flags)            \
+IMPLEMENT_FUNCTION_CALL(name, flags)   \
+IMPLEMENT_PUT_PROPERTY(name, flags)            \
+IMPLEMENT_GET_PROPERTY(name, flags)            \
+IMPLEMENT_INIT_EX(name, flags, ##name##_functions, _##name##_FunctionCall, _##name##_GetProperty, _##name##_PutProperty)\
+IMPLEMENT_DATA_HELPERS(name, flags)
+       
+MY_IMPLEMENT_CLASS(OrbitStruct, NO_FUNCTIONS);
+
+#else  /* !SERIALIZABLE_STRUCT */
+
+IMPLEMENT_CLASS(OrbitStruct, NO_FUNCTIONS);
+
+#endif /* SERIALIZABLE_STRUCT */
+
+#if SERIALIZABLE_STRUCT
+
+/*
+ * prepare for serialization
+ */
+static void OrbitStruct_Sleep(INTERNAL_FUNCTION_PARAMETERS)
+{
+       /* get struct data */
+       OrbitStruct * p_struct = OrbitStruct_RetrieveData(this_ptr);
+       
+       /* validate data */
+       if (p_struct == NULL)
+       {
+               goto error;
+       }
+
+#if 0
+       /* add property to zval */
+       add_property_string(this_ptr, IOR_PROPERTY_KEY, p_ior, TRUE);
+       
+       /* create array */
+       array_init(return_value);
+
+       /* add name of property IOR to array */
+       add_next_index_string(return_value, IOR_PROPERTY_KEY, TRUE);
+#endif
+       
+       return;
+
+error:
+       RETURN_NULL();
+}
+
+static void OrbitStruct_Wakeup(INTERNAL_FUNCTION_PARAMETERS)
+{
+}
+
+#endif /* SERIALIZABLE_STRUCT */
+
+char * OrbitStruct_GetRepositoryId(OrbitStruct * pStruct)
+{
+       if (pStruct->mIsException)
+               return ExceptionType_GetRepositoryId(pStruct->u.mpExceptionType);
+       else
+               return StructType_GetRepositoryId(pStruct->u.mpStructType);
+}
+
+static zend_bool OrbitStruct_InitializeMembers(OrbitStruct * pStruct)
+{
+       MemberType * p_member = NULL;
+       if (pStruct->mIsException)
+               p_member = ExceptionType_GetFirstMember(pStruct->u.mpExceptionType);
+       else
+               p_member = StructType_GetFirstMember(pStruct->u.mpStructType);
+       
+       zend_hash_init(                                                                                 
+                       &pStruct->mMembers,                                     /* hash table */
+                       0,                                                                                                      /* size */
+                       NULL,                                                                                           /* hash function */
+                       ZVAL_DESTRUCTOR,                                                /* destructor */
+                       0);                                                                                                     /* persistent */
+
+       if (!MemberType_IsValid(p_member))
+               return TRUE;    /* no members */
+
+       do
+       {
+               zval * p_value = NULL;
+               char * p_name = MemberType_GetName(p_member);
+
+               ALLOC_ZVAL(p_value);
+               ZVAL_NULL(p_value);
+               
+               zend_hash_add(
+                               &pStruct->mMembers,
+                               p_name,
+                               strlen(p_name)+1,       /* important: include terminating zero byte */
+                               p_value,
+                               sizeof(zval),
+                               NULL
+                               );
+       } while (MemberType_GetNext(p_member));
+       
+       return TRUE;
+}
+
+static zend_bool OrbitStruct_Initialize(const char * pId, OrbitStruct * pStruct)
+{
+       /* find type info */
+       pStruct->u.mpStructType = TypeManager_FindStruct(pId);
+
+       if (pStruct->u.mpStructType == NULL)
+       {
+               /* not a struct -- maybe an exception? */
+               pStruct->u.mpExceptionType = TypeManager_FindException(pId);
+               if (pStruct->u.mpExceptionType == NULL)
+               {
+                       zend_error(E_ERROR, "(Satellite) unknown struct or exception '%s'", pId);
+               
+                       goto error;     
+               }
+
+               pStruct->mIsException = TRUE;
+       }
+
+       /* initialize members */
+       if (!OrbitStruct_InitializeMembers(pStruct))
+               goto error;     
+
+       return TRUE;
+
+error:
+       return FALSE;
+}
+
+/*
+ * used by orbit_namedvalue_to_zval_struct(...)
+ */
+zend_bool OrbitStruct_Create(const char * pId, zval * pDestination)
+{
+       /* allocate buffer */
+       OrbitStruct * p_struct = orbit_new(OrbitStruct);
+       
+       /* initialize struct */
+       if (!OrbitStruct_Initialize(pId, p_struct))
+               goto error;
+
+       /* set zval members */
+       pDestination->type = IS_OBJECT;
+       pDestination->is_ref = 1;
+       pDestination->refcount = 1;
+
+       pDestination->value.obj.ce = &OrbitStruct_class_entry;
+       pDestination->value.obj.properties = orbit_new(HashTable);
+
+       zend_hash_init(
+                       pDestination->value.obj.properties,     /* hash table */
+                       0,                                                                                                                                      /* size */
+                       NULL,                                                                                                                   /* hash function */
+                       ZVAL_PTR_DTOR,                                                                                  /* destructor */
+                       0);                                                                                                                                     /* persistent */
+
+       /* save orbit data */
+       OrbitStruct_SaveData(pDestination, p_struct);
+
+       return TRUE;
+
+error:
+       orbit_delete(p_struct);
+       return FALSE;
+}
+
+/*
+ * Constructor
+ *
+ * Parameters: Repository ID of struct
+ */
+zend_bool  OrbitStruct_Constructor(OrbitStruct  ** ppStruct, 
+               int parameterCount, const zval ** ppParameters)
+{
+       /* allocate buffer */
+       OrbitStruct * p_struct = orbit_new(OrbitStruct);
+
+       /* check parameter count */
+       if (parameterCount != 1)
+       {
+               wrong_param_count();
+               goto error;
+       }
+
+       /* validate parameter types */
+       if (ppParameters[0]->type != IS_STRING)
+               goto error;
+       
+       /* initialize struct */
+       if (!OrbitStruct_Initialize(ppParameters[0]->value.str.val, p_struct))
+               goto error;
+       
+       *ppStruct = p_struct;
+       return TRUE;
+
+error:
+       OrbitStruct_Destructor(p_struct);
+       *ppStruct = NULL;
+       return FALSE;
+}
+
+zend_bool  OrbitStruct_Destructor(OrbitStruct  * pStruct)
+{
+       if (pStruct->mIsException)
+               ExceptionType_release(pStruct->u.mpExceptionType);
+       else
+               StructType_release(pStruct->u.mpStructType);
+       
+       /* will crash on uninitialized members structure :-( */
+       zend_hash_destroy(&pStruct->mMembers);
+       orbit_delete(pStruct);
+
+       return TRUE;
+}
+
+/* not used */
+zend_bool  OrbitStruct_CallFunction(OrbitStruct  * pStruct, 
+               const char * pFunctionName, int parameterCount, const zval ** ppParameters, zval * pResult)
+{
+       return FALSE;
+}
+
+zend_bool  OrbitStruct_PutProperty(OrbitStruct  * pStruct, 
+               const char * pPropertyName, const zval * pValue)
+{
+       zend_bool result;
+       
+       result = orbit_store_by_key(&pStruct->mMembers, pPropertyName, pValue);
+
+       if (!result)
+       {
+               zend_error(E_ERROR, "(Satellite) unknown member '%s' in struct '%s'",
+                               pPropertyName, OrbitStruct_GetRepositoryId(pStruct));
+       }
+
+       return result;
+}
+
+zend_bool  OrbitStruct_GetProperty(OrbitStruct  * pStruct, 
+               const char * pPropertyName, zval * pReturnValue)
+{
+       zval * p_value = orbit_find_by_key(&pStruct->mMembers, pPropertyName);
+
+       if (p_value == NULL)
+       {
+               zend_error(E_ERROR, "(Satellite) unknown member '%s' in struct '%s'",
+                               pPropertyName, OrbitStruct_GetRepositoryId(pStruct));
+
+               ZVAL_NULL(pReturnValue);
+               return FALSE;
+       }
+       else
+       {
+               memcpy(pReturnValue, p_value, sizeof(zval));            /* raw data copy */
+               zval_copy_ctor(pReturnValue);                                                                   /* smart data copy */
+               INIT_PZVAL(pReturnValue);                                                                                       /* set reference count */
+               return TRUE;
+       }
+}
+
diff --git a/ext/satellite/struct.h b/ext/satellite/struct.h
new file mode 100644 (file)
index 0000000..2025a13
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 (file)
index 0000000..1075dbb
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $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 (file)
index 0000000..a191e81
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+#ifndef __typecode_h__
+#define __typecode_h__
+
+#include <libIDL/IDL.h>
+#include <orb/orbit.h>
+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 (file)
index 0000000..454fd1e
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/*
+ * Type manager
+ */
+#include <string.h>
+#include <orb/orbit.h>
+#include "common.h"
+#include "typemanager.h"
+#include "typecode.h"
+#include "findtype.h"
+#include <glob.h>
+
+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 (file)
index 0000000..18fb941
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+#ifndef __typemanager_h__
+#define __typemanager_h__
+
+#include <orb/orbit.h>
+
+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 (file)
index 0000000..a1de332
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+/* -----------------------------------------------------------------------
+ * 
+ * Functions to convert a zval to a CORBA_NamedValue
+ *
+ * -----------------------------------------------------------------------
+ */
+#include <zend_API.h>
+#include "zval_to_namedvalue.h"
+#include "object.h"
+#include "struct.h"
+#include "common.h"
+#include "corba.h"
+
+#include <ORBitutil/util.h>            /* 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 (file)
index 0000000..debc467
--- /dev/null
@@ -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 <eriksson@php.net>                            |
+   +----------------------------------------------------------------------+
+ */
+
+/*
+ * $Id$
+ * vim: syntax=c tabstop=2 shiftwidth=2
+ */
+
+#ifndef __zval_to_namedvalue_h__
+#define __zval_to_namedvalue_h__
+
+#include <zend.h>
+#include <orb/orbit.h>
+
+zend_bool orbit_zval_to_namedvalue(const zval * pSource, CORBA_NamedValue * pDestination);
+
+#endif /* __zval_to_namedvalue_h__ */
+