- Initial submission of CORBA extension for PHP: Satellite

This commit is contained in:
David Eriksson 2000-09-01 22:10:15 +00:00
parent cd8af6aa44
commit 2ad0310fd3
29 changed files with 4844 additions and 0 deletions

54
ext/satellite/Makefile.in Normal file
View file

@ -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

59
ext/satellite/README Normal file
View file

@ -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

180
ext/satellite/class.c Normal file
View file

@ -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;
}

219
ext/satellite/class.h Normal file
View file

@ -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__ */

31
ext/satellite/common.c Normal file
View file

@ -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"

70
ext/satellite/common.h Normal file
View file

@ -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__ */

40
ext/satellite/config.m4 Normal file
View file

@ -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

128
ext/satellite/corba.c Normal file
View file

@ -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;
}

43
ext/satellite/corba.h Normal file
View file

@ -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__ */

174
ext/satellite/enum.c Normal file
View file

@ -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;
}
}

34
ext/satellite/enum.h Normal file
View file

@ -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__ */

145
ext/satellite/findtype.c Normal file
View file

@ -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;
}

43
ext/satellite/findtype.h Normal file
View file

@ -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__ */

101
ext/satellite/hashtable.c Normal file
View file

@ -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;
}

35
ext/satellite/hashtable.h Normal file
View file

@ -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__ */

View file

@ -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);
}

View file

@ -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__ */

851
ext/satellite/object.c Normal file
View file

@ -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;
}

37
ext/satellite/object.h Normal file
View file

@ -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__ */

199
ext/satellite/php_orbit.c Normal file
View file

@ -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);
}

42
ext/satellite/php_orbit.h Normal file
View file

@ -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 */

330
ext/satellite/struct.c Normal file
View file

@ -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;
}
}

35
ext/satellite/struct.h Normal file
View file

@ -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__ */

437
ext/satellite/typecode.c Normal file
View file

@ -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;
}

34
ext/satellite/typecode.h Normal file
View file

@ -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__ */

552
ext/satellite/typemanager.c Normal file
View file

@ -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); }

112
ext/satellite/typemanager.h Normal file
View file

@ -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__ */

View file

@ -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;
}

View file

@ -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__ */