diff options
author | Mark Spruiell <mes@zeroc.com> | 2003-07-10 18:31:12 +0000 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2003-07-10 18:31:12 +0000 |
commit | 0a9c5805cf4583db4e87329e6e3b71ff7f2093c7 (patch) | |
tree | 5d2e48621f97b2815ba93b78c1428fff7d38c2ef /php/src | |
parent | Fixed incorrect include level update for interface and class definitions. (diff) | |
download | ice-0a9c5805cf4583db4e87329e6e3b71ff7f2093c7.tar.bz2 ice-0a9c5805cf4583db4e87329e6e3b71ff7f2093c7.tar.xz ice-0a9c5805cf4583db4e87329e6e3b71ff7f2093c7.zip |
initial check-in
Diffstat (limited to 'php/src')
-rw-r--r-- | php/src/ice/.cvsignore | 3 | ||||
-rw-r--r-- | php/src/ice/communicator.cpp | 253 | ||||
-rw-r--r-- | php/src/ice/communicator.h | 43 | ||||
-rw-r--r-- | php/src/ice/config.m4 | 68 | ||||
-rw-r--r-- | php/src/ice/exception.cpp | 169 | ||||
-rw-r--r-- | php/src/ice/exception.h | 41 | ||||
-rw-r--r-- | php/src/ice/ice.cpp | 146 | ||||
-rw-r--r-- | php/src/ice/objectprx.cpp | 1065 | ||||
-rw-r--r-- | php/src/ice/objectprx.h | 97 | ||||
-rw-r--r-- | php/src/ice/php_ice.h | 47 | ||||
-rw-r--r-- | php/src/ice/slice.cpp | 171 | ||||
-rw-r--r-- | php/src/ice/slice.h | 31 | ||||
-rw-r--r-- | php/src/ice/util.cpp | 114 | ||||
-rw-r--r-- | php/src/ice/util.h | 57 |
14 files changed, 2305 insertions, 0 deletions
diff --git a/php/src/ice/.cvsignore b/php/src/ice/.cvsignore new file mode 100644 index 00000000000..da7f324ebec --- /dev/null +++ b/php/src/ice/.cvsignore @@ -0,0 +1,3 @@ +.deps +*.lo +*.la diff --git a/php/src/ice/communicator.cpp b/php/src/ice/communicator.cpp new file mode 100644 index 00000000000..db1cf845316 --- /dev/null +++ b/php/src/ice/communicator.cpp @@ -0,0 +1,253 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "communicator.h" +#include "objectprx.h" +#include "exception.h" +#include "util.h" + +using namespace std; + +// +// The global communicator. +// +static Ice::CommunicatorPtr _communicator; + +// +// Class entries represent the PHP class implementations we have registered. +// +static zend_class_entry* Ice_Communicator_entry_ptr; + +// +// Ice::Communicator support. +// +static zend_object_handlers Ice_Communicator_handlers; +static zend_object_value Ice_Communicator_alloc(zend_class_entry* TSRMLS_DC); +static void Ice_Communicator_dtor(void*, zend_object_handle TSRMLS_DC); + +// +// Function entries for Ice::Communicator methods. +// +static function_entry Ice_Communicator_methods[] = +{ + {"__construct", PHP_FN(Ice_Communicator___construct), NULL}, + {"stringToProxy", PHP_FN(Ice_Communicator_stringToProxy), NULL}, + {"proxyToString", PHP_FN(Ice_Communicator_proxyToString), NULL}, + {NULL, NULL, NULL} +}; + +bool +Ice_Communicator_init(TSRMLS_DC) +{ + // + // Register the Ice_Communicator class. + // + zend_class_entry ce_Communicator; + INIT_CLASS_ENTRY(ce_Communicator, "Ice_Communicator", Ice_Communicator_methods); + ce_Communicator.create_object = Ice_Communicator_alloc; + Ice_Communicator_entry_ptr = zend_register_internal_class(&ce_Communicator TSRMLS_CC); + memcpy(&Ice_Communicator_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + + // + // Initialize the global communicator. + // + try + { + Ice::PropertiesPtr props = Ice::createProperties(); + + char* config = INI_STR("ice.config"); + if(config && strlen(config) > 0) + { + props->load(config); + } + + int argc = 0; + char** argv; + _communicator = Ice::initializeWithProperties(argc, argv, props); + } + catch(const IceUtil::Exception& ex) + { + ostringstream ostr; + ex.ice_print(ostr); + php_error(E_ERROR, "unable to create Ice::Communicator:\n%s", ostr.str().c_str()); + return false; + } + + return true; +} + +bool +Ice_Communicator_create(zval* zv TSRMLS_DC) +{ + assert(_communicator); + + if(object_init_ex(zv, Ice_Communicator_entry_ptr) != SUCCESS) + { + php_error(E_ERROR, "unable to initialize global variable in %s()", get_active_function_name(TSRMLS_C)); + return false; + } + + ice_object* obj = ice_object_get(zv TSRMLS_CC); + if(!obj) + { + return false; + } + assert(!obj->ptr); + Ice::CommunicatorPtr* communicator = new Ice::CommunicatorPtr(_communicator); + obj->ptr = (void*)communicator; + + return true; +} + +bool +Ice_Communicator_shutdown(TSRMLS_DC) +{ + if(_communicator) + { + try + { + _communicator->destroy(); + _communicator = 0; + } + catch(const IceUtil::Exception& ex) + { + ostringstream ostr; + ex.ice_print(ostr); + php_error(E_ERROR, "unable to destroy Ice::Communicator:\n%s", ostr.str().c_str()); + return false; + } + } + + return true; +} + +ZEND_FUNCTION(Ice_Communicator___construct) +{ + php_error(E_ERROR, "Ice_Communicator cannot be instantiated, use the global variable $ICE"); +} + +ZEND_FUNCTION(Ice_Communicator_stringToProxy) +{ + ice_object* obj = ice_object_get(getThis() TSRMLS_CC); + if(!obj) + { + return; + } + assert(!obj->ptr); + Ice::CommunicatorPtr* _this = (Ice::CommunicatorPtr*)obj->ptr; + + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + char *str; + int len; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) + { + RETURN_NULL(); + } + + Ice::ObjectPrx proxy; + try + { + proxy = (*_this)->stringToProxy(str); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } + + if(!Ice_ObjectPrx_create(return_value, proxy TSRMLS_CC)) + { + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_Communicator_proxyToString) +{ + ice_object* obj = ice_object_get(getThis() TSRMLS_CC); + if(!obj) + { + return; + } + assert(!obj->ptr); + Ice::CommunicatorPtr* _this = (Ice::CommunicatorPtr*)obj->ptr; + + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + zval* zprx; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zprx, Ice_ObjectPrx_entry_ptr) == FAILURE) + { + RETURN_EMPTY_STRING(); + } + + Ice::ObjectPrx proxy; + if(!Ice_ObjectPrx_fetch(zprx, proxy TSRMLS_CC)) + { + RETURN_EMPTY_STRING(); + } + + try + { + string result = (*_this)->proxyToString(proxy); + RETURN_STRING((char*)result.c_str(), 1); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_EMPTY_STRING(); + } +} + +static zend_object_value +Ice_Communicator_alloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + ice_object* obj = ice_object_new(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, Ice_Communicator_dtor, NULL TSRMLS_CC); + result.handlers = &Ice_Communicator_handlers; + + return result; +} + +static void +Ice_Communicator_dtor(void* p, zend_object_handle handle TSRMLS_DC) +{ + ice_object* obj = (ice_object*)p; + if(obj->ptr) + { + // + // Delete the smart pointer - the communicator will be destroyed when + // the module shuts down. + // + Ice::CommunicatorPtr* _this = (Ice::CommunicatorPtr*)obj->ptr; + delete _this; + } + + zend_objects_destroy_object((zend_object*)p, handle TSRMLS_CC); +} diff --git a/php/src/ice/communicator.h b/php/src/ice/communicator.h new file mode 100644 index 00000000000..89477f0e51c --- /dev/null +++ b/php/src/ice/communicator.h @@ -0,0 +1,43 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef ICE_PHP_COMMUNICATOR_H +#define ICE_PHP_COMMUNICATOR_H + +extern "C" +{ +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +} + +#include <Ice/Ice.h> + +bool Ice_Communicator_init(TSRMLS_DC); +bool Ice_Communicator_create(zval* TSRMLS_DC); +bool Ice_Communicator_shutdown(TSRMLS_DC); + +// +// Ice_Communicator class methods. +// +ZEND_FUNCTION(Ice_Communicator___construct); +ZEND_FUNCTION(Ice_Communicator_stringToProxy); +ZEND_FUNCTION(Ice_Communicator_proxyToString); + +#define ICE_PHP_COMMUNICATOR_FUNCTIONS \ + ZEND_FE(Ice_Communicator___construct, NULL) \ + ZEND_FE(Ice_Communicator_stringToProxy, NULL) \ + ZEND_FE(Ice_Communicator_proxyToString, NULL) + +#endif diff --git a/php/src/ice/config.m4 b/php/src/ice/config.m4 new file mode 100644 index 00000000000..c3956965e94 --- /dev/null +++ b/php/src/ice/config.m4 @@ -0,0 +1,68 @@ +dnl $Id$ +dnl config.m4 for extension ice + +dnl Comments in this file start with the string 'dnl'. +dnl Remove where necessary. This file will not work +dnl without editing. + +dnl If your extension references something external, use with: + +PHP_ARG_WITH(ice, for Ice support, +[ --with-ice Include Ice support]) + +dnl Otherwise use enable: + +dnl PHP_ARG_ENABLE(ice, whether to enable Ice support, +dnl Make sure that the comment is aligned: +dnl [ --enable-ice Enable Ice support]) + +if test "$PHP_ICE" != "no"; then + dnl Write more examples of tests here... + + # --with-ice -> check with-path + SEARCH_PATH="/usr/local /usr" # you might want to change this + SEARCH_FOR="/include/Ice/Ice.h" + if test -r $PHP_ICE/$SEARCH_FOR; then # path given as parameter + ICE_DIR=$PHP_ICE + else # search default path list + AC_MSG_CHECKING([for Ice files in default path]) + for i in $SEARCH_PATH ; do + if test -r $i/$SEARCH_FOR; then + ICE_DIR=$i + AC_MSG_RESULT(found in $i) + fi + done + fi + + if test -z "$ICE_DIR"; then + AC_MSG_RESULT([not found]) + AC_MSG_ERROR([Please reinstall the Ice distribution]) + fi + + # --with-ice -> add include path + PHP_ADD_INCLUDE($ICE_DIR/include) + + dnl # --with-ice -> check for lib and symbol presence + dnl LIBNAME=Ice # you may want to change this + dnl LIBSYMBOL=ice # you most likely want to change this + + dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, + dnl [ + dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $ICE_DIR/lib, ICE_SHARED_LIBADD) + dnl AC_DEFINE(HAVE_ICELIB,1,[ ]) + dnl ],[ + dnl AC_MSG_ERROR([wrong Ice lib version or lib not found]) + dnl ],[ + dnl -L$ICE_DIR/lib -lm -ldl + dnl ]) + dnl + dnl PHP_SUBST(ICE_SHARED_LIBADD) + + PHP_REQUIRE_CXX() + PHP_ADD_LIBPATH($ICE_DIR/lib, ICE_SHARED_LIBADD) + PHP_ADD_LIBRARY(Ice, 1, ICE_SHARED_LIBADD) + PHP_ADD_LIBRARY(Slice, 1, ICE_SHARED_LIBADD) + PHP_ADD_LIBRARY(IceUtil, 1, ICE_SHARED_LIBADD) + PHP_ADD_LIBRARY(stdc++, 1, ICE_SHARED_LIBADD) + PHP_NEW_EXTENSION(ice, ice.cpp communicator.cpp exception.cpp objectprx.cpp slice.cpp util.cpp, $ext_shared) +fi diff --git a/php/src/ice/exception.cpp b/php/src/ice/exception.cpp new file mode 100644 index 00000000000..56addfaf796 --- /dev/null +++ b/php/src/ice/exception.cpp @@ -0,0 +1,169 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "exception.h" +#include "util.h" + +using namespace std; + +// +// Class entries represent the PHP class implementations we have registered. +// +static zend_class_entry* Ice_LocalException_entry_ptr; + +// +// Ice::LocalException support. +// +static zend_object_handlers Ice_LocalException_handlers; +static zend_object_value Ice_LocalException_alloc(zend_class_entry* TSRMLS_DC); +static void Ice_LocalException_dtor(void*, zend_object_handle TSRMLS_DC); + +// +// Function entries for Ice::LocalException methods. +// +static function_entry Ice_LocalException_methods[] = +{ + {"__construct", PHP_FN(Ice_LocalException___construct), NULL}, + {"message", PHP_FN(Ice_LocalException_message), NULL}, + {NULL, NULL, NULL} +}; + +bool +Ice_LocalException_init(TSRMLS_DC) +{ + // + // Register the Ice_LocalException class. + // + zend_class_entry ce_LocalException; + INIT_CLASS_ENTRY(ce_LocalException, "Ice_LocalException", Ice_LocalException_methods); + ce_LocalException.create_object = Ice_LocalException_alloc; + Ice_LocalException_entry_ptr = zend_register_internal_class(&ce_LocalException TSRMLS_CC); + memcpy(&Ice_LocalException_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); +} + +void +ice_throw_exception(const IceUtil::Exception& ex TSRMLS_DC) +{ + try + { + ex.ice_throw(); + } + catch(const Ice::LocalException& e) + { + zval* zex; + MAKE_STD_ZVAL(zex); + if(object_init_ex(zex, Ice_LocalException_entry_ptr) != SUCCESS) + { + php_error(E_ERROR, "unable to create LocalException in %s()", get_active_function_name(TSRMLS_C)); + return; + } + + ice_object* obj = ice_object_get(zex TSRMLS_CC); + if(!obj) + { + return; + } + assert(!obj->ptr); + + ostringstream ostr; + e.ice_print(ostr); + obj->ptr = estrdup(ostr.str().c_str()); + EG(exception) = zex; + } + catch(const Ice::UserException& e) + { + // TODO + } + catch(const IceUtil::Exception& e) + { + ostringstream ostr; + e.ice_print(ostr); + php_error(E_ERROR, "exception: %s", ostr.str().c_str()); + } +} + +ZEND_FUNCTION(Ice_LocalException___construct) +{ + if(ZEND_NUM_ARGS() > 1) + { + WRONG_PARAM_COUNT; + } + + char *msg = ""; + int len; + + if(ZEND_NUM_ARGS() > 0) + { + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &msg, &len) == FAILURE) + { + RETURN_NULL(); + } + } + + ice_object* obj = ice_object_get(getThis() TSRMLS_CC); + if(!obj) + { + RETURN_NULL(); + } + assert(!obj->ptr); + obj->ptr = estrdup(msg); +} + +ZEND_FUNCTION(Ice_LocalException_message) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = ice_object_get(getThis() TSRMLS_CC); + if(!obj) + { + RETURN_EMPTY_STRING(); + } + assert(obj->ptr); + RETURN_STRING((char*)obj->ptr, 1); +} + +static zend_object_value +Ice_LocalException_alloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + ice_object* obj = ice_object_new(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, Ice_LocalException_dtor, NULL TSRMLS_CC); + result.handlers = &Ice_LocalException_handlers; + + return result; +} + +static void +Ice_LocalException_dtor(void* p, zend_object_handle handle TSRMLS_DC) +{ + ice_object* obj = (ice_object*)p; + + if(obj->ptr) + { + efree(obj->ptr); + obj->ptr = 0; + } + + zend_objects_destroy_object((zend_object*)p, handle TSRMLS_CC); +} diff --git a/php/src/ice/exception.h b/php/src/ice/exception.h new file mode 100644 index 00000000000..99ec13d0497 --- /dev/null +++ b/php/src/ice/exception.h @@ -0,0 +1,41 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef ICE_PHP_EXCEPTION_H +#define ICE_PHP_EXCEPTION_H + +extern "C" +{ +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +} + +#include <Ice/Ice.h> + +bool Ice_LocalException_init(TSRMLS_DC); + +void ice_throw_exception(const IceUtil::Exception& TSRMLS_DC); + +// +// Ice_LocalException class methods. +// +ZEND_FUNCTION(Ice_LocalException___construct); +ZEND_FUNCTION(Ice_LocalException_message); + +#define ICE_PHP_LOCAL_EXCEPTION_FUNCTIONS \ + ZEND_FE(Ice_LocalException___construct, NULL) \ + ZEND_FE(Ice_LocalException_message, NULL) + +#endif diff --git a/php/src/ice/ice.cpp b/php/src/ice/ice.cpp new file mode 100644 index 00000000000..d54212e93ba --- /dev/null +++ b/php/src/ice/ice.cpp @@ -0,0 +1,146 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "communicator.h" +#include "objectprx.h" +#include "exception.h" +#include "slice.h" +#include "util.h" +#include "php_ice.h" + +using namespace std; + +ZEND_DECLARE_MODULE_GLOBALS(ice) + +// +// Function entries for all objects. +// +function_entry ice_functions[] = +{ + ICE_PHP_COMMUNICATOR_FUNCTIONS + ICE_PHP_OBJECT_PRX_FUNCTIONS + ICE_PHP_LOCAL_EXCEPTION_FUNCTIONS + {NULL, NULL, NULL} +}; + +zend_module_entry ice_module_entry = +{ + STANDARD_MODULE_HEADER, + "Ice", + ice_functions, + ZEND_MINIT(ice), + ZEND_MSHUTDOWN(ice), + ZEND_RINIT(ice), + ZEND_RSHUTDOWN(ice), + ZEND_MINFO(ice), + NO_VERSION_YET, + STANDARD_MODULE_PROPERTIES +}; + +#ifdef COMPILE_DL_ICE +ZEND_GET_MODULE(ice) +#endif + +// +// Declare initialization file entries. +// +PHP_INI_BEGIN() + PHP_INI_ENTRY("ice.config", "", PHP_INI_SYSTEM, NULL) + PHP_INI_ENTRY("ice.parse", "", PHP_INI_SYSTEM, NULL) +PHP_INI_END() + +ZEND_MINIT_FUNCTION(ice) +{ + REGISTER_INI_ENTRIES(); + + if(!Ice_Communicator_init(TSRMLS_CC)) + { + return FAILURE; + } + + if(!Ice_ObjectPrx_init(TSRMLS_CC)) + { + return FAILURE; + } + + if(!Ice_LocalException_init(TSRMLS_CC)) + { + return FAILURE; + } + + if(!Slice_init(TSRMLS_CC)) + { + return FAILURE; + } + + return SUCCESS; +} + +ZEND_MSHUTDOWN_FUNCTION(ice) +{ + UNREGISTER_INI_ENTRIES(); + + int status = SUCCESS; + + if(!Ice_Communicator_shutdown(TSRMLS_CC)) + { + status = FAILURE; + } + + if(!Slice_shutdown(TSRMLS_CC)) + { + status = FAILURE; + } + + return status; +} + +ZEND_RINIT_FUNCTION(ice) +{ + // + // Register the global variable "ICE" to hold the communicator. We have to do this + // during request initialization, and not module initialization, because PHP's + // environment is essentially recreated for each request. + // + zval* global; + MAKE_STD_ZVAL(global); + if(!Ice_Communicator_create(global TSRMLS_CC)) + { + return FAILURE; + } + + ICE_G(z_communicator) = global; + ZEND_SET_GLOBAL_VAR("ICE", global); + + return SUCCESS; +} + +ZEND_RSHUTDOWN_FUNCTION(ice) +{ + return SUCCESS; +} + +ZEND_MINFO_FUNCTION(ice) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "Ice support", "enabled"); + php_info_print_table_row(2, "Ice version", ICE_STRING_VERSION); + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); +} diff --git a/php/src/ice/objectprx.cpp b/php/src/ice/objectprx.cpp new file mode 100644 index 00000000000..9944bf66311 --- /dev/null +++ b/php/src/ice/objectprx.cpp @@ -0,0 +1,1065 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "objectprx.h" +#include "exception.h" +#include "slice.h" +#include "util.h" + +using namespace std; + +// +// Class entries represent the PHP class implementations we have registered. +// +zend_class_entry* Ice_ObjectPrx_entry_ptr; + +// +// Encapsulates an operation description. +// +class Operation : public IceUtil::SimpleShared +{ +public: + Operation(const Ice::ObjectPrx&, const Slice::OperationPtr&); + virtual ~Operation(); + + void invoke(INTERNAL_FUNCTION_PARAMETERS); + +private: + Ice::ObjectPrx _proxy; + Slice::OperationPtr _op; +}; +typedef IceUtil::Handle<Operation> OperationPtr; + +// +// Encapsulates proxy and type information. +// +class Proxy +{ +public: + Proxy(const Ice::ObjectPrx&); + Proxy(const Ice::ObjectPrx&, const Slice::ClassDefPtr&); + + const Ice::ObjectPrx& getProxy() const; + const Slice::ClassDefPtr& getClass() const; + + OperationPtr getOperation(const string&); + +private: + Ice::ObjectPrx _proxy; + Slice::ClassDefPtr _class; + Slice::OperationList _classOps; + map<string, OperationPtr> _ops; +}; + +// +// Ice::ObjectPrx support. +// +static zend_object_handlers Ice_ObjectPrx_handlers; +static zend_object_value Ice_ObjectPrx_alloc(zend_class_entry* TSRMLS_DC); +static void Ice_ObjectPrx_dtor(void*, zend_object_handle TSRMLS_DC); +static union _zend_function* Ice_ObjectPrx_get_method(zval*, char*, int TSRMLS_DC); +ZEND_FUNCTION(Ice_ObjectPrx_call); +//static int Ice_ObjectPrx_call(char*, INTERNAL_FUNCTION_PARAMETERS); + +// +// Function entries for Ice::ObjectPrx methods. +// +static function_entry Ice_ObjectPrx_methods[] = +{ + {"__construct", PHP_FN(Ice_ObjectPrx___construct), NULL}, + {"ice_isA", PHP_FN(Ice_ObjectPrx_ice_isA), NULL}, + {"ice_ping", PHP_FN(Ice_ObjectPrx_ice_ping), NULL}, + {"ice_id", PHP_FN(Ice_ObjectPrx_ice_id), NULL}, + {"ice_ids", PHP_FN(Ice_ObjectPrx_ice_ids), NULL}, + {"ice_facets", PHP_FN(Ice_ObjectPrx_ice_facets), NULL}, + {"ice_getFacet", PHP_FN(Ice_ObjectPrx_ice_getFacet), NULL}, + {"ice_newFacet", PHP_FN(Ice_ObjectPrx_ice_newFacet), NULL}, + {"ice_appendFacet", PHP_FN(Ice_ObjectPrx_ice_appendFacet), NULL}, + {"ice_twoway", PHP_FN(Ice_ObjectPrx_ice_twoway), NULL}, + {"ice_isTwoway", PHP_FN(Ice_ObjectPrx_ice_isTwoway), NULL}, + {"ice_oneway", PHP_FN(Ice_ObjectPrx_ice_oneway), NULL}, + {"ice_isOneway", PHP_FN(Ice_ObjectPrx_ice_isOneway), NULL}, + {"ice_batchOneway", PHP_FN(Ice_ObjectPrx_ice_batchOneway), NULL}, + {"ice_isBatchOneway", PHP_FN(Ice_ObjectPrx_ice_isBatchOneway), NULL}, + {"ice_datagram", PHP_FN(Ice_ObjectPrx_ice_datagram), NULL}, + {"ice_isDatagram", PHP_FN(Ice_ObjectPrx_ice_isDatagram), NULL}, + {"ice_batchDatagram", PHP_FN(Ice_ObjectPrx_ice_batchDatagram), NULL}, + {"ice_isBatchDatagram", PHP_FN(Ice_ObjectPrx_ice_isBatchDatagram), NULL}, + {"ice_secure", PHP_FN(Ice_ObjectPrx_ice_secure), NULL}, + {"ice_compress", PHP_FN(Ice_ObjectPrx_ice_compress), NULL}, + {"ice_timeout", PHP_FN(Ice_ObjectPrx_ice_timeout), NULL}, + {"ice_default", PHP_FN(Ice_ObjectPrx_ice_default), NULL}, + {"ice_flush", PHP_FN(Ice_ObjectPrx_ice_flush), NULL}, + {"ice_uncheckedCast", PHP_FN(Ice_ObjectPrx_ice_uncheckedCast), NULL}, + {NULL, NULL, NULL} +}; + +bool +Ice_ObjectPrx_init(TSRMLS_DC) +{ + // + // Register the Ice_ObjectPrx class. + // + zend_class_entry ce_ObjectPrx; + INIT_CLASS_ENTRY(ce_ObjectPrx, "Ice_ObjectPrx", Ice_ObjectPrx_methods); + ce_ObjectPrx.create_object = Ice_ObjectPrx_alloc; + Ice_ObjectPrx_entry_ptr = zend_register_internal_class(&ce_ObjectPrx TSRMLS_CC); + memcpy(&Ice_ObjectPrx_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + Ice_ObjectPrx_handlers.get_method = Ice_ObjectPrx_get_method; + //Ice_ObjectPrx_handlers.call_method = Ice_ObjectPrx_call; + + return true; +} + +// +// Overloaded version of create for internal use. +// +static bool +Ice_ObjectPrx_create(zval* zv, const Ice::ObjectPrx& p, const Slice::ClassDefPtr& def TSRMLS_DC) +{ + if(object_init_ex(zv, Ice_ObjectPrx_entry_ptr) != SUCCESS) + { + php_error(E_ERROR, "unable to initialize Ice_ObjectPrx in %s()", get_active_function_name(TSRMLS_C)); + return false; + } + + ice_object* zprx = (ice_object*)zend_object_store_get_object(zv TSRMLS_CC); + assert(!zprx->ptr); + zprx->ptr = (void*)new Proxy(p, def); + return true; +} + +bool +Ice_ObjectPrx_create(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC) +{ + return Ice_ObjectPrx_create(zv, p, 0 TSRMLS_CC); +} + +bool +Ice_ObjectPrx_fetch(zval* zv, Ice::ObjectPrx& prx TSRMLS_DC) +{ + if(!ZVAL_IS_NULL(zv)) + { + ice_object* p = (ice_object*)zend_object_store_get_object(zv TSRMLS_CC); + assert(p->ptr); + Proxy* proxy = (Proxy*)p->ptr; + prx = proxy->getProxy(); + } + return true; +} + +ZEND_FUNCTION(Ice_ObjectPrx___construct) +{ + php_error(E_ERROR, "Ice_ObjectPrx cannot be instantiated, use $ICE->stringToProxy()"); +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isA) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + char *id; + int len; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &len) == FAILURE) + { + RETURN_FALSE; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + if(_this->getProxy()->ice_isA(id)) + { + RETVAL_TRUE; + } + else + { + RETVAL_FALSE; + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETVAL_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_ping) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + _this->getProxy()->ice_ping(); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + } + + RETURN_NULL(); +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_id) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + string id = _this->getProxy()->ice_id(); + RETURN_STRINGL((char*)id.c_str(), id.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_ids) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + vector<string> ids = _this->getProxy()->ice_ids(); + array_init(return_value); + uint idx = 0; + for(vector<string>::const_iterator p = ids.begin(); p != ids.end(); ++p, ++idx) + { + add_index_stringl(return_value, idx, (char*)(*p).c_str(), (*p).length(), 1); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_facets) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Ice::FacetPath facets = _this->getProxy()->ice_facets(); + array_init(return_value); + uint idx = 0; + for(vector<string>::const_iterator p = facets.begin(); p != facets.end(); ++p, ++idx) + { + add_index_stringl(return_value, idx, (char*)(*p).c_str(), (*p).length(), 1); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getFacet) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Ice::FacetPath facet = _this->getProxy()->ice_getFacet(); + array_init(return_value); + uint idx = 0; + for(vector<string>::const_iterator p = facet.begin(); p != facet.end(); ++p, ++idx) + { + add_index_stringl(return_value, idx, (char*)(*p).c_str(), (*p).length(), 1); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_newFacet) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + zval* zarr; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zarr) == FAILURE) + { + RETURN_NULL(); + } + + Ice::FacetPath facet; + HashTable* arr = Z_ARRVAL_P(zarr); + HashPosition pos; + zval** val; + + zend_hash_internal_pointer_reset_ex(arr, &pos); + while(zend_hash_get_current_data_ex(arr, (void**)&val, &pos) != FAILURE) + { + if(Z_TYPE_PP(val) != IS_STRING) + { + php_error(E_ERROR, "facet must be a string array"); + RETURN_NULL(); + } + facet.push_back(string(Z_STRVAL_PP(val), Z_STRLEN_PP(val))); + zend_hash_move_forward_ex(arr, &pos); + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + + Ice::ObjectPrx prx = _this->getProxy()->ice_newFacet(facet); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_appendFacet) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + char *name; + int len; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) + { + RETURN_NULL(); + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Ice::FacetPath facet; + + Ice::ObjectPrx prx = _this->getProxy()->ice_appendFacet(name); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_twoway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_twoway(); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isTwoway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + bool b = _this->getProxy()->ice_isTwoway(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_oneway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_oneway(); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isOneway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + bool b = _this->getProxy()->ice_isOneway(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_batchOneway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_batchOneway(); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchOneway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + bool b = _this->getProxy()->ice_isBatchOneway(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_datagram) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_datagram(); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isDatagram) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + bool b = _this->getProxy()->ice_isDatagram(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_batchDatagram) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_batchDatagram(); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchDatagram) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + bool b = _this->getProxy()->ice_isBatchDatagram(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_secure) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + zend_bool b; + if(zend_parse_parameters(ZEND_NUM_ARGS(), "b", &b) != SUCCESS) + { + RETURN_NULL(); + } + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_secure(b ? true : false); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_compress) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + zend_bool b; + if(zend_parse_parameters(ZEND_NUM_ARGS(), "b", &b) != SUCCESS) + { + RETURN_NULL(); + } + Ice::ObjectPrx prx = _this->getProxy()->ice_compress(b ? true : false); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + long l; + if(zend_parse_parameters(ZEND_NUM_ARGS(), "l", &l) != SUCCESS) + { + RETURN_NULL(); + } + // TODO: range check? + Ice::ObjectPrx prx = _this->getProxy()->ice_timeout(l); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_default) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_default(); + if(!Ice_ObjectPrx_create(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_flush) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + _this->getProxy()->ice_flush(); + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_uncheckedCast) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + char *id; + int len; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &len) == FAILURE) + { + RETURN_NULL(); + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + try + { + Slice::ClassDefPtr def = _this->getClass(); + if(def && def->scoped() == id) + { + // TODO: legal? + *return_value = *(getThis()); + return; + } + else + { + Slice::UnitPtr unit = Slice_getUnit(); + Slice::TypeList l; + + if(unit) + { + l = unit->lookupTypeNoBuiltin(id, false); + } + + if(l.empty()) + { + php_error(E_ERROR, "%s(): no Slice definition found for type %s", get_active_function_name(TSRMLS_C), + id); + RETURN_NULL(); + } + + // + // Allow the use of "::Type" (ClassDecl) or "::Type*" (Proxy). + // + Slice::ClassDeclPtr decl; + Slice::ProxyPtr proxy = Slice::ProxyPtr::dynamicCast(l.front()); + if(proxy) + { + decl = proxy->_class(); + } + else + { + decl = Slice::ClassDeclPtr::dynamicCast(l.front()); + } + + if(!decl) + { + php_error(E_ERROR, "%s(): type %s is not a class or interface", get_active_function_name(TSRMLS_C), + id); + RETURN_NULL(); + } + + def = decl->definition(); + if(!def) + { + php_error(E_ERROR, "%s(): no definition for type %s", get_active_function_name(TSRMLS_C), id); + RETURN_NULL(); + } + + if(!Ice_ObjectPrx_create(return_value, _this->getProxy(), def TSRMLS_CC)) + { + RETURN_NULL(); + } + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + RETVAL_FALSE; + } +} + +Operation::Operation(const Ice::ObjectPrx& proxy, const Slice::OperationPtr& op) : + _proxy(proxy), _op(op) +{ +} + +Operation::~Operation() +{ +} + +void +Operation::invoke(INTERNAL_FUNCTION_PARAMETERS) +{ + Ice::ByteSeq params, results; + Ice::OperationMode mode = (Ice::OperationMode)_op->mode(); + + try + { + if(!_proxy->ice_invoke(_op->name(), mode, params, results)) + { + // TODO + php_error(E_ERROR, "user exception occurred"); + return; + } + } + catch(const IceUtil::Exception& ex) + { + ice_throw_exception(ex TSRMLS_CC); + } +} + +Proxy::Proxy(const Ice::ObjectPrx& proxy) : + _proxy(proxy) +{ +} + +Proxy::Proxy(const Ice::ObjectPrx& proxy, const Slice::ClassDefPtr& cls) : + _proxy(proxy), _class(cls) +{ + if(cls) + { + _classOps = _class->allOperations(); + } +} + +const Ice::ObjectPrx& +Proxy::getProxy() const +{ + return _proxy; +} + +const Slice::ClassDefPtr& +Proxy::getClass() const +{ + return _class; +} + +OperationPtr +Proxy::getOperation(const string& name) +{ + OperationPtr result; + + string n = ice_lowercase(name); + map<string, OperationPtr>::const_iterator p = _ops.find(n); + if(p == _ops.end()) + { + for(Slice::OperationList::const_iterator q = _classOps.begin(); q != _classOps.end(); ++q) + { + if(n == ice_lowercase((*q)->name())) + { + result = new Operation(_proxy, *q); + _ops[n] = result; + break; + } + } + } + else + { + result = p->second; + } + + return result; +} + +static zend_object_value +Ice_ObjectPrx_alloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + ice_object* obj = ice_object_new(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, Ice_ObjectPrx_dtor, NULL TSRMLS_CC); + result.handlers = &Ice_ObjectPrx_handlers; + + return result; +} + +static void +Ice_ObjectPrx_dtor(void* p, zend_object_handle handle TSRMLS_DC) +{ + ice_object* obj = (ice_object*)p; + Proxy* _this = (Proxy*)obj->ptr; + + delete _this; + + zend_objects_destroy_object((zend_object*)p, handle TSRMLS_CC); +} + +static union _zend_function* +Ice_ObjectPrx_get_method(zval* zv, char* method, int len TSRMLS_DC) +{ + zend_function* result; + + // + // First delegate to the standard implementation of get_method. This will find + // any of our predefined proxy methods. If it returns NULL, then we return a + // function that will check the class definition. + // + result = zend_get_std_object_handlers()->get_method(zv, method, len TSRMLS_CC); + if(result == NULL) + { + ice_object* obj = (ice_object*)zend_object_store_get_object(zv TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + if(!_this->getClass()) + { + php_error(E_ERROR, "proxy has not been narrowed"); + return NULL; + } + + OperationPtr op = _this->getOperation(method); + if(!op) + { + php_error(E_ERROR, "unknown operation %s", method); + return NULL; + } + + // TODO: Leak? + zend_internal_function* zif = (zend_internal_function*)emalloc(sizeof(zend_internal_function)); + zif->arg_types = NULL; + zif->function_name = estrndup(method, len); + zif->handler = ZEND_FN(Ice_ObjectPrx_call); + zif->scope = Ice_ObjectPrx_entry_ptr; + zif->type = ZEND_INTERNAL_FUNCTION; + zif->fn_flags = ZEND_ACC_PUBLIC; + result = (zend_function*)zif; + } + + return result; +} + +ZEND_FUNCTION(Ice_ObjectPrx_call) +{ + ice_object* obj = (ice_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + assert(obj->ptr); + Proxy* _this = (Proxy*)obj->ptr; + + OperationPtr op = _this->getOperation(get_active_function_name(TSRMLS_C)); + assert(op); // get_method should have already verified the operation's existence. + + op->invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static int +Ice_ObjectPrx_call(char* method, INTERNAL_FUNCTION_PARAMETERS) +{ + cerr << "Method `" << method << "' was invoked on Ice_ObjectPrx" << endl; +} diff --git a/php/src/ice/objectprx.h b/php/src/ice/objectprx.h new file mode 100644 index 00000000000..9bbcc3f06dd --- /dev/null +++ b/php/src/ice/objectprx.h @@ -0,0 +1,97 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef ICE_PHP_OBJECT_PRX_H +#define ICE_PHP_OBJECT_PRX_H + +extern "C" +{ +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +} + +#include <Ice/Ice.h> + +bool Ice_ObjectPrx_init(TSRMLS_DC); +bool Ice_ObjectPrx_create(zval*, const Ice::ObjectPrx& TSRMLS_DC); +bool Ice_ObjectPrx_fetch(zval*, Ice::ObjectPrx& TSRMLS_DC); + +// +// Class entry. +// +extern zend_class_entry* Ice_ObjectPrx_entry_ptr; + +// +// Ice_ObjectPrx class methods. +// +ZEND_FUNCTION(Ice_ObjectPrx___construct); +ZEND_FUNCTION(Ice_ObjectPrx_ice_isA); +ZEND_FUNCTION(Ice_ObjectPrx_ice_ping); +ZEND_FUNCTION(Ice_ObjectPrx_ice_id); +ZEND_FUNCTION(Ice_ObjectPrx_ice_ids); +ZEND_FUNCTION(Ice_ObjectPrx_ice_facets); +//ZEND_FUNCTION(Ice_ObjectPrx_ice_getIdentity); +//ZEND_FUNCTION(Ice_ObjectPrx_ice_newIdentity); +ZEND_FUNCTION(Ice_ObjectPrx_ice_getFacet); +ZEND_FUNCTION(Ice_ObjectPrx_ice_newFacet); +ZEND_FUNCTION(Ice_ObjectPrx_ice_appendFacet); +ZEND_FUNCTION(Ice_ObjectPrx_ice_twoway); +ZEND_FUNCTION(Ice_ObjectPrx_ice_isTwoway); +ZEND_FUNCTION(Ice_ObjectPrx_ice_oneway); +ZEND_FUNCTION(Ice_ObjectPrx_ice_isOneway); +ZEND_FUNCTION(Ice_ObjectPrx_ice_batchOneway); +ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchOneway); +ZEND_FUNCTION(Ice_ObjectPrx_ice_datagram); +ZEND_FUNCTION(Ice_ObjectPrx_ice_isDatagram); +ZEND_FUNCTION(Ice_ObjectPrx_ice_batchDatagram); +ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchDatagram); +ZEND_FUNCTION(Ice_ObjectPrx_ice_secure); +ZEND_FUNCTION(Ice_ObjectPrx_ice_compress); +ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout); +//ZEND_FUNCTION(Ice_ObjectPrx_ice_router); +//ZEND_FUNCTION(Ice_ObjectPrx_ice_locator); +//ZEND_FUNCTION(Ice_ObjectPrx_ice_collocationOptimization); +ZEND_FUNCTION(Ice_ObjectPrx_ice_default); +ZEND_FUNCTION(Ice_ObjectPrx_ice_flush); +ZEND_FUNCTION(Ice_ObjectPrx_ice_uncheckedCast); + +#define ICE_PHP_OBJECT_PRX_FUNCTIONS \ + ZEND_FE(Ice_ObjectPrx___construct, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_isA, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_ping, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_id, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_ids, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_facets, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_getFacet, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_newFacet, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_appendFacet, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_twoway, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_isTwoway, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_oneway, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_isOneway, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_batchOneway, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_isBatchOneway, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_datagram, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_isDatagram, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_batchDatagram, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_isBatchDatagram, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_secure, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_compress, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_timeout, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_default, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_flush, NULL) \ + ZEND_FE(Ice_ObjectPrx_ice_uncheckedCast, NULL) + +#endif diff --git a/php/src/ice/php_ice.h b/php/src/ice/php_ice.h new file mode 100644 index 00000000000..24490296be7 --- /dev/null +++ b/php/src/ice/php_ice.h @@ -0,0 +1,47 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef PHP_ICE_H +#define PHP_ICE_H + +extern zend_module_entry ice_module_entry; +#define phpext_ice_ptr &ice_module_entry + +#ifdef PHP_WIN32 +#define PHP_ICE_API __declspec(dllexport) +#else +#define PHP_ICE_API +#endif + +#ifdef ZTS +#include "TSRM.h" +#endif + +ZEND_MINIT_FUNCTION(ice); +ZEND_MSHUTDOWN_FUNCTION(ice); +ZEND_RINIT_FUNCTION(ice); +ZEND_RSHUTDOWN_FUNCTION(ice); +ZEND_MINFO_FUNCTION(ice); + +ZEND_BEGIN_MODULE_GLOBALS(ice) + zval* z_communicator; +ZEND_END_MODULE_GLOBALS(ice) + +#ifdef ZTS +#define ICE_G(v) TSRMG(ice_globals_id, zend_ice_globals*, v) +#else +#define ICE_G(v) (ice_globals.v) +#endif + +#endif /* PHP_ICE_H */ diff --git a/php/src/ice/slice.cpp b/php/src/ice/slice.cpp new file mode 100644 index 00000000000..9402c76656d --- /dev/null +++ b/php/src/ice/slice.cpp @@ -0,0 +1,171 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "slice.h" +#include "util.h" +#include "php_ice.h" + +#include <Slice/Preprocessor.h> + +using namespace std; + +// +// The Slice parse tree. +// +static Slice::UnitPtr _unit; + +// +// Parse the Slice files that define the types and operations available to a PHP script. +// +static bool +parse_slice(const string& argStr) +{ + vector<string> args; + if(!ice_split_string(argStr, args)) + { + return false; + } + + string cppArgs; + vector<string> files; + bool debug = false; + bool ice = false; + bool caseSensitive = false; + + vector<string>::const_iterator p; + for(p = args.begin(); p != args.end(); ++p) + { + string arg = *p; + if(arg.substr(0, 2) == "-I" || arg.substr(0, 2) == "-D" || arg.substr(0, 2) == "-U") + { + cppArgs += ' '; + if(arg.find(' ') != string::npos) + { + cppArgs += "'"; + cppArgs += arg; + cppArgs += "'"; + } + else + { + cppArgs += arg; + } + } + else if(arg == "--ice") + { + ice = true; + } + else if(arg == "--case-sensitive") + { + caseSensitive = true; + } + else if(arg[0] == '-') + { + php_error(E_ERROR, "unknown option `%s' in ice.parse", arg.c_str()); + return false; + } + else + { + files.push_back(arg); + } + } + + if(files.empty()) + { + php_error(E_ERROR, "no Slice files specified in ice.parse"); + return false; + } + + bool ignoreRedefs = false; + bool all = false; + _unit = Slice::Unit::createUnit(ignoreRedefs, all, ice, caseSensitive); + bool status = true; + + for(p = files.begin(); p != files.end(); ++p) + { + Slice::Preprocessor icecpp("icecpp", *p, cppArgs); + FILE* cppHandle = icecpp.preprocess(false); + + if(cppHandle == 0) + { + status = false; + break; + } + + int parseStatus = _unit->parse(cppHandle, debug); + + if(!icecpp.close()) + { + status = false; + break; + } + + if(parseStatus == EXIT_FAILURE) + { + status = false; + break; + } + } + + return status; +} + +bool +Slice_init(TSRMLS_DC) +{ + // + // Parse the Slice files. + // + char* parse = INI_STR("ice.parse"); + if(parse && strlen(parse) > 0) + { + if(!parse_slice(parse)) + { + return false; + } + } + + return true; +} + +Slice::UnitPtr +Slice_getUnit(TSRMLS_DC) +{ + return _unit; +} + +bool +Slice_shutdown(TSRMLS_DC) +{ + if(_unit) + { + try + { + _unit->destroy(); + _unit = 0; + } + catch(const IceUtil::Exception& ex) + { + ostringstream ostr; + ex.ice_print(ostr); + php_error(E_ERROR, "unable to destroy Slice parse tree:\n%s", ostr.str().c_str()); + return false; + } + } + + return true; +} diff --git a/php/src/ice/slice.h b/php/src/ice/slice.h new file mode 100644 index 00000000000..880bba1a23f --- /dev/null +++ b/php/src/ice/slice.h @@ -0,0 +1,31 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef ICE_PHP_SLICE_H +#define ICE_PHP_SLICE_H + +extern "C" +{ +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +} + +#include <Slice/Parser.h> + +bool Slice_init(TSRMLS_DC); +Slice::UnitPtr Slice_getUnit(TSRMLS_DC); +bool Slice_shutdown(TSRMLS_DC); + +#endif diff --git a/php/src/ice/util.cpp b/php/src/ice/util.cpp new file mode 100644 index 00000000000..f7ff0489598 --- /dev/null +++ b/php/src/ice/util.cpp @@ -0,0 +1,114 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "util.h" +#include <algorithm> +#include <ctype.h> + +using namespace std; + +ice_object* +ice_object_new(zend_class_entry* ce TSRMLS_DC) +{ + ice_object* obj; + zval* tmp; + + obj = (ice_object*)emalloc(sizeof(ice_object)); + obj->zobj.ce = ce; + obj->zobj.in_get = 0; + obj->zobj.in_set = 0; + obj->ptr = 0; + + ALLOC_HASHTABLE(obj->zobj.properties); + zend_hash_init(obj->zobj.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(obj->zobj.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, + (void *) &tmp, sizeof(zval *)); + + return obj; +} + +ice_object* +ice_object_get(zval* zv TSRMLS_DC) +{ + if(!zv) + { + php_error(E_ERROR, "method %s() must be invoked on an object", get_active_function_name(TSRMLS_C)); + return 0; + } + + ice_object* obj = (ice_object*)zend_object_store_get_object(zv TSRMLS_CC); + if(!obj) + { + php_error(E_ERROR, "no object found in %s()", get_active_function_name(TSRMLS_C)); + return 0; + } + + return obj; +} + +bool +ice_split_string(const string& str, vector<string>& args) +{ + string delim = " \t\n\r"; + string::size_type beg; + string::size_type end = 0; + while(true) + { + beg = str.find_first_not_of(delim, end); + if(beg == string::npos) + { + break; + } + + // + // Check for quoted argument. + // + char ch = str[beg]; + if(ch == '"' || ch == '\'') + { + beg++; + end = str.find(ch, beg); + if(end == string::npos) + { + php_error(E_ERROR, "unterminated quote in `%s'", str.c_str()); + return false; + } + args.push_back(str.substr(beg, end - beg)); + end++; // Skip end quote. + } + else + { + end = str.find_first_of(delim + "'\"", beg); + if(end == string::npos) + { + end = str.length(); + } + args.push_back(str.substr(beg, end - beg)); + } + } + + return true; +} + +string +ice_lowercase(const string& s) +{ + string result(s); + transform(result.begin(), result.end(), result.begin(), ::tolower); + return result; +} diff --git a/php/src/ice/util.h b/php/src/ice/util.h new file mode 100644 index 00000000000..0c7661448a2 --- /dev/null +++ b/php/src/ice/util.h @@ -0,0 +1,57 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef ICE_PHP_UTIL_H +#define ICE_PHP_UTIL_H + +extern "C" +{ +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +} + +#include <Ice/Ice.h> + +// +// PHP wrapper for C++ objects. +// +struct ice_object +{ + zend_object zobj; + void* ptr; // For object data. +}; + +// +// Create a new ice_object for a class entry. The allocator registered for the +// class entry will be invoked, but the C++ object is not created here. +// +ice_object* ice_object_new(zend_class_entry* TSRMLS_DC); + +// +// Retrieve the ice_object given a zval. +// +ice_object* ice_object_get(zval* TSRMLS_DC); + +// +// Split a string into a vector of arguments. Quoted arguments are supported. +// +bool ice_split_string(const std::string&, std::vector<std::string>&); + +// +// Convert a string to lowercase. +// +std::string ice_lowercase(const std::string&); + +#endif |