diff options
author | Mark Spruiell <mes@zeroc.com> | 2006-11-09 18:38:47 +0000 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2006-11-09 18:38:47 +0000 |
commit | 9fc8c2106fdb8e918eefd8614aef6dd77a9c29e3 (patch) | |
tree | 3942117e687cbe34477b9d2f48d82fe098cd972b /php/src/IcePHP/Proxy.cpp | |
parent | clean up; align with C++; bug fix (diff) | |
download | ice-9fc8c2106fdb8e918eefd8614aef6dd77a9c29e3.tar.bz2 ice-9fc8c2106fdb8e918eefd8614aef6dd77a9c29e3.tar.xz ice-9fc8c2106fdb8e918eefd8614aef6dd77a9c29e3.zip |
Reorganizing source code. Changing build process to use Makefiles instead
of configure. Desupporting all platforms except Linux and Windows.
Diffstat (limited to 'php/src/IcePHP/Proxy.cpp')
-rw-r--r-- | php/src/IcePHP/Proxy.cpp | 2475 |
1 files changed, 2475 insertions, 0 deletions
diff --git a/php/src/IcePHP/Proxy.cpp b/php/src/IcePHP/Proxy.cpp new file mode 100644 index 00000000000..48b06536bf6 --- /dev/null +++ b/php/src/IcePHP/Proxy.cpp @@ -0,0 +1,2475 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/DisableWarnings.h> +#include <Proxy.h> +#include <Communicator.h> +#include <Marshal.h> +#include <Profile.h> +#include <Util.h> + +using namespace std; +using namespace IcePHP; + +ZEND_EXTERN_MODULE_GLOBALS(ice) + +// +// Here's a brief description of how proxies are handled by this extension. +// +// A single PHP class, Ice_ObjectPrx, is registered. This is an "internal" class, +// i.e., implemented by this extension, and it is used to represent all proxies +// regardless of interface type. +// +// Like in C++, a proxy is only capable of invoking the Ice::ObjectPrx operations +// until it is narrowed with a checked or unchecked cast. Unlike C++, no PHP classes +// are created for proxies, because all marshaling activity is driven by the Slice +// definitions, not by statically-generated code. +// +// In order to perform a checked or unchecked cast, the user invokes ice_checkedCast +// or ice_uncheckedCast on the proxy to be narrowed, supplying a scoped name for the +// desired type. Internally, the proxy validates the scoped name and returns a new +// proxy containing the Slice class or interface definition. This proxy is considered +// to be narrowed to that interface and therefore supports user-defined operations. +// +// Naturally, there are many predefined proxy methods (e.g., ice_isA, etc.), but +// the proxy also needs to support user-defined operations (if it has type information). +// We use a Zend API hook that allows us to intercept the invocation of unknown methods +// on the proxy object. At this point, the proxy checks the interface definition for +// an operation with the given name, and then creates an Operation object (see below) +// that is responsible for invoking the operation. The proxy caches the Operation objects +// for future reuse. +// + +// +// Class entries represent the PHP class implementations we have registered. +// +namespace IcePHP +{ +zend_class_entry* proxyClassEntry = 0; +zend_class_entry* endpointClassEntry = 0; +zend_class_entry* connectionClassEntry = 0; +} + +// +// Ice::ObjectPrx and Ice::Endpoint support. +// +static zend_object_handlers _proxyHandlers; +static zend_object_handlers _endpointHandlers; +static zend_object_handlers _connectionHandlers; + +extern "C" +{ +static zend_object_value handleProxyAlloc(zend_class_entry* TSRMLS_DC); +static void handleProxyFreeStorage(void* TSRMLS_DC); +static zend_object_value handleProxyClone(zval* TSRMLS_DC); +static union _zend_function* handleProxyGetMethod(zval**, char*, int TSRMLS_DC); +static int handleProxyCompare(zval*, zval* TSRMLS_DC); +ZEND_FUNCTION(Ice_ObjectPrx_call); + +static zend_object_value handleEndpointAlloc(zend_class_entry* TSRMLS_DC); +static void handleEndpointFreeStorage(void* TSRMLS_DC); + +static zend_object_value handleConnectionAlloc(zend_class_entry* TSRMLS_DC); +static void handleConnectionFreeStorage(void* TSRMLS_DC); +static int handleConnectionCompare(zval*, zval* TSRMLS_DC); +} + +namespace IcePHP +{ + +// +// Encapsulates an operation description. +// +class Operation : public IceUtil::SimpleShared +{ +public: + Operation(const Ice::ObjectPrx&, const string&, const Slice::OperationPtr&, const Ice::CommunicatorPtr& + TSRMLS_DC); + virtual ~Operation(); + + zend_function* getZendFunction() const; + void invoke(INTERNAL_FUNCTION_PARAMETERS); + +private: + void throwUserException(Ice::InputStreamPtr& TSRMLS_DC); + + Ice::ObjectPrx _proxy; + string _name; // Local name, not the on-the-wire name + Slice::OperationPtr _op; + Ice::CommunicatorPtr _communicator; +#ifdef ZTS + TSRMLS_D; +#endif + vector<string> _paramNames; + MarshalerPtr _result; + vector<MarshalerPtr> _inParams; + vector<MarshalerPtr> _outParams; + zend_internal_function* _zendFunction; +}; +typedef IceUtil::Handle<Operation> OperationPtr; + +// +// Encapsulates proxy and type information. +// +class Proxy +{ +public: + Proxy(const Ice::ObjectPrx&, const Slice::ClassDefPtr& TSRMLS_DC); + ~Proxy(); + + const Ice::ObjectPrx& getProxy() const; + const Slice::ClassDefPtr& getClass() const; + + OperationPtr getOperation(const string&); + + string toString() const; + +private: + Ice::ObjectPrx _proxy; + Slice::ClassDefPtr _class; +#ifdef ZTS + TSRMLS_D; +#endif + zval _communicatorZval; + Ice::CommunicatorPtr _communicator; + Slice::OperationList _classOps; + map<string, OperationPtr> _ops; +}; + +} // End of namespace IcePHP + +// +// Predefined methods for Ice_ObjectPrx. +// +static function_entry _proxyMethods[] = +{ + {"__construct", PHP_FN(Ice_ObjectPrx___construct), NULL}, + {"__tostring", PHP_FN(Ice_ObjectPrx___tostring), NULL}, + {"ice_getCommunicator", PHP_FN(Ice_ObjectPrx_ice_getCommunicator), NULL}, + {"ice_toString", PHP_FN(Ice_ObjectPrx_ice_toString), 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_getIdentity", PHP_FN(Ice_ObjectPrx_ice_getIdentity), NULL}, + {"ice_newIdentity", PHP_FN(Ice_ObjectPrx_ice_identity), NULL}, + {"ice_identity", PHP_FN(Ice_ObjectPrx_ice_identity), NULL}, + {"ice_getContext", PHP_FN(Ice_ObjectPrx_ice_getContext), NULL}, + {"ice_newContext", PHP_FN(Ice_ObjectPrx_ice_context), NULL}, + {"ice_context", PHP_FN(Ice_ObjectPrx_ice_context), NULL}, + {"ice_defaultContext", PHP_FN(Ice_ObjectPrx_ice_defaultContext), NULL}, + {"ice_getFacet", PHP_FN(Ice_ObjectPrx_ice_getFacet), NULL}, + {"ice_newFacet", PHP_FN(Ice_ObjectPrx_ice_facet), NULL}, + {"ice_facet", PHP_FN(Ice_ObjectPrx_ice_facet), NULL}, + {"ice_getAdapterId", PHP_FN(Ice_ObjectPrx_ice_getAdapterId), NULL}, + {"ice_newAdapterId", PHP_FN(Ice_ObjectPrx_ice_adapterId), NULL}, + {"ice_adapterId", PHP_FN(Ice_ObjectPrx_ice_adapterId), NULL}, + {"ice_getEndpoints", PHP_FN(Ice_ObjectPrx_ice_getEndpoints), NULL}, + {"ice_newEndpoints", PHP_FN(Ice_ObjectPrx_ice_endpoints), NULL}, + {"ice_endpoints", PHP_FN(Ice_ObjectPrx_ice_endpoints), NULL}, + {"ice_getLocatorCacheTimeout", PHP_FN(Ice_ObjectPrx_ice_getLocatorCacheTimeout), NULL}, + {"ice_locatorCacheTimeout", PHP_FN(Ice_ObjectPrx_ice_locatorCacheTimeout), NULL}, + {"ice_isConnectionCached", PHP_FN(Ice_ObjectPrx_ice_isConnectionCached), NULL}, + {"ice_connectionCached", PHP_FN(Ice_ObjectPrx_ice_connectionCached), NULL}, + {"ice_getEndpointSelection", PHP_FN(Ice_ObjectPrx_ice_getEndpointSelection), NULL}, + {"ice_endpointSelection", PHP_FN(Ice_ObjectPrx_ice_endpointSelection), NULL}, + {"ice_isSecure", PHP_FN(Ice_ObjectPrx_ice_isSecure), NULL}, + {"ice_secure", PHP_FN(Ice_ObjectPrx_ice_secure), 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_compress", PHP_FN(Ice_ObjectPrx_ice_compress), NULL}, + {"ice_timeout", PHP_FN(Ice_ObjectPrx_ice_timeout), NULL}, + {"ice_connectionId", PHP_FN(Ice_ObjectPrx_ice_connectionId), NULL}, + {"ice_getConnection", PHP_FN(Ice_ObjectPrx_ice_getConnection), NULL}, + {"ice_uncheckedCast", PHP_FN(Ice_ObjectPrx_ice_uncheckedCast), NULL}, + {"ice_checkedCast", PHP_FN(Ice_ObjectPrx_ice_checkedCast), NULL}, + {NULL, NULL, NULL} +}; + +// +// Predefined methods for Ice_Endpoint. +// +static function_entry _endpointMethods[] = +{ + {"__construct", PHP_FN(Ice_Endpoint___construct), NULL}, + {"__tostring", PHP_FN(Ice_Endpoint___tostring), NULL}, + {"toString", PHP_FN(Ice_Endpoint_toString), NULL}, + {NULL, NULL, NULL} +}; + +// +// Predefined methods for Ice_Connection. +// +static function_entry _connectionMethods[] = +{ + {"__construct", PHP_FN(Ice_Connection___construct), NULL}, + {"__tostring", PHP_FN(Ice_Connection___tostring), NULL}, + {"close", PHP_FN(Ice_Connection_close), NULL}, + {"flushBatchRequests", PHP_FN(Ice_Connection_flushBatchRequests), NULL}, + {"type", PHP_FN(Ice_Connection_type), NULL}, + {"timeout", PHP_FN(Ice_Connection_timeout), NULL}, + {"toString", PHP_FN(Ice_Connection_toString), NULL}, + {NULL, NULL, NULL} +}; + +bool +IcePHP::proxyInit(TSRMLS_D) +{ + // + // Register the Ice_ObjectPrx class. + // + zend_class_entry ce; + INIT_CLASS_ENTRY(ce, "Ice_ObjectPrx", _proxyMethods); + ce.create_object = handleProxyAlloc; + proxyClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_proxyHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + _proxyHandlers.clone_obj = handleProxyClone; + _proxyHandlers.get_method = handleProxyGetMethod; + _proxyHandlers.compare_objects = handleProxyCompare; + + // + // Register the Ice_Endpoint class. + // + INIT_CLASS_ENTRY(ce, "Ice_Endpoint", _endpointMethods); + ce.create_object = handleEndpointAlloc; + endpointClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_endpointHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + + // + // Register the Ice_Connection class. + // + INIT_CLASS_ENTRY(ce, "Ice_Connection", _connectionMethods); + ce.create_object = handleConnectionAlloc; + connectionClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_connectionHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + _connectionHandlers.compare_objects = handleConnectionCompare; + + return true; +} + +bool +IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC) +{ + return createProxy(zv, p, 0 TSRMLS_CC); +} + +bool +IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const Slice::ClassDefPtr& def TSRMLS_DC) +{ + if(object_init_ex(zv, proxyClassEntry) != SUCCESS) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "unable to initialize proxy"); + return false; + } + + ice_object* zprx = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC)); + assert(!zprx->ptr); + zprx->ptr = new Proxy(p, def TSRMLS_CC); + + return true; +} + +bool +IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, Slice::ClassDefPtr& def TSRMLS_DC) +{ + if(!ZVAL_IS_NULL(zv)) + { + void* p = zend_object_store_get_object(zv TSRMLS_CC); + if(!p) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "unable to retrieve proxy object from object store"); + return false; + } + if(Z_OBJCE_P(zv) != proxyClassEntry) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "value is not a proxy"); + return false; + } + ice_object* obj = static_cast<ice_object*>(p); + assert(obj->ptr); + Proxy* proxy = static_cast<Proxy*>(obj->ptr); + prx = proxy->getProxy(); + def = proxy->getClass(); + } + return true; +} + +static bool +createEndpoint(zval* zv, const Ice::EndpointPtr& p TSRMLS_DC) +{ + if(object_init_ex(zv, endpointClassEntry) != SUCCESS) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "unable to initialize endpoint"); + return false; + } + + ice_object* ze = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC)); + assert(!ze->ptr); + ze->ptr = new Ice::EndpointPtr(p); + + return true; +} + +static bool +fetchEndpoint(zval* zv, Ice::EndpointPtr& endpoint TSRMLS_DC) +{ + if(!ZVAL_IS_NULL(zv)) + { + void* p = zend_object_store_get_object(zv TSRMLS_CC); + if(!p) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "unable to retrieve endpoint object from object store"); + return false; + } + if(Z_OBJCE_P(zv) != endpointClassEntry) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "value is not an endpoint"); + return false; + } + ice_object* obj = static_cast<ice_object*>(p); + assert(obj->ptr); + Ice::EndpointPtr* pe = static_cast<Ice::EndpointPtr*>(obj->ptr); + endpoint = *pe; + } + return true; +} + +static bool +createConnection(zval* zv, const Ice::ConnectionPtr& p TSRMLS_DC) +{ + if(object_init_ex(zv, connectionClassEntry) != SUCCESS) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "unable to initialize connection"); + return false; + } + + ice_object* ze = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC)); + assert(!ze->ptr); + ze->ptr = new Ice::ConnectionPtr(p); + + return true; +} + +ZEND_FUNCTION(Ice_ObjectPrx___construct) +{ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Ice_ObjectPrx cannot be instantiated, use $ICE->stringToProxy()"); +} + +ZEND_FUNCTION(Ice_ObjectPrx___tostring) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + string str = _this->toString(); + RETURN_STRINGL(const_cast<char*>(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getCommunicator) +{ + zval* zc = getCommunicatorZval(TSRMLS_C); + + Z_TYPE_P(return_value) = IS_OBJECT; + return_value->value.obj = zc->value.obj; + Z_OBJ_HT_P(return_value)->add_ref(return_value TSRMLS_CC); +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_toString) +{ + ZEND_FN(Ice_ObjectPrx___tostring)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isA) +{ + if(ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2) + { + WRONG_PARAM_COUNT; + } + + char* id; + int len; + zval* arr = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &id, &len, &arr) == FAILURE) + { + RETURN_FALSE; + } + + // + // Populate the context (if necessary). + // + Ice::Context ctx; + if(arr && !extractContext(arr, ctx TSRMLS_CC)) + { + RETURN_FALSE; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + bool b; + if(arr) + { + b = _this->getProxy()->ice_isA(id, ctx); + } + else + { + b = _this->getProxy()->ice_isA(id); + } + + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETVAL_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_ping) +{ + if(ZEND_NUM_ARGS() > 1) + { + WRONG_PARAM_COUNT; + } + + zval* arr = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &arr) == FAILURE) + { + RETURN_NULL(); + } + + // + // Populate the context (if necessary). + // + Ice::Context ctx; + if(arr && !extractContext(arr, ctx TSRMLS_CC)) + { + RETURN_NULL(); + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + if(arr) + { + _this->getProxy()->ice_ping(ctx); + } + else + { + _this->getProxy()->ice_ping(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + } + + RETURN_NULL(); +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_id) +{ + if(ZEND_NUM_ARGS() > 1) + { + WRONG_PARAM_COUNT; + } + + zval* arr = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &arr) == FAILURE) + { + RETURN_NULL(); + } + + // + // Populate the context (if necessary). + // + Ice::Context ctx; + if(arr && !extractContext(arr, ctx TSRMLS_CC)) + { + RETURN_NULL(); + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + string id; + if(arr) + { + id = _this->getProxy()->ice_id(ctx); + } + else + { + id = _this->getProxy()->ice_id(); + } + RETURN_STRINGL(const_cast<char*>(id.c_str()), id.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_ids) +{ + if(ZEND_NUM_ARGS() > 1) + { + WRONG_PARAM_COUNT; + } + + zval* arr = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &arr) == FAILURE) + { + RETURN_NULL(); + } + + // + // Populate the context (if necessary). + // + Ice::Context ctx; + if(arr && !extractContext(arr, ctx TSRMLS_CC)) + { + RETURN_NULL(); + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + vector<string> ids; + if(arr) + { + ids = _this->getProxy()->ice_ids(ctx); + } + else + { + 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, const_cast<char*>((*p).c_str()), (*p).length(), 1); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getIdentity) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + createIdentity(return_value, _this->getProxy()->ice_getIdentity() TSRMLS_CC); +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_identity) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC); + assert(cls); + + zval *zid; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zid, cls) == FAILURE) + { + RETURN_NULL(); + } + + Ice::Identity id; + if(extractIdentity(zid, id TSRMLS_CC)) + { + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_identity(id); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getContext) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + createContext(return_value, _this->getProxy()->ice_getContext() TSRMLS_CC); +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_context) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + zval* arr = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) + { + RETURN_NULL(); + } + + // + // Populate the context. + // + Ice::Context ctx; + if(arr && !extractContext(arr, ctx TSRMLS_CC)) + { + RETURN_NULL(); + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_context(ctx); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_defaultContext) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_defaultContext(); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getFacet) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + string facet = _this->getProxy()->ice_getFacet(); + ZVAL_STRINGL(return_value, const_cast<char*>(facet.c_str()), facet.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_facet) +{ + 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 = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_facet(name); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getAdapterId) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + string id = _this->getProxy()->ice_getAdapterId(); + ZVAL_STRINGL(return_value, const_cast<char*>(id.c_str()), id.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_adapterId) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + char* id; + int len; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &len) == FAILURE) + { + RETURN_NULL(); + } + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_adapterId(id); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpoints) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::EndpointSeq endpoints = _this->getProxy()->ice_getEndpoints(); + + array_init(return_value); + uint idx = 0; + for(Ice::EndpointSeq::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p, ++idx) + { + zval* elem; + MAKE_STD_ZVAL(elem); + if(!createEndpoint(elem, *p TSRMLS_CC)) + { + zval_ptr_dtor(&elem); + RETURN_NULL(); + } + add_index_zval(return_value, idx, elem); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + zval* zv; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zv) == FAILURE) + { + RETURN_NULL(); + } + + Ice::EndpointSeq seq; + + HashTable* arr = Z_ARRVAL_P(zv); + 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_OBJECT) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "expected an element of type Ice_Endpoint"); + RETURN_NULL(); + } + + Ice::EndpointPtr endpoint; + if(!fetchEndpoint(*val, endpoint TSRMLS_CC)) + { + RETURN_NULL(); + } + + seq.push_back(endpoint); + + zend_hash_move_forward_ex(arr, &pos); + } + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_endpoints(seq); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocatorCacheTimeout) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::Int timeout = _this->getProxy()->ice_getLocatorCacheTimeout(); + ZVAL_LONG(return_value, static_cast<long>(timeout)); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_locatorCacheTimeout) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + long l; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &l) != SUCCESS) + { + RETURN_NULL(); + } + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_locatorCacheTimeout(l); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isConnectionCached) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + bool b = _this->getProxy()->ice_isConnectionCached(); + ZVAL_BOOL(return_value, b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionCached) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + zend_bool b; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b) != SUCCESS) + { + RETURN_NULL(); + } + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_connectionCached(b ? true : false); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpointSelection) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::EndpointSelectionType type = _this->getProxy()->ice_getEndpointSelection(); + ZVAL_LONG(return_value, type == Ice::Random ? 0 : 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_endpointSelection) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + long l; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &l) != SUCCESS) + { + RETURN_NULL(); + } + + if(l < 0 || l > 1) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "expecting Random or Ordered"); + RETURN_NULL(); + } + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_endpointSelection(l == 0 ? Ice::Random : Ice::Ordered); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isSecure) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + bool b = _this->getProxy()->ice_isSecure(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_secure) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + zend_bool b; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b TSRMLS_CC) != SUCCESS) + { + RETURN_NULL(); + } + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_secure(b ? true : false); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_twoway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_twoway(); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isTwoway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + bool b = _this->getProxy()->ice_isTwoway(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_oneway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_oneway(); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isOneway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + bool b = _this->getProxy()->ice_isOneway(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_batchOneway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_batchOneway(); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchOneway) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + bool b = _this->getProxy()->ice_isBatchOneway(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_datagram) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_datagram(); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isDatagram) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + bool b = _this->getProxy()->ice_isDatagram(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_batchDatagram) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::ObjectPrx prx = _this->getProxy()->ice_batchDatagram(); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchDatagram) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + bool b = _this->getProxy()->ice_isBatchDatagram(); + RETURN_BOOL(b ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_compress) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + zend_bool b; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b) != SUCCESS) + { + RETURN_NULL(); + } + Ice::ObjectPrx prx = _this->getProxy()->ice_compress(b ? true : false); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + long l; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &l) != SUCCESS) + { + RETURN_NULL(); + } + // TODO: range check? + Ice::ObjectPrx prx = _this->getProxy()->ice_timeout(l); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionId) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + char* id; + int idLen; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &idLen) != SUCCESS) + { + RETURN_NULL(); + } + Ice::ObjectPrx prx = _this->getProxy()->ice_connectionId(id); + if(!createProxy(return_value, prx TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_getConnection) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Ice::ConnectionPtr con = _this->getProxy()->ice_getConnection(); + if(!createConnection(return_value, con TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +static void +do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check) +{ + // + // First argument is required and should be a scoped name. The second argument + // is optional and represents a facet name. + // + if(ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2) + { + WRONG_PARAM_COUNT; + } + + char* id; + int idLen; + char* facet = NULL; + int facetLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &id, &idLen, &facet, &facetLen) == FAILURE) + { + RETURN_NULL(); + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + try + { + Slice::TypeList l; + Profile* profile = static_cast<Profile*>(ICE_G(profile)); + if(profile) + { + l = profile->unit->lookupTypeNoBuiltin(id, false); + } + + if(l.empty()) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "no Slice definition found for type %s", id); + RETURN_NULL(); + } + + // + // Allow the use of "::Type" (ClassDecl) or "::Type*" (Proxy). + // + Slice::ClassDeclPtr decl; + Slice::TypePtr type = l.front(); + Slice::ProxyPtr proxy = Slice::ProxyPtr::dynamicCast(type); + if(proxy) + { + decl = proxy->_class(); + } + else + { + decl = Slice::ClassDeclPtr::dynamicCast(type); + } + + if(!decl) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "type %s is not a class or interface", id); + RETURN_NULL(); + } + + if(decl->isLocal()) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "%s is a local type", id); + RETURN_NULL(); + } + + Slice::ClassDefPtr def = decl->definition(); + if(!def) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "%s is declared but not defined", id); + RETURN_NULL(); + } + + string scoped = decl->scoped(); + + // + // Verify that the script has compiled the Slice definition for this type. + // + if(findClassScoped(scoped TSRMLS_CC) == 0) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "the Slice definition for type %s has not been compiled", + scoped.c_str()); + RETURN_NULL(); + } + + Ice::ObjectPrx prx = _this->getProxy(); + if(facet) + { + prx = prx->ice_facet(facet); + } + + if(check) + { + // + // Verify that the object supports the requested type. We don't use id here, + // because it might contain a proxy type (e.g., "::MyClass*"). + // + if(!prx->ice_isA(scoped)) + { + RETURN_NULL(); + } + } + + if(!createProxy(return_value, prx, def TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETVAL_FALSE; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_uncheckedCast) +{ + do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); +} + +ZEND_FUNCTION(Ice_ObjectPrx_ice_checkedCast) +{ + do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); +} + +ZEND_FUNCTION(Ice_Endpoint___construct) +{ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Ice_Endpoint cannot be instantiated"); +} + +ZEND_FUNCTION(Ice_Endpoint___tostring) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Ice::EndpointPtr* _this = static_cast<Ice::EndpointPtr*>(obj->ptr); + + try + { + string str = (*_this)->toString(); + RETURN_STRINGL(const_cast<char*>(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_Endpoint_toString) +{ + ZEND_FN(Ice_Endpoint___tostring)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +ZEND_FUNCTION(Ice_Connection___construct) +{ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Ice_Connection cannot be instantiated"); +} + +ZEND_FUNCTION(Ice_Connection___tostring) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr); + + try + { + string str = (*_this)->toString(); + RETURN_STRINGL(const_cast<char*>(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_Connection_close) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr); + + zend_bool b; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b TSRMLS_CC) != SUCCESS) + { + RETURN_NULL(); + } + + try + { + (*_this)->close(b ? true : false); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_Connection_flushBatchRequests) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr); + + try + { + (*_this)->flushBatchRequests(); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_Connection_type) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr); + + try + { + string str = (*_this)->type(); + RETURN_STRINGL(const_cast<char*>(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_Connection_timeout) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr); + + try + { + Ice::Int timeout = (*_this)->timeout(); + ZVAL_LONG(return_value, static_cast<long>(timeout)); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_FUNCTION(Ice_Connection_toString) +{ + ZEND_FN(Ice_Connection___tostring)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +IcePHP::Operation::Operation(const Ice::ObjectPrx& proxy, const string& name, const Slice::OperationPtr& op, + const Ice::CommunicatorPtr& communicator TSRMLS_DC) : + _proxy(proxy), _name(name), _op(op), _communicator(communicator), _zendFunction(0) +{ +#ifdef ZTS + this->TSRMLS_C = TSRMLS_C; +#endif + // + // Create Marshaler objects for return type and parameters. + // + Slice::TypePtr ret = op->returnType(); + if(ret) + { + _result = Marshaler::createMarshaler(ret TSRMLS_CC); + if(!_result) + { + return; + } + } + + Slice::ParamDeclList params = op->parameters(); + + // + // Create an array that indicates how arguments are passed to the operation. + // + zend_arg_info* argInfo = new zend_arg_info[params.size()]; + + int i; + Slice::ParamDeclList::const_iterator p; + for(p = params.begin(), i = 0; p != params.end(); ++p, ++i) + { + Slice::TypePtr paramType = (*p)->type(); + MarshalerPtr m = Marshaler::createMarshaler(paramType TSRMLS_CC); + if(!m) + { + break; + } + _paramNames.push_back((*p)->name()); + argInfo[i].name = NULL; + argInfo[i].class_name = NULL; + argInfo[i].allow_null = 1; + Slice::ContainedPtr cont = Slice::ContainedPtr::dynamicCast(paramType); + if(cont) + { + argInfo[i].array_type_hint = ((cont->containedType() == Slice::Contained::ContainedTypeSequence || + cont->containedType() == Slice::Contained::ContainedTypeDictionary) ? 1 : 0); + } + else + { + argInfo[i].array_type_hint = 0; + } + argInfo[i].return_reference = 0; + argInfo[i].required_num_args = static_cast<zend_uint>(params.size()); + if((*p)->isOutParam()) + { + argInfo[i].pass_by_reference = 1; + _outParams.push_back(m); + } + else + { + argInfo[i].pass_by_reference = 0; + _inParams.push_back(m); + } + } + + _zendFunction = static_cast<zend_internal_function*>(emalloc(sizeof(zend_internal_function))); + _zendFunction->type = ZEND_INTERNAL_FUNCTION; + _zendFunction->function_name = estrndup(const_cast<char*>(name.c_str()), name.length()); + _zendFunction->scope = proxyClassEntry; + _zendFunction->fn_flags = ZEND_ACC_PUBLIC; + _zendFunction->prototype = 0; + _zendFunction->num_args = static_cast<zend_uint>(params.size()); + _zendFunction->arg_info = argInfo; + _zendFunction->pass_rest_by_reference = 0; + _zendFunction->required_num_args = _zendFunction->num_args; + _zendFunction->return_reference = 0; + _zendFunction->handler = ZEND_FN(Ice_ObjectPrx_call); +} + +IcePHP::Operation::~Operation() +{ + if(_zendFunction) + { + delete []_zendFunction->arg_info; + efree(_zendFunction->function_name); + efree(_zendFunction); + } +} + +zend_function* +IcePHP::Operation::getZendFunction() const +{ + return (zend_function*)_zendFunction; +} + +void +IcePHP::Operation::invoke(INTERNAL_FUNCTION_PARAMETERS) +{ + Ice::OperationMode mode = (Ice::OperationMode)_op->sendMode(); + int i; + + // + // Verify that the expected number of arguments are supplied. The context argument is optional. + // + int numParams = static_cast<int>(_inParams.size() + _outParams.size()); + if(ZEND_NUM_ARGS() != numParams && ZEND_NUM_ARGS() != numParams + 1) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "incorrect number of parameters (%d)", numParams); + return; + } + + // + // Retrieve the arguments. + // + zval*** args = static_cast<zval***>(emalloc(ZEND_NUM_ARGS() * sizeof(zval**))); + AutoEfree autoArgs(args); // Call efree on return + if(zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "unable to get arguments"); + return; + } + + // + // Verify that the zvals for out parameters are passed by reference. + // + for(i = static_cast<int>(_inParams.size()); i < numParams; ++i) + { + if(!PZVAL_IS_REF(*args[i])) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "argument for out parameter %s must be passed by reference", + _paramNames[i].c_str()); + return; + } + } + + try + { + // + // Marshal the arguments. + // + Ice::OutputStreamPtr os = Ice::createOutputStream(_communicator); + ObjectMap objectMap; + vector<MarshalerPtr>::iterator p; + for(i = 0, p = _inParams.begin(); p != _inParams.end(); ++i, ++p) + { + if(!(*p)->marshal(*args[i], os, objectMap TSRMLS_CC)) + { + return; + } + } + + if(_op->sendsClasses()) + { + os->writePendingObjects(); + } + + Ice::ByteSeq params; + os->finished(params); + + // + // Populate the context (if necessary). + // + Ice::Context ctx; + bool haveContext = false; + if(ZEND_NUM_ARGS() == numParams + 1) + { + if(extractContext(*args[numParams], ctx TSRMLS_CC)) + { + haveContext = true; + } + else + { + return; + } + } + + // + // Invoke the operation. Don't use _name here. + // + Ice::ByteSeq result; + bool status; + if(haveContext) + { + status = _proxy->ice_invoke(_op->name(), mode, params, result, ctx); + } + else + { + status = _proxy->ice_invoke(_op->name(), mode, params, result); + } + + // + // Process the reply. + // + if(_proxy->ice_isTwoway()) + { + Ice::InputStreamPtr is = Ice::createInputStream(_communicator, result); + + if(status) + { + // + // Unmarshal the results. + // + // TODO: Check for oneway/datagram errors + // + for(i = _inParams.size(), p = _outParams.begin(); p != _outParams.end(); ++i, ++p) + { + // + // We must explicitly destroy the existing contents of all zvals passed + // as out parameters, otherwise leaks occur. + // + zval_dtor(*args[i]); + if(!(*p)->unmarshal(*args[i], is TSRMLS_CC)) + { + return; + } + } + if(_result) + { + if(!_result->unmarshal(return_value, is TSRMLS_CC)) + { + return; + } + } + if(_op->returnsClasses()) + { + is->readPendingObjects(); + } + } + else + { + // + // Unmarshal and "throw" a user exception. + // + throwUserException(is TSRMLS_CC); + } + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + } +} + +void +IcePHP::Operation::throwUserException(Ice::InputStreamPtr& is TSRMLS_DC) +{ + Slice::UnitPtr unit = _op->unit(); + + is->readBool(); // usesClasses + + string id = is->readString(); + while(!id.empty()) + { + // + // Look for a definition of this type. + // + Slice::ExceptionPtr ex = unit->lookupException(id, false); + if(ex) + { + if(ex->isLocal()) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "cannot unmarshal local exception %s", id.c_str()); + return; + } + + MarshalerPtr m = Marshaler::createExceptionMarshaler(ex TSRMLS_CC); + assert(m); + + zval* zex; + MAKE_STD_ZVAL(zex); + if(m->unmarshal(zex, is TSRMLS_CC)) + { + if(ex->usesClasses()) + { + is->readPendingObjects(); + } + zend_throw_exception_object(zex TSRMLS_CC); + } + else + { + zval_dtor(zex); + } + + return; + } + else + { + is->skipSlice(); + id = is->readString(); + } + } + // + // Getting here should be impossible: we can get here only if the + // sender has marshaled a sequence of type IDs, none of which we + // have factory for. This means that sender and receiver disagree + // about the Slice definitions they use. + // + throw Ice::UnknownUserException(__FILE__, __LINE__); +} + +IcePHP::Proxy::Proxy(const Ice::ObjectPrx& proxy, const Slice::ClassDefPtr& cls TSRMLS_DC) : + _proxy(proxy), _class(cls) +{ +#ifdef ZTS + this->TSRMLS_C = TSRMLS_C; +#endif + + // + // We want to ensure that the PHP object corresponding to the communicator is + // not destroyed until after this proxy is destroyed. We keep a copy of the + // communicator's zval because the symbol table holding the communicator's zval + // may be destroyed before this proxy, therefore our destructor cannot rely on + // symbol table lookup when it needs to decrement the reference count. + // + zval* zc = getCommunicatorZval(TSRMLS_C); + _communicatorZval = *zc; // This is legal - it simply copies the object's handle + Z_OBJ_HT(_communicatorZval)->add_ref(&_communicatorZval TSRMLS_CC); + + _communicator = getCommunicator(TSRMLS_C); + + if(cls) + { + _classOps = _class->allOperations(); + } +} + +IcePHP::Proxy::~Proxy() +{ + // + // In order to avoid the communicator's "leak warning", we have to ensure that we + // remove any references to the communicator or its supporting objects. This must + // be done prior to invoking del_ref(), because the C++ communicator object may + // be destroyed during this call. + // + _communicator = 0; + _ops.clear(); + _proxy = 0; + Z_OBJ_HT(_communicatorZval)->del_ref(&_communicatorZval TSRMLS_CC); +} + +const Ice::ObjectPrx& +IcePHP::Proxy::getProxy() const +{ + return _proxy; +} + +const Slice::ClassDefPtr& +IcePHP::Proxy::getClass() const +{ + return _class; +} + +OperationPtr +IcePHP::Proxy::getOperation(const string& name) +{ + OperationPtr result; + + string n = 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) + { + string opName = lowerCase(fixIdent((*q)->name())); + if(n == opName) + { + result = new Operation(_proxy, opName, *q, _communicator TSRMLS_CC); + _ops[opName] = result; + break; + } + } + } + else + { + result = p->second; + } + + return result; +} + +string +IcePHP::Proxy::toString() const +{ + return _communicator->proxyToString(_proxy); +} + +#ifdef WIN32 +extern "C" +#endif +static zend_object_value +handleProxyAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + ice_object* obj = newObject(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, NULL, (zend_objects_free_object_storage_t)handleProxyFreeStorage, + NULL TSRMLS_CC); + result.handlers = &_proxyHandlers; + + return result; +} + +#ifdef WIN32 +extern "C" +#endif +static void +handleProxyFreeStorage(void* p TSRMLS_DC) +{ + ice_object* obj = (ice_object*)p; + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + delete _this; + + zend_objects_free_object_storage((zend_object*)p TSRMLS_CC); +} + +#ifdef WIN32 +extern "C" +#endif +static zend_object_value +handleProxyClone(zval* zv TSRMLS_DC) +{ + // + // Create a new object that shares a C++ proxy instance with this object. + // + + zend_object_value result; + memset(&result, 0, sizeof(zend_object_value)); + + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + zval* clone; + MAKE_STD_ZVAL(clone); + if(object_init_ex(clone, IcePHP::proxyClassEntry) != SUCCESS) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "unable to initialize proxy"); + return result; + } + + ice_object* cobj = static_cast<ice_object*>(zend_object_store_get_object(clone TSRMLS_CC)); + assert(!cobj->ptr); + cobj->ptr = new Proxy(_this->getProxy(), _this->getClass() TSRMLS_CC); + + // + // We only need to return the new object's handle, so we must destroy the zval containing + // a reference to the new object. We increment the object's reference count to ensure it + // does not get destroyed. + // + result = clone->value.obj; + Z_OBJ_HT_P(clone)->add_ref(clone TSRMLS_CC); + zval_dtor(clone); + efree(clone); + + return result; +} + +#ifdef WIN32 +extern "C" +#endif +static union _zend_function* +handleProxyGetMethod(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 = static_cast<ice_object*>(zend_object_store_get_object(*zv TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + Slice::ClassDefPtr def = _this->getClass(); + if(!def) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "unknown method %s invoked on untyped proxy", method); + return NULL; + } + + OperationPtr op = _this->getOperation(method); + if(!op) + { + string scoped = def->scoped(); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "unknown operation %s invoked on proxy of type %s", method, + scoped.c_str()); + return NULL; + } + + result = op->getZendFunction(); + } + + return result; +} + +#ifdef WIN32 +extern "C" +#endif +static int +handleProxyCompare(zval* zobj1, zval* zobj2 TSRMLS_DC) +{ + // + // PHP guarantees that the objects have the same class. + // + + ice_object* obj1 = static_cast<ice_object*>(zend_object_store_get_object(zobj1 TSRMLS_CC)); + assert(obj1->ptr); + Proxy* _this1 = static_cast<Proxy*>(obj1->ptr); + Ice::ObjectPrx prx1 = _this1->getProxy(); + + ice_object* obj2 = static_cast<ice_object*>(zend_object_store_get_object(zobj2 TSRMLS_CC)); + assert(obj2->ptr); + Proxy* _this2 = static_cast<Proxy*>(obj2->ptr); + Ice::ObjectPrx prx2 = _this2->getProxy(); + + if(prx1 == prx2) + { + return 0; + } + else if(prx1 < prx2) + { + return -1; + } + else + { + return 1; + } +} + +ZEND_FUNCTION(Ice_ObjectPrx_call) +{ + ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); + assert(obj->ptr); + Proxy* _this = static_cast<Proxy*>(obj->ptr); + + OperationPtr op = _this->getOperation(get_active_function_name(TSRMLS_C)); + assert(op); // handleGetethod should have already verified the operation's existence. + + op->invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +#ifdef WIN32 +extern "C" +#endif +static zend_object_value +handleEndpointAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + ice_object* obj = newObject(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, NULL, (zend_objects_free_object_storage_t)handleEndpointFreeStorage, + NULL TSRMLS_CC); + result.handlers = &_endpointHandlers; + + return result; +} + +#ifdef WIN32 +extern "C" +#endif +static void +handleEndpointFreeStorage(void* p TSRMLS_DC) +{ + ice_object* obj = (ice_object*)p; + Ice::EndpointPtr* _this = static_cast<Ice::EndpointPtr*>(obj->ptr); + + delete _this; + + zend_objects_free_object_storage((zend_object*)p TSRMLS_CC); +} + +#ifdef WIN32 +extern "C" +#endif +static zend_object_value +handleConnectionAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + ice_object* obj = newObject(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, NULL, (zend_objects_free_object_storage_t)handleConnectionFreeStorage, + NULL TSRMLS_CC); + result.handlers = &_connectionHandlers; + + return result; +} + +#ifdef WIN32 +extern "C" +#endif +static void +handleConnectionFreeStorage(void* p TSRMLS_DC) +{ + ice_object* obj = (ice_object*)p; + Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr); + + delete _this; + + zend_objects_free_object_storage((zend_object*)p TSRMLS_CC); +} + +#ifdef WIN32 +extern "C" +#endif +static int +handleConnectionCompare(zval* zobj1, zval* zobj2 TSRMLS_DC) +{ + // + // PHP guarantees that the objects have the same class. + // + + ice_object* obj1 = static_cast<ice_object*>(zend_object_store_get_object(zobj1 TSRMLS_CC)); + assert(obj1->ptr); + Ice::ConnectionPtr* _this1 = static_cast<Ice::ConnectionPtr*>(obj1->ptr); + Ice::ConnectionPtr con1 = *_this1; + + ice_object* obj2 = static_cast<ice_object*>(zend_object_store_get_object(zobj2 TSRMLS_CC)); + assert(obj2->ptr); + Ice::ConnectionPtr* _this2 = static_cast<Ice::ConnectionPtr*>(obj2->ptr); + Ice::ConnectionPtr con2 = *_this2; + + if(con1 == con2) + { + return 0; + } + else if(con1 < con2) + { + return -1; + } + else + { + return 1; + } +} |