diff options
Diffstat (limited to 'php')
135 files changed, 11532 insertions, 7118 deletions
diff --git a/php/INSTALL b/php/INSTALL index c9219093343..4a29d76358f 100644 --- a/php/INSTALL +++ b/php/INSTALL @@ -6,7 +6,7 @@ Requirements * 5.1.2 (SLES 10) * 5.1.6 (RHEL) - * 5.2.6 (source builds) + * 5.2.x or 5.3.x (source builds) You can download PHP from @@ -32,7 +32,8 @@ Follow the steps below to build Ice for PHP: 2. Edit config/Make.rules and review the build settings. For example, you may want to enable OPTIMIZE. If your PHP installation resides in a non-standard location, modify the PHP_HOME setting to contain - the installation directory. + the installation directory. If you are using PHP 5.3 or later and + wish to use PHP namespaces, set USE_NAMESPACES=yes. 3. If you have not built Ice for C++ from the cpp subdirectory, then set the ICE_HOME environment variable to the directory containing @@ -53,20 +54,20 @@ Building PHP with the Ice extension (Windows) ====================================================================== Compiling PHP from source code on Windows is a tedious process, -therefore we recommend that you download the binary distribution -for PHP and use it along with the precompiled dynamic Ice extension -included in the Ice installer for Visual C++ 6.0. +therefore we recommend that you download a binary distribution of PHP +and use it along with the precompiled dynamic Ice extension included +in the Ice installer for Visual C++ 6.0 (VC6). If you prefer to build the Ice extension yourself, you must first understand the C run time dependency issues. Specifically, the Ice extension must use the same C run time as PHP5. Since the binary distribution of PHP5 available from php.net depends on the Visual C++ 6.0 run time DLL (MSVCRT), you must also build the Ice extension using -Visual C++ 6.0 if you want to use Ice with this PHP distribution. This -is why the precompiled Ice extension is included in the Ice installer -for Visual C++ 6.0, as attempting to use an Ice extension that was -built with a newer compiler together with the binary PHP distribution -results in undefined behavior. +VC6 if you want to use Ice with this PHP distribution. This is why the +precompiled Ice extension is included in the Ice installer for VC6, as +attempting to use an Ice extension that was built with a newer +compiler together with the binary PHP distribution results in +undefined behavior. To use a later version of Visual C++, you must obtain (or build) PHP5 with the desired compiler, and use the same compiler to build the Ice @@ -79,7 +80,15 @@ Follow these instructions to build the Ice extension: the distribution. 2) Download and extract the PHP5 sources (Ice for PHP requires the PHP - header files). + header files). If you are using PHP 5.3, change to the PHP5 source + directory and run the following commands: + + > buildconf + > configure + + You do not need to actually build PHP from source, but these two + steps are necessary to generate header files that are required by + the Ice extension. 3) Open a command window. @@ -97,14 +106,17 @@ Follow these instructions to build the Ice extension: necessary changes. In particular, you may need to change the values of PHP_HOME and PHP_BIN_HOME to refer to your PHP source and binary installations, respectively. If you compiled PHP from source, you - should also review the setting of PHP_LIBDIR. + should also review the setting of PHP_LIBDIR. If you are using PHP + 5.3 or later and wish to use PHP namespaces, set + USE_NAMESPACES=yes. Finally, if you are using a non-thread-safe PHP + installation, set PHP_ZTS=no. 7) Start NMAKE: nmake /f Makefile.mak 8) Upon successful completion, the Ice for PHP extension is created as - bin\php_ice.dll (Release) or bin\php_iced.dll (Debug). + lib\php_ice.dll (Release) or lib\php_iced.dll (Debug). ====================================================================== @@ -216,8 +228,9 @@ Dependencies PHP will need to be able to locate the Ice run-time libraries "Ice", "Slice", "IceUtil" and "bzip2" (Windows) or "libbz2" (Unix). On -Windows, the STLport library is also necessary. In general, these -libraries must reside in a directory of the user's PATH. +Windows, the STLport library is also necessary when using VC6. In +general, these libraries must reside in a directory of the user's +PATH. For Web servers, the libraries may need to reside in a system directory. For example, on Linux you can add the directory containing @@ -244,14 +257,33 @@ will also need access to the shared libraries for IceSSL and OpenSSL. ====================================================================== +Source Files +====================================================================== + +In addition to the binary Ice extension module, you will also need to +make the Ice for PHP source files available to your scripts. These +files are located in the "lib" subdirectory and consist of the Ice run +time definitions (Ice.php or Ice_ns.php) along with PHP source files +generated from the Slice files included in the Ice distribution. + +The Ice extension makes no assumptions about the location of these +files, so you can install them anywhere you like. For example, you can +simply include them in the same directory as your application scripts. +Alternatively, if you prefer to install them in a common directory, +you may need to modify PHP's include_path directive so that the PHP +interpreter is able to locate these files. + + +====================================================================== Permissions ====================================================================== The Web server normally runs in a special user account that may not -necessarily have access to the Ice extension, its dependent libraries, -and other resources such as Ice configuration files, Slice files, and -PHP scripts. It is very important that you review the permissions of -these files and verify that the Web server has sufficient access. +necessarily have access to the Ice extension, its dependent libraries +and PHP source files, and other resources such as Ice configuration +and your application scripts. It is very important that you review the +permissions of these files and verify that the Web server has +sufficient access. For example, on Windows the Apache server typically runs as a service in the "Local System" account. You will need to modify the access @@ -273,39 +305,6 @@ accessible. ====================================================================== -Apache Notes (Windows) -====================================================================== - -Apache's executable has a relatively small default stack size. You can -determine its current stack size with the following commands: - - cd \Program Files\Apache Software Foundation\Apache2.2\bin - dumpbin /all httpd.exe | find "stack" - -The relevant output line is shown below: - - 40000 size of stack reserve - -The default size is 0x40000 bytes, which is too small to effectively -use the Ice extension. Attempting to load even a trivial Slice file -causes Apache to fail during startup with a stack overflow error. - -To increase the stack size, use the editbin utility. Note that the -new stack size is given in decimal: - - editbin /stack:1048576 httpd.exe - -Now execute dumpbin again to verify that the change was made: - - dumpbin /all httpd.exe | find "stack" - -The new output line is shown below: - - 100000 size of stack reserve - - - -====================================================================== SELinux Notes ====================================================================== diff --git a/php/Makefile b/php/Makefile index dd86d998f1a..e11c52fcf3e 100644 --- a/php/Makefile +++ b/php/Makefile @@ -11,13 +11,13 @@ top_srcdir = . include $(top_srcdir)/config/Make.rules -SUBDIRS = src +SUBDIRS = src lib demo test install:: install-common - @if test ! -d $(install_libdir) ; \ + @if test ! -d $(install_phpdir) ; \ then \ - echo "Creating $(install_libdir)..." ; \ - $(call mkdir,$(install_libdir)) ; \ + echo "Creating $(install_phpdir)..." ; \ + $(call mkdir,$(install_phpdir)) ; \ fi $(EVERYTHING):: diff --git a/php/Makefile.mak b/php/Makefile.mak index 152ad0dc3d6..ac141432a40 100644 --- a/php/Makefile.mak +++ b/php/Makefile.mak @@ -11,7 +11,7 @@ top_srcdir = . !include $(top_srcdir)\config\Make.rules.mak
-SUBDIRS = src
+SUBDIRS = src lib demo test
install:: install-common
@if not exist $(install_libdir) \
diff --git a/php/allTests.py b/php/allTests.py index 8267c7a7a10..90bcfe96d79 100755 --- a/php/allTests.py +++ b/php/allTests.py @@ -29,6 +29,7 @@ tests = [ ("Ice/exceptions", ["core"]), ("Ice/inheritance", ["core"]), ("Ice/binding", ["core"]), + ("Ice/checksum", ["core"]), ("Ice/facets", ["core"]), ("Ice/objects", ["core"]), ("Ice/slicing/exceptions", ["core"]), diff --git a/php/bin/.gitignore b/php/bin/.gitignore deleted file mode 100644 index 39af5887579..00000000000 --- a/php/bin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -# Dummy file, so that git retains this otherwise empty directory. diff --git a/php/config/Make.rules b/php/config/Make.rules index 89715f202d6..d6a6f58885e 100644 --- a/php/config/Make.rules +++ b/php/config/Make.rules @@ -39,6 +39,12 @@ embedded_runpath_prefix ?= /opt/Ice-$(VERSION_MAJOR).$(VERSION_MINOR) # # +# Determines whether the extension uses PHP namespaces (requires +# PHP 5.3 or later). +# +#USE_NAMESPACES ?= yes + +# # If you've built PHP yourself then set PHP_HOME to contain the # installation directory; the rest of the PHP-related settings # should be correct. @@ -85,7 +91,7 @@ PHP_FLAGS ?= -I$(PHP_INCLUDE_DIR) -I$(PHP_INCLUDE_DIR)/main -I$(PHP_INCLUDE_DIR) # ice_language = php ice_require_cpp = yes -slice_translator = slice2cpp +slice_translator = slice2php ifeq ($(shell test -f $(top_srcdir)/config/Make.common.rules && echo 0),0) include $(top_srcdir)/config/Make.common.rules @@ -94,7 +100,8 @@ else endif libdir = $(top_srcdir)/lib -install_libdir = $(prefix)/$(libsubdir) +install_phpdir = $(prefix)/php +install_libdir = $(prefix)/php # # Platform specific definitions @@ -104,7 +111,7 @@ ifeq ($(shell test -f $(top_srcdir)/config/Make.rules.$(UNAME) && echo 0),0) else configdir = $(top_srcdir)/../cpp/config endif -include $(configdir)/Make.rules.$(UNAME) +include $(configdir)/Make.rules.$(UNAME) ifdef ice_src_dist ifeq ($(ice_cpp_dir), $(ice_dir)/cpp) @@ -121,13 +128,29 @@ endif ICE_LIBS = $(ICE_LIB_DIR) -lIce -lSlice -lIceUtil ifneq ($(embedded_runpath_prefix),) - runpath_libdir := $(embedded_runpath_prefix)/lib$(lp64suffix) + runpath_libdir := $(embedded_runpath_prefix)/lib$(lp64suffix) endif CPPFLAGS = ICECPPFLAGS = -I$(slicedir) +SLICE2PHPFLAGS = $(ICECPPFLAGS) LDFLAGS = $(LDPLATFORMFLAGS) $(CXXFLAGS) -L$(libdir) +ifeq ("$(USE_NAMESPACES)","yes") + CPPFLAGS := $(CPPFLAGS) -DICEPHP_USE_NAMESPACES + SLICE2PHPFLAGS := $(SLICE2PHPFLAGS) -n +endif + +ifdef ice_src_dist + ifeq ($(ice_cpp_dir), $(ice_dir)/cpp) + SLICE2PHP = $(ice_cpp_dir)/bin/slice2php + else + SLICE2PHP = $(ice_cpp_dir)/$(binsubdir)/slice2php + endif +else + SLICE2PHP = $(ice_dir)/$(binsubdir)/slice2php +endif + ifeq ($(installphplib),) installphplib = $(INSTALL) $(1) $(2); \ chmod a+rx $(2)/$(notdir $(1)) @@ -141,10 +164,14 @@ mkphplibname = $(subst lib,,$(call mklibname,$(1))) EVERYTHING = all depend clean install .SUFFIXES: -.SUFFIXES: .cpp .o .py +.SUFFIXES: .cpp .o .py .php all:: $(SRCS) +%.php: $(SDIR)/%.ice + rm -f $(*F).php + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + .cpp.o: $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< @@ -154,11 +181,7 @@ clean:: all:: $(SRCS) $(TARGETS) -depend:: $(SRCS) $(SLICE_SRCS) - -rm -f .depend - if test -n "$(SRCS)" ; then \ - $(CXX) -DMAKEDEPEND -M $(CXXFLAGS) $(CPPFLAGS) $(SRCS) | $(ice_dir)/config/makedepend.py >> .depend; \ - fi +depend:: ifneq ($(TEMPLATE_REPOSITORY),) clean:: diff --git a/php/config/Make.rules.mak b/php/config/Make.rules.mak index 515f5a9b8ec..37f2889f75b 100644 --- a/php/config/Make.rules.mak +++ b/php/config/Make.rules.mak @@ -23,17 +23,25 @@ OPTIMIZE = yes #
# Specify your C++ compiler. Supported values are:
-# VC60
+# VC60, VC90, VC90_EXPRESS
#
!if "$(CPP_COMPILER)" == ""
CPP_COMPILER = VC60
!endif
#
+# Determines whether the extension uses PHP namespaces (requires
+# PHP 5.3 or later).
+#
+!if "$(USE_NAMESPACES)" == ""
+USE_NAMESPACES = no
+!endif
+
+#
# Set PHP_HOME to your PHP source directory.
#
!if "$(PHP_HOME)" == ""
-PHP_HOME = C:\php-5.2.6
+PHP_HOME = C:\php-5.2.9
!endif
#
@@ -44,6 +52,13 @@ PHP_BIN_HOME = C:\Program Files\PHP !endif
#
+# Set PHP_ZTS to "no" (or comment it out) to disable Zend Thread Safety.
+#
+!if "$(PHP_ZTS)" == ""
+PHP_ZTS = yes
+!endif
+
+#
# STLPort is required if using MSVC++ 6.0. Change if STLPort
# is located in a different location.
#
@@ -65,7 +80,7 @@ STLPORT_HOME = C:\Ice-$(VERSION)-ThirdParty-VC60 #
ice_language = php
ice_require_cpp = yes
-slice_translator = slice2cpp.exe
+slice_translator = slice2php.exe
!if exist ($(top_srcdir)\..\config\Make.common.rules.mak)
!include $(top_srcdir)\..\config\Make.common.rules.mak
@@ -73,11 +88,11 @@ slice_translator = slice2cpp.exe !include $(top_srcdir)\config\Make.common.rules.mak
!endif
-bindir = $(top_srcdir)\bin
libdir = $(top_srcdir)\lib
-install_bindir = $(prefix)\bin
+install_phpdir = $(prefix)\php
+install_libdir = $(prefix)\php
-!if "$(CPP_COMPILER)" != "VC60"
+!if "$(CPP_COMPILER)" != "VC60" && "$(CPP_COMPILER)" != "VC90" && "$(CPP_COMPILER)" != "VC90_EXPRESS"
!error Invalid setting for CPP_COMPILER: $(CPP_COMPILER)
!endif
@@ -110,24 +125,49 @@ ICE_LDFLAGS = /LIBPATH:"$(ice_dir)\lib" slicedir = $(ice_dir)\slice
+!if "$(PHP_ZTS)" == "yes"
+PHP_LIB_PREFIX = php5ts
+!else
+PHP_LIB_PREFIX = php5
+!endif
+
!if "$(OPTIMIZE)" != "yes"
PHP_LDFLAGS = /LIBPATH:"$(PHP_BIN_HOME)"
-PHP_LIBS = php5ts_debug.lib
+PHP_LIBS = $(PHP_LIB_PREFIX)_debug.lib
PHP_ZEND_DEBUG = 1
!else
PHP_LDFLAGS = /LIBPATH:"$(PHP_BIN_HOME)\dev"
-PHP_LIBS = php5ts.lib
+PHP_LIBS = $(PHP_LIB_PREFIX).lib
PHP_ZEND_DEBUG = 0
!endif
-PHP_CPPFLAGS = -I"$(PHP_HOME)" -I"$(PHP_HOME)\main" -I"$(PHP_HOME)\TSRM" -I"$(PHP_HOME)\Zend" -DPHP_WIN32 -DZEND_WIN32 -DZEND_DEBUG=$(PHP_ZEND_DEBUG) -DZTS -DWIN32
+PHP_CPPFLAGS = -I"$(PHP_HOME)" -I"$(PHP_HOME)\main" -I"$(PHP_HOME)\TSRM" -I"$(PHP_HOME)\Zend" -DPHP_WIN32 -DZEND_WIN32 -DZEND_DEBUG=$(PHP_ZEND_DEBUG) -DWIN32
+!if "$(PHP_ZTS)" == "yes"
+PHP_CPPFLAGS = $(PHP_CPPFLAGS) -DZTS
+!endif
ICECPPFLAGS = -I$(slicedir)
+SLICE2PHPFLAGS = $(ICECPPFLAGS)
+
+!if "$(USE_NAMESPACES)" == "yes"
+CPPFLAGS = $(CPPFLAGS) -DICEPHP_USE_NAMESPACES
+SLICE2PHPFLAGS = $(SLICE2PHPFLAGS) -n
+!endif
+
+!if "$(ice_src_dist)" != ""
+!if "$(ice_cpp_dir)" == "$(ice_dir)\cpp"
+SLICE2PHP = "$(ice_cpp_dir)\bin\slice2php.exe"
+!else
+SLICE2PHP = "$(ice_cpp_dir)\bin$(x64suffix)\slice2php.exe"
+!endif
+!else
+SLICE2PHP = "$(ice_dir)\bin$(x64suffix)\slice2php.exe"
+!endif
EVERYTHING = all clean install
.SUFFIXES:
-.SUFFIXES: .cpp .obj .rb
+.SUFFIXES: .cpp .obj .php
all:: $(SRCS)
diff --git a/php/demo/Glacier2/Makefile b/php/demo/Glacier2/Makefile new file mode 100644 index 00000000000..c3e3118ecf4 --- /dev/null +++ b/php/demo/Glacier2/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../.. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = hello + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/php/demo/Glacier2/Makefile.mak b/php/demo/Glacier2/Makefile.mak new file mode 100644 index 00000000000..02303e64b28 --- /dev/null +++ b/php/demo/Glacier2/Makefile.mak @@ -0,0 +1,19 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = hello
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/demo/Glacier2/hello/.gitignore b/php/demo/Glacier2/hello/.gitignore new file mode 100644 index 00000000000..0b9d5a958ca --- /dev/null +++ b/php/demo/Glacier2/hello/.gitignore @@ -0,0 +1 @@ +Hello.php diff --git a/php/demo/Glacier2/hello/Hello.ice b/php/demo/Glacier2/hello/Hello.ice new file mode 100644 index 00000000000..bcaed6ad877 --- /dev/null +++ b/php/demo/Glacier2/hello/Hello.ice @@ -0,0 +1,24 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef HELLO_ICE +#define HELLO_ICE + +module Demo +{ + +interface Hello +{ + idempotent void sayHello(int delay); + void shutdown(); +}; + +}; + +#endif diff --git a/php/demo/Glacier2/hello/Makefile b/php/demo/Glacier2/hello/Makefile new file mode 100644 index 00000000000..99d7b9d48a9 --- /dev/null +++ b/php/demo/Glacier2/hello/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Hello.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/demo/Glacier2/hello/Makefile.mak b/php/demo/Glacier2/hello/Makefile.mak new file mode 100644 index 00000000000..9cb7c656975 --- /dev/null +++ b/php/demo/Glacier2/hello/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Hello.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/demo/Glacier2/hello/README b/php/demo/Glacier2/hello/README new file mode 100644 index 00000000000..7e6b55cd922 --- /dev/null +++ b/php/demo/Glacier2/hello/README @@ -0,0 +1,90 @@ +This directory contains a PHP/HTML application that demonstrates how +a PHP session can register an Ice communicator and use it in +subsequent page requests. + +To use the application, a user must first log in by providing any +username and password combination (see login.php). Clicking the +'Login' button causes the application to create a communicator, +establish a Glacier2 session, and redirect the user to the session +page (see session.php). From this page the user can invoke the +'sayHello' operation on a hello server via the Glacier2 session. + +NOTE: As explained in the Ice manual, the ability to register a +communicator for use by a PHP session is only useful when the +session's page requests are serviced by the same web server process. +In order to use this demo effectively, you may need to modify your +Web server configuration (e.g., to use a single persistent process). +Non-persistent Web server models (e.g., CGI) cannot be used with this +demo. + +Follow these steps to install the demo: + +1) Install the Ice extension and run-time files as described in the + top-level INSTALL or README file that accompanied your Ice + distribution. Restart the Web server if necessary. + +2) Install the following files in your Web server's document + directory: + + * login.php + * session.php + * Hello.php + + The file Hello.php is generated from Hello.ice when you run make or + nmake in this directory. Verify that the files have appropriate + access rights. + +3) In a command window on the Web server host, start a Glacier2 router + using the configuration file provided in this directory: + + % glacier2router --Ice.Config=config.glacier2 + +4) In a separate command window on the same host, start a hello + server. You can use a server from any Ice language mapping. + +5) Start a Web browser and open the login.php page to begin using the + demo. Note that the Glacier2 configuration uses a session timeout + of 30 seconds. + +If you want to run the Glacier2 router on a different host than the +Web server, you will need to modify the router's endpoint in +config.glacier2 and login.php. To run the hello server on a different +host, modify the endpoint in session.php. + + +====================================================================== +SELinux Notes +====================================================================== + +SELinux augments the traditional Unix permissions with a number of +new features. In particular, SELinux can prevent the httpd daemon from +opening network connections and reading files without the proper +SELinux types. + +If you suspect that your IcePHP application does not work due to +SELinux restrictions, we recommend that you first try it with SELinux +disabled. As root, run: + +# setenforce 0 + +to disable SELinux until the next reboot of your computer. + +If you want to run httpd with IcePHP and SELinux enabled, you must do +the following: + +- Allow httpd to open network connections: + + # setsebool httpd_can_network_connect=1 + + (add the -P option to make this setting persistent across reboots) + +- Make sure any .ice file used by your PHP scripts can be read by + httpd. The enclosing directory also needs to be accessible. For + example: + + # chcon -R -t httpd_sys_content_t /opt/MyApp/slice + +For more information on SELinux in Red Hat Enterprise Linux 4, refer +to the link below: + + http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/selinux-guide/ diff --git a/php/demo/Glacier2/hello/config.glacier2 b/php/demo/Glacier2/hello/config.glacier2 new file mode 100644 index 00000000000..f57636d73ed --- /dev/null +++ b/php/demo/Glacier2/hello/config.glacier2 @@ -0,0 +1,23 @@ +# +# Set the Glacier2 instance name. +# +Glacier2.InstanceName=DemoGlacier2 + +# +# The client-visible endpoint of Glacier2. This should be an endpoint +# visible from the public Internet, and it should typically be secure. +# +Glacier2.Client.Endpoints=tcp -p 4063 -h 127.0.0.1 + +# +# For this demo, we use the null permissions verifier. This permissions +# verifier allows any user-id / password combination. +# +Glacier2.PermissionsVerifier=DemoGlacier2/NullPermissionsVerifier + +# +# The timeout for inactive sessions. If any client session is inactive +# for longer than this value, the session expires and is removed. The +# unit is seconds. +# +Glacier2.SessionTimeout=30 diff --git a/php/demo/Glacier2/hello/login.php b/php/demo/Glacier2/hello/login.php new file mode 100644 index 00000000000..fae442f3b4d --- /dev/null +++ b/php/demo/Glacier2/hello/login.php @@ -0,0 +1,105 @@ +<HTML> +<HEAD> +<TITLE>Session Demo - Login</TITLE> +</HEAD> + +<BODY> +<H1>Session Demo - Login</H1> + +<?php +require 'Ice.php'; +require 'Glacier2.php'; + +session_start(); + +try +{ + // + // Check for an existing session. + // + $ICE = Ice_find(session_id()); + if(isset($_SESSION['authenticated']) || $ICE != null) + { + unset($_SESSION['authenticated']); + Ice_unregister(session_id()); + echo "<P><HR><I>Destroyed previous session.</I><HR></P>\n"; + } + + // + // Generate a new session ID. + // + session_regenerate_id(); + + if(isset($_POST["submitted"])) + { + // + // Initialize a communicator using the default properties. + // + $initData = new Ice_InitializationData; + $initData->properties = Ice_createProperties(); + $initData->properties->setProperty("Ice.Default.Router", "DemoGlacier2/router:tcp -p 4063 -h 127.0.0.1"); + $ICE = Ice_initialize($initData); + + try + { + // + // Verify that we are using a Glacier2 router. + // + $router = Glacier2_RouterPrxHelper::checkedCast($ICE->getDefaultRouter()); + if($router == null) + { + echo "<P><HR><B>Configured router is not a Glacier2 router.</B><HR></P>\n"; + die(); + } + + $user = ""; + $password = ""; + + if(isset($_POST["user"])) + { + $user = $_POST["user"]; + } + if(isset($_POST["password"])) + { + $password = $_POST["password"]; + } + + if(isset($_POST["login"])) + { + $router->createSession($user, $password); + $_SESSION['authenticated'] = 'true'; + Ice_register($ICE, session_id(), session_cache_expire()); + header("Location: session.php"); // Redirect. + exit(); + } + } + catch(Glacier2_PermissionDeniedException $ex) + { + echo "<P><HR><B>Login failure: " . $ex->reason . "</B><HR></P>\n"; + } + } +} +catch(Ice_LocalException $ex) +{ + echo "<P><HR><B>\n"; + echo "<PRE>\n"; + print_r($ex); + echo "</PRE>\n"; + echo "</B><HR></P>\n"; +} +?> + + <P> + <FORM method="POST" action="<?php echo basename($_SERVER["PHP_SELF"]); ?>"> + <P>This demo accepts any username / password combination.</P> + <P> + Username: <INPUT type="text" size="12" name="user"><BR> + <BR> + Password: <INPUT type="text" size="12" name="password"><BR> + </P> + <P> + <INPUT type="hidden" name="submitted" value="yes"> + <INPUT type="submit" name="login" value="Login"> + </FORM> +</BODY> +</HTML> diff --git a/php/demo/Glacier2/hello/session.php b/php/demo/Glacier2/hello/session.php new file mode 100644 index 00000000000..fae291ae0ac --- /dev/null +++ b/php/demo/Glacier2/hello/session.php @@ -0,0 +1,99 @@ +<HTML> +<HEAD> +<TITLE>Session Demo</TITLE> +</HEAD> + +<BODY> + +<H1>Session Demo</H1> + +<?php +require 'Ice.php'; +require 'Glacier2.php'; +require 'Hello.php'; + +session_start(); + +try +{ + // + // Attempt to retrieve the communicator that was registered in login.php + // for the session ID. + // + $ICE = Ice_find(session_id()); + if(!isset($_SESSION['authenticated']) || $ICE == null) + { + echo "<P><HR><B>\n"; + echo "No active session found. Visit the <a href=\"login.php\">login</a> page to proceed.\n"; + echo "</B><HR></P>\n"; + exit(); + } + + if(isset($_POST["submitted"])) + { + if(isset($_POST["sayHello"])) + { + $hello = Demo_HelloPrxHelper::uncheckedCast($ICE->stringToProxy("hello:tcp -p 10000")); + $hello->sayHello(0); + echo "<P><HR><I>Success.</I><HR></P>\n"; + } + elseif(isset($_POST["logout"])) + { + try + { + $router = Glacier2_RouterPrxHelper::uncheckedCast($ICE->getDefaultRouter()); + $router->destroySession(); + } + catch(Ice_ConnectionLostException $ex) + { + // + // This exception is expected when the session is destroyed. + // + } + catch(Glacier2_SessionNotExistException $ex) + { + // + // This exception is expected if the session has expired. + // + } + catch(Exception $ex) + { + // Ignore. + } + unset($_SESSION['authenticated']); + Ice_unregister(session_id()); + echo "<P><HR><B>\n"; + echo "Session destroyed. Visit the <a href=\"login.php\">login</a> page to proceed.\n"; + echo "</B><HR></P>\n"; + exit(); + } + } +} +catch(Ice_Exception $ex) +{ + echo "<P><HR><B>\n"; + echo "<PRE>\n"; + print_r($ex); + echo "</PRE>\n"; + echo "</P>\n"; + echo "<P>\n"; + echo "Visit the <a href=\"login.php\">login</a> page to proceed.\n"; + echo "</B><HR></P>\n"; + unset($_SESSION['authenticated']); + Ice_unregister(session_id()); + exit(); +} +?> + + <P> + <FORM method="POST" action="<?php echo basename($_SERVER["PHP_SELF"]); ?>"> + <P>Click <B>Say Hello</B> to invoke on the server and keep the session alive. + Click <B>Logout</B> to destroy the session.</P> + </P> + <P> + <INPUT type="hidden" name="submitted" value="yes"> + <INPUT type="submit" name="sayHello" value="Say Hello"> + <INPUT type="submit" name="logout" value="Logout"> + </FORM> +</BODY> +</HTML> diff --git a/php/demo/Ice/Makefile b/php/demo/Ice/Makefile new file mode 100644 index 00000000000..2c1a13bfebe --- /dev/null +++ b/php/demo/Ice/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../.. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = hello value + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/php/demo/Ice/Makefile.mak b/php/demo/Ice/Makefile.mak new file mode 100644 index 00000000000..2dee4965246 --- /dev/null +++ b/php/demo/Ice/Makefile.mak @@ -0,0 +1,19 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = hello value
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/demo/Ice/hello/.gitignore b/php/demo/Ice/hello/.gitignore new file mode 100644 index 00000000000..0b9d5a958ca --- /dev/null +++ b/php/demo/Ice/hello/.gitignore @@ -0,0 +1 @@ +Hello.php diff --git a/php/demo/Ice/hello/Makefile b/php/demo/Ice/hello/Makefile new file mode 100644 index 00000000000..99d7b9d48a9 --- /dev/null +++ b/php/demo/Ice/hello/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Hello.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/demo/Ice/hello/Makefile.mak b/php/demo/Ice/hello/Makefile.mak new file mode 100644 index 00000000000..9cb7c656975 --- /dev/null +++ b/php/demo/Ice/hello/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Hello.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/demo/Ice/hello/README b/php/demo/Ice/hello/README index 7c3e5a50d8c..001e75d23c0 100644 --- a/php/demo/Ice/hello/README +++ b/php/demo/Ice/hello/README @@ -1,32 +1,29 @@ This directory contains a PHP/HTML implementation of the Ice hello -client. The procedure for installing this script depends on your Web -server environment. For example, if you're using PHP as a Web server -module, then you'll need to install this script in your document root -directory. +client. -Alternatively, if you're using CGI, then you will need to make this -script executable, add a line at the top of the script to indicate the -path to the PHP CGI binary, and copy the script to your cgi-bin -directory. On Unix platforms, the line at the top of the file should -look something like the one below, where /opt/php5 is the PHP5 -installation directory: +Follow these steps to install the demo: -#! /opt/php5/bin/php +1) Install the Ice extension and run-time files as described in the + top-level INSTALL or README file that accompanied your Ice + distribution. Restart the Web server if necessary. -Next, the PHP configuration must be modified to load the Slice -definitions required by this example. In php.ini, set this directive: +2) Install the following files in your Web server's document + directory: -ice.slice=/opt/icephp/demo/Ice/hello/Hello.ice + * client.php + * Hello.php -For a Linux RPM installation, this directive can be added to -/etc/php.d/ice.ini. + The file Hello.php is generated from Hello.ice when you run make or + nmake in this directory. Verify that the files have appropriate + access rights. -Finally, start the hello server on the Web server host and try out the -script. You can use a hello server from any language mapping. +3) In a command window on the Web server host, start a hello server. + You can use a server from any Ice language mapping. -Note that support for secure invocations via SSL are disabled by -default. If you have configured SSL for the Ice extension, edit -hello.php and set the have_ssl variable to true. +4) Start a Web browser and open the client.php page to begin using the + demo. Note that support for secure invocations via SSL are disabled + by default. If you have configured SSL for the Ice extension, edit + client.php and set the have_ssl variable to true. ========================================================================= diff --git a/php/demo/Ice/hello/hello.php b/php/demo/Ice/hello/client.php index 80d0ea77585..50dfb7976e7 100644 --- a/php/demo/Ice/hello/hello.php +++ b/php/demo/Ice/hello/client.php @@ -16,7 +16,10 @@ // // ********************************************************************** -Ice_loadProfile(); +require 'Ice.php'; +require 'Hello.php'; + +$ICE = Ice_initialize(); // // Change this to true if SSL is configured for the PHP extension. @@ -67,11 +70,11 @@ if(isset($_POST["submitted"])) if($p->ice_isTwoway()) { - $hello = $p->ice_checkedCast("::Demo::Hello"); + $hello = Demo_HelloPrxHelper::checkedCast($p); } else { - $hello = $p->ice_uncheckedCast("::Demo::Hello"); + $hello = Demo_HelloPrxHelper::uncheckedCast($p); } if(isset($_POST["sayHello"])) diff --git a/php/demo/Ice/value/.gitignore b/php/demo/Ice/value/.gitignore new file mode 100644 index 00000000000..5c706038d7c --- /dev/null +++ b/php/demo/Ice/value/.gitignore @@ -0,0 +1 @@ +Value.php diff --git a/php/demo/Ice/value/Client.php b/php/demo/Ice/value/Client.php index 961de48151c..7f0699cf4da 100644 --- a/php/demo/Ice/value/Client.php +++ b/php/demo/Ice/value/Client.php @@ -8,7 +8,10 @@ // // ********************************************************************** -Ice_loadProfile(); +require 'Ice.php'; +require 'Value.php'; + +$ICE = Ice_initialize(); class PrinterI extends Demo_Printer { @@ -57,7 +60,7 @@ class ObjectFactory implements Ice_ObjectFactory try { $base = $ICE->stringToProxy("initial:default -p 10000"); - $initial = $base->ice_checkedCast("::Demo::Initial"); + $initial = Demo_InitialPrxHelper::checkedCast($base); echo "\n"; echo "Let's first transfer a simple object, for a class without\n"; @@ -125,7 +128,7 @@ try fgets(STDIN); $derivedAsBase = $initial->getDerivedPrinter(); - echo "==> The type ID of the received object is \"",get_class($derivedAsBase),"\"\n"; + echo "==> The class of the received object is \"",get_class($derivedAsBase),"\"\n"; assert($derivedAsBase instanceof Demo_Printer); echo "\n"; @@ -141,7 +144,7 @@ try assert($derivedAsBase instanceof Demo_DerivedPrinter); $derived = $derivedAsBase; echo "==> dynamic_cast<> to derived object succeeded\n"; - echo "==> The type ID of the received object is \"",get_class($derived),"\"\n"; + echo "==> The class of the received object is \"",get_class($derived),"\"\n"; echo "\n"; echo "Let's print the message contained in the derived object, and\n"; diff --git a/php/demo/Ice/value/Client_ns.php b/php/demo/Ice/value/Client_ns.php new file mode 100644 index 00000000000..d75bdea4079 --- /dev/null +++ b/php/demo/Ice/value/Client_ns.php @@ -0,0 +1,191 @@ +<?php +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +require 'Ice_ns.php'; +require 'Value.php'; + +$ICE = Ice\initialize(); + +class PrinterI extends Demo\Printer +{ + function printBackwards() + { + echo strrev($this->message),"\n"; + } +} + +class DerivedPrinterI extends Demo\DerivedPrinter +{ + function printBackwards() + { + echo strrev($this->message),"\n"; + } + + function printUpperCase() + { + echo strtoupper($this->derivedMessage),"\n"; + } +} + +class ObjectFactory implements Ice\ObjectFactory +{ + function create($type) + { + if($type == "::Demo::Printer") + { + return new PrinterI; + } + + if($type == "::Demo::DerivedPrinter") + { + return new DerivedPrinterI; + } + + assert(false); + return null; + } + + function destroy() + { + } +} + +try +{ + $base = $ICE->stringToProxy("initial:default -p 10000"); + $initial = Demo\InitialPrxHelper::checkedCast($base); + + echo "\n"; + echo "Let's first transfer a simple object, for a class without\n"; + echo "operations, and print its contents. No factory is required\n"; + echo "for this.\n"; + echo "[press enter]\n"; + fgets(STDIN); + + $simple = $initial->getSimple(); + echo "==> ",$simple->message,"\n"; + + echo "\n"; + echo "Yes, this worked. Now let's try to transfer an object for a class\n"; + echo "with operations as type ::Printer, without installing a factory first.\n"; + echo "This should give us a `no factory' exception.\n"; + echo "[press enter]\n"; + fgets(STDIN); + + try + { + $initial->getPrinter($printer, $printerProxy); + die("Did not get the expected NoObjectFactoryException!"); + } + catch(Ice\NoObjectFactoryException $ex) + { + print_r($ex); + } + + echo "\n"; + echo "Yep, that's what we expected. Now let's try again, but with\n"; + echo "installing an appropriate factory first. If successful, we print\n"; + echo "the object's content.\n"; + echo "[press enter]\n"; + fgets(STDIN); + + $factory = new ObjectFactory; + $ICE->addObjectFactory($factory, "::Demo::Printer"); + + $initial->getPrinter($printer, $printerProxy); + echo "==> ",$printer->message,"\n"; + + echo "\n";; + echo "Cool, it worked! Let's try calling the printBackwards() method\n"; + echo "on the object we just received locally.\n"; + echo "[press enter]\n"; + fgets(STDIN); + + echo "==> "; + $printer->printBackwards(); + + echo "\n"; + echo "Now we call the same method, but on the remote object. Watch the\n"; + echo "server's output.\n"; + echo "[press enter]\n"; + fgets(STDIN); + + $printerProxy->printBackwards(); + + echo "\n"; + echo "Next, we transfer a derived object from the server as a base\n"; + echo "object. Since we haven't yet installed a factory for the derived\n"; + echo "class, the derived class (::Demo::DerivedPrinter) is sliced\n"; + echo "to its base class (::Demo::Printer).\n"; + echo "[press enter]\n"; + fgets(STDIN); + + $derivedAsBase = $initial->getDerivedPrinter(); + echo "==> The class of the received object is \"",get_class($derivedAsBase),"\"\n"; + assert($derivedAsBase instanceof Demo\Printer); + + echo "\n"; + echo "Now we install a factory for the derived class, and try again.\n"; + echo "Because we receive the derived object as a base object, we\n"; + echo "we need to do a dynamic_cast<> to get from the base to the derived object.\n"; + echo "[press enter]\n"; + fgets(STDIN); + + $ICE->addObjectFactory($factory, "::Demo::DerivedPrinter"); + + $derivedAsBase = $initial->getDerivedPrinter(); + assert($derivedAsBase instanceof Demo\DerivedPrinter); + $derived = $derivedAsBase; + echo "==> dynamic_cast<> to derived object succeeded\n"; + echo "==> The class of the received object is \"",get_class($derived),"\"\n"; + + echo "\n"; + echo "Let's print the message contained in the derived object, and\n"; + echo "call the operation printUppercase() on the derived object\n"; + echo "locally.\n"; + echo "[press enter]\n"; + fgets(STDIN); + + echo "==> ",$derived->derivedMessage,"\n"; + echo "==> "; + $derived->printUppercase(); + + echo "\n"; + echo "Finally, we try the same again, but instead of returning the\n"; + echo "derived object, we throw an exception containing the derived\n"; + echo "object.\n"; + echo "[press enter]\n"; + fgets(STDIN); + + try + { + $initial->throwDerivedPrinter(); + die("Did not get the expected DerivedPrinterException!"); + } + catch(Demo\DerivedPrinterException $ex) + { + $derived = $ex->derived; + assert($derived != null); + } + + echo "==> ",$derived->derivedMessage,"\n"; + echo "==> "; + $derived->printUppercase(); + + echo "\n"; + echo "That's it for this demo. Have fun with Ice!\n"; + + $initial->shutdown(); +} +catch(Ice_LocalException $ex) +{ + print_r($ex); +} +?> diff --git a/php/demo/Ice/value/Makefile b/php/demo/Ice/value/Makefile new file mode 100644 index 00000000000..6e89da926b1 --- /dev/null +++ b/php/demo/Ice/value/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Value.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/demo/Ice/value/Makefile.mak b/php/demo/Ice/value/Makefile.mak new file mode 100644 index 00000000000..6ecb5c99128 --- /dev/null +++ b/php/demo/Ice/value/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Value.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/demo/Ice/value/php.ini b/php/demo/Ice/value/php.ini index df79f3d08d2..ba8717cc1ab 100644 --- a/php/demo/Ice/value/php.ini +++ b/php/demo/Ice/value/php.ini @@ -1,25 +1,22 @@ -ice.slice=Value.ice - ; ; Windows Configuration ; --------------------- ; -; Enable the two lines below. Replace "C:\Ice\bin" with the -; bin directory of your Ice installation. +; Enable the lines below. Replace "C:\Ice" with the directory of +; your Ice installation. ; -;extension_dir = C:\Ice\bin +;extension_dir = C:\Ice\php ;extension = php_ice.dll +;include_path = C:\Ice\php ; ; Unix Configuration ; ------------------ ; ; If you are using a dynamic Ice extension on Unix, enable the -; two lines below. Replace "/opt/Ice/lib" with the directory -; containing the extension's shared library. -; -; Furthermore, if you built the dynamic Ice extension from source, -; replace "icephp.so" in the second line with "ice.so". +; lines below. Replace "/opt/Ice" with the directory of your +; Ice installation. ; -;extension_dir = /opt/Ice/lib +;extension_dir = /opt/Ice/php ;extension = IcePHP.so +;include_path = /opt/Ice/php diff --git a/php/demo/Makefile b/php/demo/Makefile new file mode 100644 index 00000000000..33208ca279b --- /dev/null +++ b/php/demo/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = .. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = Ice Glacier2 + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/php/demo/Makefile.mak b/php/demo/Makefile.mak new file mode 100644 index 00000000000..87075f70eba --- /dev/null +++ b/php/demo/Makefile.mak @@ -0,0 +1,19 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = Ice Glacier2
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/lib/.gitignore b/php/lib/.gitignore index 39af5887579..337b0d0e758 100644 --- a/php/lib/.gitignore +++ b/php/lib/.gitignore @@ -1 +1,6 @@ -# Dummy file, so that git retains this otherwise empty directory. +Glacier2 +Ice +IceBox +IceGrid +IcePatch2 +IceStorm diff --git a/php/lib/Glacier2.php b/php/lib/Glacier2.php new file mode 100644 index 00000000000..dea4a62062e --- /dev/null +++ b/php/lib/Glacier2.php @@ -0,0 +1,13 @@ +<?php +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +require 'Glacier2/Router.php'; +require 'Glacier2/PermissionsVerifier.php'; +?> diff --git a/php/lib/Ice.php b/php/lib/Ice.php new file mode 100644 index 00000000000..e301c9d1ffe --- /dev/null +++ b/php/lib/Ice.php @@ -0,0 +1,177 @@ +<?php +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +// +// Exceptions. +// +abstract class Ice_Exception extends Exception +{ + public function __construct($message = '') + { + parent::__construct($message); + } + + abstract public function ice_name(); +} + +abstract class Ice_UserException extends Ice_Exception +{ + public function __construct($message = '') + { + parent::__construct($message); + } +} + +abstract class Ice_LocalException extends Ice_Exception +{ + public function __construct($message = '') + { + parent::__construct($message); + } +} + +interface Ice_Object +{ + public function ice_isA($id); + public function ice_ping(); + public function ice_ids(); + public function ice_id(); + + // + // No need to define these here; the marshaling code will invoke them if defined by a subclass. + // + //public function ice_preMarshal(); + //public function ice_postUnmarshal(); +} + +abstract class Ice_ObjectImpl implements Ice_Object +{ + public function ice_isA($id) + { + return array_search($id, ice_ids()); + } + + public function ice_ping() + { + } + + public function ice_ids() + { + return array(ice_id()); + } + + public function ice_id() + { + return "::Ice::Object"; + } +} + +$Ice__t_Object = IcePHP_defineClass('::Ice::Object', "Ice_Object", true, null, null, null); +$Ice__t_ObjectSeq = IcePHP_defineSequence('::Ice::ObjectSeq', $Ice__t_Object, true, 4); +$Ice__t_LocalObject = IcePHP_defineClass('::Ice::LocalObject', "Ice_LocalObject", true, null, null, null); +$Ice__t_ObjectPrx = IcePHP_defineProxy($Ice__t_Object); +$Ice__t_ObjectProxySeq = IcePHP_defineSequence('::Ice::ObjectProxySeq', $Ice__t_ObjectPrx, true, 2); + +interface Ice_ObjectFactory +{ + public function create($id); + public function destroy(); +} + +class Ice_InitializationData +{ + public function __construct($properties=null, $logger=null) + { + $this->properties = $properties; + $this->logger = $logger; + } + + public $properties; + public $logger; +} + +$Ice_sliceChecksums = array(); + +// +// Include certain generated files. +// +require 'Ice/BuiltinSequences.php'; +require 'Ice/EndpointTypes.php'; +require 'Ice/LocalException.php'; +require 'Ice/Locator.php'; +require 'Ice/ObjectFactory.php'; +require 'Ice/Process.php'; +require 'Ice/Router.php'; + +IcePHP_defineOperation($Ice__t_Object, 'ice_isA', 0, 0, array($IcePHP__t_string), null, $IcePHP__t_bool, null); +IcePHP_defineOperation($Ice__t_Object, 'ice_ping', 0, 0, null, null, null, null); +IcePHP_defineOperation($Ice__t_Object, 'ice_id', 0, 0, null, null, $IcePHP__t_string, null); +IcePHP_defineOperation($Ice__t_Object, 'ice_ids', 0, 0, null, null, $Ice__t_StringSeq, null); + +// +// Proxy comparison functions. +// +function Ice_proxyIdentityCompare($lhs, $rhs) +{ + if(($lhs != null && !($lhs instanceof Ice_ObjectPrx)) || ($rhs != null && !($rhs instanceof Ice_ObjectPrx))) + { + throw new InvalidArgumentException('argument is not a proxy'); + } + if($lhs == null && $rhs == null) + { + return 0; + } + elseif($lhs == null && $rhs != null) + { + return -1; + } + elseif($lhs != null && $rhs == null) + { + return 1; + } + else + { + $lid = $lhs->ice_getIdentity(); + $rid = $rhs->ice_getIdentity(); + if($lid < $rid) + { + return -1; + } + elseif($lid > $rid) + { + return 1; + } + else + { + return 0; + } + } +} + +function Ice_proxyIdentityEqual($lhs, $rhs) +{ + return Ice_proxyIdentityCompare($lhs, $rhs) == 0; +} + +function Ice_proxyIdentityAndFacetCompare($lhs, $rhs) +{ + $n = Ice_proxyIdentityCompare($lhs, $rhs); + if($n == 0 && $lhs != null && $rhs != null) + { + $n = strcmp($lhs->ice_getFacet(), $rhs->ice_getFacet()); + } + return $n; +} + +function Ice_proxyIdentityAndFacetEqual($lhs, $rhs) +{ + return Ice_proxyIdentityAndFacetCompare($lhs, $rhs) == 0; +} +?> diff --git a/php/lib/IceBox.php b/php/lib/IceBox.php new file mode 100644 index 00000000000..15501980f30 --- /dev/null +++ b/php/lib/IceBox.php @@ -0,0 +1,12 @@ +<?php +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +require 'IceBox/IceBox.php'; +?> diff --git a/php/lib/IceGrid.php b/php/lib/IceGrid.php new file mode 100644 index 00000000000..fc42e00c418 --- /dev/null +++ b/php/lib/IceGrid.php @@ -0,0 +1,19 @@ +<?php +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +require 'IceGrid/Admin.php'; +require 'IceGrid/Descriptor.php'; +require 'IceGrid/FileParser.php'; +require 'IceGrid/Locator.php'; +require 'IceGrid/Observer.php'; +require 'IceGrid/Query.php'; +require 'IceGrid/Registry.php'; +require 'IceGrid/UserAccountMapper.php'; +?> diff --git a/php/lib/IcePatch2.php b/php/lib/IcePatch2.php new file mode 100644 index 00000000000..93a990aa73f --- /dev/null +++ b/php/lib/IcePatch2.php @@ -0,0 +1,12 @@ +<?php +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +require 'IcePatch2/FileServer.php'; +?> diff --git a/php/lib/IceStorm.php b/php/lib/IceStorm.php new file mode 100644 index 00000000000..8a396345124 --- /dev/null +++ b/php/lib/IceStorm.php @@ -0,0 +1,12 @@ +<?php +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +require 'IceStorm/IceStorm.php'; +?> diff --git a/php/lib/Ice_ns.php b/php/lib/Ice_ns.php new file mode 100644 index 00000000000..12c4d3159fd --- /dev/null +++ b/php/lib/Ice_ns.php @@ -0,0 +1,186 @@ +<?php +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +namespace Ice +{ + // + // Exceptions. + // + abstract class Exception extends \Exception + { + public function __construct($message = '') + { + parent::__construct($message); + } + + abstract public function ice_name(); + } + + abstract class UserException extends Exception + { + public function __construct($message = '') + { + parent::__construct($message); + } + } + + abstract class LocalException extends Exception + { + public function __construct($message = '') + { + parent::__construct($message); + } + } + + interface Object + { + public function ice_isA($id); + public function ice_ping(); + public function ice_ids(); + public function ice_id(); + + // + // No need to define these here; the marshaling code will invoke them if defined by a subclass. + // + //public function ice_preMarshal(); + //public function ice_postUnmarshal(); + } + + abstract class ObjectImpl implements Object + { + public function ice_isA($id) + { + return array_search($id, ice_ids()); + } + + public function ice_ping() + { + } + + public function ice_ids() + { + return array(ice_id()); + } + + public function ice_id() + { + return "::Ice::Object"; + } + } + + $Ice__t_Object = IcePHP_defineClass('::Ice::Object', "Ice\\Object", true, null, null, null); + $Ice__t_ObjectSeq = IcePHP_defineSequence('::Ice::ObjectSeq', $Ice__t_Object, true, 4); + $Ice__t_LocalObject = IcePHP_defineClass('::Ice::LocalObject', "Ice\\LocalObject", true, null, null, null); + $Ice__t_ObjectPrx = IcePHP_defineProxy($Ice__t_Object); + $Ice__t_ObjectProxySeq = IcePHP_defineSequence('::Ice::ObjectProxySeq', $Ice__t_ObjectPrx, true, 2); + + interface ObjectFactory + { + public function create($id); + public function destroy(); + } + + class InitializationData + { + public function __construct($properties=null, $logger=null) + { + $this->properties = $properties; + $this->logger = $logger; + } + + public $properties; + public $logger; + } + + $Ice_sliceChecksums = array(); +} + +namespace +{ +// +// Include certain generated files. +// +require 'Ice/BuiltinSequences.php'; +require 'Ice/EndpointTypes.php'; +require 'Ice/LocalException.php'; +require 'Ice/Locator.php'; +require 'Ice/ObjectFactory.php'; +require 'Ice/Process.php'; +require 'Ice/Router.php'; + +IcePHP_defineOperation($Ice__t_Object, 'ice_isA', 0, 0, array($IcePHP__t_string), array(), $IcePHP__t_bool, null); +IcePHP_defineOperation($Ice__t_Object, 'ice_ping', 0, 0, null, null, null, null); +IcePHP_defineOperation($Ice__t_Object, 'ice_id', 0, 0, null, null, $IcePHP__t_string, null); +IcePHP_defineOperation($Ice__t_Object, 'ice_ids', 0, 0, null, null, $Ice__t_StringSeq, null); +} + +namespace Ice +{ + // + // Proxy comparison functions. + // + function proxyIdentityCompare($lhs, $rhs) + { + if(($lhs != null && !($lhs instanceof ObjectPrx)) || ($rhs != null && !($rhs instanceof ObjectPrx))) + { + throw new InvalidArgumentException('argument is not a proxy'); + } + if($lhs == null && $rhs == null) + { + return 0; + } + elseif($lhs == null && $rhs != null) + { + return -1; + } + elseif($lhs != null && $rhs == null) + { + return 1; + } + else + { + $lid = $lhs->ice_getIdentity(); + $rid = $rhs->ice_getIdentity(); + if($lid < $rid) + { + return -1; + } + elseif($lid > $rid) + { + return 1; + } + else + { + return 0; + } + } + } + + function proxyIdentityEqual($lhs, $rhs) + { + return proxyIdentityCompare($lhs, $rhs) == 0; + } + + function proxyIdentityAndFacetCompare($lhs, $rhs) + { + $n = proxyIdentityCompare($lhs, $rhs); + if($n == 0 && $lhs != null && $rhs != null) + { + $n = strcmp($lhs->ice_getFacet(), $rhs->ice_getFacet()); + } + return $n; + } + + function proxyIdentityAndFacetEqual($lhs, $rhs) + { + return proxyIdentityAndFacetCompare($lhs, $rhs) == 0; + } +} +?> diff --git a/php/lib/Makefile b/php/lib/Makefile new file mode 100644 index 00000000000..4124ea83ca2 --- /dev/null +++ b/php/lib/Makefile @@ -0,0 +1,142 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = .. + +include $(top_srcdir)/config/Make.rules + +# +# IMPORTANT: If you add or remove Slice files, you also need to check Ice.php! +# +ICE_SRCS = Ice/LocalException.php \ + Ice/Communicator.php \ + Ice/CommunicatorF.php \ + Ice/Logger.php \ + Ice/LoggerF.php \ + Ice/BuiltinSequences.php \ + Ice/ObjectAdapterF.php \ + Ice/Properties.php \ + Ice/PropertiesF.php \ + Ice/ObjectFactory.php \ + Ice/ObjectFactoryF.php \ + Ice/Identity.php \ + Ice/Current.php \ + Ice/ImplicitContextF.php \ + Ice/ImplicitContext.php \ + Ice/Router.php \ + Ice/RouterF.php \ + Ice/Plugin.php \ + Ice/PluginF.php \ + Ice/Locator.php \ + Ice/LocatorF.php \ + Ice/StatsF.php \ + Ice/Stats.php \ + Ice/Process.php \ + Ice/ProcessF.php \ + Ice/FacetMap.php \ + Ice/Connection.php \ + Ice/ConnectionF.php \ + Ice/SliceChecksumDict.php \ + Ice/Endpoint.php \ + Ice/EndpointF.php \ + Ice/EndpointTypes.php + +# +# IMPORTANT: If you add or remove Slice files, you also need to check Glacier2.php! +# +GLACIER2_SRCS = Glacier2/RouterF.php \ + Glacier2/Router.php \ + Glacier2/Session.php \ + Glacier2/PermissionsVerifierF.php \ + Glacier2/PermissionsVerifier.php \ + Glacier2/SSLInfo.php + +# +# IMPORTANT: If you add or remove Slice files, you also need to check IceBox.php! +# +ICEBOX_SRCS = IceBox/IceBox.php + +# +# IMPORTANT: If you add or remove Slice files, you also need to check IceGrid.php! +# +ICEGRID_SRCS = IceGrid/Admin.php \ + IceGrid/Descriptor.php \ + IceGrid/Exception.php \ + IceGrid/FileParser.php \ + IceGrid/Locator.php \ + IceGrid/Observer.php \ + IceGrid/Query.php \ + IceGrid/Registry.php \ + IceGrid/Session.php \ + IceGrid/UserAccountMapper.php + +# +# IMPORTANT: If you add or remove Slice files, you also need to check IcePatch2.php! +# +ICEPATCH2_SRCS = IcePatch2/FileInfo.php \ + IcePatch2/FileServer.php + +# +# IMPORTANT: If you add or remove Slice files, you also need to check IceStorm.php! +# +ICESTORM_SRCS = IceStorm/IceStorm.php + +ALL_SRCS = $(ICE_SRCS) \ + $(GLACIER2_SRCS) \ + $(ICEBOX_SRCS) \ + $(ICEGRID_SRCS) \ + $(ICEPATCH2_SRCS) \ + $(ICESTORM_SRCS) + +MODULES = Glacier2 Ice IceBox IceGrid IcePatch2 IceStorm +ifeq ("$(USE_NAMESPACES)","yes") +MODULE_SRCS = Glacier2.php Ice_ns.php IceBox.php IceGrid.php IcePatch2.php IceStorm.php +else +MODULE_SRCS = Glacier2.php Ice.php IceBox.php IceGrid.php IcePatch2.php IceStorm.php +endif + +all:: $(ALL_SRCS) + +Ice/%.php: $(slicedir)/Ice/%.ice + @mkdir -p $(notdir $(<D)) + $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $< + +Glacier2/%.php: $(slicedir)/Glacier2/%.ice + @mkdir -p $(notdir $(<D)) + $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $< + +IceBox/%.php: $(slicedir)/IceBox/%.ice + @mkdir -p $(notdir $(<D)) + $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $< + +IceGrid/%.php: $(slicedir)/IceGrid/%.ice + @mkdir -p $(notdir $(<D)) + $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $< + +IcePatch2/%.php: $(slicedir)/IcePatch2/%.ice + @mkdir -p $(notdir $(<D)) + $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $< + +IceStorm/%.php: $(slicedir)/IceStorm/%.ice + @mkdir -p $(notdir $(<D)) + $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $< + +install:: $(ALL_SRCS) + @echo "Installing generated code" + @for i in $(MODULES) ; \ + do \ + $(INSTALL_DATA) -r $$i $(install_phpdir) ; \ + done + @for i in $(MODULE_SRCS) ; \ + do \ + $(INSTALL_DATA) $$i $(install_phpdir) ; \ + done + +clean:: + rm -rf $(MODULES) diff --git a/php/lib/Makefile.mak b/php/lib/Makefile.mak new file mode 100644 index 00000000000..6bdc68f9c02 --- /dev/null +++ b/php/lib/Makefile.mak @@ -0,0 +1,123 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check Ice.php!
+#
+ICE_SRCS = Ice\LocalException.php \
+ Ice\Communicator.php \
+ Ice\CommunicatorF.php \
+ Ice\Logger.php \
+ Ice\LoggerF.php \
+ Ice\BuiltinSequences.php \
+ Ice\ObjectAdapterF.php \
+ Ice\Properties.php \
+ Ice\PropertiesF.php \
+ Ice\ObjectFactory.php \
+ Ice\ObjectFactoryF.php \
+ Ice\Identity.php \
+ Ice\Current.php \
+ Ice\ImplicitContextF.php \
+ Ice\ImplicitContext.php \
+ Ice\Router.php \
+ Ice\RouterF.php \
+ Ice\Plugin.php \
+ Ice\PluginF.php \
+ Ice\Locator.php \
+ Ice\LocatorF.php \
+ Ice\StatsF.php \
+ Ice\Stats.php \
+ Ice\Process.php \
+ Ice\ProcessF.php \
+ Ice\FacetMap.php \
+ Ice\Connection.php \
+ Ice\ConnectionF.php \
+ Ice\SliceChecksumDict.php \
+ Ice\Endpoint.php \
+ Ice\EndpointF.php \
+ Ice\EndpointTypes.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check Glacier2.php!
+#
+GLACIER2_SRCS = Glacier2\RouterF.php \
+ Glacier2\Router.php \
+ Glacier2\Session.php \
+ Glacier2\PermissionsVerifierF.php \
+ Glacier2\PermissionsVerifier.php \
+ Glacier2\SSLInfo.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IceBox.php!
+#
+ICEBOX_SRCS = IceBox\IceBox.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IceGrid.php!
+#
+ICEGRID_SRCS = IceGrid\Admin.php \
+ IceGrid\Descriptor.php \
+ IceGrid\Exception.php \
+ IceGrid\FileParser.php \
+ IceGrid\Locator.php \
+ IceGrid\Observer.php \
+ IceGrid\Query.php \
+ IceGrid\Registry.php \
+ IceGrid\Session.php \
+ IceGrid\UserAccountMapper.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IcePatch2.php!
+#
+ICEPATCH2_SRCS = IcePatch2\FileInfo.php \
+ IcePatch2\FileServer.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IceStorm.php!
+#
+ICESTORM_SRCS = IceStorm\IceStorm.php
+
+ALL_SRCS = $(ICE_SRCS) \
+ $(GLACIER2_SRCS) \
+ $(ICEBOX_SRCS) \
+ $(ICEGRID_SRCS) \
+ $(ICEPATCH2_SRCS) \
+ $(ICESTORM_SRCS)
+
+MODULES = Glacier2 Ice IceBox IceGrid IcePatch2 IceStorm
+!if "$(USE_NAMESPACES)" == "yes"
+MODULE_SRCS = Glacier2.php Ice_ns.php IceBox.php IceGrid.php IcePatch2.php IceStorm.php
+!else
+MODULE_SRCS = Glacier2.php Ice.php IceBox.php IceGrid.php IcePatch2.php IceStorm.php
+!endif
+
+all:: $(ALL_SRCS)
+
+$(MODULES):
+ -mkdir $@
+
+$(ALL_SRCS): $(MODULES) {$(slicedir)}$*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) --output-dir $(*D) --ice $(slicedir)\$*.ice
+
+install::
+ @echo "Installing generated code"
+ @for %i in ( $(MODULES) ) do \
+ @if not exist $(install_phpdir)\%i \
+ mkdir $(install_phpdir)\%i
+ @for %i in ( $(MODULES) ) do \
+ copy %i\* $(install_phpdir)\%i
+ @for %i in ( $(MODULE_SRCS) ) do \
+ copy %i $(install_phpdir)
+
+clean::
+ -rmdir /S /Q $(MODULES)
diff --git a/php/src/IcePHP/.depend b/php/src/IcePHP/.depend index e69de29bb2d..d82ec855f70 100644 --- a/php/src/IcePHP/.depend +++ b/php/src/IcePHP/.depend @@ -0,0 +1,10 @@ +Communicator$(OBJEXT): Communicator.cpp Communicator.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Logger.h Properties.h Proxy.h Types.h Operation.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Util.h $(ice_cpp_dir)/include/IceUtil/Options.h $(ice_cpp_dir)/include/IceUtil/RecMutex.h +Connection$(OBJEXT): Connection.cpp Connection.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Util.h +Endpoint$(OBJEXT): Endpoint.cpp Endpoint.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Util.h +Init$(OBJEXT): Init.cpp Communicator.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Connection.h Endpoint.h Logger.h Operation.h Properties.h Proxy.h Types.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Util.h +Logger$(OBJEXT): Logger.cpp Logger.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Util.h +Operation$(OBJEXT): Operation.cpp Operation.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Communicator.h Proxy.h Types.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Util.h $(ice_cpp_dir)/include/Slice/PHPUtil.h $(ice_cpp_dir)/include/Slice/Parser.h +Properties$(OBJEXT): Properties.cpp Properties.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Util.h +Proxy$(OBJEXT): Proxy.cpp Proxy.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Communicator.h Types.h Operation.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Connection.h Endpoint.h Util.h +Types$(OBJEXT): Types.cpp Types.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Communicator.h Operation.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Proxy.h Util.h $(ice_cpp_dir)/include/IceUtil/InputUtil.h $(ice_cpp_dir)/include/IceUtil/ScopedArray.h $(ice_cpp_dir)/include/Slice/PHPUtil.h $(ice_cpp_dir)/include/Slice/Parser.h +Util$(OBJEXT): Util.cpp Util.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h $(ice_cpp_dir)/include/IceUtil/UUID.h $(ice_cpp_dir)/include/Slice/PHPUtil.h $(ice_cpp_dir)/include/Slice/Parser.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h diff --git a/php/src/IcePHP/Communicator.cpp b/php/src/IcePHP/Communicator.cpp index 40a315a3f84..ca48dc52565 100644 --- a/php/src/IcePHP/Communicator.cpp +++ b/php/src/IcePHP/Communicator.cpp @@ -7,11 +7,14 @@ // // ********************************************************************** -#include <IceUtil/DisableWarnings.h> #include <Communicator.h> +#include <Logger.h> +#include <Properties.h> #include <Proxy.h> -#include <Marshal.h> #include <Util.h> +#include <IceUtil/Options.h> +#include <IceUtil/StaticMutex.h> +#include <IceUtil/Timer.h> using namespace std; using namespace IcePHP; @@ -21,704 +24,1554 @@ ZEND_EXTERN_MODULE_GLOBALS(ice) // // Class entries represent the PHP class implementations we have registered. // -static zend_class_entry* _communicatorClassEntry; +namespace IcePHP +{ + +zend_class_entry* communicatorClassEntry = 0; // -// Ice::Communicator support. +// An active communicator is in use by at least one request and may have +// registered so that it remains active after a request completes. The +// communicator is destroyed when there are no more references to this +// object. // -static zend_object_handlers _handlers; +class ActiveCommunicator : public IceUtil::Shared +{ +public: -extern "C" + ActiveCommunicator(const Ice::CommunicatorPtr& c); + ~ActiveCommunicator(); + + const Ice::CommunicatorPtr communicator; + vector<string> ids; + int expires; + IceUtil::Time lastAccess; +}; +typedef IceUtil::Handle<ActiveCommunicator> ActiveCommunicatorPtr; + +typedef std::map<std::string, zval*> ObjectFactoryMap; + +class CommunicatorInfoI : public CommunicatorInfo { -static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC); -static zend_object_value handleClone(zval* TSRMLS_DC); -static void handleFreeStorage(void* TSRMLS_DC); +public: -static union _zend_function* handleGetMethod(zval**, char*, int TSRMLS_DC); -} + CommunicatorInfoI(const ActiveCommunicatorPtr&, zval*); + + virtual void getZval(zval* TSRMLS_DC); + virtual void addRef(TSRMLS_D); + virtual void decRef(TSRMLS_D); + + virtual Ice::CommunicatorPtr getCommunicator() const; -static void initCommunicator(ice_object* TSRMLS_DC); + bool addObjectFactory(const std::string&, zval* TSRMLS_DC); + bool findObjectFactory(const std::string&, zval* TSRMLS_DC); + void destroyObjectFactories(TSRMLS_D); + + const ActiveCommunicatorPtr ac; + const zval zv; + ObjectFactoryMap objectFactories; +}; +typedef IceUtil::Handle<CommunicatorInfoI> CommunicatorInfoIPtr; // -// Function entries for Ice::Communicator methods. +// Each PHP request has its own set of object factories. More precisely, there is +// an object factory map for each communicator that is created by a PHP request. +// The factory class defined below delegates the create/destroy methods to PHP +// objects supplied by the application. An instance of this class is installed +// as the communicator's default object factory, and the class holds a reference +// to its communicator. When create is invoked, the class resolves the appropriate +// PHP object as follows: // -static function_entry _methods[] = -{ - {"__construct", PHP_FN(Ice_Communicator___construct), 0}, - {"getProperty", PHP_FN(Ice_Communicator_getProperty), 0}, - {"setProperty", PHP_FN(Ice_Communicator_setProperty), 0}, - {"stringToProxy", PHP_FN(Ice_Communicator_stringToProxy), 0}, - {"proxyToString", PHP_FN(Ice_Communicator_proxyToString), 0}, - {"propertyToProxy", PHP_FN(Ice_Communicator_propertyToProxy), 0}, - {"stringToIdentity", PHP_FN(Ice_Communicator_stringToIdentity), 0}, - {"identityToString", PHP_FN(Ice_Communicator_identityToString), 0}, - {"addObjectFactory", PHP_FN(Ice_Communicator_addObjectFactory), 0}, - {"findObjectFactory", PHP_FN(Ice_Communicator_findObjectFactory), 0}, - {"flushBatchRequests", PHP_FN(Ice_Communicator_flushBatchRequests), 0}, - {0, 0, 0} +// * Using its communicator reference as the key, look up the corresponding +// CommunicatorInfoI object in the request-specific communicator map. +// +// * In the object factory map held by the CommunicatorInfoI object, look for a +// PHP factory object using the same algorithm as the Ice core. +// +class ObjectFactoryI : public Ice::ObjectFactory +{ +public: + + ObjectFactoryI(const Ice::CommunicatorPtr&); + + virtual Ice::ObjectPtr create(const std::string&); + virtual void destroy(); + +private: + + Ice::CommunicatorPtr _communicator; }; -bool -IcePHP::communicatorInit(TSRMLS_D) +class ReaperTask : public IceUtil::TimerTask { - // - // Register the Ice_Communicator class. - // - zend_class_entry ce; - INIT_CLASS_ENTRY(ce, "Ice_Communicator", _methods); - ce.create_object = handleAlloc; - _communicatorClassEntry = zend_register_internal_class(&ce TSRMLS_CC); - memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - _handlers.clone_obj = handleClone; - _handlers.get_method = handleGetMethod; +public: + + virtual void runTimerTask(); +}; - return true; } -bool -IcePHP::createCommunicator(TSRMLS_D) +// +// Communicator support. +// +static zend_object_handlers _handlers; + +// +// The profile map holds Properties objects corresponding to the "default" profile +// (defined via the ice.config & ice.options settings in php.ini) as well as named +// profiles defined in an external file. +// +typedef map<string, Ice::PropertiesPtr> ProfileMap; +static ProfileMap _profiles; +static const string _defaultProfileName = ""; + +// +// This map represents communicators that have been registered so that they can be used +// by multiple PHP requests. +// +typedef map<string, ActiveCommunicatorPtr> RegisteredCommunicatorMap; +static RegisteredCommunicatorMap _registeredCommunicators; +static IceUtil::StaticMutex _registeredCommunicatorsMutex = ICE_STATIC_MUTEX_INITIALIZER; + +static IceUtil::TimerPtr _timer; + +// +// This map is stored in the "global" variables for each PHP request and holds +// the communicators that have been created (or registered communicators that have +// been used) by the request. +// +typedef map<Ice::CommunicatorPtr, CommunicatorInfoIPtr> CommunicatorMap; + +extern "C" { - zval* global; - MAKE_STD_ZVAL(global); +static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC); +static void handleFreeStorage(void* TSRMLS_DC); +static zend_object_value handleClone(zval* TSRMLS_DC); +} + +ZEND_METHOD(Ice_Communicator, __construct) +{ + runtimeError("communicators cannot be instantiated directly" TSRMLS_CC); +} + +ZEND_METHOD(Ice_Communicator, destroy) +{ + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); // - // Create the global variable for the communicator, but delay creation of the communicator - // itself until it is first used (see handleGetMethod). + // Remove all registrations. // - if(object_init_ex(global, _communicatorClassEntry) != SUCCESS) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create object for communicator"); - return false; + IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex); + for(vector<string>::iterator p = _this->ac->ids.begin(); p != _this->ac->ids.end(); ++p) + { + _registeredCommunicators.erase(*p); + } + _this->ac->ids.clear(); } // - // Register the global variable "ICE" to hold the communicator. + // We need to destroy any object factories installed by this request. // - ICE_G(communicator) = global; - ZEND_SET_GLOBAL_VAR("ICE", global); + _this->destroyObjectFactories(TSRMLS_C); - return true; + Ice::CommunicatorPtr c = _this->getCommunicator(); + assert(c); + CommunicatorMap* m = reinterpret_cast<CommunicatorMap*>(ICE_G(communicatorMap)); + assert(m); + assert(m->find(c) != m->end()); + m->erase(c); + + try + { + c->destroy(); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } } -Ice::CommunicatorPtr -IcePHP::getCommunicator(TSRMLS_D) +ZEND_METHOD(Ice_Communicator, stringToProxy) { - Ice::CommunicatorPtr result; + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); - void* data; - if(zend_hash_find(&EG(symbol_table), "ICE", sizeof("ICE"), &data) == SUCCESS) + char* str; + int strLen; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &strLen) != SUCCESS) { - zval** zv = reinterpret_cast<zval**>(data); - ice_object* obj = getObject(*zv TSRMLS_CC); - assert(obj); + RETURN_NULL(); + } + string s(str, strLen); - // - // Initialize the communicator if necessary. - // - if(!obj->ptr) + try + { + Ice::ObjectPrx prx = _this->getCommunicator()->stringToProxy(s); + if(!createProxy(return_value, prx, _this TSRMLS_CC)) { - try - { - initCommunicator(obj TSRMLS_CC); - } - catch(const IceUtil::Exception& ex) - { - ostringstream ostr; - ex.ice_print(ostr); - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize communicator:\n%s", ostr.str().c_str()); - return 0; - } + RETURN_NULL(); } - - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); - result = *_this; } - - return result; -} - -zval* -IcePHP::getCommunicatorZval(TSRMLS_D) -{ - void* data = 0; - zend_hash_find(&EG(symbol_table), "ICE", sizeof("ICE"), &data); - assert(data); - zval **zv = reinterpret_cast<zval**>(data); - return *zv; + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } } -ZEND_FUNCTION(Ice_Communicator___construct) +ZEND_METHOD(Ice_Communicator, proxyToString) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "Ice_Communicator cannot be instantiated, use the global variable $ICE"); -} + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); -ZEND_FUNCTION(Ice_Communicator_getProperty) -{ - if(ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2) + zval* zv; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zv, proxyClassEntry) != SUCCESS) { - WRONG_PARAM_COUNT; + RETURN_NULL(); } - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) + try { - return; + string str; + if(zv) + { + Ice::ObjectPrx prx; + ClassInfoPtr info; + if(!fetchProxy(zv, prx, info TSRMLS_CC)) + { + RETURN_NULL(); + } + assert(prx); + str = prx->ice_toString(); + } + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); } - assert(obj->ptr); - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); +} - char *name; - int nameLen; - char *def = 0; - int defLen = 0; +ZEND_METHOD(Ice_Communicator, propertyToProxy) +{ + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name, &nameLen, &def, &defLen) == FAILURE) + char* str; + int strLen; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &strLen) != SUCCESS) { RETURN_NULL(); } + string s(str, strLen); try { - string val = (*_this)->getProperties()->getProperty(name); - if(val.empty() && def) - { - RETURN_STRING(def, 1); - } - else + Ice::ObjectPrx prx = _this->getCommunicator()->propertyToProxy(s); + if(!createProxy(return_value, prx, _this TSRMLS_CC)) { - RETURN_STRING(const_cast<char*>(val.c_str()), 1); + RETURN_NULL(); } } catch(const IceUtil::Exception& ex) { throwException(ex TSRMLS_CC); - RETURN_EMPTY_STRING(); + RETURN_NULL(); } } -ZEND_FUNCTION(Ice_Communicator_setProperty) +ZEND_METHOD(Ice_Communicator, stringToIdentity) { - if(ZEND_NUM_ARGS() != 2) + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + char* str; + int strLen; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &strLen) != SUCCESS) { - WRONG_PARAM_COUNT; + RETURN_NULL(); } + string s(str, strLen); - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) + try { - return; + Ice::Identity id = _this->getCommunicator()->stringToIdentity(s); + if(!createIdentity(return_value, id TSRMLS_CC)) + { + RETURN_NULL(); + } } - assert(obj->ptr); - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Communicator, identityToString) +{ + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); - char *prop; - int propLen; - char *val; - int valLen; + zend_class_entry* identityClass = idToClass("::Ice::Identity" TSRMLS_CC); + assert(identityClass); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &prop, &propLen, &val, &valLen) == FAILURE) + zval* zv; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zv, identityClass) != SUCCESS) + { + RETURN_NULL(); + } + Ice::Identity id; + if(!extractIdentity(zv, id TSRMLS_CC)) { RETURN_NULL(); } try { - (*_this)->getProperties()->setProperty(prop, val); + string str = _this->getCommunicator()->identityToString(id); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); } catch(const IceUtil::Exception& ex) { throwException(ex TSRMLS_CC); + RETURN_NULL(); } - RETURN_EMPTY_STRING(); } -ZEND_FUNCTION(Ice_Communicator_stringToProxy) +ZEND_METHOD(Ice_Communicator, addObjectFactory) { - if(ZEND_NUM_ARGS() != 1) + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + zend_class_entry* factoryClass = idToClass("Ice::ObjectFactory" TSRMLS_CC); + assert(factoryClass); + + zval* factory; + char* id; + int idLen; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os!", &factory, factoryClass, &id, &idLen TSRMLS_CC) != + SUCCESS) { - WRONG_PARAM_COUNT; + RETURN_NULL(); } - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) + string type; + if(id) { - return; + type = string(id, idLen); } - assert(obj->ptr); - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); - - char *str; - int len; - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) + if(!_this->addObjectFactory(type, factory TSRMLS_CC)) { RETURN_NULL(); } +} - Ice::ObjectPrx proxy; - try +ZEND_METHOD(Ice_Communicator, findObjectFactory) +{ + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + char* id; + int idLen; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &id, &idLen TSRMLS_CC) != SUCCESS) { - proxy = (*_this)->stringToProxy(str); + RETURN_NULL(); } - catch(const IceUtil::Exception& ex) + + string type; + if(id) { - throwException(ex TSRMLS_CC); - RETURN_NULL(); + type = string(id, idLen); } - if(!createProxy(return_value, proxy TSRMLS_CC)) + if(!_this->findObjectFactory(type, return_value TSRMLS_CC)) { RETURN_NULL(); } } -ZEND_FUNCTION(Ice_Communicator_proxyToString) +ZEND_METHOD(Ice_Communicator, getImplicitContext) { - if(ZEND_NUM_ARGS() != 1) - { - WRONG_PARAM_COUNT; - } + runtimeError("not implemented" TSRMLS_CC); +} - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) +ZEND_METHOD(Ice_Communicator, getProperties) +{ + if(ZEND_NUM_ARGS() > 0) { - return; + WRONG_PARAM_COUNT; } - assert(obj->ptr); - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); - zval* zprx; + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zprx, proxyClassEntry) == FAILURE) + try { - RETURN_EMPTY_STRING(); + Ice::PropertiesPtr props = _this->getCommunicator()->getProperties(); + if(!createProperties(return_value, props TSRMLS_CC)) + { + RETURN_NULL(); + } } - - Ice::ObjectPrx proxy; - Slice::ClassDefPtr def; - if(!zprx || !fetchProxy(zprx, proxy, def TSRMLS_CC)) + catch(const IceUtil::Exception& ex) { - RETURN_EMPTY_STRING(); + throwException(ex TSRMLS_CC); + RETURN_NULL(); } +} + +ZEND_METHOD(Ice_Communicator, getLogger) +{ + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - string result = (*_this)->proxyToString(proxy); - RETURN_STRING(const_cast<char*>(result.c_str()), 1); + Ice::LoggerPtr logger = _this->getCommunicator()->getLogger(); + if(!createLogger(return_value, logger TSRMLS_CC)) + { + RETURN_NULL(); + } } catch(const IceUtil::Exception& ex) { throwException(ex TSRMLS_CC); - RETURN_EMPTY_STRING(); + RETURN_NULL(); } } -ZEND_FUNCTION(Ice_Communicator_propertyToProxy) +ZEND_METHOD(Ice_Communicator, getDefaultRouter) { - if(ZEND_NUM_ARGS() != 1) + if(ZEND_NUM_ARGS() > 0) { WRONG_PARAM_COUNT; } - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try { - return; + Ice::RouterPrx router = _this->getCommunicator()->getDefaultRouter(); + if(router) + { + ClassInfoPtr info = getClassInfoById("::Ice::Router" TSRMLS_CC); + if(!info) + { + runtimeError("no definition for Ice::Router" TSRMLS_CC); + RETURN_NULL(); + } + if(!createProxy(return_value, router, info, _this TSRMLS_CC)) + { + RETURN_NULL(); + } + } + else + { + RETURN_NULL(); + } } - assert(obj->ptr); - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} - char *str; - int len; +ZEND_METHOD(Ice_Communicator, setDefaultRouter) +{ + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) + zval* zv; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zv, proxyClassEntry TSRMLS_CC) != SUCCESS) { RETURN_NULL(); } Ice::ObjectPrx proxy; + ClassInfoPtr info; + if(zv && !fetchProxy(zv, proxy, info TSRMLS_CC)) + { + RETURN_NULL(); + } + try { - proxy = (*_this)->propertyToProxy(str); + Ice::RouterPrx router; + if(proxy) + { + if(!info || !info->isA("::Ice::Router")) + { + invalidArgument("setDefaultRouter requires a proxy narrowed to Ice::Router" TSRMLS_CC); + RETURN_NULL(); + } + router = Ice::RouterPrx::uncheckedCast(proxy); + } + _this->getCommunicator()->setDefaultRouter(router); } catch(const IceUtil::Exception& ex) { throwException(ex TSRMLS_CC); RETURN_NULL(); } - - if(!createProxy(return_value, proxy TSRMLS_CC)) - { - RETURN_NULL(); - } } -ZEND_FUNCTION(Ice_Communicator_identityToString) +ZEND_METHOD(Ice_Communicator, getDefaultLocator) { - if(ZEND_NUM_ARGS() != 1) + if(ZEND_NUM_ARGS() > 0) { WRONG_PARAM_COUNT; } - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + Ice::LocatorPrx locator = _this->getCommunicator()->getDefaultLocator(); + if(locator) + { + ClassInfoPtr info = getClassInfoById("::Ice::Locator" TSRMLS_CC); + if(!info) + { + runtimeError("no definition for Ice::Locator" TSRMLS_CC); + RETURN_NULL(); + } + if(!createProxy(return_value, locator, info, _this TSRMLS_CC)) + { + RETURN_NULL(); + } + } + else + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) { - return; + throwException(ex TSRMLS_CC); + RETURN_NULL(); } - assert(obj->ptr); - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); +} - zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC); - assert(cls); +ZEND_METHOD(Ice_Communicator, setDefaultLocator) +{ + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); - zval *zid; + zval* zv; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zv, proxyClassEntry TSRMLS_CC) != SUCCESS) + { + RETURN_NULL(); + } - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zid, cls) == FAILURE) + Ice::ObjectPrx proxy; + ClassInfoPtr info; + if(zv && !fetchProxy(zv, proxy, info TSRMLS_CC)) { RETURN_NULL(); } - Ice::Identity id; - if(extractIdentity(zid, id TSRMLS_CC)) + try { - string s = (*_this)->identityToString(id); - RETURN_STRINGL(const_cast<char*>(s.c_str()), s.length(), 1); + Ice::LocatorPrx locator; + if(proxy) + { + if(!info || !info->isA("::Ice::Locator")) + { + invalidArgument("setDefaultRouter requires a proxy narrowed to Ice::Locator" TSRMLS_CC); + RETURN_NULL(); + } + locator = Ice::LocatorPrx::uncheckedCast(proxy); + } + _this->getCommunicator()->setDefaultLocator(locator); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); } } -ZEND_FUNCTION(Ice_Communicator_stringToIdentity) +ZEND_METHOD(Ice_Communicator, flushBatchRequests) { - if(ZEND_NUM_ARGS() != 1) + CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + if(ZEND_NUM_ARGS() != 8) { WRONG_PARAM_COUNT; } - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) + try { - return; + _this->getCommunicator()->flushBatchRequests(); } - assert(obj->ptr); - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); - - char* str; - int len; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) + catch(const IceUtil::Exception& ex) { + throwException(ex TSRMLS_CC); RETURN_NULL(); } +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + Wrapper<CommunicatorInfoIPtr>* obj = Wrapper<CommunicatorInfoIPtr>::create(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC); + result.handlers = &_handlers; + return result; +} + +#ifdef _WIN32 +extern "C" +#endif +static void +handleFreeStorage(void* p TSRMLS_DC) +{ + Wrapper<CommunicatorInfoIPtr>* obj = static_cast<Wrapper<CommunicatorInfoIPtr>*>(p); + delete obj->ptr; + zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleClone(zval* zv TSRMLS_DC) +{ + php_error_docref(0 TSRMLS_CC, E_ERROR, "communicators cannot be cloned"); + return zend_object_value(); +} + +static CommunicatorInfoIPtr +createCommunicator(zval* zv, const ActiveCommunicatorPtr& ac TSRMLS_DC) +{ try { - Ice::Identity id = (*_this)->stringToIdentity(str); - createIdentity(return_value, id TSRMLS_CC); + if(object_init_ex(zv, communicatorClassEntry) != SUCCESS) + { + runtimeError("unable to initialize communicator object" TSRMLS_CC); + return 0; + } + + Wrapper<CommunicatorInfoIPtr>* obj = Wrapper<CommunicatorInfoIPtr>::extract(zv TSRMLS_CC); + assert(!obj->ptr); + + CommunicatorInfoIPtr info = new CommunicatorInfoI(ac, zv); + obj->ptr = new CommunicatorInfoIPtr(info); + + CommunicatorMap* m; + if(ICE_G(communicatorMap)) + { + m = reinterpret_cast<CommunicatorMap*>(ICE_G(communicatorMap)); + } + else + { + m = new CommunicatorMap; + ICE_G(communicatorMap) = m; + } + m->insert(CommunicatorMap::value_type(ac->communicator, info)); + + return info; } catch(const IceUtil::Exception& ex) { throwException(ex TSRMLS_CC); + return 0; } } -ZEND_FUNCTION(Ice_Communicator_addObjectFactory) +static CommunicatorInfoIPtr +initializeCommunicator(zval* zv, Ice::StringSeq& args, const Ice::InitializationData& initData TSRMLS_DC) { - if(ZEND_NUM_ARGS() != 2) + try { - WRONG_PARAM_COUNT; + Ice::CommunicatorPtr c = Ice::initialize(args, initData); + ActiveCommunicatorPtr ac = new ActiveCommunicator(c); + + // + // Install a default object factory that delegates to PHP factories. + // + c->addObjectFactory(new ObjectFactoryI(c), ""); + + CommunicatorInfoIPtr info = createCommunicator(zv, ac TSRMLS_CC); + if(!info) + { + try + { + c->destroy(); + } + catch(...) + { + } + } + + return info; } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + return 0; + } +} - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) +ZEND_FUNCTION(Ice_initialize) +{ + if(ZEND_NUM_ARGS() > 2) { - return; + runtimeError("too many arguments" TSRMLS_CC); + RETURN_NULL(); } - assert(obj->ptr); - zval* zfactory; - char* id; - int len; + zend_class_entry* initClass = idToClass("::Ice::InitializationData" TSRMLS_CC); + assert(initClass); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "os", &zfactory, &id, &len) == FAILURE) + // + // 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) { - return; + runtimeError("unable to get arguments" TSRMLS_CC); + RETURN_NULL(); } + Ice::StringSeq seq; + Ice::InitializationData initData; + zval* zvinit = 0; + // - // Verify that the object implements Ice_ObjectFactory. + // Accept the following invocations: // - // TODO: When zend_check_class is changed to also check interfaces, we can remove this code and - // pass the class entry for Ice_ObjectFactory to zend_parse_parameters instead. + // initialize(array, InitializationData) + // initialize(array) + // initialize(InitializationData) + // initialize() // - zend_class_entry* ce = Z_OBJCE_P(zfactory); - zend_class_entry* base = findClass("Ice_ObjectFactory" TSRMLS_CC); - assert(base); - if(!checkClass(ce, base)) + if(ZEND_NUM_ARGS()) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "object does not implement Ice_ObjectFactory"); - return; + if(Z_TYPE_PP(args[0]) == IS_ARRAY) + { + if(!extractStringArray(*args[0], seq TSRMLS_CC)) + { + RETURN_NULL(); + } + if(ZEND_NUM_ARGS() > 1) + { + if(Z_TYPE_PP(args[1]) != IS_OBJECT || Z_OBJCE_PP(args[1]) != initClass) + { + string s = zendTypeToString(Z_TYPE_PP(args[1])); + invalidArgument("expected InitializationData object but received %s" TSRMLS_CC, s.c_str()); + RETURN_NULL(); + } + zvinit = *args[1]; + } + } + else if(Z_TYPE_PP(args[0]) == IS_OBJECT && Z_OBJCE_PP(args[0]) == initClass) + { + if(ZEND_NUM_ARGS() > 1) + { + runtimeError("too many arguments" TSRMLS_CC); + RETURN_NULL(); + } + zvinit = *args[0]; + } + else + { + string s = zendTypeToString(Z_TYPE_PP(args[0])); + invalidArgument("unexpected argument type %s" TSRMLS_CC, s.c_str()); + RETURN_NULL(); + } } - ObjectFactoryMap* ofm = static_cast<ObjectFactoryMap*>(ICE_G(objectFactoryMap)); - ObjectFactoryMap::iterator p = ofm->find(id); - if(p != ofm->end()) + if(zvinit) { - Ice::AlreadyRegisteredException ex(__FILE__, __LINE__); - ex.kindOfObject = "object factory"; - ex.id = id; - throwException(ex TSRMLS_CC); - return; - } + void* data; + string member; - // - // Create a new zval with the same object handle as the factory. - // - zval* zv; - MAKE_STD_ZVAL(zv); - Z_TYPE_P(zv) = IS_OBJECT; - zv->value.obj = zfactory->value.obj; + member = "properties"; + if(zend_hash_find(Z_OBJPROP_P(zvinit), STRCAST(member.c_str()), member.size() + 1, &data) == SUCCESS) + { + zval** val = reinterpret_cast<zval**>(data); + if(!fetchProperties(*val, initData.properties TSRMLS_CC)) + { + RETURN_NULL(); + } + } - // - // Increment the factory's reference count. - // - Z_OBJ_HT_P(zv)->add_ref(zv TSRMLS_CC); + member = "logger"; + if(zend_hash_find(Z_OBJPROP_P(zvinit), STRCAST(member.c_str()), member.size() + 1, &data) == SUCCESS) + { + zval** val = reinterpret_cast<zval**>(data); + if(!fetchLogger(*val, initData.logger TSRMLS_CC)) + { + RETURN_NULL(); + } + } + } - // - // Update the factory map. - // - ofm->insert(ObjectFactoryMap::value_type(id, zv)); + CommunicatorInfoIPtr info = initializeCommunicator(return_value, seq, initData TSRMLS_CC); + if(!info) + { + RETURN_NULL(); + } } -ZEND_FUNCTION(Ice_Communicator_findObjectFactory) +ZEND_FUNCTION(Ice_register) { - if(ZEND_NUM_ARGS() != 1) + zval* comm; + char* s; + int sLen; + long expires = 0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &comm, communicatorClassEntry, &s, &sLen, &expires + TSRMLS_CC) != SUCCESS) { - WRONG_PARAM_COUNT; + RETURN_NULL(); } - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) + string id(s, sLen); + if(id.empty()) { + invalidArgument("communicator id cannot be empty" TSRMLS_CC); RETURN_NULL(); } - assert(obj->ptr); - char* id; - int len; + CommunicatorInfoIPtr info = Wrapper<CommunicatorInfoIPtr>::value(comm TSRMLS_CC); + assert(info); + + IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &len) == FAILURE) + RegisteredCommunicatorMap::iterator p = _registeredCommunicators.find(id); + if(p != _registeredCommunicators.end()) { - RETURN_NULL(); + if(p->second->communicator != info->getCommunicator()) + { + // + // A different communicator is already registered with that ID. + // + RETURN_FALSE; + } } - - ObjectFactoryMap* ofm = static_cast<ObjectFactoryMap*>(ICE_G(objectFactoryMap)); - ObjectFactoryMap::iterator p = ofm->find(id); - if(p == ofm->end()) + else { - RETURN_NULL(); + info->ac->ids.push_back(id); + _registeredCommunicators[id] = info->ac; } - // - // Set the zval with the same object handle as the factory. - // - Z_TYPE_P(return_value) = IS_OBJECT; - return_value->value.obj = p->second->value.obj; + if(expires > 0) + { + // + // Update the expiration time. If a communicator is registered with multiple IDs, we + // always use the most recent expiration setting. + // + info->ac->expires = static_cast<int>(expires); + info->ac->lastAccess = IceUtil::Time::now(); - // - // Increment the factory's reference count. - // - Z_OBJ_HT_P(p->second)->add_ref(p->second TSRMLS_CC); + // + // Start the timer if necessary. Reap expired communicators every five minutes. + // + if(!_timer) + { + _timer = new IceUtil::Timer; + _timer->scheduleRepeated(new ReaperTask, IceUtil::Time::seconds(5 * 60)); + } + } + + RETURN_TRUE; } -ZEND_FUNCTION(Ice_Communicator_flushBatchRequests) +ZEND_FUNCTION(Ice_unregister) { - if(ZEND_NUM_ARGS() != 0) - { - WRONG_PARAM_COUNT; - } - - ice_object* obj = getObject(getThis() TSRMLS_CC); - if(!obj) + char* s; + int sLen; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s, &sLen TSRMLS_CC) != SUCCESS) { RETURN_NULL(); } - assert(obj->ptr); - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); - try - { - (*_this)->flushBatchRequests();; - } - catch(const IceUtil::Exception& ex) + string id(s, sLen); + + IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex); + + RegisteredCommunicatorMap::iterator p = _registeredCommunicators.find(id); + if(p == _registeredCommunicators.end()) { - throwException(ex TSRMLS_CC); + // + // No communicator registered with that ID. + // + RETURN_FALSE; } + + // + // Remove the ID from the ActiveCommunicator's list of registered IDs. + // + ActiveCommunicatorPtr ac = p->second; + vector<string>::iterator q = find(ac->ids.begin(), ac->ids.end(), id); + assert(q != ac->ids.end()); + ac->ids.erase(q); + + _registeredCommunicators.erase(p); + + RETURN_TRUE; } -ZEND_FUNCTION(Ice_stringToIdentity) +ZEND_FUNCTION(Ice_find) { - if(ZEND_NUM_ARGS() != 1) + char* s; + int sLen; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s, &sLen TSRMLS_CC) != SUCCESS) { - WRONG_PARAM_COUNT; + RETURN_NULL(); } - char* str; - int len; + string id(s, sLen); + + IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) + RegisteredCommunicatorMap::iterator p = _registeredCommunicators.find(id); + if(p == _registeredCommunicators.end()) { + // + // No communicator registered with that ID. + // RETURN_NULL(); } - try + if(p->second->expires > 0) { - Ice::CommunicatorPtr communicator = getCommunicator(TSRMLS_C); - Ice::Identity id = communicator->stringToIdentity(str); - createIdentity(return_value, id TSRMLS_CC); + p->second->lastAccess = IceUtil::Time::now(); } - catch(const IceUtil::Exception& ex) + + // + // Check if this communicator has already been obtained by the current request. + // If so, we can return the existing PHP object that corresponds to the communicator. + // + CommunicatorMap* m = reinterpret_cast<CommunicatorMap*>(ICE_G(communicatorMap)); + if(m) { - throwException(ex TSRMLS_CC); + CommunicatorMap::iterator q = m->find(p->second->communicator); + if(q != m->end()) + { + q->second->getZval(return_value TSRMLS_CC); + return; + } + } + + if(!createCommunicator(return_value, p->second TSRMLS_CC)) + { + RETURN_NULL(); } } -ZEND_FUNCTION(Ice_identityToString) +ZEND_FUNCTION(Ice_getProperties) { - if(ZEND_NUM_ARGS() != 1) + char* s = 0; + int sLen; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &s, &sLen TSRMLS_CC) != SUCCESS) { - WRONG_PARAM_COUNT; + RETURN_NULL(); } - zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC); - assert(cls); - - zval *zid; + string name; + if(s) + { + name = string(s, sLen); + } - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zid, cls) == FAILURE) + ProfileMap::iterator p = _profiles.find(name); + if(p == _profiles.end()) { RETURN_NULL(); } - Ice::Identity id; - if(extractIdentity(zid, id TSRMLS_CC)) + Ice::PropertiesPtr clone = p->second->clone(); + if(!createProperties(return_value, clone TSRMLS_CC)) { - Ice::CommunicatorPtr communicator = getCommunicator(TSRMLS_C); - string s = communicator->identityToString(id); - RETURN_STRINGL(const_cast<char*>(s.c_str()), s.length(), 1); + RETURN_NULL(); } } -#ifdef _WIN32 -extern "C" -#endif -static zend_object_value -handleAlloc(zend_class_entry* ce TSRMLS_DC) +// +// Predefined methods for Communicator. +// +static function_entry _interfaceMethods[] = { - zend_object_value result; - - ice_object* obj = newObject(ce TSRMLS_CC); - assert(obj); + {0, 0, 0} +}; +static function_entry _classMethods[] = +{ + ZEND_ME(Ice_Communicator, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) + ZEND_ME(Ice_Communicator, destroy, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, stringToProxy, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, proxyToString, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, propertyToProxy, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, stringToIdentity, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, identityToString, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, addObjectFactory, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, findObjectFactory, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, getImplicitContext, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, getProperties, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, getLogger, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, getDefaultRouter, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, setDefaultRouter, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, getDefaultLocator, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, setDefaultLocator, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Communicator, flushBatchRequests, NULL, ZEND_ACC_PUBLIC) + {0, 0, 0} +}; - result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC); - result.handlers = &_handlers; +static bool +createProfile(const string& name, const string& config, const string& options TSRMLS_DC) +{ + ProfileMap::iterator p = _profiles.find(name); + if(p != _profiles.end()) + { + php_error_docref(0 TSRMLS_CC, E_WARNING, "duplicate Ice profile `%s'", name.c_str()); + return false; + } - return result; -} + Ice::PropertiesPtr properties = Ice::createProperties(); -#ifdef _WIN32 -extern "C" -#endif -static zend_object_value -handleClone(zval* zv TSRMLS_DC) -{ - zend_object_value result; - memset(&result, 0, sizeof(zend_object_value)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "__clone is not supported for Ice_Communicator"); - return result; -} + if(!config.empty()) + { + try + { + properties->load(config); + } + catch(const IceUtil::Exception& ex) + { + ostringstream ostr; + ex.ice_print(ostr); + php_error_docref(0 TSRMLS_CC, E_WARNING, "unable to load Ice configuration file %s:\n%s", config.c_str(), + ostr.str().c_str()); + return false; + } + } -#ifdef _WIN32 -extern "C" -#endif -static void -handleFreeStorage(void* p TSRMLS_DC) -{ - ice_object* obj = static_cast<ice_object*>(p); - if(obj->ptr) + if(!options.empty()) { - Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr); + vector<string> args; try { - (*_this)->destroy(); + args = IceUtilInternal::Options::split(options); } catch(const IceUtil::Exception& ex) { ostringstream ostr; ex.ice_print(ostr); - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to destroy communicator:\n%s", ostr.str().c_str()); + string msg = ostr.str(); + php_error_docref(0 TSRMLS_CC, E_WARNING, "error occurred while parsing the options `%s':\n%s", + options.c_str(), msg.c_str()); + return false; } - delete _this; + + properties->parseCommandLineOptions("", args); } - zend_objects_free_object_storage(reinterpret_cast<zend_object*>(p) TSRMLS_CC); + _profiles[name] = properties; + return true; } -#ifdef _WIN32 -extern "C" -#endif -static union _zend_function* -handleGetMethod(zval** zv, char* method, int len TSRMLS_DC) +static bool +parseProfiles(const string& file TSRMLS_DC) { // - // Delegate to the standard implementation of get_method. We're simply using this hook - // as a convenient way of implementing lazy initialization of the communicator. + // The Zend engine doesn't export a function for loading an INI file, so we + // have to do it ourselves. The format is: + // + // [profile-name] + // ice.config = config-file + // ice.options = args // - zend_function* result = zend_get_std_object_handlers()->get_method(zv, method, len TSRMLS_CC); - if(result) + ifstream in(file.c_str()); + if(!in) { - ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(*zv TSRMLS_CC)); - if(!obj->ptr) + php_error_docref(0 TSRMLS_CC, E_WARNING, "unable to open Ice profiles in %s", file.c_str()); + return false; + } + + string name, config, options; + char line[1024]; + while(in.getline(line, 1024)) + { + const string delim = " \t\r\n"; + string s = line; + + string::size_type idx = s.find(';'); + if(idx != string::npos) + { + s.erase(idx); + } + + idx = s.find_last_not_of(delim); + if(idx != string::npos && idx + 1 < s.length()) + { + s.erase(idx + 1); + } + + string::size_type beg = s.find_first_not_of(delim); + if(beg == string::npos) { - if(!ICE_G(profile)) + continue; + } + + if(s[beg] == '[') + { + beg++; + string::size_type end = s.find_first_of(" \t]", beg); + if(end == string::npos || s[s.length() - 1] != ']') { - php_error_docref(0 TSRMLS_CC, E_ERROR, "$ICE used before a profile was loaded"); - return 0; + php_error_docref(0 TSRMLS_CC, E_WARNING, "invalid profile section in file %s:\n%s\n", file.c_str(), + line); + return false; } - try + if(!name.empty()) { - initCommunicator(obj TSRMLS_CC); + createProfile(name, config, options TSRMLS_CC); + config.clear(); + options.clear(); } - catch(const IceUtil::Exception& ex) + + name = s.substr(beg, end - beg); + } + else + { + string::size_type end = s.find_first_of(delim + "=", beg); + assert(end != string::npos); + + string key = s.substr(beg, end - beg); + + end = s.find('=', end); + if(end == string::npos) + { + php_error_docref(0 TSRMLS_CC, E_WARNING, "invalid profile entry in file %s:\n%s\n", file.c_str(), line); + return false; + } + ++end; + + string value; + beg = s.find_first_not_of(delim, end); + if(beg != string::npos) + { + end = s.length(); + value = s.substr(beg, end - beg); + } + + if(key == "config" || key == "ice.config") + { + config = value; + } + else if(key == "options" || key == "ice.options") + { + options = value; + } + else + { + php_error_docref(0 TSRMLS_CC, E_WARNING, "unknown profile entry in file %s:\n%s\n", file.c_str(), line); + } + + if(name.empty()) { - ostringstream ostr; - ex.ice_print(ostr); - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize communicator:\n%s", ostr.str().c_str()); - return 0; + php_error_docref(0 TSRMLS_CC, E_WARNING, "no section for profile entry in file %s:\n%s\n", file.c_str(), + line); + return false; } } } - return result; + if(!name.empty()) + { + if(!createProfile(name, config, options TSRMLS_CC)) + { + return false; + } + } + + return true; } -// -// Initialize a communicator instance and store it in the given object. Can raise exceptions. -// -static void -initCommunicator(ice_object* obj TSRMLS_DC) +bool +IcePHP::communicatorInit(TSRMLS_D) { - assert(!obj->ptr); + // + // We register an interface and a class that implements the interface. This allows + // applications to safely include the Slice-generated code for the type. + // + + // + // Register the Communicator interface. + // + zend_class_entry ce; +#ifdef ICEPHP_USE_NAMESPACES + INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Communicator"), _interfaceMethods); +#else + INIT_CLASS_ENTRY(ce, "Ice_Communicator", _interfaceMethods); +#endif + zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC); - Ice::PropertiesPtr* properties = static_cast<Ice::PropertiesPtr*>(ICE_G(properties)); + // + // Register the Communicator class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_Communicator", _classMethods); + ce.create_object = handleAlloc; + communicatorClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + _handlers.clone_obj = handleClone; + zend_class_implements(communicatorClassEntry TSRMLS_CC, 1, interface); - Ice::InitializationData initData; - initData.properties = *properties; - Ice::CommunicatorPtr communicator = Ice::initialize(initData); - obj->ptr = new Ice::CommunicatorPtr(communicator); + // + // Create the profiles from configuration settings. + // + const char* config = INI_STR("ice.config"); + const char* options = INI_STR("ice.options"); + if(!createProfile(_defaultProfileName, config, options TSRMLS_CC)) + { + return false; + } + + const char* profiles = INI_STR("ice.profiles"); + if(strlen(profiles) > 0) + { + if(!parseProfiles(profiles TSRMLS_CC)) + { + return false; + } + + if(INI_BOOL("ice.hide_profiles")) + { + memset(const_cast<char*>(profiles), '*', strlen(profiles)); + // + // For some reason the code below does not work as expected. It causes a call + // to ini_get_all() to segfault. + // + /* + if(zend_alter_ini_entry("ice.profiles", sizeof("ice.profiles"), "<hidden>", sizeof("<hidden>") - 1, + PHP_INI_ALL, PHP_INI_STAGE_STARTUP) == FAILURE) + { + return false; + } + */ + } + } + + return true; +} + +bool +IcePHP::communicatorShutdown(TSRMLS_D) +{ + _profiles.clear(); + + IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex); + + if(_timer) + { + _timer->destroy(); + _timer = 0; + } + + // + // Clearing the map releases the last remaining reference counts of the ActiveCommunicator + // objects. The ActiveCommunicator destructor destroys its communicator. + // + _registeredCommunicators.clear(); + + return true; +} + +bool +IcePHP::communicatorRequestInit(TSRMLS_D) +{ + ICE_G(communicatorMap) = 0; + + return true; +} + +bool +IcePHP::communicatorRequestShutdown(TSRMLS_D) +{ + if(ICE_G(communicatorMap)) + { + CommunicatorMap* m = static_cast<CommunicatorMap*>(ICE_G(communicatorMap)); + for(CommunicatorMap::iterator p = m->begin(); p != m->end(); ++p) + { + CommunicatorInfoIPtr info = p->second; + + // + // We need to destroy any object factories installed during this request. + // + info->destroyObjectFactories(TSRMLS_C); + } + + // + // Deleting the map decrements the reference count of its ActiveCommunicator + // values. If there are no other references to an ActiveCommunicator, its + // destructor destroys the communicator. + // + delete m; + } + + return true; +} + +IcePHP::ActiveCommunicator::ActiveCommunicator(const Ice::CommunicatorPtr& c) : + communicator(c), expires(0) +{ +} +IcePHP::ActiveCommunicator::~ActiveCommunicator() +{ // - // Register our default object factory with the communicator. + // There are no more references to this communicator, so we can safely destroy it now. // - Ice::ObjectFactoryPtr factory = new PHPObjectFactory(TSRMLS_C); - communicator->addObjectFactory(factory, ""); + try + { + communicator->destroy(); + } + catch(...) + { + } +} + +IcePHP::CommunicatorInfoI::CommunicatorInfoI(const ActiveCommunicatorPtr& c, zval* z) : + ac(c), + zv(*z) // This is legal - it simply copies the object's handle. +{ +} + +void +IcePHP::CommunicatorInfoI::getZval(zval* z TSRMLS_DC) +{ + Z_TYPE_P(z) = IS_OBJECT; + z->value.obj = zv.value.obj; + addRef(TSRMLS_C); +} + +void +IcePHP::CommunicatorInfoI::addRef(TSRMLS_D) +{ + zval* p = const_cast<zval*>(&zv); + Z_OBJ_HT_P(p)->add_ref(p TSRMLS_CC); +} + +void +IcePHP::CommunicatorInfoI::decRef(TSRMLS_D) +{ + zval* p = const_cast<zval*>(&zv); + Z_OBJ_HT(zv)->del_ref(p TSRMLS_CC); +} + +Ice::CommunicatorPtr +IcePHP::CommunicatorInfoI::getCommunicator() const +{ + return ac->communicator; +} + +bool +IcePHP::CommunicatorInfoI::addObjectFactory(const string& id, zval* factory TSRMLS_DC) +{ + ObjectFactoryMap::iterator p = objectFactories.find(id); + if(p != objectFactories.end()) + { + Ice::AlreadyRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "object factory"; + ex.id = id; + throwException(ex TSRMLS_CC); + return false; + } + + objectFactories.insert(ObjectFactoryMap::value_type(id, factory)); + Z_ADDREF_P(factory); + + return true; +} + +bool +IcePHP::CommunicatorInfoI::findObjectFactory(const string& id, zval* zv TSRMLS_DC) +{ + ObjectFactoryMap::iterator p = objectFactories.find(id); + if(p != objectFactories.end()) + { + *zv = *p->second; // This is legal - it simply copies the object's handle. + INIT_PZVAL(zv); + zval_copy_ctor(zv); + return true; + } + + return false; +} + +void +IcePHP::CommunicatorInfoI::destroyObjectFactories(TSRMLS_D) +{ + for(ObjectFactoryMap::iterator p = objectFactories.begin(); p != objectFactories.end(); ++p) + { + // + // Invoke the destroy method on each registered PHP factory. + // + invokeMethod(p->second, "destroy" TSRMLS_CC); + zend_clear_exception(TSRMLS_C); + zval_ptr_dtor(&p->second); + } +} + +IcePHP::ObjectFactoryI::ObjectFactoryI(const Ice::CommunicatorPtr& communicator) : + _communicator(communicator) +{ +} + +Ice::ObjectPtr +IcePHP::ObjectFactoryI::create(const string& id) +{ + // + // Get the TSRM id for the current request. + // + TSRMLS_FETCH(); + + CommunicatorMap* m = static_cast<CommunicatorMap*>(ICE_G(communicatorMap)); + assert(m); + CommunicatorMap::iterator p = m->find(_communicator); + assert(p != m->end()); + + CommunicatorInfoIPtr info = p->second; + + zval* factory = 0; + + // + // Check if the application has registered a factory for this id. + // + ObjectFactoryMap::iterator q = info->objectFactories.find(id); + if(q == info->objectFactories.end()) + { + q = info->objectFactories.find(""); // Look for a default factory. + } + if(q != info->objectFactories.end()) + { + factory = q->second; + } + + // + // Get the type information. + // + ClassInfoPtr cls = getClassInfoById(id TSRMLS_CC); + if(!cls) + { + return 0; + } + + if(factory) + { + zval* arg; + MAKE_STD_ZVAL(arg); + ZVAL_STRINGL(arg, STRCAST(id.c_str()), id.length(), 1); + + zval* obj = 0; + + zend_try + { + zend_call_method_with_1_params(&factory, 0, 0, "create", &obj, arg); + } + zend_catch + { + obj = 0; + } + zend_end_try(); + + zval_ptr_dtor(&arg); + + // + // Bail out if an exception has already been thrown. + // + if(!obj || EG(exception)) + { + throw AbortMarshaling(); + } + + AutoDestroy destroy(obj); + + if(Z_TYPE_P(obj) == IS_NULL) + { + return 0; + } + + return new ObjectReader(obj, cls, info TSRMLS_CC); + } + + // + // If the requested type is an abstract class, then we give up. + // + if(cls->isAbstract) + { + return 0; + } + + // + // Instantiate the object. + // + zval* obj; + MAKE_STD_ZVAL(obj); + AutoDestroy destroy(obj); + + if(object_init_ex(obj, cls->zce) != SUCCESS) + { + throw AbortMarshaling(); + } + + if(!invokeMethod(obj, ZEND_CONSTRUCTOR_FUNC_NAME TSRMLS_CC)) + { + throw AbortMarshaling(); + } + + return new ObjectReader(obj, cls, info TSRMLS_CC); +} + +void +IcePHP::ObjectFactoryI::destroy() +{ + _communicator = 0; +} + +void +IcePHP::ReaperTask::runTimerTask() +{ + IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex); + + IceUtil::Time now = IceUtil::Time::now(); + RegisteredCommunicatorMap::iterator p = _registeredCommunicators.begin(); + while(p != _registeredCommunicators.end()) + { + if(p->second->lastAccess + IceUtil::Time::seconds(p->second->expires * 60) <= now) + { + try + { + p->second->communicator->destroy(); + } + catch(...) + { + } + _registeredCommunicators.erase(p++); + } + else + { + ++p; + } + } } diff --git a/php/src/IcePHP/Communicator.h b/php/src/IcePHP/Communicator.h index 25483ffd644..c6f59c1cba5 100644 --- a/php/src/IcePHP/Communicator.h +++ b/php/src/IcePHP/Communicator.h @@ -7,63 +7,69 @@ // // ********************************************************************** -#ifndef ICE_PHP_COMMUNICATOR_H -#define ICE_PHP_COMMUNICATOR_H +#ifndef ICEPHP_COMMUNICATOR_H +#define ICEPHP_COMMUNICATOR_H #include <Config.h> +#include <Ice/CommunicatorF.h> // -// Ice_Communicator class methods. +// Global functions. // extern "C" { -ZEND_FUNCTION(Ice_Communicator___construct); -ZEND_FUNCTION(Ice_Communicator_getProperty); -ZEND_FUNCTION(Ice_Communicator_setProperty); -ZEND_FUNCTION(Ice_Communicator_stringToProxy); -ZEND_FUNCTION(Ice_Communicator_proxyToString); -ZEND_FUNCTION(Ice_Communicator_propertyToProxy); -ZEND_FUNCTION(Ice_Communicator_stringToIdentity); -ZEND_FUNCTION(Ice_Communicator_identityToString); -ZEND_FUNCTION(Ice_Communicator_addObjectFactory); -ZEND_FUNCTION(Ice_Communicator_findObjectFactory); -ZEND_FUNCTION(Ice_Communicator_flushBatchRequests); +ZEND_FUNCTION(Ice_initialize); +ZEND_FUNCTION(Ice_register); +ZEND_FUNCTION(Ice_unregister); +ZEND_FUNCTION(Ice_find); +ZEND_FUNCTION(Ice_getProperties); } -#define ICE_PHP_COMMUNICATOR_FUNCTIONS \ - ZEND_FE(Ice_Communicator___construct, NULL) \ - ZEND_FE(Ice_Communicator_getProperty, NULL) \ - ZEND_FE(Ice_Communicator_setProperty, NULL) \ - ZEND_FE(Ice_Communicator_stringToProxy, NULL) \ - ZEND_FE(Ice_Communicator_proxyToString, NULL) \ - ZEND_FE(Ice_Communicator_propertyToProxy, NULL) \ - ZEND_FE(Ice_Communicator_stringToIdentity, NULL) \ - ZEND_FE(Ice_Communicator_identityToString, NULL) \ - ZEND_FE(Ice_Communicator_addObjectFactory, NULL) \ - ZEND_FE(Ice_Communicator_findObjectFactory, NULL) \ - ZEND_FE(Ice_Communicator_flushBatchRequests, NULL) +#define ICEPHP_COMMUNICATOR_FUNCTIONS \ + ZEND_FE(Ice_initialize, NULL) \ + ZEND_FE(Ice_register, NULL) \ + ZEND_FE(Ice_unregister, NULL) \ + ZEND_FE(Ice_find, NULL) \ + ZEND_FE(Ice_getProperties, NULL) -// -// Ice_Identity global functions. -// -extern "C" -{ -ZEND_FUNCTION(Ice_stringToIdentity); -ZEND_FUNCTION(Ice_identityToString); -} - -#define ICE_PHP_IDENTITY_FUNCTIONS \ - ZEND_FE(Ice_stringToIdentity, NULL) \ - ZEND_FE(Ice_identityToString, NULL) +#ifdef ICEPHP_USE_NAMESPACES +# define ICEPHP_COMMUNICATOR_NS_FUNCTIONS \ + ZEND_NS_FALIAS("Ice", initialize, Ice_initialize, NULL) \ + ZEND_NS_FALIAS("Ice", register, Ice_register, NULL) \ + ZEND_NS_FALIAS("Ice", unregister, Ice_unregister, NULL) \ + ZEND_NS_FALIAS("Ice", find, Ice_find, NULL) \ + ZEND_NS_FALIAS("Ice", getProperties, Ice_getProperties, NULL) +#else +# define ICEPHP_COMMUNICATOR_NS_FUNCTIONS +#endif namespace IcePHP { bool communicatorInit(TSRMLS_D); +bool communicatorShutdown(TSRMLS_D); +bool communicatorRequestInit(TSRMLS_D); +bool communicatorRequestShutdown(TSRMLS_D); + +// +// Class entry. +// +extern zend_class_entry* communicatorClassEntry; + +// +// The CommunicatorInfo class represents a communicator that is in use by a PHP request. +// +class CommunicatorInfo : public IceUtil::Shared +{ +public: + + virtual void getZval(zval* TSRMLS_DC) = 0; + virtual void addRef(TSRMLS_D) = 0; + virtual void decRef(TSRMLS_D) = 0; -bool createCommunicator(TSRMLS_D); -Ice::CommunicatorPtr getCommunicator(TSRMLS_D); -zval* getCommunicatorZval(TSRMLS_D); + virtual Ice::CommunicatorPtr getCommunicator() const = 0; +}; +typedef IceUtil::Handle<CommunicatorInfo> CommunicatorInfoPtr; } // End of namespace IcePHP diff --git a/php/src/IcePHP/Config.h b/php/src/IcePHP/Config.h index 304d31dd625..46601ec260b 100644 --- a/php/src/IcePHP/Config.h +++ b/php/src/IcePHP/Config.h @@ -21,7 +21,6 @@ #endif #include <Ice/Ice.h> -#include <Slice/Parser.h> #ifdef _WIN32 # undef WIN32_LEAN_AND_MEAN @@ -60,6 +59,13 @@ extern zend_module_entry ice_module_entry; #include "TSRM.h" #endif +// +// The PHP header files define a macro named "inline". +// +#ifdef inline +# undef inline +#endif + ZEND_MINIT_FUNCTION(ice); ZEND_MSHUTDOWN_FUNCTION(ice); ZEND_RINIT_FUNCTION(ice); @@ -67,17 +73,37 @@ ZEND_RSHUTDOWN_FUNCTION(ice); ZEND_MINFO_FUNCTION(ice); ZEND_BEGIN_MODULE_GLOBALS(ice) - zval* communicator; - void* marshalerMap; - void* profile; - void* properties; - void* objectFactoryMap; + void* communicatorMap; + void* idToClassInfoMap; + void* nameToClassInfoMap; + void* proxyInfoMap; + void* exceptionInfoMap; ZEND_END_MODULE_GLOBALS(ice) #ifdef ZTS -#define ICE_G(v) TSRMG(ice_globals_id, zend_ice_globals*, v) +# define ICE_G(v) TSRMG(ice_globals_id, zend_ice_globals*, v) +#else +# define ICE_G(v) (ice_globals.v) +#endif + +#ifndef Z_ADDREF_P +# ifndef ZVAL_ADDREF +# error "Unknown PHP version" +# endif +# define Z_ADDREF_P(zv) ZVAL_ADDREF(zv) +#endif + +#ifndef ZEND_MN +# define ZEND_MN(name) ZEND_FN(name) +#endif + +#ifdef STRCAST +# error "STRCAST already defined!" +#endif +#if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) +# define STRCAST(s) s #else -#define ICE_G(v) (ice_globals.v) +# define STRCAST(s) const_cast<char*>(s) #endif #endif diff --git a/php/src/IcePHP/Connection.cpp b/php/src/IcePHP/Connection.cpp new file mode 100644 index 00000000000..e4bad5a0352 --- /dev/null +++ b/php/src/IcePHP/Connection.cpp @@ -0,0 +1,304 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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 <Connection.h> +#include <Util.h> + +using namespace std; +using namespace IcePHP; + +ZEND_EXTERN_MODULE_GLOBALS(ice) + +// +// Class entries represent the PHP class implementations we have registered. +// +namespace IcePHP +{ +zend_class_entry* connectionClassEntry = 0; +} + +// +// Ice::Connection support. +// +static zend_object_handlers _handlers; + +extern "C" +{ +static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC); +static void handleFreeStorage(void* TSRMLS_DC); +static int handleCompare(zval*, zval* TSRMLS_DC); +} + +ZEND_METHOD(Ice_Connection, __construct) +{ + runtimeError("Connection cannot be instantiated" TSRMLS_CC); +} + +ZEND_METHOD(Ice_Connection, __toString) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + string str = _this->toString(); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Connection, close) +{ + Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + 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_METHOD(Ice_Connection, flushBatchRequests) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + _this->flushBatchRequests(); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Connection, type) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + string str = _this->type(); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Connection, timeout) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + 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_METHOD(Ice_Connection, toString) +{ + ZEND_MN(Ice_Connection___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::create(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC); + result.handlers = &_handlers; + + return result; +} + +#ifdef _WIN32 +extern "C" +#endif +static void +handleFreeStorage(void* p TSRMLS_DC) +{ + Wrapper<Ice::ConnectionPtr>* obj = static_cast<Wrapper<Ice::ConnectionPtr>*>(p); + delete obj->ptr; + zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); +} + +#ifdef _WIN32 +extern "C" +#endif +static int +handleCompare(zval* zobj1, zval* zobj2 TSRMLS_DC) +{ + // + // PHP guarantees that the objects have the same class. + // + + Ice::ConnectionPtr con1 = Wrapper<Ice::ConnectionPtr>::value(zobj1 TSRMLS_CC); + assert(con1); + Ice::ConnectionPtr con2 = Wrapper<Ice::ConnectionPtr>::value(zobj2 TSRMLS_CC); + assert(con2); + + if(con1 == con2) + { + return 0; + } + else if(con1 < con2) + { + return -1; + } + else + { + return 1; + } +} + +// +// Predefined methods for Connection. +// +static function_entry _interfaceMethods[] = +{ + {0, 0, 0} +}; +static function_entry _classMethods[] = +{ + ZEND_ME(Ice_Connection, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) + ZEND_ME(Ice_Connection, __toString, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Connection, close, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Connection, flushBatchRequests, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Connection, type, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Connection, timeout, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Connection, toString, NULL, ZEND_ACC_PUBLIC) + {0, 0, 0} +}; + +bool +IcePHP::connectionInit(TSRMLS_D) +{ + // + // We register an interface and a class that implements the interface. This allows + // applications to safely include the Slice-generated code for the type. + // + + // + // Register the Connection interface. + // + zend_class_entry ce; +#ifdef ICEPHP_USE_NAMESPACES + INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Connection"), _interfaceMethods); +#else + INIT_CLASS_ENTRY(ce, "Ice_Connection", _interfaceMethods); +#endif + zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC); + + // + // Register the Connection class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_Connection", _classMethods); + ce.create_object = handleAlloc; + connectionClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + _handlers.compare_objects = handleCompare; + zend_class_implements(connectionClassEntry TSRMLS_CC, 1, interface); + + return true; +} + +bool +IcePHP::createConnection(zval* zv, const Ice::ConnectionPtr& p TSRMLS_DC) +{ + if(object_init_ex(zv, connectionClassEntry) != SUCCESS) + { + runtimeError("unable to initialize connection" TSRMLS_CC); + return false; + } + + Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::extract(zv TSRMLS_CC); + assert(obj); + assert(!obj->ptr); + obj->ptr = new Ice::ConnectionPtr(p); + + return true; +} + +bool +IcePHP::fetchConnection(zval* zv, Ice::ConnectionPtr& connection TSRMLS_DC) +{ + if(ZVAL_IS_NULL(zv)) + { + connection = 0; + } + else + { + if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != connectionClassEntry) + { + invalidArgument("value is not a connection" TSRMLS_CC); + return false; + } + Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::extract(zv TSRMLS_CC); + if(!obj) + { + return false; + } + connection = *obj->ptr; + } + return true; +} diff --git a/php/src/IcePHP/Connection.h b/php/src/IcePHP/Connection.h new file mode 100644 index 00000000000..03d67d71357 --- /dev/null +++ b/php/src/IcePHP/Connection.h @@ -0,0 +1,30 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef ICEPHP_CONNECTION_H +#define ICEPHP_CONNECTION_H + +#include <Config.h> + +namespace IcePHP +{ + +bool connectionInit(TSRMLS_D); + +bool createConnection(zval*, const Ice::ConnectionPtr& TSRMLS_DC); +bool fetchConnection(zval*, Ice::ConnectionPtr& TSRMLS_DC); + +// +// Class entry. +// +extern zend_class_entry* connectionClassEntry; + +} // End of namespace IcePHP + +#endif diff --git a/php/src/IcePHP/Endpoint.cpp b/php/src/IcePHP/Endpoint.cpp new file mode 100644 index 00000000000..b4b41f6a43a --- /dev/null +++ b/php/src/IcePHP/Endpoint.cpp @@ -0,0 +1,500 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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 <Endpoint.h> +#include <Util.h> + +using namespace std; +using namespace IcePHP; + +ZEND_EXTERN_MODULE_GLOBALS(ice) + +// +// Class entries represent the PHP class implementations we have registered. +// +namespace IcePHP +{ +zend_class_entry* endpointClassEntry = 0; +} + +static zend_class_entry* tcpEndpointClassEntry = 0; +static zend_class_entry* udpEndpointClassEntry = 0; +static zend_class_entry* opaqueEndpointClassEntry = 0; + +// +// Ice::Endpoint support. +// +static zend_object_handlers _handlers; + +extern "C" +{ +static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC); +static void handleFreeStorage(void* TSRMLS_DC); +} + +ZEND_METHOD(Ice_Endpoint, __construct) +{ + runtimeError("Endpoint cannot be instantiated" TSRMLS_CC); +} + +ZEND_METHOD(Ice_Endpoint, __toString) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr _this = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + string str = _this->toString(); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Endpoint, toString) +{ + ZEND_MN(Ice_Endpoint___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +ZEND_METHOD(Ice_Endpoint, timeout) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr _this = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + long timeout = static_cast<long>(_this->timeout()); + RETURN_LONG(timeout); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Endpoint, compress) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr _this = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + RETURN_BOOL(_this->timeout() ? 1 : 0); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_TcpEndpoint, host) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(base); + Ice::TcpEndpointPtr _this = Ice::TcpEndpointPtr::dynamicCast(base); + assert(_this); + + try + { + string str = _this->host(); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_TcpEndpoint, port) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(base); + Ice::TcpEndpointPtr _this = Ice::TcpEndpointPtr::dynamicCast(base); + assert(_this); + + try + { + long port = static_cast<long>(_this->port()); + RETURN_LONG(port); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_UdpEndpoint, host) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(base); + Ice::UdpEndpointPtr _this = Ice::UdpEndpointPtr::dynamicCast(base); + assert(_this); + + try + { + string str = _this->host(); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_UdpEndpoint, port) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(base); + Ice::UdpEndpointPtr _this = Ice::UdpEndpointPtr::dynamicCast(base); + assert(_this); + + try + { + long port = static_cast<long>(_this->port()); + RETURN_LONG(port); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_UdpEndpoint, mcastInterface) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(base); + Ice::UdpEndpointPtr _this = Ice::UdpEndpointPtr::dynamicCast(base); + assert(_this); + + try + { + string str = _this->mcastInterface(); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_UdpEndpoint, mcastTtl) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(base); + Ice::UdpEndpointPtr _this = Ice::UdpEndpointPtr::dynamicCast(base); + assert(_this); + + try + { + long port = static_cast<long>(_this->mcastTtl()); + RETURN_LONG(port); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_OpaqueEndpoint, rawBytes) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC); + assert(base); + Ice::OpaqueEndpointPtr _this = Ice::OpaqueEndpointPtr::dynamicCast(base); + assert(_this); + + try + { + Ice::ByteSeq seq = _this->rawBytes(); + array_init(return_value); + for(Ice::ByteSeq::iterator p = seq.begin(); p != seq.end(); ++p) + { + add_next_index_long(return_value, static_cast<long>(*p)); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::create(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC); + result.handlers = &_handlers; + + return result; +} + +#ifdef _WIN32 +extern "C" +#endif +static void +handleFreeStorage(void* p TSRMLS_DC) +{ + Wrapper<Ice::EndpointPtr>* obj = static_cast<Wrapper<Ice::EndpointPtr>*>(p); + delete obj->ptr; + zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); +} + +// +// Predefined methods for Endpoint. +// +static function_entry _interfaceMethods[] = +{ + {0, 0, 0} +}; +static function_entry _endpointMethods[] = +{ + ZEND_ME(Ice_Endpoint, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) + ZEND_ME(Ice_Endpoint, __toString, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Endpoint, toString, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Endpoint, timeout, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Endpoint, compress, NULL, ZEND_ACC_PUBLIC) + {0, 0, 0} +}; +static function_entry _tcpEndpointMethods[] = +{ + ZEND_ME(Ice_TcpEndpoint, host, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_TcpEndpoint, port, NULL, ZEND_ACC_PUBLIC) + {0, 0, 0} +}; +static function_entry _udpEndpointMethods[] = +{ + ZEND_ME(Ice_UdpEndpoint, host, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_UdpEndpoint, port, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_UdpEndpoint, mcastInterface, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_UdpEndpoint, mcastTtl, NULL, ZEND_ACC_PUBLIC) + {0, 0, 0} +}; +static function_entry _opaqueEndpointMethods[] = +{ + ZEND_ME(Ice_OpaqueEndpoint, rawBytes, NULL, ZEND_ACC_PUBLIC) + {0, 0, 0} +}; + +bool +IcePHP::endpointInit(TSRMLS_D) +{ + // + // We register an interface and a class that implements the interface. This allows + // applications to safely include the Slice-generated code for the type. + // + + // + // Register the Endpoint interface. + // + zend_class_entry ce; +#ifdef ICEPHP_USE_NAMESPACES + INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Endpoint"), _interfaceMethods); +#else + INIT_CLASS_ENTRY(ce, "Ice_Endpoint", _interfaceMethods); +#endif + zend_class_entry* endpointInterface = zend_register_internal_interface(&ce TSRMLS_CC); + + // + // Register the TcpEndpoint interface. + // +#ifdef ICEPHP_USE_NAMESPACES + INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("TcpEndpoint"), _interfaceMethods); +#else + INIT_CLASS_ENTRY(ce, "Ice_TcpEndpoint", _interfaceMethods); +#endif + zend_class_entry* tcpEndpointInterface = zend_register_internal_interface(&ce TSRMLS_CC); + zend_class_implements(tcpEndpointInterface TSRMLS_CC, 1, endpointInterface); + + // + // Register the UdpEndpoint interface. + // +#ifdef ICEPHP_USE_NAMESPACES + INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("UdpEndpoint"), _interfaceMethods); +#else + INIT_CLASS_ENTRY(ce, "Ice_UdpEndpoint", _interfaceMethods); +#endif + zend_class_entry* udpEndpointInterface = zend_register_internal_interface(&ce TSRMLS_CC); + zend_class_implements(udpEndpointInterface TSRMLS_CC, 1, endpointInterface); + + // + // Register the OpaqueEndpoint interface. + // +#ifdef ICEPHP_USE_NAMESPACES + INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("OpaqueEndpoint"), _interfaceMethods); +#else + INIT_CLASS_ENTRY(ce, "Ice_OpaqueEndpoint", _interfaceMethods); +#endif + zend_class_entry* opaqueEndpointInterface = zend_register_internal_interface(&ce TSRMLS_CC); + zend_class_implements(opaqueEndpointInterface TSRMLS_CC, 1, endpointInterface); + + // + // Register the Endpoint class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_Endpoint", _endpointMethods); + ce.create_object = handleAlloc; + endpointClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + zend_class_implements(endpointClassEntry TSRMLS_CC, 1, endpointInterface); + + // + // Register the TcpEndpoint class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_TcpEndpoint", _tcpEndpointMethods); + ce.create_object = handleAlloc; + tcpEndpointClassEntry = zend_register_internal_class_ex(&ce, endpointClassEntry, NULL TSRMLS_CC); + memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + zend_class_implements(tcpEndpointClassEntry TSRMLS_CC, 1, tcpEndpointInterface); + + // + // Register the UdpEndpoint class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_UdpEndpoint", _udpEndpointMethods); + ce.create_object = handleAlloc; + udpEndpointClassEntry = zend_register_internal_class_ex(&ce, endpointClassEntry, NULL TSRMLS_CC); + memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + zend_class_implements(udpEndpointClassEntry TSRMLS_CC, 1, udpEndpointInterface); + + // + // Register the OpaqueEndpoint class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_OpaqueEndpoint", _opaqueEndpointMethods); + ce.create_object = handleAlloc; + opaqueEndpointClassEntry = zend_register_internal_class_ex(&ce, endpointClassEntry, NULL TSRMLS_CC); + memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + zend_class_implements(opaqueEndpointClassEntry TSRMLS_CC, 1, opaqueEndpointInterface); + + return true; +} + +bool +IcePHP::createEndpoint(zval* zv, const Ice::EndpointPtr& p TSRMLS_DC) +{ + zend_class_entry* ce; + if(Ice::TcpEndpointPtr::dynamicCast(p)) + { + ce = tcpEndpointClassEntry; + } + else if(Ice::UdpEndpointPtr::dynamicCast(p)) + { + ce = udpEndpointClassEntry; + } + else if(Ice::OpaqueEndpointPtr::dynamicCast(p)) + { + ce = opaqueEndpointClassEntry; + } + else + { + ce = endpointClassEntry; + } + + if(object_init_ex(zv, ce) != SUCCESS) + { + runtimeError("unable to initialize endpoint" TSRMLS_CC); + return false; + } + + Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::extract(zv TSRMLS_CC); + assert(obj); + assert(!obj->ptr); + obj->ptr = new Ice::EndpointPtr(p); + + return true; +} + +bool +IcePHP::fetchEndpoint(zval* zv, Ice::EndpointPtr& endpoint TSRMLS_DC) +{ + if(ZVAL_IS_NULL(zv)) + { + endpoint = 0; + } + else + { + if(Z_TYPE_P(zv) != IS_OBJECT || !checkClass(Z_OBJCE_P(zv), endpointClassEntry)) + { + invalidArgument("value is not an endpoint" TSRMLS_CC); + return false; + } + Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::extract(zv TSRMLS_CC); + if(!obj) + { + return false; + } + endpoint = *obj->ptr; + } + return true; +} diff --git a/php/src/IcePHP/Endpoint.h b/php/src/IcePHP/Endpoint.h new file mode 100644 index 00000000000..dbf1556bb99 --- /dev/null +++ b/php/src/IcePHP/Endpoint.h @@ -0,0 +1,30 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef ICEPHP_ENDPOINT_H +#define ICEPHP_ENDPOINT_H + +#include <Config.h> + +namespace IcePHP +{ + +bool endpointInit(TSRMLS_D); + +bool createEndpoint(zval*, const Ice::EndpointPtr& TSRMLS_DC); +bool fetchEndpoint(zval*, Ice::EndpointPtr& TSRMLS_DC); + +// +// Class entry. +// +extern zend_class_entry* endpointClassEntry; + +} // End of namespace IcePHP + +#endif diff --git a/php/src/IcePHP/Init.cpp b/php/src/IcePHP/Init.cpp index 338a2276fb2..6ffa681f534 100644 --- a/php/src/IcePHP/Init.cpp +++ b/php/src/IcePHP/Init.cpp @@ -8,9 +8,13 @@ // ********************************************************************** #include <Communicator.h> -#include <Marshal.h> -#include <Profile.h> +#include <Connection.h> +#include <Endpoint.h> +#include <Logger.h> +#include <Operation.h> +#include <Properties.h> #include <Proxy.h> +#include <Types.h> #include <Util.h> using namespace std; @@ -19,14 +23,18 @@ using namespace IcePHP; ZEND_DECLARE_MODULE_GLOBALS(ice) // -// Entries for all object methods and global functions. +// Entries for all global functions. // function_entry ice_functions[] = { - ICE_PHP_COMMUNICATOR_FUNCTIONS - ICE_PHP_IDENTITY_FUNCTIONS - ICE_PHP_PROXY_FUNCTIONS - ICE_PHP_PROFILE_FUNCTIONS + ICEPHP_COMMUNICATOR_FUNCTIONS + ICEPHP_COMMUNICATOR_NS_FUNCTIONS + ICEPHP_OPERATION_FUNCTIONS + ICEPHP_PROPERTIES_FUNCTIONS + ICEPHP_PROPERTIES_NS_FUNCTIONS + ICEPHP_TYPE_FUNCTIONS + ICEPHP_UTIL_FUNCTIONS + ICEPHP_UTIL_NS_FUNCTIONS {0, 0, 0} }; @@ -53,16 +61,17 @@ PHP_INI_BEGIN() PHP_INI_ENTRY("ice.config", "", PHP_INI_SYSTEM, 0) PHP_INI_ENTRY("ice.options", "", PHP_INI_SYSTEM, 0) PHP_INI_ENTRY("ice.profiles", "", PHP_INI_SYSTEM, 0) - PHP_INI_ENTRY("ice.slice", "", PHP_INI_SYSTEM, 0) + PHP_INI_ENTRY("ice.hide_profiles", "1", PHP_INI_SYSTEM, 0) PHP_INI_END() extern "C" int initIceGlobals(zend_ice_globals* g) { - g->communicator = 0; - g->marshalerMap = 0; - g->profile = 0; - g->properties = 0; + g->communicatorMap = 0; + g->idToClassInfoMap = 0; + g->nameToClassInfoMap = 0; + g->proxyInfoMap = 0; + g->exceptionInfoMap = 0; return SUCCESS; } @@ -71,12 +80,12 @@ ZEND_MINIT_FUNCTION(ice) REGISTER_INI_ENTRIES(); ZEND_INIT_MODULE_GLOBALS(ice, initIceGlobals, 0); - if(!profileInit(TSRMLS_C)) + if(!communicatorInit(TSRMLS_C)) { return FAILURE; } - if(!communicatorInit(TSRMLS_C)) + if(!propertiesInit(TSRMLS_C)) { return FAILURE; } @@ -86,6 +95,26 @@ ZEND_MINIT_FUNCTION(ice) return FAILURE; } + if(!typesInit(TSRMLS_C)) + { + return FAILURE; + } + + if(!loggerInit(TSRMLS_C)) + { + return FAILURE; + } + + if(!endpointInit(TSRMLS_C)) + { + return FAILURE; + } + + if(!connectionInit(TSRMLS_C)) + { + return FAILURE; + } + return SUCCESS; } @@ -95,7 +124,7 @@ ZEND_MSHUTDOWN_FUNCTION(ice) int status = SUCCESS; - if(!profileShutdown(TSRMLS_C)) + if(!communicatorShutdown(TSRMLS_C)) { status = FAILURE; } @@ -105,18 +134,14 @@ ZEND_MSHUTDOWN_FUNCTION(ice) ZEND_RINIT_FUNCTION(ice) { - ICE_G(communicator) = 0; - ICE_G(marshalerMap) = new MarshalerMap; - ICE_G(profile) = 0; - ICE_G(properties) = 0; - ICE_G(objectFactoryMap) = new ObjectFactoryMap; - - // - // Create the global variable "ICE" to hold the communicator for this request. The - // communicator won't actually be created until the script uses this global variable - // for the first time. - // - if(!createCommunicator(TSRMLS_C)) + ICE_G(communicatorMap) = 0; + + if(!communicatorRequestInit(TSRMLS_C)) + { + return FAILURE; + } + + if(!typesRequestInit(TSRMLS_C)) { return FAILURE; } @@ -126,20 +151,15 @@ ZEND_RINIT_FUNCTION(ice) ZEND_RSHUTDOWN_FUNCTION(ice) { - // - // Invoke destroy() on each registered factory. - // - ObjectFactoryMap* ofm = static_cast<ObjectFactoryMap*>(ICE_G(objectFactoryMap)); - for(ObjectFactoryMap::iterator p = ofm->begin(); p != ofm->end(); ++p) + if(!communicatorRequestShutdown(TSRMLS_C)) { - zval* factory = p->second; - zend_call_method_with_0_params(&factory, 0, 0, "destroy", 0); - zval_ptr_dtor(&factory); + return FAILURE; } - delete ofm; - delete static_cast<MarshalerMap*>(ICE_G(marshalerMap)); - delete static_cast<Ice::PropertiesPtr*>(ICE_G(properties)); + if(!typesRequestShutdown(TSRMLS_C)) + { + return FAILURE; + } return SUCCESS; } diff --git a/php/src/IcePHP/Logger.cpp b/php/src/IcePHP/Logger.cpp new file mode 100644 index 00000000000..62bba11f75a --- /dev/null +++ b/php/src/IcePHP/Logger.cpp @@ -0,0 +1,278 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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 <Logger.h> +#include <Util.h> + +using namespace std; +using namespace IcePHP; + +ZEND_EXTERN_MODULE_GLOBALS(ice) + +// +// Class entries represent the PHP class implementations we have registered. +// +namespace IcePHP +{ +zend_class_entry* loggerClassEntry = 0; +} + +// +// Logger support. +// +static zend_object_handlers _loggerHandlers; + +extern "C" +{ +static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC); +static void handleFreeStorage(void* TSRMLS_DC); +static zend_object_value handleClone(zval* TSRMLS_DC); +} + +ZEND_METHOD(Ice_Logger, __construct) +{ + runtimeError("logger objects cannot be instantiated" TSRMLS_CC); +} + +ZEND_METHOD(Ice_Logger, __toString) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + RETURN_NULL(); +} + +ZEND_METHOD(Ice_Logger, print) +{ + char* m; + int mLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &m, &mLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string msg(m, mLen); + try + { + _this->print(msg); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Logger, trace) +{ + char* c; + int cLen; + char* m; + int mLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &c, &cLen, &m, &mLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string category(c, cLen); + string msg(m, mLen); + try + { + _this->trace(category, msg); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Logger, warning) +{ + char* m; + int mLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &m, &mLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string msg(m, mLen); + try + { + _this->warning(msg); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Logger, error) +{ + char* m; + int mLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &m, &mLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string msg(m, mLen); + try + { + _this->error(msg); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::create(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC); + result.handlers = &_loggerHandlers; + + return result; +} + +#ifdef _WIN32 +extern "C" +#endif +static void +handleFreeStorage(void* p TSRMLS_DC) +{ + Wrapper<Ice::LoggerPtr>* obj = static_cast<Wrapper<Ice::LoggerPtr>*>(p); + delete obj->ptr; + zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleClone(zval* zv TSRMLS_DC) +{ + php_error_docref(0 TSRMLS_CC, E_ERROR, "loggers cannot be cloned"); + return zend_object_value(); +} + +// +// Predefined methods for Logger. +// +static function_entry _interfaceMethods[] = +{ + {0, 0, 0} +}; +static function_entry _classMethods[] = +{ + ZEND_ME(Ice_Logger, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) + ZEND_ME(Ice_Logger, __toString, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Logger, print, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Logger, trace, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Logger, warning, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Logger, error, NULL, ZEND_ACC_PUBLIC) + {0, 0, 0} +}; + +bool +IcePHP::loggerInit(TSRMLS_D) +{ + // + // We register an interface and a class that implements the interface. This allows + // applications to safely include the Slice-generated code for the type. + // + + // + // Register the Logger interface. + // + zend_class_entry ce; +#ifdef ICEPHP_USE_NAMESPACES + INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Logger"), _interfaceMethods); +#else + INIT_CLASS_ENTRY(ce, "Ice_Logger", _interfaceMethods); +#endif + zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC); + + // + // Register the Logger class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_Logger", _classMethods); + ce.create_object = handleAlloc; + loggerClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_loggerHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + _loggerHandlers.clone_obj = handleClone; + zend_class_implements(loggerClassEntry TSRMLS_CC, 1, interface); + + return true; +} + +bool +IcePHP::createLogger(zval* zv, const Ice::LoggerPtr& p TSRMLS_DC) +{ + if(object_init_ex(zv, loggerClassEntry) != SUCCESS) + { + runtimeError("unable to initialize logger object" TSRMLS_CC); + return false; + } + + Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::extract(zv TSRMLS_CC); + assert(!obj->ptr); + obj->ptr = new Ice::LoggerPtr(p); + + return true; +} + +bool +IcePHP::fetchLogger(zval* zv, Ice::LoggerPtr& p TSRMLS_DC) +{ + if(!ZVAL_IS_NULL(zv)) + { + if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != loggerClassEntry) + { + invalidArgument("value is not a logger object" TSRMLS_CC); + return false; + } + p = Wrapper<Ice::LoggerPtr>::value(zv TSRMLS_CC); + if(!p) + { + runtimeError("unable to retrieve logger object from object store" TSRMLS_CC); + return false; + } + } + return true; +} diff --git a/php/src/IcePHP/Logger.h b/php/src/IcePHP/Logger.h new file mode 100644 index 00000000000..e2eb76937bb --- /dev/null +++ b/php/src/IcePHP/Logger.h @@ -0,0 +1,30 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef ICEPHP_LOGGER_H +#define ICEPHP_LOGGER_H + +#include <Config.h> + +namespace IcePHP +{ + +bool loggerInit(TSRMLS_D); + +bool createLogger(zval*, const Ice::LoggerPtr& TSRMLS_DC); +bool fetchLogger(zval*, Ice::LoggerPtr& TSRMLS_DC); + +// +// Class entry. +// +extern zend_class_entry* loggerClassEntry; + +} // End of namespace IcePHP + +#endif diff --git a/php/src/IcePHP/Makefile b/php/src/IcePHP/Makefile index 6d56a5f21cf..e375b035dd7 100644 --- a/php/src/IcePHP/Makefile +++ b/php/src/IcePHP/Makefile @@ -15,10 +15,14 @@ SONAME = $(LIBNAME) TARGETS = $(libdir)/$(LIBNAME) OBJS = Communicator.o \ + Connection.o \ + Endpoint.o \ Init.o \ - Marshal.o \ - Profile.o \ + Logger.o \ + Operation.o \ + Properties.o \ Proxy.o \ + Types.o \ Util.o SRCS = $(OBJS:.o=.cpp) @@ -36,4 +40,10 @@ $(libdir)/$(LIBNAME): $(OBJS) install:: all $(call installphplib,$(libdir)/$(LIBNAME),$(install_libdir)) +depend:: $(SRCS) + -rm -f .depend + if test -n "$(SRCS)" ; then \ + $(CXX) -DMAKEDEPEND -M $(CXXFLAGS) $(CPPFLAGS) $(SRCS) | $(ice_dir)/config/makedepend.py >> .depend; \ + fi + include .depend diff --git a/php/src/IcePHP/Makefile.mak b/php/src/IcePHP/Makefile.mak index 61de9aecb85..0600357074e 100644 --- a/php/src/IcePHP/Makefile.mak +++ b/php/src/IcePHP/Makefile.mak @@ -10,22 +10,29 @@ top_srcdir = ..\..
LIBNAME = php_ice$(LIBSUFFIX).lib
-DLLNAME = $(bindir)\php_ice$(LIBSUFFIX).dll
+DLLNAME = $(libdir)\php_ice$(LIBSUFFIX).dll
TARGETS = $(LIBNAME) $(DLLNAME)
OBJS = Communicator.obj \
+ Connection.obj \
+ Endpoint.obj \
Init.obj \
- Marshal.obj \
- Profile.obj \
+ Logger.obj \
+ Operation.obj \
+ Properties.obj \
Proxy.obj \
+ Types.obj \
Util.obj
SRCS = $(OBJS:.obj=.cpp)
!include $(top_srcdir)\config\Make.rules.mak
-CPPFLAGS = -I. -I.. $(CPPFLAGS) $(ICE_CPPFLAGS) $(PHP_CPPFLAGS)
+CPPFLAGS = -I. -I.. $(CPPFLAGS) $(ICE_CPPFLAGS) $(PHP_CPPFLAGS)
+!if "$(CPP_COMPILER)" == "VC90" || "$(CPP_COMPILER)" == "VC90_EXPRESS"
+CPPFLAGS = $(CPPFLAGS) -D_USE_32BIT_TIME_T
+!endif
!if "$(OPTIMIZE)" != "yes"
PDBFLAGS = /pdb:$(LIBNAME:.lib=.pdb)
!endif
@@ -40,6 +47,6 @@ $(DLLNAME): $(OBJS) move $(DLLNAME:.dll=.lib) $(LIBNAME)
install:: all
- copy $(DLLNAME) $(install_bindir)
+ copy $(DLLNAME) $(install_libdir)
!include .depend
diff --git a/php/src/IcePHP/Marshal.cpp b/php/src/IcePHP/Marshal.cpp deleted file mode 100644 index fe802f345d1..00000000000 --- a/php/src/IcePHP/Marshal.cpp +++ /dev/null @@ -1,2305 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2009 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 <Marshal.h> -#include <Profile.h> -#include <Proxy.h> -#include <Util.h> - -#include <IceUtil/InputUtil.h> -#include <IceUtil/OutputUtil.h> -#include <IceUtil/ScopedArray.h> - -using namespace std; -using namespace IcePHP; - -ZEND_EXTERN_MODULE_GLOBALS(ice) - -// -// The marshaling implementation is fairly straightforward. The factory methods in the -// Marshaler base class examine the given Slice type and create a Marshaler subclass -// that is responsible for marshaling that type. Some caching is done for complex types -// such as struct and class; the cached Marshaler instance is stored as a member of the -// ice_class_entry struct. (Cached instances are destroyed by Slice_destroyClasses.) -// -// The implementation of Ice object marshaling is more complex. In order to interface -// with the Ice stream interface, we need to supply Ice::Object instances, and we must -// be able to properly handle object graphs and cycles. The solution is to wrap each -// PHP object with a temporary Ice::Object, and maintain a table that associates each PHP -// object to its wrapper, so that graphs work correctly. -// -// The ObjectMarshaler class doesn't actually marshal object instances. Rather, it -// represents the top-level marshaler for a particular formal type (i.e., the declared -// type of a data member or operation parameter). During marshaling, the ObjectMarshaler -// validates the type of the object to ensure it is compatible with the formal type, -// and then obtains or creates an ObjectWriter instance for the object. Since each PHP -// object is represented by an unsigned integer handle, looking up the wrapper is simple. -// -// Once the writer is obtained, the marshaler gives it to the stream. Eventually, the -// stream will invoke write on the writer, at which point the data members are -// marshaled. For efficiency, each "slice" of the object's state is marshaled by an -// ObjectSliceMarshaler, which is cached for future reuse. -// -// Note that a graph of PHP objects does not result in an equivalent graph of writers. -// Links between objects exist only in the PHP object representation. Furthermore, the -// lifetime of the writers is bound to the operation, not to the PHP objects. Writers -// exist only as a bridge to the C++ marshaling facility. -// -// Unmarshaling of Ice objects works in a similar fashion. A default object factory -// is installed in the communicator that is capable of instantiating any concrete -// class type for which a definition is present, including the type "::Ice::Object". -// It returns an instance of ObjectReader, a subclass of Ice::Object that overrides -// the read method to unmarshal object state. The setValue method is eventually -// called on the ObjectReader in order to transfer its object handle to a different -// zval value. -// - -namespace IcePHP -{ - -// -// Marshaler subclass definitions. -// -class PrimitiveMarshaler : public Marshaler -{ -public: - PrimitiveMarshaler(const Slice::BuiltinPtr&); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - - bool validate(zval* TSRMLS_DC); - -private: - Slice::BuiltinPtr _type; -}; -typedef IceUtil::Handle<PrimitiveMarshaler> PrimitiveMarshalerPtr; - -class SequenceMarshaler : public Marshaler -{ -public: - SequenceMarshaler(const Slice::SequencePtr& TSRMLS_DC); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - -private: - Slice::SequencePtr _type; - Slice::BuiltinPtr _builtin; - MarshalerPtr _elementMarshaler; -}; - -class ProxyMarshaler : public Marshaler -{ -public: - ProxyMarshaler(const Slice::ProxyPtr&); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - -private: - Slice::ProxyPtr _type; -}; - -class MemberMarshaler : public Marshaler -{ -public: - MemberMarshaler(const string&, const MarshalerPtr&); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - -private: - string _name; - MarshalerPtr _marshaler; -}; - -class StructMarshaler : public Marshaler -{ -public: - StructMarshaler(const Slice::StructPtr& TSRMLS_DC); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - -private: - Slice::StructPtr _type; - zend_class_entry* _class; - vector<MarshalerPtr> _members; -}; - -class EnumMarshaler : public Marshaler -{ -public: - EnumMarshaler(const Slice::EnumPtr& TSRMLS_DC); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - -private: - zend_class_entry* _class; - long _count; -}; - -class NativeDictionaryMarshaler : public Marshaler -{ -public: - NativeDictionaryMarshaler(const Slice::TypePtr&, const Slice::TypePtr& TSRMLS_DC); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - -private: - Slice::Builtin::Kind _keyKind; - MarshalerPtr _keyMarshaler; - MarshalerPtr _valueMarshaler; -}; - -class ExceptionMarshaler : public Marshaler -{ -public: - ExceptionMarshaler(const Slice::ExceptionPtr& TSRMLS_DC); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - -private: - Slice::ExceptionPtr _ex; - zend_class_entry* _class; -}; - -// -// Special marshaler just for the Ice::Object slice. -// -class IceObjectSliceMarshaler : public Marshaler -{ -public: - IceObjectSliceMarshaler(TSRMLS_D); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); -}; - -class ObjectSliceMarshaler : public Marshaler -{ -public: - ObjectSliceMarshaler(const string&, const Slice::DataMemberList& TSRMLS_DC); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - -private: - string _scoped; - vector<MarshalerPtr> _members; -}; - -class ObjectWriter : public Ice::ObjectWriter -{ -public: - ObjectWriter(zval*, const Slice::SyntaxTreeBasePtr&, ObjectMap& TSRMLS_DC); - ~ObjectWriter(); - - virtual void ice_preMarshal(); - - virtual void write(const Ice::OutputStreamPtr&) const; - -private: - zval* _value; - Slice::ClassDefPtr _type; // nil if type is ::Ice::Object - ObjectMap& _map; -#ifdef ZTS - TSRMLS_D; -#endif -}; - -class ReadObjectCallback : public Ice::ReadObjectCallback -{ -public: - - virtual void invoke(const ::Ice::ObjectPtr&); - - zend_class_entry* ce; // The formal type - string scoped; - zval* zv; // The destination zval -}; -typedef IceUtil::Handle<ReadObjectCallback> ReadObjectCallbackPtr; - -class ObjectReader : public Ice::ObjectReader -{ -public: - ObjectReader(zval*, const Slice::ClassDefPtr& TSRMLS_DC); - ~ObjectReader(); - - virtual void ice_postUnmarshal(); - - virtual void read(const Ice::InputStreamPtr&, bool); - - void setValue(zend_class_entry*, const string&, zval*); - -private: - zval* _value; - Slice::ClassDefPtr _type; // nil if type is ::Ice::Object -#ifdef ZTS - TSRMLS_D; -#endif - zend_class_entry* _class; -}; -typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr; - -class ObjectMarshaler : public Marshaler -{ -public: - ObjectMarshaler(const Slice::ClassDefPtr& TSRMLS_DC); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC); - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC); - - virtual void destroy(); - -private: - Slice::ClassDefPtr _def; - zend_class_entry* _class; // The static class type. - string _scoped; -}; - -} // End of namespace IcePHP - -// -// Marshaler implementation. -// -IcePHP::Marshaler::Marshaler() -{ -} - -IcePHP::Marshaler::~Marshaler() -{ -} - -MarshalerPtr -IcePHP::Marshaler::createMarshaler(const Slice::TypePtr& type TSRMLS_DC) -{ - Slice::BuiltinPtr builtin = Slice::BuiltinPtr::dynamicCast(type); - if(builtin) - { - switch(builtin->kind()) - { - case Slice::Builtin::KindByte: - case Slice::Builtin::KindBool: - case Slice::Builtin::KindShort: - case Slice::Builtin::KindInt: - case Slice::Builtin::KindLong: - case Slice::Builtin::KindFloat: - case Slice::Builtin::KindDouble: - case Slice::Builtin::KindString: - return new PrimitiveMarshaler(builtin); - - case Slice::Builtin::KindObject: - return new ObjectMarshaler(0 TSRMLS_CC); - - case Slice::Builtin::KindObjectProxy: - return new ProxyMarshaler(0); - - case Slice::Builtin::KindLocalObject: - php_error_docref(0 TSRMLS_CC, E_ERROR, "unexpected local type"); - return 0; - } - } - - Slice::SequencePtr seq = Slice::SequencePtr::dynamicCast(type); - if(seq) - { - return new SequenceMarshaler(seq TSRMLS_CC); - } - - Slice::ProxyPtr proxy = Slice::ProxyPtr::dynamicCast(type); - if(proxy) - { - return new ProxyMarshaler(proxy); - } - - Slice::StructPtr st = Slice::StructPtr::dynamicCast(type); - if(st) - { - // - // Check to see if a marshaler for this type has already been created. If not, create - // one and cache it in the marshaler map for future use. - // - string scoped = st->scoped(); - MarshalerMap* marshalerMap = static_cast<MarshalerMap*>(ICE_G(marshalerMap)); - MarshalerMap::iterator p = marshalerMap->find(scoped); - if(p != marshalerMap->end()) - { - return p->second; - } - else - { - MarshalerPtr result = new StructMarshaler(st TSRMLS_CC); - marshalerMap->insert(pair<string, MarshalerPtr>(scoped, result)); - return result; - } - } - - Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(type); - if(en) - { - return new EnumMarshaler(en TSRMLS_CC); - } - - Slice::DictionaryPtr dict = Slice::DictionaryPtr::dynamicCast(type); - if(dict) - { - if(isNativeKey(dict->keyType())) - { - return new NativeDictionaryMarshaler(dict->keyType(), dict->valueType() TSRMLS_CC); - } - } - - Slice::ClassDeclPtr cl = Slice::ClassDeclPtr::dynamicCast(type); - if(cl) - { - // - // Don't cache ObjectMarshaler - we cache ObjectSliceMarshaler instead. - // - Slice::ClassDefPtr def = cl->definition(); - if(!def) - { - string scoped = cl->scoped(); - php_error_docref(0 TSRMLS_CC, E_ERROR, "cannot use Slice %s %s because it has not been defined", - cl->isInterface() ? "interface" : "class", scoped.c_str()); - return 0; - } - return new ObjectMarshaler(def TSRMLS_CC); - } - - return 0; -} - -MarshalerPtr -IcePHP::Marshaler::createMemberMarshaler(const string& name, const Slice::TypePtr& type TSRMLS_DC) -{ - MarshalerPtr result; - MarshalerPtr m = createMarshaler(type TSRMLS_CC); - if(m) - { - result = new MemberMarshaler(name, m); - } - return result; -} - -MarshalerPtr -IcePHP::Marshaler::createExceptionMarshaler(const Slice::ExceptionPtr& ex TSRMLS_DC) -{ - return new ExceptionMarshaler(ex TSRMLS_CC); -} - -// -// PrimitiveMarshaler implementation. -// -IcePHP::PrimitiveMarshaler::PrimitiveMarshaler(const Slice::BuiltinPtr& type) : - _type(type) -{ -} - -bool -IcePHP::PrimitiveMarshaler::validate(zval* zv TSRMLS_DC) -{ - switch(_type->kind()) - { - case Slice::Builtin::KindBool: - { - if(Z_TYPE_P(zv) != IS_BOOL) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected boolean value but received %s", s.c_str()); - return false; - } - break; - } - case Slice::Builtin::KindByte: - { - if(Z_TYPE_P(zv) != IS_LONG) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected byte value but received %s", s.c_str()); - return false; - } - long val = Z_LVAL_P(zv); - if(val < 0 || val > 255) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "value %ld is out of range for a byte", val); - return false; - } - break; - } - case Slice::Builtin::KindShort: - { - if(Z_TYPE_P(zv) != IS_LONG) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected short value but received %s", s.c_str()); - return false; - } - long val = Z_LVAL_P(zv); - if(val < SHRT_MIN || val > SHRT_MAX) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "value %ld is out of range for a short", val); - return false; - } - break; - } - case Slice::Builtin::KindInt: - { - if(Z_TYPE_P(zv) != IS_LONG) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected int value but received %s", s.c_str()); - return false; - } - long val = Z_LVAL_P(zv); - if(val < INT_MIN || val > INT_MAX) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "value %ld is out of range for an int", val); - return false; - } - break; - } - case Slice::Builtin::KindLong: - { - // - // The platform's 'long' type may not be 64 bits, so we also accept - // a string argument for this type. - // - if(Z_TYPE_P(zv) != IS_LONG && Z_TYPE_P(zv) != IS_STRING) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected long value but received %s", s.c_str()); - return false; - } - Ice::Long val; - if(Z_TYPE_P(zv) == IS_LONG) - { - val = Z_LVAL_P(zv); - } - else - { - string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); - if(!IceUtilInternal::stringToInt64(sval, val)) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "invalid long value `%s'", Z_STRVAL_P(zv)); - return false; - } - } - break; - } - case Slice::Builtin::KindFloat: - { - if(Z_TYPE_P(zv) != IS_DOUBLE) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected float value but received %s", s.c_str()); - return false; - } - break; - } - case Slice::Builtin::KindDouble: - { - if(Z_TYPE_P(zv) != IS_DOUBLE) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected double value but received %s", s.c_str()); - return false; - } - break; - } - case Slice::Builtin::KindString: - { - if(Z_TYPE_P(zv) != IS_STRING && Z_TYPE_P(zv) != IS_NULL) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected string value but received %s", s.c_str()); - return false; - } - break; - } - - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - assert(false); - } - return true; -} - -bool -IcePHP::PrimitiveMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& TSRMLS_DC) -{ - if(!validate(zv TSRMLS_CC)) - { - return false; - } - - switch(_type->kind()) - { - case Slice::Builtin::KindBool: - { - assert(Z_TYPE_P(zv) == IS_BOOL); - os->writeBool(Z_BVAL_P(zv) ? true : false); - break; - } - case Slice::Builtin::KindByte: - { - assert(Z_TYPE_P(zv) == IS_LONG); - long val = Z_LVAL_P(zv); - assert(val >= 0 && val <= 255); - os->writeByte(static_cast<Ice::Byte>(val)); - break; - } - case Slice::Builtin::KindShort: - { - assert(Z_TYPE_P(zv) == IS_LONG); - long val = Z_LVAL_P(zv); - assert(val >= SHRT_MIN && val <= SHRT_MAX); - os->writeShort(static_cast<Ice::Short>(val)); - break; - } - case Slice::Builtin::KindInt: - { - assert(Z_TYPE_P(zv) == IS_LONG); - long val = Z_LVAL_P(zv); - assert(val >= INT_MIN && val <= INT_MAX); - os->writeInt(static_cast<Ice::Int>(val)); - break; - } - case Slice::Builtin::KindLong: - { - // - // The platform's 'long' type may not be 64 bits, so we also accept - // a string argument for this type. - // - assert(Z_TYPE_P(zv) == IS_LONG || Z_TYPE_P(zv) == IS_STRING); - Ice::Long val; - if(Z_TYPE_P(zv) == IS_LONG) - { - val = Z_LVAL_P(zv); - } - else - { - string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); - IceUtilInternal::stringToInt64(sval, val); - } - os->writeLong(val); - break; - } - case Slice::Builtin::KindFloat: - { - assert(Z_TYPE_P(zv) == IS_DOUBLE); - double val = Z_DVAL_P(zv); - os->writeFloat(static_cast<Ice::Float>(val)); - break; - } - case Slice::Builtin::KindDouble: - { - assert(Z_TYPE_P(zv) == IS_DOUBLE); - double val = Z_DVAL_P(zv); - os->writeDouble(val); - break; - } - case Slice::Builtin::KindString: - { - assert(Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_NULL); - if(Z_TYPE_P(zv) == IS_STRING) - { - string val(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); - os->writeString(val); - } - else - { - os->writeString(string()); - } - break; - } - - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - assert(false); - } - return true; -} - -bool -IcePHP::PrimitiveMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - switch(_type->kind()) - { - case Slice::Builtin::KindBool: - { - bool val = is->readBool(); - ZVAL_BOOL(zv, val ? 1 : 0); - break; - } - case Slice::Builtin::KindByte: - { - Ice::Byte val = is->readByte(); - ZVAL_LONG(zv, val & 0xff); - break; - } - case Slice::Builtin::KindShort: - { - Ice::Short val = is->readShort(); - ZVAL_LONG(zv, val); - break; - } - case Slice::Builtin::KindInt: - { - Ice::Int val = is->readInt(); - ZVAL_LONG(zv, val); - break; - } - case Slice::Builtin::KindLong: - { - Ice::Long val = is->readLong(); - - // - // The platform's 'long' type may not be 64 bits, so we store 64-bit - // values as a string. - // - if(sizeof(Ice::Long) > sizeof(long) && (val < LONG_MIN || val > LONG_MAX)) - { - string str = IceUtilInternal::int64ToString(val); - ZVAL_STRINGL(zv, const_cast<char*>(str.c_str()), str.length(), 1); - } - else - { - ZVAL_LONG(zv, static_cast<long>(val)); - } - break; - } - case Slice::Builtin::KindFloat: - { - Ice::Float val = is->readFloat(); - ZVAL_DOUBLE(zv, val); - break; - } - case Slice::Builtin::KindDouble: - { - Ice::Double val = is->readDouble(); - ZVAL_DOUBLE(zv, val); - break; - } - case Slice::Builtin::KindString: - { - string val = is->readString(); - ZVAL_STRINGL(zv, const_cast<char*>(val.c_str()), val.length(), 1); - break; - } - - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - assert(false); - } - - return true; -} - -void -IcePHP::PrimitiveMarshaler::destroy() -{ -} - -// -// SequenceMarshaler implementation. -// -IcePHP::SequenceMarshaler::SequenceMarshaler(const Slice::SequencePtr& type TSRMLS_DC) : - _type(type) -{ - Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type); - if(b && b->kind() != Slice::Builtin::KindObject && b->kind() != Slice::Builtin::KindObjectProxy) - { - _builtin = b; - } - _elementMarshaler = createMarshaler(type->type() TSRMLS_CC); -} - -bool -IcePHP::SequenceMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC) -{ - if(Z_TYPE_P(zv) != IS_ARRAY && Z_TYPE_P(zv) != IS_NULL) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected array or null for sequence but received %s", s.c_str()); - return false; - } - - if(Z_TYPE_P(zv) == IS_NULL) - { - os->writeSize(0); - return true; - } - - HashTable* arr = Z_ARRVAL_P(zv); - - HashPosition pos; - zend_hash_internal_pointer_reset_ex(arr, &pos); - Ice::Int sz = static_cast<Ice::Int>(zend_hash_num_elements(arr)); - - if(_builtin) - { - PrimitiveMarshalerPtr pm = PrimitiveMarshalerPtr::dynamicCast(_elementMarshaler); - assert(pm); - switch(_builtin->kind()) - { - case Slice::Builtin::KindBool: - { - Ice::BoolSeq seq(sz); - Ice::Int i = 0; - void* data; - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(!pm->validate(*val TSRMLS_CC)) - { - return false; - } - seq[i++] = Z_BVAL_P(*val) ? true : false; - zend_hash_move_forward_ex(arr, &pos); - } - os->writeBoolSeq(seq); - break; - } - case Slice::Builtin::KindByte: - { - Ice::ByteSeq seq(sz); - Ice::Int i = 0; - void* data; - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(!pm->validate(*val TSRMLS_CC)) - { - return false; - } - long l = Z_LVAL_P(*val); - assert(l >= 0 && l <= 255); - seq[i++] = static_cast<Ice::Byte>(l); - zend_hash_move_forward_ex(arr, &pos); - } - os->writeByteSeq(seq); - break; - } - case Slice::Builtin::KindShort: - { - Ice::ShortSeq seq(sz); - Ice::Int i = 0; - void* data; - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(!pm->validate(*val TSRMLS_CC)) - { - return false; - } - long l = Z_LVAL_P(*val); - assert(l >= SHRT_MIN && l <= SHRT_MAX); - seq[i++] = static_cast<Ice::Short>(l); - zend_hash_move_forward_ex(arr, &pos); - } - os->writeShortSeq(seq); - break; - } - case Slice::Builtin::KindInt: - { - Ice::IntSeq seq(sz); - Ice::Int i = 0; - void* data; - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(!pm->validate(*val TSRMLS_CC)) - { - return false; - } - long l = Z_LVAL_P(*val); - assert(l >= INT_MIN && l <= INT_MAX); - seq[i++] = static_cast<Ice::Int>(l); - zend_hash_move_forward_ex(arr, &pos); - } - os->writeIntSeq(seq); - break; - } - case Slice::Builtin::KindLong: - { - Ice::LongSeq seq(sz); - Ice::Int i = 0; - void* data; - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(!pm->validate(*val TSRMLS_CC)) - { - return false; - } - // - // The platform's 'long' type may not be 64 bits, so we also accept - // a string argument for this type. - // - assert(Z_TYPE_P(*val) == IS_LONG || Z_TYPE_P(*val) == IS_STRING); - Ice::Long l; - if(Z_TYPE_P(*val) == IS_LONG) - { - l = Z_LVAL_P(*val); - } - else - { - string sval(Z_STRVAL_P(*val), Z_STRLEN_P(*val)); - IceUtilInternal::stringToInt64(sval, l); - } - seq[i++] = l; - zend_hash_move_forward_ex(arr, &pos); - } - os->writeLongSeq(seq); - break; - } - case Slice::Builtin::KindFloat: - { - Ice::FloatSeq seq(sz); - Ice::Int i = 0; - void* data; - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(!pm->validate(*val TSRMLS_CC)) - { - return false; - } - double d = Z_DVAL_P(*val); - seq[i++] = static_cast<Ice::Float>(d); - zend_hash_move_forward_ex(arr, &pos); - } - os->writeFloatSeq(seq); - break; - } - case Slice::Builtin::KindDouble: - { - Ice::DoubleSeq seq(sz); - Ice::Int i = 0; - void* data; - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(!pm->validate(*val TSRMLS_CC)) - { - return false; - } - double d = Z_DVAL_P(*val); - seq[i++] = d; - zend_hash_move_forward_ex(arr, &pos); - } - os->writeDoubleSeq(seq); - break; - } - case Slice::Builtin::KindString: - { - Ice::StringSeq seq(sz); - Ice::Int i = 0; - void* data; - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(!pm->validate(*val TSRMLS_CC)) - { - return false; - } - string s; - if(Z_TYPE_P(*val) == IS_STRING) - { - s = string(Z_STRVAL_P(*val), Z_STRLEN_P(*val)); - } - else - { - assert(Z_TYPE_P(*val) == IS_NULL); - } - seq[i++] = s; - zend_hash_move_forward_ex(arr, &pos); - } - os->writeStringSeq(seq); - break; - } - - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - assert(false); - } - } - else - { - os->writeSize(sz); - - void* data; - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(!_elementMarshaler->marshal(*val, os, m TSRMLS_CC)) - { - return false; - } - zend_hash_move_forward_ex(arr, &pos); - } - } - - return true; -} - -bool -IcePHP::SequenceMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - array_init(zv); - - if(_builtin) - { - switch(_builtin->kind()) - { - case Slice::Builtin::KindBool: - { - pair<const bool*, const bool*> pr; - IceUtilInternal::ScopedArray<bool> arr(is->readBoolSeq(pr)); - Ice::Int i = 0; - for(const bool* p = pr.first; p != pr.second; ++p, ++i) - { - zval* val; - MAKE_STD_ZVAL(val); - ZVAL_BOOL(val, *p ? 1 : 0); - add_index_zval(zv, i, val); - } - break; - } - case Slice::Builtin::KindByte: - { - pair<const Ice::Byte*, const Ice::Byte*> pr; - is->readByteSeq(pr); - Ice::Int i = 0; - for(const Ice::Byte* p = pr.first; p != pr.second; ++p, ++i) - { - zval* val; - MAKE_STD_ZVAL(val); - ZVAL_LONG(val, *p & 0xff); - add_index_zval(zv, i, val); - } - break; - } - case Slice::Builtin::KindShort: - { - pair<const Ice::Short*, const Ice::Short*> pr; - IceUtilInternal::ScopedArray<Ice::Short> arr(is->readShortSeq(pr)); - Ice::Int i = 0; - for(const Ice::Short* p = pr.first; p != pr.second; ++p, ++i) - { - zval* val; - MAKE_STD_ZVAL(val); - ZVAL_LONG(val, *p); - add_index_zval(zv, i, val); - } - break; - } - case Slice::Builtin::KindInt: - { - pair<const Ice::Int*, const Ice::Int*> pr; - IceUtilInternal::ScopedArray<Ice::Int> arr(is->readIntSeq(pr)); - Ice::Int i = 0; - for(const Ice::Int* p = pr.first; p != pr.second; ++p, ++i) - { - zval* val; - MAKE_STD_ZVAL(val); - ZVAL_LONG(val, *p); - add_index_zval(zv, i, val); - } - break; - } - case Slice::Builtin::KindLong: - { - pair<const Ice::Long*, const Ice::Long*> pr; - IceUtilInternal::ScopedArray<Ice::Long> arr(is->readLongSeq(pr)); - Ice::Int i = 0; - for(const Ice::Long* p = pr.first; p != pr.second; ++p, ++i) - { - zval* val; - MAKE_STD_ZVAL(val); - // - // The platform's 'long' type may not be 64 bits, so we store 64-bit - // values as a string. - // - if(sizeof(Ice::Long) > sizeof(long) && (*p < LONG_MIN || *p > LONG_MAX)) - { - string str = IceUtilInternal::int64ToString(*p); - ZVAL_STRINGL(val, const_cast<char*>(str.c_str()), str.length(), 1); - } - else - { - ZVAL_LONG(val, static_cast<long>(*p)); - } - add_index_zval(zv, i, val); - } - break; - } - case Slice::Builtin::KindFloat: - { - pair<const Ice::Float*, const Ice::Float*> pr; - IceUtilInternal::ScopedArray<Ice::Float> arr(is->readFloatSeq(pr)); - Ice::Int i = 0; - for(const Ice::Float* p = pr.first; p != pr.second; ++p, ++i) - { - zval* val; - MAKE_STD_ZVAL(val); - ZVAL_DOUBLE(zv, *p); - add_index_zval(zv, i, val); - } - break; - } - case Slice::Builtin::KindDouble: - { - pair<const Ice::Double*, const Ice::Double*> pr; - IceUtilInternal::ScopedArray<Ice::Double> arr(is->readDoubleSeq(pr)); - Ice::Int i = 0; - for(const Ice::Double* p = pr.first; p != pr.second; ++p, ++i) - { - zval* val; - MAKE_STD_ZVAL(val); - ZVAL_DOUBLE(zv, *p); - add_index_zval(zv, i, val); - } - break; - } - case Slice::Builtin::KindString: - { - Ice::StringSeq seq = is->readStringSeq(); - Ice::Int i = 0; - for(Ice::StringSeq::iterator p = seq.begin(); p != seq.end(); ++p, ++i) - { - zval* val; - MAKE_STD_ZVAL(val); - ZVAL_STRINGL(val, const_cast<char*>(p->c_str()), p->length(), 1); - add_index_zval(zv, i, val); - } - break; - } - - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - assert(false); - } - } - else - { - Ice::Int sz = is->readSize(); - for(Ice::Int i = 0; i < sz; ++i) - { - zval* val; - MAKE_STD_ZVAL(val); - if(!_elementMarshaler->unmarshal(val, is TSRMLS_CC)) - { - return false; - } - add_index_zval(zv, i, val); - } - } - - return true; -} - -void -IcePHP::SequenceMarshaler::destroy() -{ - _elementMarshaler->destroy(); - _elementMarshaler = 0; -} - -// -// ProxyMarshaler implementation. -// -IcePHP::ProxyMarshaler::ProxyMarshaler(const Slice::ProxyPtr& type) : - _type(type) -{ -} - -bool -IcePHP::ProxyMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& TSRMLS_DC) -{ - if(Z_TYPE_P(zv) != IS_OBJECT && Z_TYPE_P(zv) != IS_NULL) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected proxy value but received %s", s.c_str()); - return false; - } - - Ice::ObjectPrx proxy; - Slice::ClassDefPtr def; - if(!ZVAL_IS_NULL(zv)) - { - if(!fetchProxy(zv, proxy, def TSRMLS_CC)) - { - return false; - } - - if(_type) - { - string scoped = _type->_class()->scoped(); - if(def) - { - if(!def->isA(scoped)) - { - string s = def->scoped(); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected a proxy of type %s but received %s", - scoped.c_str(), s.c_str()); - return false; - } - } - else - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected a proxy of type %s", scoped.c_str()); - return false; - } - } - } - os->writeProxy(proxy); - - return true; -} - -bool -IcePHP::ProxyMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - Ice::ObjectPrx proxy = is->readProxy(); - - if(!proxy) - { - ZVAL_NULL(zv); - return true; - } - - // - // If _type is not a primitive proxy (i.e., Builtin::KindObjectProxy), then we - // want to associate our class with the proxy so that it is considered to be - // "narrowed". - // - Slice::ClassDefPtr def; - if(_type) - { - def = _type->_class()->definition(); - } - - if(!createProxy(zv, proxy, def TSRMLS_CC)) - { - return false; - } - - return true; -} - -void -IcePHP::ProxyMarshaler::destroy() -{ -} - -// -// MemberMarshaler implementation. -// -IcePHP::MemberMarshaler::MemberMarshaler(const string& name, const MarshalerPtr& marshaler) : - _name(name), _marshaler(marshaler) -{ -} - -bool -IcePHP::MemberMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC) -{ - void* data; - if(zend_hash_find(Z_OBJPROP_P(zv), const_cast<char*>(_name.c_str()), _name.length() + 1, &data) == FAILURE) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "member `%s' is not defined", _name.c_str()); - return false; - } - - zval** val = reinterpret_cast<zval**>(data); - return _marshaler->marshal(*val, os, m TSRMLS_CC);; -} - -bool -IcePHP::MemberMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - zval* val; - MAKE_STD_ZVAL(val); - - if(!_marshaler->unmarshal(val, is TSRMLS_CC)) - { - return false; - } - - // - // The add_property_zval function fails if the data member has protected visibility. - // As a workaround, before calling the function we change the current scope to be that - // of the object. - // - zend_class_entry *oldScope = EG(scope); - EG(scope) = Z_OBJCE_P(zv); - - int status = add_property_zval(zv, const_cast<char*>(_name.c_str()), val); - - EG(scope) = oldScope; // Restore the previous scope. - - if(status == FAILURE) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to set member `%s'", _name.c_str()); - return false; - } - - zval_ptr_dtor(&val); // add_property_zval increments the refcount. - - return true; -} - -void -IcePHP::MemberMarshaler::destroy() -{ - _marshaler->destroy(); - _marshaler = 0; -} - -// -// StructMarshaler implementation. -// -IcePHP::StructMarshaler::StructMarshaler(const Slice::StructPtr& type TSRMLS_DC) : - _type(type) -{ - _class = findClassScoped(type->scoped() TSRMLS_CC); - assert(_class); - - Slice::DataMemberList members = type->dataMembers(); - for(Slice::DataMemberList::iterator q = members.begin(); q != members.end(); ++q) - { - MarshalerPtr marshaler = createMemberMarshaler((*q)->name(), (*q)->type() TSRMLS_CC); - assert(marshaler); - _members.push_back(marshaler); - } -} - -bool -IcePHP::StructMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC) -{ - if(Z_TYPE_P(zv) != IS_OBJECT) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected struct value of type %s but received %s", _class->name, - s.c_str()); - return false; - } - - // - // Compare class entries. - // - zend_class_entry* ce = Z_OBJCE_P(zv); - if(ce != _class) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected struct value of type %s but received %s", _class->name, - ce->name); - return false; - } - - for(vector<MarshalerPtr>::iterator p = _members.begin(); p != _members.end(); ++p) - { - if(!(*p)->marshal(zv, os, m TSRMLS_CC)) - { - return false; - } - } - - return true; -} - -bool -IcePHP::StructMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - if(object_init_ex(zv, _class) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize object of type %s", _class->name); - return false; - } - - for(vector<MarshalerPtr>::iterator p = _members.begin(); p != _members.end(); ++p) - { - if(!(*p)->unmarshal(zv, is TSRMLS_CC)) - { - return false; - } - } - - return true; -} - -void -IcePHP::StructMarshaler::destroy() -{ - vector<MarshalerPtr> members = _members; - _members.clear(); - for(vector<MarshalerPtr>::iterator p = members.begin(); p != members.end(); ++p) - { - (*p)->destroy(); - } -} - -// -// EnumMarshaler implementation. -// -IcePHP::EnumMarshaler::EnumMarshaler(const Slice::EnumPtr& type TSRMLS_DC) -{ - _class = findClassScoped(type->scoped() TSRMLS_CC); - assert(_class); - _count = static_cast<long>(type->getEnumerators().size()); -} - -bool -IcePHP::EnumMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& TSRMLS_DC) -{ - if(Z_TYPE_P(zv) != IS_LONG) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected long value for enum %s but received %s", _class->name, - s.c_str()); - return false; - } - - // - // Validate value. - // - long val = Z_LVAL_P(zv); - if(val < 0 || val >= _count) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "value %ld is out of range for enum %s", val, _class->name); - return false; - } - - if(_count <= 127) - { - os->writeByte(static_cast<Ice::Byte>(val)); - } - else if(_count <= 32767) - { - os->writeShort(static_cast<Ice::Short>(val)); - } - else - { - os->writeInt(static_cast<Ice::Int>(val)); - } - - return true; -} - -bool -IcePHP::EnumMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - if(_count <= 127) - { - Ice::Byte val = is->readByte(); - ZVAL_LONG(zv, val); - } - else if(_count <= 32767) - { - Ice::Short val = is->readShort(); - ZVAL_LONG(zv, val); - } - else - { - Ice::Int val = is->readInt(); - ZVAL_LONG(zv, val); - } - - return true; -} - -void -IcePHP::EnumMarshaler::destroy() -{ -} - -// -// NativeDictionaryMarshaler implementation. -// -IcePHP::NativeDictionaryMarshaler::NativeDictionaryMarshaler(const Slice::TypePtr& keyType, - const Slice::TypePtr& valueType TSRMLS_DC) -{ - Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(keyType); - assert(b); - _keyKind = b->kind(); - _keyMarshaler = createMarshaler(keyType TSRMLS_CC); - _valueMarshaler = createMarshaler(valueType TSRMLS_CC); -} - -bool -IcePHP::NativeDictionaryMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC) -{ - if(Z_TYPE_P(zv) != IS_ARRAY && Z_TYPE_P(zv) != IS_NULL) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected array or null for dictionary but received %s", s.c_str()); - return false; - } - - if(Z_TYPE_P(zv) == IS_NULL) - { - os->writeSize(0); - return true; - } - - HashTable* arr = Z_ARRVAL_P(zv); - HashPosition pos; - void* data; - - os->writeSize(zend_hash_num_elements(arr)); - - zend_hash_internal_pointer_reset_ex(arr, &pos); - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - - // - // Get the key (which can be a long or a string). - // - char* keyStr; - uint keyLen; - ulong keyNum; - int keyType = zend_hash_get_current_key_ex(arr, &keyStr, &keyLen, &keyNum, 0, &pos); - - // - // Store the key in a zval, so that we can reuse the PrimitiveMarshaler logic. - // - zval zkey; - if(keyType == HASH_KEY_IS_LONG) - { - ZVAL_LONG(&zkey, keyNum); - } - else - { - ZVAL_STRINGL(&zkey, keyStr, keyLen - 1, 1); - } - - // - // Convert the zval to the key type required by Slice, if necessary. - // - switch(_keyKind) - { - case Slice::Builtin::KindBool: - { - convert_to_boolean(&zkey); - break; - } - - case Slice::Builtin::KindByte: - case Slice::Builtin::KindShort: - case Slice::Builtin::KindInt: - case Slice::Builtin::KindLong: - { - if(keyType == HASH_KEY_IS_STRING) - { - convert_to_long(&zkey); - } - break; - } - - case Slice::Builtin::KindString: - { - if(keyType == HASH_KEY_IS_LONG) - { - convert_to_string(&zkey); - } - break; - } - - case Slice::Builtin::KindFloat: - case Slice::Builtin::KindDouble: - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - assert(false); - } - - // - // Marshal the key. - // - if(!_keyMarshaler->marshal(&zkey, os, m TSRMLS_CC)) - { - zval_dtor(&zkey); - return false; - } - - zval_dtor(&zkey); - - // - // Marshal the value. - // - if(!_valueMarshaler->marshal(*val, os, m TSRMLS_CC)) - { - return false; - } - - zend_hash_move_forward_ex(arr, &pos); - } - - return true; -} - -bool -IcePHP::NativeDictionaryMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - array_init(zv); - - Ice::Int sz = is->readSize(); - - for(Ice::Int i = 0; i < sz; ++i) - { - zval key; - zval* val; - INIT_ZVAL(key); - MAKE_STD_ZVAL(val); - - if(!_keyMarshaler->unmarshal(&key, is TSRMLS_CC)) - { - return false; - } - if(!_valueMarshaler->unmarshal(val, is TSRMLS_CC)) - { - return false; - } - - switch(Z_TYPE(key)) - { - case IS_LONG: - add_index_zval(zv, Z_LVAL(key), val); - break; - case IS_BOOL: - add_index_zval(zv, Z_BVAL(key) ? 1 : 0, val); - break; - case IS_STRING: - add_assoc_zval_ex(zv, Z_STRVAL(key), Z_STRLEN(key) + 1, val); - break; - default: - assert(false); - return false; - } - zval_dtor(&key); - } - - return true; -} - -void -IcePHP::NativeDictionaryMarshaler::destroy() -{ - _keyMarshaler->destroy(); - _keyMarshaler = 0; - _valueMarshaler->destroy(); - _valueMarshaler = 0; -} - -// -// ExceptionMarshaler implementation. -// -IcePHP::ExceptionMarshaler::ExceptionMarshaler(const Slice::ExceptionPtr& ex TSRMLS_DC) : - _ex(ex) -{ - _class = findClassScoped(ex->scoped() TSRMLS_CC); - assert(_class); -} - -bool -IcePHP::ExceptionMarshaler::marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC) -{ - // - // We never need to marshal an exception. - // - php_error_docref(0 TSRMLS_CC, E_ERROR, "exception marshaling is not supported"); - return false; -} - -bool -IcePHP::ExceptionMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - if(object_init_ex(zv, _class) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize exception %s", _class->name); - return false; - } - - // - // NOTE: The type id for the first slice has already been read. - // - - Slice::ExceptionPtr ex = _ex; - while(ex) - { - Slice::DataMemberList members = ex->dataMembers(); - is->startSlice(); - for(Slice::DataMemberList::iterator p = members.begin(); p != members.end(); ++p) - { - MarshalerPtr member = createMemberMarshaler((*p)->name(), (*p)->type() TSRMLS_CC); - if(!member->unmarshal(zv, is TSRMLS_CC)) - { - return false; - } - } - is->endSlice(); - ex = ex->base(); - if(ex) - { - is->readString(); // Skip id. - } - } - - return true; -} - -void -IcePHP::ExceptionMarshaler::destroy() -{ -} - -// -// IceObjectSliceMarshaler implementation. -// -IcePHP::IceObjectSliceMarshaler::IceObjectSliceMarshaler(TSRMLS_D) -{ -} - -bool -IcePHP::IceObjectSliceMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& TSRMLS_DC) -{ - assert(Z_TYPE_P(zv) == IS_OBJECT); - - os->writeTypeId(Ice::Object::ice_staticId()); - os->startSlice(); - os->writeSize(0); // For compatibility with the old AFM. - os->endSlice(); - - return true; -} - -bool -IcePHP::IceObjectSliceMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - assert(Z_TYPE_P(zv) == IS_OBJECT); - - // - // Do not read type id here - see ObjectReader::__read(). - // - //is->readTypeId() - - is->startSlice(); - - // For compatibility with the old AFM. - Ice::Int sz = is->readSize(); - if(sz != 0) - { - throw Ice::MarshalException(__FILE__, __LINE__); - } - - is->endSlice(); - - return true; -} - -void -IcePHP::IceObjectSliceMarshaler::destroy() -{ -} - -// -// ObjectSliceMarshaler implementation. -// -IcePHP::ObjectSliceMarshaler::ObjectSliceMarshaler(const string& scoped, - const Slice::DataMemberList& members TSRMLS_DC) : - _scoped(scoped) -{ - for(Slice::DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p) - { - MarshalerPtr marshaler = createMemberMarshaler((*p)->name(), (*p)->type() TSRMLS_CC); - assert(marshaler); - _members.push_back(marshaler); - } -} - -bool -IcePHP::ObjectSliceMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC) -{ - assert(Z_TYPE_P(zv) == IS_OBJECT); - - os->writeTypeId(_scoped); - os->startSlice(); - for(vector<MarshalerPtr>::iterator p = _members.begin(); p != _members.end(); ++p) - { - if(!(*p)->marshal(zv, os, m TSRMLS_CC)) - { - return false; - } - } - os->endSlice(); - - return true; -} - -bool -IcePHP::ObjectSliceMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - assert(Z_TYPE_P(zv) == IS_OBJECT); - - // - // Do not read type id here - see ObjectReader::__read(). - // - //is->readTypeId() - - is->startSlice(); - for(vector<MarshalerPtr>::iterator p = _members.begin(); p != _members.end(); ++p) - { - if(!(*p)->unmarshal(zv, is TSRMLS_CC)) - { - return false; - } - } - is->endSlice(); - - return true; -} - -void -IcePHP::ObjectSliceMarshaler::destroy() -{ - vector<MarshalerPtr> members = _members; - _members.clear(); - for(vector<MarshalerPtr>::iterator p = members.begin(); p != members.end(); ++p) - { - (*p)->destroy(); - } -} - -// -// ObjectWriter implementation. -// -IcePHP::ObjectWriter::ObjectWriter(zval* value, const Slice::SyntaxTreeBasePtr& type, ObjectMap& m TSRMLS_DC) : - _value(value), _map(m) -{ -#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530) -// Strange Sun C++ 5.3 bug. - const IceUtil::HandleBase<Slice::SyntaxTreeBase>& hb = type; - _type = Slice::ClassDefPtr::dynamicCast(hb); -#else - _type = Slice::ClassDefPtr::dynamicCast(type); -#endif - -#ifdef ZTS - this->TSRMLS_C = TSRMLS_C; -#endif - - Z_OBJ_HT_P(_value)->add_ref(_value TSRMLS_CC); -} - -IcePHP::ObjectWriter::~ObjectWriter() -{ - Z_OBJ_HT_P(_value)->del_ref(_value TSRMLS_CC); -} - -void -IcePHP::ObjectWriter::ice_preMarshal() -{ - zend_call_method_with_0_params(&_value, 0, 0, "ice_preMarshal", 0); -} - -void -IcePHP::ObjectWriter::write(const Ice::OutputStreamPtr& os) const -{ - MarshalerMap* marshalerMap = static_cast<MarshalerMap*>(ICE_G(marshalerMap)); - ObjectMap& objectMap = const_cast<ObjectMap&>(_map); - zval* value = const_cast<zval*>(_value); - - Slice::ClassDefPtr def = _type; - while(true) - { - string scoped = def->scoped(); - MarshalerPtr slice; - MarshalerMap::iterator p = marshalerMap->find(scoped); - if(p != marshalerMap->end()) - { - slice = p->second; - } - else - { - slice = new ObjectSliceMarshaler(scoped, def->dataMembers() TSRMLS_CC); - marshalerMap->insert(pair<string, MarshalerPtr>(scoped, slice)); - } - - if(!slice->marshal(value, os, objectMap TSRMLS_CC)) - { - Ice::MarshalException ex(__FILE__, __LINE__); - ex.reason = "unable to marshal object slice of type " + scoped; - throw ex; - } - - Slice::ClassList bases = def->bases(); - if(!bases.empty() && !bases.front()->isInterface()) - { - def = bases.front(); - } - else - { - break; - } - } - - // - // Marshal the Ice::Object slice. - // - MarshalerPtr slice; - MarshalerMap::iterator p = marshalerMap->find(Ice::Object::ice_staticId()); - if(p != marshalerMap->end()) - { - slice = p->second; - } - else - { - slice = new IceObjectSliceMarshaler(TSRMLS_C); - marshalerMap->insert(pair<string, MarshalerPtr>(Ice::Object::ice_staticId(), slice)); - } - - if(!slice->marshal(value, os, objectMap TSRMLS_CC)) - { - Ice::MarshalException ex(__FILE__, __LINE__); - ex.reason = "unable to marshal object slice of type Ice::Object"; - throw ex; - } -} - -// -// ReadObjectCallback implementation. -// -void -IcePHP::ReadObjectCallback::invoke(const Ice::ObjectPtr& v) -{ - ObjectReaderPtr p = ObjectReaderPtr::dynamicCast(v); - if(p) - { - p->setValue(ce, scoped, zv); - } - else - { - ZVAL_NULL(zv); - } -} - -// -// ObjectReader implementation. -// -IcePHP::ObjectReader::ObjectReader(zval* val, const Slice::ClassDefPtr& type TSRMLS_DC) : - _value(val), _type(type) -{ -#ifdef ZTS - this->TSRMLS_C = TSRMLS_C; -#endif - - ZVAL_ADDREF(_value); - - _class = Z_OBJCE_P(_value); -} - -IcePHP::ObjectReader::~ObjectReader() -{ - zval_ptr_dtor(&_value); -} - -void -IcePHP::ObjectReader::ice_postUnmarshal() -{ - zend_call_method_with_0_params(&_value, 0, 0, "ice_postUnmarshal", 0); -} - -void -IcePHP::ObjectReader::read(const Ice::InputStreamPtr& is, bool rid) -{ - MarshalerMap* marshalerMap = static_cast<MarshalerMap*>(ICE_G(marshalerMap)); - - // - // Unmarshal the slices of a user-defined class. - // - if(_type) - { - Slice::ClassDefPtr def = _type; - while(true) - { - string scoped; - if(rid) - { - scoped = is->readTypeId(); - } - else - { - scoped = def->scoped(); - } - - MarshalerPtr slice; - MarshalerMap::iterator p = marshalerMap->find(scoped); - if(p != marshalerMap->end()) - { - slice = p->second; - } - else - { - slice = new ObjectSliceMarshaler(scoped, def->dataMembers() TSRMLS_CC); - marshalerMap->insert(pair<string, MarshalerPtr>(scoped, slice)); - } - - if(!slice->unmarshal(_value, is TSRMLS_CC)) - { - Ice::MarshalException ex(__FILE__, __LINE__); - ex.reason = "unable to unmarshal object slice of type " + scoped; - throw ex; - } - - rid = true; - - Slice::ClassList bases = def->bases(); - if(!bases.empty() && !bases.front()->isInterface()) - { - def = bases.front(); - } - else - { - break; - } - } - } - - // - // Unmarshal the Ice::Object slice. - // - if(rid) - { - is->readTypeId(); - } - - MarshalerPtr slice; - MarshalerMap::iterator p = marshalerMap->find(Ice::Object::ice_staticId()); - if(p != marshalerMap->end()) - { - slice = p->second; - } - else - { - slice = new IceObjectSliceMarshaler(TSRMLS_C); - marshalerMap->insert(pair<string, MarshalerPtr>(Ice::Object::ice_staticId(), slice)); - } - - if(!slice->unmarshal(_value, is TSRMLS_CC)) - { - Ice::MarshalException ex(__FILE__, __LINE__); - ex.reason = "unable to unmarshal object slice of type Ice::Object"; - throw ex; - } -} - -void -IcePHP::ObjectReader::setValue(zend_class_entry* ce, const string& scoped, zval* zv) -{ - // - // Compare the class entries. The argument "ce" represents the formal type. - // - if(!checkClass(_class, ce)) - { - Ice::UnexpectedObjectException ex(__FILE__, __LINE__); - ex.type = _type ? _type->scoped() : "::Ice::Object"; - ex.expectedType = scoped; - throw ex; - } - - // - // Now both zvals have the same object handle (they point at the same object). We need to - // increment the object's reference count accordingly. - // - Z_TYPE_P(zv) = IS_OBJECT; - zv->value.obj = _value->value.obj; - Z_OBJ_HT_P(_value)->add_ref(_value TSRMLS_CC); -} - -// -// ObjectMarshaler implementation. -// -IcePHP::ObjectMarshaler::ObjectMarshaler(const Slice::ClassDefPtr& def TSRMLS_DC) : - _def(def) -{ - // - // Find the class entry for this type. - // - if(def) - { - _scoped = def->scoped(); - _class = findClassScoped(_scoped TSRMLS_CC); - } - else - { - _scoped = "::Ice::Object"; - _class = findClass("Ice_Object" TSRMLS_CC); - } - - assert(_class); -} - -bool -IcePHP::ObjectMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC) -{ - if(Z_TYPE_P(zv) == IS_NULL) - { - os->writeObject(0); - return true; - } - - if(Z_TYPE_P(zv) != IS_OBJECT) - { - string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected object value of type %s but received %s", _class->name, - s.c_str()); - return false; - } - - // - // Verify that the given object is compatible with the formal type. - // - zend_class_entry* ce = Z_OBJCE_P(zv); - if(!checkClass(ce, _class)) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected object value of type %s but received %s", _class->name, - ce->name); - return false; - } - - // - // ObjectWriter is a subclass of Ice::Object that wraps a PHP object for marshaling. It is - // possible that this PHP object has already been marshaled, therefore we first must check - // the object map to see if this object is present. If so, we use the existing ObjectWriter, - // otherwise we create a new one. The key of the map is the object's handle. - // - Ice::ObjectPtr writer; - - ObjectMap::iterator q = m.find(Z_OBJ_HANDLE_P(zv)); - if(q == m.end()) - { - // - // Determine the most-derived Slice type implemented by this object by scanning its - // inheritance hierarchy until we find a class or interface that we recognize. - // - Profile* profile = static_cast<Profile*>(ICE_G(profile)); - assert(profile); - zend_class_entry* cls = ce; - const Profile::ClassMap& classes = profile->classes(); - Profile::ClassMap::const_iterator p = classes.find(cls->name); - while(p == classes.end()) - { - if(cls->parent) - { - p = classes.find(cls->parent->name); - } - for(zend_uint i = 0; i < cls->num_interfaces && p == classes.end(); ++i) - { - p = classes.find(cls->interfaces[i]->name); - } - cls = cls->parent; - } - assert(p != classes.end()); - - writer = new ObjectWriter(zv, p->second, m TSRMLS_CC); - m.insert(pair<unsigned int, Ice::ObjectPtr>(Z_OBJ_HANDLE_P(zv), writer)); - } - else - { - writer = q->second; - } - - // - // Give the writer to the stream. The stream will eventually call write() on it. - // - os->writeObject(writer); - - return true; -} - -bool -IcePHP::ObjectMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC) -{ - ReadObjectCallbackPtr cb = new ReadObjectCallback; - cb->ce = _class; - cb->scoped = _scoped; - cb->zv = zv; - - // - // Invoke readObject(), passing our callback object. When the object is eventually unmarshaled, - // our callback will be invoked and we will assign a value to zv. - // - is->readObject(cb); - - return true; -} - -void -IcePHP::ObjectMarshaler::destroy() -{ -} - -// -// PHPObjectFactory implementation. -// -IcePHP::PHPObjectFactory::PHPObjectFactory(TSRMLS_D) -{ -#ifdef ZTS - this->TSRMLS_C = TSRMLS_C; -#endif -} - -Ice::ObjectPtr -IcePHP::PHPObjectFactory::create(const string& scoped) -{ - Profile* profile = static_cast<Profile*>(ICE_G(profile)); - assert(profile); - - ObjectFactoryMap* ofm = static_cast<ObjectFactoryMap*>(ICE_G(objectFactoryMap)); - assert(ofm); - - // - // We can only unmarshal an object if we have the definition of its Slice type. - // - const Profile::ClassMap& classes = profile->classes(); - Profile::ClassMap::const_iterator p = classes.find(flatten(scoped)); - Slice::ClassDefPtr def; - if(p != classes.end()) - { - def = p->second; - } - else - { - return 0; - } - - // - // First check our map for a factory registered for this type. - // - ObjectFactoryMap::iterator q = ofm->find(scoped); - if(q == ofm->end()) - { - // - // Next, check for a default factory. - // - q = ofm->find(""); - } - - // - // If we found a factory, invoke create() on the object. - // - if(q != ofm->end()) - { - zval* id; - MAKE_STD_ZVAL(id); - ZVAL_STRINGL(id, const_cast<char*>(scoped.c_str()), scoped.length(), 1); - - zval* zresult = 0; - - zend_call_method_with_1_params(&q->second, 0, 0, "create", &zresult, id); - - zval_ptr_dtor(&id); - - AutoDestroy destroyResult(zresult); - - // - // Bail out if an exception has already been thrown. - // - if(EG(exception)) - { - throw AbortMarshaling(); - } - - if(zresult) - { - // - // If the factory returned a non-null value, verify that it is an object, and that it - // implements Ice_Object. - // - if(!ZVAL_IS_NULL(zresult)) - { - if(Z_TYPE_P(zresult) != IS_OBJECT) - { - Ice::MarshalException ex(__FILE__, __LINE__); - ex.reason = "object factory did not return an object for type " + scoped; - throw ex; - } - - zend_class_entry* ce = Z_OBJCE_P(zresult); - zend_class_entry* base = findClass("Ice_Object" TSRMLS_CC); - if(!checkClass(ce, base)) - { - Ice::MarshalException ex(__FILE__, __LINE__); - ex.reason = "object returned by factory does not implement Ice_Object"; - throw ex; - } - - return new ObjectReader(zresult, def TSRMLS_CC); - } - } - } - - // - // Attempt to find a class entry for the given type id. If no class entry is - // found, or the class is abstract, then we return nil and the stream will skip - // the slice and try again. - // - zend_class_entry* cls = findClassScoped(scoped TSRMLS_CC); - - // - // Instantiate the class if it's not abstract. - // - Ice::ObjectPtr result; - const int abstractFlags = ZEND_ACC_INTERFACE | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; - if(cls && (cls->ce_flags & abstractFlags) == 0) - { - zval* obj; - MAKE_STD_ZVAL(obj); - object_init_ex(obj, cls); - result = new ObjectReader(obj, def TSRMLS_CC); - zval_ptr_dtor(&obj); - } - - return result; -} - -void -IcePHP::PHPObjectFactory::destroy() -{ -} diff --git a/php/src/IcePHP/Marshal.h b/php/src/IcePHP/Marshal.h deleted file mode 100644 index 620c33c7ddf..00000000000 --- a/php/src/IcePHP/Marshal.h +++ /dev/null @@ -1,83 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2009 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. -// -// ********************************************************************** - -#ifndef ICE_PHP_MARSHAL_H -#define ICE_PHP_MARSHAL_H - -#include <Config.h> - -namespace IcePHP -{ - -// -// The object map associates a Zend object handle to an Ice object. -// -typedef std::map<unsigned int, Ice::ObjectPtr> ObjectMap; - -class Marshaler; -typedef IceUtil::Handle<Marshaler> MarshalerPtr; - -class Marshaler : public IceUtil::SimpleShared -{ -public: - virtual ~Marshaler(); - - static MarshalerPtr createMarshaler(const Slice::TypePtr& TSRMLS_DC); - static MarshalerPtr createMemberMarshaler(const std::string&, const Slice::TypePtr& TSRMLS_DC); - static MarshalerPtr createExceptionMarshaler(const Slice::ExceptionPtr& TSRMLS_DC); - - virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC) = 0; - virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC) = 0; - - virtual void destroy() = 0; - -protected: - Marshaler(); -}; - -// -// Associates a scoped type id to its marshaler. -// -typedef std::map<std::string, MarshalerPtr> MarshalerMap; - -// -// Associates a scoped type id to its factory. -// -typedef std::map<std::string, zval*> ObjectFactoryMap; - -// -// This class is raised as an exception when object marshaling needs to be aborted. -// -class AbortMarshaling -{ -}; - -// -// PHPObjectFactory is an implementation of Ice::ObjectFactory that creates PHP objects. -// It is also the registry for user-defined PHP factory implementations. A single instance -// can be used for all types. -// -class PHPObjectFactory : public Ice::ObjectFactory -{ -public: - PHPObjectFactory(TSRMLS_D); - - virtual Ice::ObjectPtr create(const std::string&); - virtual void destroy(); - -#ifdef ZTS -private: - TSRMLS_D; -#endif -}; -typedef IceUtil::Handle<PHPObjectFactory> PHPObjectFactoryPtr; - -} // End of namespace IcePHP - -#endif diff --git a/php/src/IcePHP/Operation.cpp b/php/src/IcePHP/Operation.cpp new file mode 100644 index 00000000000..64ff018487b --- /dev/null +++ b/php/src/IcePHP/Operation.cpp @@ -0,0 +1,711 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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 <Operation.h> +#include <Communicator.h> +#include <Proxy.h> +#include <Types.h> +#include <Util.h> +#include <Slice/PHPUtil.h> + +using namespace std; +using namespace IcePHP; +using namespace Slice::PHP; + +extern "C" +{ +ZEND_FUNCTION(IcePHP_Operation_call); +} + +namespace IcePHP +{ + +// +// Receives an out parameter or return value. +// +class ResultCallback : public UnmarshalCallback +{ +public: + + ResultCallback(); + ~ResultCallback(); + + virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC); + + zval* zv; +}; +typedef IceUtil::Handle<ResultCallback> ResultCallbackPtr; +typedef vector<ResultCallbackPtr> ResultCallbackList; + +// +// Encapsulates attributes of an operation. +// +class OperationI : public Operation +{ +public: + + OperationI(const char*, Ice::OperationMode, Ice::OperationMode, zval*, zval*, zval*, zval* TSRMLS_DC); + ~OperationI(); + + virtual zend_function* function(); + + string name; // On-the-wire name. + Ice::OperationMode mode; + Ice::OperationMode sendMode; + TypeInfoList inParams; + TypeInfoList outParams; + TypeInfoPtr returnType; + ExceptionInfoList exceptions; + bool sendsClasses; + bool returnsClasses; + int numParams; + +private: + + zend_internal_function* _zendFunction; + + static void convertParams(zval*, TypeInfoList&, bool& TSRMLS_DC); + static void getArgInfo(zend_arg_info&, const TypeInfoPtr&, bool); +}; +typedef IceUtil::Handle<OperationI> OperationIPtr; + +// +// The base class for client-side invocations. +// +class Invocation : virtual public IceUtil::Shared +{ +public: + + Invocation(const Ice::ObjectPrx&, const CommunicatorInfoPtr& TSRMLS_DC); + + virtual void invoke(INTERNAL_FUNCTION_PARAMETERS) = 0; + +protected: + + Ice::ObjectPrx _prx; + CommunicatorInfoPtr _communicator; +#ifdef ZTS + TSRMLS_D; +#endif +}; +typedef IceUtil::Handle<Invocation> InvocationPtr; + +// +// TypedInvocation uses the information in the given operation to validate, marshal, and unmarshal +// parameters and exceptions. +// +class TypedInvocation : virtual public Invocation +{ +public: + + TypedInvocation(const Ice::ObjectPrx&, const CommunicatorInfoPtr&, const OperationIPtr& TSRMLS_DC); + +protected: + + OperationIPtr _op; + + bool prepareRequest(int, zval**, Ice::ByteSeq& TSRMLS_DC); + void unmarshalResults(int, zval**, zval*, const pair<const Ice::Byte*, const Ice::Byte*>& TSRMLS_DC); + zval* unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& TSRMLS_DC); + bool validateException(const ExceptionInfoPtr& TSRMLS_DC) const; + void checkTwowayOnly(const Ice::ObjectPrx&) const; +}; + +// +// A synchronous typed invocation. +// +class SyncTypedInvocation : virtual public TypedInvocation +{ +public: + + SyncTypedInvocation(const Ice::ObjectPrx&, const CommunicatorInfoPtr&, const OperationIPtr& TSRMLS_DC); + + virtual void invoke(INTERNAL_FUNCTION_PARAMETERS); +}; + +} + +// +// ResultCallback implementation. +// +IcePHP::ResultCallback::ResultCallback() : + zv(0) +{ +} + +IcePHP::ResultCallback::~ResultCallback() +{ + if(zv) + { + zval_ptr_dtor(&zv); + } +} + +void +IcePHP::ResultCallback::unmarshaled(zval* val, zval*, void* TSRMLS_DC) +{ + // + // Keep a reference to the unmarshaled value. + // + zv = val; + Z_ADDREF_P(zv); +} + +// +// OperationI implementation. +// +IcePHP::OperationI::OperationI(const char* n, Ice::OperationMode m, Ice::OperationMode sm, zval* in, zval* out, + zval* ret, zval* ex TSRMLS_DC) : + name(n), mode(m), sendMode(sm), sendsClasses(false), returnsClasses(false), _zendFunction(0) +{ + // + // inParams + // + if(in) + { + convertParams(in, inParams, sendsClasses TSRMLS_CC); + } + + // + // outParams + // + if(out) + { + convertParams(out, outParams, returnsClasses TSRMLS_CC); + } + + numParams = static_cast<int>(inParams.size() + outParams.size()); + + // + // returnType + // + if(ret) + { + returnType = Wrapper<TypeInfoPtr>::value(ret TSRMLS_CC); + if(!returnsClasses) + { + returnsClasses = returnType->usesClasses(); + } + } + + // + // exceptions + // + if(ex) + { + HashTable* arr = Z_ARRVAL_P(ex); + HashPosition pos; + zend_hash_internal_pointer_reset_ex(arr, &pos); + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + ExceptionInfoPtr i = Wrapper<ExceptionInfoPtr>::value(*val TSRMLS_CC); + exceptions.push_back(i); + zend_hash_move_forward_ex(arr, &pos); + } + } +} + +IcePHP::OperationI::~OperationI() +{ + if(_zendFunction) + { + delete []_zendFunction->arg_info; + efree(_zendFunction->function_name); + efree(_zendFunction); + } +} + +zend_function* +IcePHP::OperationI::function() +{ + if(!_zendFunction) + { + // + // Create an array that indicates how arguments are passed to the operation. + // + zend_arg_info* argInfo = new zend_arg_info[numParams]; + + int i = 0; + TypeInfoList::const_iterator p; + for(p = inParams.begin(); p != inParams.end(); ++p, ++i) + { + getArgInfo(argInfo[i], *p, false); + argInfo[i].required_num_args = static_cast<zend_uint>(numParams); + } + for(p = outParams.begin(); p != outParams.end(); ++p, ++i) + { + getArgInfo(argInfo[i], *p, true); + argInfo[i].required_num_args = static_cast<zend_uint>(numParams); + } + + string fixed = fixIdent(name); + _zendFunction = static_cast<zend_internal_function*>(emalloc(sizeof(zend_internal_function))); + _zendFunction->type = ZEND_INTERNAL_FUNCTION; + _zendFunction->function_name = estrndup(STRCAST(fixed.c_str()), fixed.length()); + _zendFunction->scope = proxyClassEntry; + _zendFunction->fn_flags = ZEND_ACC_PUBLIC; + _zendFunction->prototype = 0; + _zendFunction->num_args = static_cast<zend_uint>(numParams); + _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(IcePHP_Operation_call); + } + + return reinterpret_cast<zend_function*>(_zendFunction); +} + +void +IcePHP::OperationI::convertParams(zval* p, TypeInfoList& params, bool& usesClasses TSRMLS_DC) +{ + usesClasses = false; + + assert(Z_TYPE_P(p) == IS_ARRAY); + HashTable* arr = Z_ARRVAL_P(p); + HashPosition pos; + zend_hash_internal_pointer_reset_ex(arr, &pos); + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(*val TSRMLS_CC); + params.push_back(type); + if(!usesClasses) + { + usesClasses = type->usesClasses(); + } + zend_hash_move_forward_ex(arr, &pos); + } +} + +void +IcePHP::OperationI::getArgInfo(zend_arg_info& arg, const TypeInfoPtr& info, bool out) +{ + arg.name = 0; + arg.class_name = 0; + arg.allow_null = 1; + if(SequenceInfoPtr::dynamicCast(info) || DictionaryInfoPtr::dynamicCast(info)) + { + arg.array_type_hint = 1; + } + else + { + arg.array_type_hint = 0; + } + arg.return_reference = 0; + arg.pass_by_reference = out ? 1 : 0; +} + +// +// Invocation +// +IcePHP::Invocation::Invocation(const Ice::ObjectPrx& prx, const CommunicatorInfoPtr& communicator TSRMLS_DC) : + _prx(prx), _communicator(communicator) +{ +#ifdef ZTS + this->TSRMLS_C = TSRMLS_C; +#endif +} + +// +// TypedInvocation +// +IcePHP::TypedInvocation::TypedInvocation(const Ice::ObjectPrx& prx, const CommunicatorInfoPtr& communicator, + const OperationIPtr& op TSRMLS_DC) : + Invocation(prx, communicator TSRMLS_CC), _op(op) +{ +} + +bool +IcePHP::TypedInvocation::prepareRequest(int argc, zval** args, Ice::ByteSeq& bytes TSRMLS_DC) +{ + // + // Verify that the expected number of arguments are supplied. The context argument is optional. + // + if(argc != _op->numParams && argc != _op->numParams + 1) + { + runtimeError("incorrect number of parameters (%d)" TSRMLS_CC, argc); + return false; + } + + // + // The operation's configuration (zend_function) forces out parameters + // to be passed by reference. + // + for(int i = static_cast<int>(_op->inParams.size()); i < _op->numParams; ++i) + { + assert(PZVAL_IS_REF(args[i])); + } + + if(!_op->inParams.empty()) + { + try + { + // + // Marshal the in parameters. + // + Ice::OutputStreamPtr os = Ice::createOutputStream(_communicator->getCommunicator()); + + ObjectMap objectMap; + int i = 0; + for(TypeInfoList::iterator p = _op->inParams.begin(); p != _op->inParams.end(); ++p, ++i) + { + zval* arg = args[i]; + if(!(*p)->validate(arg TSRMLS_CC)) + { + invalidArgument("invalid value for argument %d in operation `%s'" TSRMLS_CC, i, _op->name.c_str()); + return false; + } + (*p)->marshal(arg, os, &objectMap TSRMLS_CC); + } + + if(_op->sendsClasses) + { + os->writePendingObjects(); + } + + os->finished(bytes); + } + catch(const AbortMarshaling&) + { + return false; + } + catch(const Ice::Exception& ex) + { + throwException(ex TSRMLS_CC); + return false; + } + } + + return true; +} + +void +IcePHP::TypedInvocation::unmarshalResults(int argc, zval** args, zval* ret, + const pair<const Ice::Byte*, const Ice::Byte*>& bytes TSRMLS_DC) +{ + Ice::InputStreamPtr is = Ice::createInputStream(_communicator->getCommunicator(), bytes); + + // + // These callbacks collect references to the unmarshaled values. We copy them into + // the argument list *after* any pending objects have been unmarshaled. + // + ResultCallbackList outParamCallbacks; + ResultCallbackPtr retCallback; + + // + // Unmarshal the out parameters. + // + for(TypeInfoList::iterator p = _op->outParams.begin(); p != _op->outParams.end(); ++p) + { + ResultCallbackPtr cb = new ResultCallback; + outParamCallbacks.push_back(cb); + (*p)->unmarshal(is, cb, _communicator, 0, 0 TSRMLS_CC); + } + + // + // Unmarshal the return value. + // + if(_op->returnType) + { + retCallback = new ResultCallback; + _op->returnType->unmarshal(is, retCallback, _communicator, 0, 0 TSRMLS_CC); + } + + if(_op->returnsClasses) + { + is->readPendingObjects(); + } + + int i = static_cast<int>(_op->inParams.size()); + for(ResultCallbackList::iterator q = outParamCallbacks.begin(); q != outParamCallbacks.end(); ++q, ++i) + { + // + // We must explicitly destroy the existing contents of all zvals passed + // as out parameters, otherwise leaks occur. + // + zval* val = (*q)->zv; + zval_dtor(args[i]); + args[i]->value = val->value; + Z_TYPE_P(args[i]) = Z_TYPE_P(val); + zval_copy_ctor(args[i]); + } + + if(_op->returnType) + { + ret->value = retCallback->zv->value; + Z_TYPE_P(ret) = Z_TYPE_P(retCallback->zv); + zval_copy_ctor(ret); + } +} + +zval* +IcePHP::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& bytes TSRMLS_DC) +{ + int traceSlicing = -1; + + Ice::InputStreamPtr is = Ice::createInputStream(_communicator->getCommunicator(), bytes); + + is->readBool(); // usesClasses + + string id = is->readString(); + const string origId = id; + + while(!id.empty()) + { + ExceptionInfoPtr info = getExceptionInfo(id TSRMLS_CC); + if(info) + { + zval* ex = info->unmarshal(is, _communicator TSRMLS_CC); + if(ex) + { + if(info->usesClasses) + { + is->readPendingObjects(); + } + + if(validateException(info TSRMLS_CC)) + { + return ex; + } + else + { + zval_ptr_dtor(&ex); + Ice::UnknownUserException uue(__FILE__, __LINE__, + "operation raised undeclared exception `" + id + "'"); + return convertException(uue TSRMLS_CC); + } + } + } + else + { + if(traceSlicing == -1) + { + traceSlicing = + _communicator->getCommunicator()->getProperties()->getPropertyAsInt("Ice.Trace.Slicing") > 0; + } + + if(traceSlicing > 0) + { + _communicator->getCommunicator()->getLogger()->trace("Slicing", "unknown exception type `" + id + "'"); + } + + is->skipSlice(); // Slice off what we don't understand. + + try + { + id = is->readString(); // Read type id for next slice. + } + catch(Ice::UnmarshalOutOfBoundsException& ex) + { + // + // When readString raises this exception it means we've seen the last slice, + // so we set the reason member to a more helpful message. + // + ex.reason = "unknown exception type `" + origId + "'"; + return convertException(ex TSRMLS_CC); + } + } + } + + // + // 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 a factory for. This means that sender and receiver disagree + // about the Slice definitions they use. + // + Ice::UnknownUserException uue(__FILE__, __LINE__, "unknown exception type `" + origId + "'"); + return convertException(uue TSRMLS_CC); +} + +bool +IcePHP::TypedInvocation::validateException(const ExceptionInfoPtr& info TSRMLS_DC) const +{ + for(ExceptionInfoList::const_iterator p = _op->exceptions.begin(); p != _op->exceptions.end(); ++p) + { + if(info->isA((*p)->id)) + { + return true; + } + } + + return false; +} + +void +IcePHP::TypedInvocation::checkTwowayOnly(const Ice::ObjectPrx& proxy) const +{ + if((_op->returnType || !_op->outParams.empty()) && !proxy->ice_isTwoway()) + { + Ice::TwowayOnlyException ex(__FILE__, __LINE__); + ex.operation = _op->name; + throw ex; + } +} + +// +// SyncTypedInvocation +// +IcePHP::SyncTypedInvocation::SyncTypedInvocation(const Ice::ObjectPrx& prx, const CommunicatorInfoPtr& communicator, + const OperationIPtr& op TSRMLS_DC) : + Invocation(prx, communicator TSRMLS_CC), TypedInvocation(prx, communicator, op TSRMLS_CC) +{ +} + +void +IcePHP::SyncTypedInvocation::invoke(INTERNAL_FUNCTION_PARAMETERS) +{ + // + // 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) + { + runtimeError("unable to get arguments" TSRMLS_CC); + return; + } + + Ice::ByteSeq params; + if(!prepareRequest(ZEND_NUM_ARGS(), *args, params TSRMLS_CC)) + { + return; + } + + bool hasCtx = false; + Ice::Context ctx; + if(ZEND_NUM_ARGS() == _op->numParams + 1) + { + if(!extractStringMap(*args[ZEND_NUM_ARGS() - 1], ctx TSRMLS_CC)) + { + return; + } + hasCtx = true; + } + + try + { + checkTwowayOnly(_prx); + + // + // Invoke the operation. + // + vector<Ice::Byte> result; + bool status; + { + if(hasCtx) + { + status = _prx->ice_invoke(_op->name, _op->sendMode, params, result, ctx); + } + else + { + status = _prx->ice_invoke(_op->name, _op->sendMode, params, result); + } + } + + // + // Process the reply. + // + if(_prx->ice_isTwoway()) + { + if(!status) + { + // + // Unmarshal a user exception. + // + pair<const Ice::Byte*, const Ice::Byte*> rb(0, 0); + if(!result.empty()) + { + rb.first = &result[0]; + rb.second = &result[0] + result.size(); + } + + zval* ex = unmarshalException(rb TSRMLS_CC); + if(ex) + { + zend_throw_exception_object(ex TSRMLS_CC); + } + } + else if(!_op->outParams.empty() || _op->returnType) + { + // + // Unmarshal the results. + // + pair<const Ice::Byte*, const Ice::Byte*> rb(0, 0); + if(!result.empty()) + { + rb.first = &result[0]; + rb.second = &result[0] + result.size(); + } + unmarshalResults(ZEND_NUM_ARGS(), *args, return_value, rb TSRMLS_CC); + } + } + } + catch(const AbortMarshaling&) + { + } + catch(const Ice::Exception& ex) + { + throwException(ex TSRMLS_CC); + } +} + +ZEND_FUNCTION(IcePHP_defineOperation) +{ + zval* cls; + char* name; + int nameLen; + long mode; + long sendMode; + zval* inParams; + zval* outParams; + zval* returnType; + zval* exceptions; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oslla!a!o!a!", &cls, &name, &nameLen, &mode, &sendMode, + &inParams, &outParams, &returnType, &exceptions) == FAILURE) + { + return; + } + + TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(cls TSRMLS_CC); + ClassInfoPtr c = ClassInfoPtr::dynamicCast(type); + assert(c); + + OperationIPtr op = new OperationI(name, static_cast<Ice::OperationMode>(mode), + static_cast<Ice::OperationMode>(sendMode), inParams, outParams, returnType, + exceptions TSRMLS_CC); + + c->addOperation(name, op); +} + +ZEND_FUNCTION(IcePHP_Operation_call) +{ + Ice::ObjectPrx proxy; + ClassInfoPtr cls; + CommunicatorInfoPtr comm; +#ifndef NDEBUG + bool b = +#endif + fetchProxy(getThis(), proxy, cls, comm TSRMLS_CC); + assert(b); + assert(proxy); + assert(cls); + + OperationPtr op = cls->getOperation(get_active_function_name(TSRMLS_C)); + assert(op); // handleGetMethod should have already verified the operation's existence. + OperationIPtr opi = OperationIPtr::dynamicCast(op); + assert(opi); + + InvocationPtr inv = new SyncTypedInvocation(proxy, comm, opi TSRMLS_CC); + inv->invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} diff --git a/php/src/IcePHP/Operation.h b/php/src/IcePHP/Operation.h new file mode 100644 index 00000000000..aaa39b8c873 --- /dev/null +++ b/php/src/IcePHP/Operation.h @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef ICEPHP_OPERATION_H +#define ICEPHP_OPERATION_H + +#include <Config.h> + +// +// Global functions. +// +extern "C" +{ +ZEND_FUNCTION(IcePHP_defineOperation); +} + +#define ICEPHP_OPERATION_FUNCTIONS \ + ZEND_FE(IcePHP_defineOperation, NULL) + +namespace IcePHP +{ + +class Operation : public IceUtil::Shared +{ +public: + + virtual zend_function* function() = 0; + +}; +typedef IceUtil::Handle<Operation> OperationPtr; + +} + +#endif diff --git a/php/src/IcePHP/Profile.cpp b/php/src/IcePHP/Profile.cpp deleted file mode 100644 index 3e79ae26d8f..00000000000 --- a/php/src/IcePHP/Profile.cpp +++ /dev/null @@ -1,1617 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2009 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 <Profile.h> -#include <Util.h> - -#include <Slice/Preprocessor.h> -#include <IceUtil/Options.h> -#include <IceUtil/InputUtil.h> -#include <fstream> - -using namespace std; -using namespace IcePHP; - -ZEND_EXTERN_MODULE_GLOBALS(ice) - -// -// The name we give to the default profile. -// -static const char* _defaultProfileName = "__default__"; - -// -// The table of profiles. -// -static map<string, Profile*> _profiles; - -namespace IcePHP -{ - -// -// CodeVisitor descends the Slice parse tree and generates PHP code for certain Slice types. -// -class CodeVisitor : public Slice::ParserVisitor -{ -public: - CodeVisitor(ostream&, Profile::ClassMap&, bool TSRMLS_DC); - - virtual void visitClassDecl(const Slice::ClassDeclPtr&); - virtual bool visitClassDefStart(const Slice::ClassDefPtr&); - virtual void visitClassDefEnd(const Slice::ClassDefPtr&); - virtual bool visitExceptionStart(const Slice::ExceptionPtr&); - virtual void visitExceptionEnd(const Slice::ExceptionPtr&); - virtual bool visitStructStart(const Slice::StructPtr&); - virtual void visitStructEnd(const Slice::StructPtr&); - virtual void visitOperation(const Slice::OperationPtr&); - virtual void visitDataMember(const Slice::DataMemberPtr&); - virtual void visitDictionary(const Slice::DictionaryPtr&); - virtual void visitEnum(const Slice::EnumPtr&); - virtual void visitConst(const Slice::ConstPtr&); - -private: - - string getTypeHint(const Slice::TypePtr&); - string getDefaultValue(const Slice::TypePtr&); - void writeConstructorParameter(const Slice::DataMemberPtr&); - void writeConstructorAssignment(const Slice::DataMemberPtr&); - - ostream& _out; - Profile::ClassMap& _classes; - bool _suppressWarnings; -#ifdef ZTS - TSRMLS_D; -#endif -}; - -} // End of namespace IcePHP - -// -// This PHP code defines the core types we need. We supply a few of the common -// local exception subclasses; all other local exceptions are mapped to -// UnknownLocalException. We don't define Ice::Identity here because it's -// possible the user will have included its definition (see createProfile). -// -// NOTE: If a local exception is added or removed here, then changes are also -// necessary to IcePHP::throwException. -// -static const char* _coreTypes = - "abstract class Ice_Exception extends Exception\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Exception::__construct($message);\n" - " }\n" - "}\n" - "\n" - "abstract class Ice_LocalException extends Ice_Exception\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_Exception::__construct($message);\n" - " }\n" - "}\n" - "\n" - "class Ice_TwowayOnlyException extends Ice_LocalException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_LocalException::__construct($message);\n" - " }\n" - "\n" - " function __toString()\n" - " {\n" - " return get_class($this) . \"\\n\" .\n" - " \" operation: \" . $this->operation;\n" - " }\n" - "\n" - " public $operation;\n" - "}\n" - "\n" - "class Ice_UnknownException extends Ice_LocalException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_LocalException::__construct($message);\n" - " }\n" - "\n" - " function __toString()\n" - " {\n" - " return get_class($this) . \"\\n\" .\n" - " $this->unknown;\n" - " }\n" - "\n" - " public $unknown;\n" - "}\n" - "\n" - "class Ice_UnknownLocalException extends Ice_UnknownException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_UnknownException::__construct($message);\n" - " }\n" - "}\n" - "\n" - "class Ice_UnknownUserException extends Ice_UnknownException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_UnknownException::__construct($message);\n" - " }\n" - "}\n" - "\n" - "class Ice_RequestFailedException extends Ice_LocalException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_LocalException::__construct($message);\n" - " }\n" - "\n" - " function __toString()\n" - " {\n" - " return get_class($this) . \"\\n\" .\n" - " \" identity: \" . Ice_identityToString($this->id) . \"\\n\" .\n" - " \" facet: \" . $this->facet . \"\\n\" .\n" - " \" operation: \" . $this->operation;\n" - " }\n" - "\n" - " public $id;\n" - " public $facet;\n" - " public $operation;\n" - "}\n" - "\n" - "class Ice_ObjectNotExistException extends Ice_RequestFailedException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_RequestFailedException::__construct($message);\n" - " }\n" - "}\n" - "\n" - "class Ice_FacetNotExistException extends Ice_RequestFailedException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_RequestFailedException::__construct($message);\n" - " }\n" - "}\n" - "\n" - "class Ice_OperationNotExistException extends Ice_RequestFailedException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_RequestFailedException::__construct($message);\n" - " }\n" - "}\n" - "\n" - "class Ice_ProtocolException extends Ice_LocalException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_LocalException::__construct($message);\n" - " }\n" - "\n" - " function __toString()\n" - " {\n" - " return get_class($this) . \"\\n\" .\n" - " \" reason: \" . $this->reason;\n" - " }\n" - "\n" - " public $reason;\n" - "}\n" - "\n" - "class Ice_MarshalException extends Ice_ProtocolException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_ProtocolException::__construct($message);\n" - " }\n" - "}\n" - "\n" - "class Ice_NoObjectFactoryException extends Ice_MarshalException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_MarshalException::__construct($message);\n" - " }\n" - "\n" - " function __toString()\n" - " {\n" - " return get_class($this) . \"\\n\" .\n" - " \" reason: \" . $this->reason . \"\\n\" .\n" - " \" type: \" . $this->type;\n" - " }\n" - "\n" - " public $type;\n" - "}\n" - "\n" - "class Ice_UnexpectedObjectException extends Ice_MarshalException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_MarshalException::__construct($message);\n" - " }\n" - "\n" - " function __toString()\n" - " {\n" - " return get_class($this) . \"\\n\" .\n" - " \" reason: \" . $this->reason . \"\\n\" .\n" - " \" type: \" . $this->type . \"\\n\" .\n" - " \" expectedType: \" . $this->expectedType;\n" - " }\n" - "\n" - " public $type;\n" - "}\n" - "\n" - "class Ice_ProfileAlreadyLoadedException extends Ice_LocalException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_LocalException::__construct($message);\n" - " }\n" - "}\n" - "\n" - "class Ice_ProfileNotFoundException extends Ice_LocalException\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_LocalException::__construct($message);\n" - " }\n" - "\n" - " function __toString()\n" - " {\n" - " return get_class($this) . \"\\n\" .\n" - " \" name: \" . $this->name;\n" - " }\n" - "\n" - " public $name;\n" - "}\n" - "\n" - "abstract class Ice_UserException extends Ice_Exception\n" - "{\n" - " function __construct($message = '')\n" - " {\n" - " Ice_Exception::__construct($message);\n" - " }\n" - "}\n" - "\n" - "interface Ice_LocalObject\n" - "{\n" - "}\n" - "\n" - "class Ice_LocalObjectImpl implements Ice_LocalObject\n" - "{\n" - "}\n" - "\n" - "interface Ice_Object\n" - "{\n" - " function ice_preMarshal();\n" - " function ice_postUnmarshal();\n" - "}\n" - "\n" - "abstract class Ice_ObjectImpl implements Ice_Object\n" - "{\n" - " function ice_preMarshal()\n" - " {\n" - " }\n" - "\n" - " function ice_postUnmarshal()\n" - " {\n" - " }\n" - "}\n" - "\n" - "interface Ice_ObjectFactory\n" - "{\n" - " function create($id);\n" - " function destroy();\n" - "}\n" -; - -// -// Parse the Slice files that define the types and operations available to a PHP script. -// -static bool -parseSlice(const string& argStr, vector<Slice::UnitPtr>& units, bool& suppressWarnings TSRMLS_DC) -{ - vector<string> args; - try - { - args = IceUtilInternal::Options::split(argStr); - } - catch(const IceUtil::Exception& ex) - { - ostringstream ostr; - ex.ice_print(ostr); - string msg = ostr.str(); - php_error_docref(0 TSRMLS_CC, E_ERROR, "error occurred while parsing Slice options in `%s':\n%s", - argStr.c_str(), msg.c_str()); - return false; - } - - IceUtilInternal::Options opts; - opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("d", "debug"); - opts.addOpt("", "ice"); - opts.addOpt("w"); - - vector<string> files; - try - { - args.insert(args.begin(), ""); // dummy argv[0] - files = opts.parse(args); - if(files.empty() && !argStr.empty()) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "no Slice files specified in `%s'", argStr.c_str()); - return false; - } - } - catch(const IceUtil::Exception& ex) - { - ostringstream ostr; - ex.ice_print(ostr); - string msg = ostr.str(); - php_error_docref(0 TSRMLS_CC, E_ERROR, "error occurred while parsing Slice options in `%s':\n%s", - argStr.c_str(), msg.c_str()); - return false; - } - - vector<string> cppArgs; - bool debug = false; - bool ice = true; // This must be true so that we can create Ice::Identity when necessary. - if(opts.isSet("D")) - { - vector<string> optargs = opts.argVec("D"); - for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) - { - cppArgs.push_back("-D" + *i); - } - } - if(opts.isSet("U")) - { - vector<string> optargs = opts.argVec("U"); - for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) - { - cppArgs.push_back("-U" + *i); - } - } - if(opts.isSet("I")) - { - vector<string> optargs = opts.argVec("I"); - for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) - { - cppArgs.push_back("-I" + *i); - } - } - debug = opts.isSet("d") || opts.isSet("debug"); - suppressWarnings = opts.isSet("w"); - - bool ignoreRedefs = false; - bool all = true; - - for(vector<string>::iterator p = files.begin(); p != files.end(); ++p) - { - Slice::UnitPtr unit = Slice::Unit::createUnit(ignoreRedefs, all, ice); - Slice::Preprocessor icecpp("icecpp", *p, cppArgs); - FILE* cppHandle = icecpp.preprocess(false); - - if(cppHandle == 0) - { - return false; - } - - int parseStatus = unit->parse(*p, cppHandle, debug); - - if(!icecpp.close()) - { - return false; - } - - if(parseStatus == EXIT_FAILURE) - { - return false; - } - - units.push_back(unit); - } - - return true; -} - -static bool -createProfile(const string& name, const string& config, const string& options, const string& slice TSRMLS_DC) -{ - map<string, Profile*>::iterator p = _profiles.find(name); - if(p != _profiles.end()) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "profile `%s' already exists", name.c_str()); - return false; - } - - Ice::PropertiesPtr properties = Ice::createProperties(); - - if(!config.empty()) - { - try - { - properties->load(config); - } - catch(const IceUtil::Exception& ex) - { - ostringstream ostr; - ex.ice_print(ostr); - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to load Ice configuration file %s:\n%s", config.c_str(), - ostr.str().c_str()); - return false; - } - } - - if(!options.empty()) - { - vector<string> args; - try - { - args = IceUtilInternal::Options::split(options); - } - catch(const IceUtil::Exception& ex) - { - ostringstream ostr; - ex.ice_print(ostr); - string msg = ostr.str(); - php_error_docref(0 TSRMLS_CC, E_ERROR, "error occurred while parsing the options `%s':\n%s", - options.c_str(), msg.c_str()); - return false; - } - properties->parseCommandLineOptions("", args); - } - - // - // We create a Unit for each Slice file. - // - vector<Slice::UnitPtr> units; - - // - // Even if the profile specifies no Slice files, we still need to obtain builtin - // types as well as create types such as Ice::Identity. - // - { - Slice::UnitPtr unit = Slice::Unit::createUnit(false, false, true); - - // - // Create the Slice definition for Ice::Identity if it doesn't exist. The PHP class will - // be created automatically by CodeVisitor. - // - string scoped = "::Ice::Identity"; - Slice::TypeList l = unit->lookupTypeNoBuiltin(scoped, false); - if(l.empty()) - { - Slice::ContainedList c = unit->lookupContained("Ice", false); - Slice::ModulePtr module; - if(c.empty()) - { - module = unit->createModule("Ice"); - } - else - { - module = Slice::ModulePtr::dynamicCast(c.front()); - if(!module) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, - "the symbol `::Ice' is defined in Slice but is not a module"); - return false; - } - } - Slice::StructPtr identity = module->createStruct("Identity", false); - Slice::TypePtr str = unit->builtin(Slice::Builtin::KindString); - identity->createDataMember("category", str); - identity->createDataMember("name", str); - } - - // - // Create the Slice definition for Ice::EndpointSelectionType if it doesn't exist. The PHP class will - // be created automatically by CodeVisitor. - // - scoped = "::Ice::EndpointSelectionType"; - l = unit->lookupTypeNoBuiltin(scoped, false); - if(l.empty()) - { - Slice::ContainedList c = unit->lookupContained("Ice", false); - Slice::ModulePtr module; - if(c.empty()) - { - module = unit->createModule("Ice"); - } - else - { - module = Slice::ModulePtr::dynamicCast(c.front()); - if(!module) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, - "the symbol `::Ice' is defined in Slice but is not a module"); - return false; - } - } - Slice::EnumPtr en = module->createEnum("EndpointSelectionType", false); - Slice::EnumeratorList el; - el.push_back(module->createEnumerator("Random")); - el.push_back(module->createEnumerator("Ordered")); - en->setEnumerators(el); - } - - units.push_back(unit); - } - - bool suppressWarnings = false; - if(!slice.empty() && !parseSlice(slice, units, suppressWarnings TSRMLS_CC)) - { - return false; - } - - // - // Descend the parse trees to generate PHP code. - // - ostringstream out; - Profile::ClassMap classes; - for(vector<Slice::UnitPtr>::const_iterator q = units.begin(); q != units.end(); ++ q) - { - CodeVisitor visitor(out, classes, suppressWarnings TSRMLS_CC); - (*q)->visit(&visitor, false); - } - - _profiles[name] = new Profile(name, units, out.str(), classes, properties); - - return true; -} - -bool -IcePHP::profileInit(TSRMLS_D) -{ - // - // The default profile is configured using ice.config, ice.options and ice.slice. Named profiles - // are contained in a separate INI file, whose name is defined by ice.profiles. - // - const char* config = INI_STR("ice.config"); - const char* options = INI_STR("ice.options"); - const char* profiles = INI_STR("ice.profiles"); - const char* slice = INI_STR("ice.slice"); - - if(!createProfile(_defaultProfileName, config, options, slice TSRMLS_CC)) - { - return false; - } - - if(strlen(profiles) > 0) - { - // - // The Zend engine doesn't export a function for loading an INI file, so we - // have to do it ourselves. The format is: - // - // [profile-name] - // ice.config = config-file - // ice.options = args - // ice.slice = slice-args - // - ifstream in(profiles); - if(!in) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to open Ice profiles in %s", profiles); - return false; - } - - string currentName, currentConfig, currentOptions, currentSlice; - char line[1024]; - while(in.getline(line, 1024)) - { - const string delim = " \t\r\n"; - string s = line; - - string::size_type idx = s.find(';'); - if(idx != string::npos) - { - s.erase(idx); - } - - idx = s.find_last_not_of(delim); - if(idx != string::npos && idx + 1 < s.length()) - { - s.erase(idx + 1); - } - - string::size_type beg = s.find_first_not_of(delim); - if(beg == string::npos) - { - continue; - } - - if(s[beg] == '[') - { - beg++; - string::size_type end = s.find_first_of(" \t]", beg); - if(end == string::npos || s[s.length() - 1] != ']') - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "invalid profile section in file %s:\n%s\n", profiles, - line); - return false; - } - - if(!currentName.empty()) - { - if(!createProfile(currentName, currentConfig, currentOptions, currentSlice TSRMLS_CC)) - { - return false; - } - currentConfig.clear(); - currentOptions.clear(); - currentSlice.clear(); - } - - currentName = s.substr(beg, end - beg); - } - else - { - string::size_type end = s.find_first_of(delim + "=", beg); - assert(end != string::npos); - - string key = s.substr(beg, end - beg); - - end = s.find('=', end); - if(end == string::npos) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "invalid profile entry in file %s:\n%s\n", profiles, - line); - return false; - } - ++end; - - string value; - beg = s.find_first_not_of(delim, end); - if(beg != string::npos) - { - end = s.length(); - value = s.substr(beg, end - beg); - } - - if(key == "config" || key == "ice.config") - { - currentConfig = value; - } - else if(key == "options" || key == "ice.options") - { - currentOptions = value; - } - else if(key == "slice" || key == "ice.slice") - { - currentSlice = value; - } - else - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unknown profile entry in file %s:\n%s\n", profiles, - line); - return false; - } - - if(currentName.empty()) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "no section for profile entry in file %s:\n%s\n", - profiles, line); - return false; - } - } - } - - if(!currentName.empty() && !createProfile(currentName, currentConfig, currentOptions, currentSlice TSRMLS_CC)) - { - return false; - } - } - - return true; -} - -bool -IcePHP::profileShutdown(TSRMLS_D) -{ - for(map<string, Profile*>::iterator p = _profiles.begin(); p != _profiles.end(); ++p) - { - p->second->destroy(TSRMLS_C); - delete p->second; - } - - _profiles.clear(); - - return true; -} - -IcePHP::Profile::Profile(const string& name, const vector<Slice::UnitPtr>& units, const string& code, - const ClassMap& classes, const Ice::PropertiesPtr& properties) : - _name(name), _units(units), _code(code), _classes(classes), _properties(properties) -{ -} - -string -IcePHP::Profile::name() const -{ - return _name; -} - -string -IcePHP::Profile::code() const -{ - return _code; -} - -const IcePHP::Profile::ClassMap& -IcePHP::Profile::classes() const -{ - return _classes; -} - -Ice::PropertiesPtr -IcePHP::Profile::properties() const -{ - return _properties; -} - -Slice::TypePtr -IcePHP::Profile::lookupType(const string& id) const -{ - for(vector<Slice::UnitPtr>::const_iterator p = _units.begin(); p != _units.end(); ++p) - { - Slice::TypeList l = (*p)->lookupType(id, false); - if(!l.empty()) - { - return l.front(); - } - } - - return 0; -} - -Slice::ExceptionPtr -IcePHP::Profile::lookupException(const string& id) const -{ - for(vector<Slice::UnitPtr>::const_iterator p = _units.begin(); p != _units.end(); ++p) - { - Slice::ExceptionPtr ex = (*p)->lookupException(id, false); - if(ex) - { - return ex; - } - } - - return 0; -} - -void -IcePHP::Profile::destroy(TSRMLS_D) -{ - for(vector<Slice::UnitPtr>::iterator p = _units.begin(); p != _units.end(); ++p) - { - try - { - (*p)->destroy(); - } - catch(const IceUtil::Exception& ex) - { - ostringstream ostr; - ex.ice_print(ostr); - php_error_docref(0 TSRMLS_CC, E_ERROR, "error while destroying Slice parse tree:\n%s\n", - ostr.str().c_str()); - } - } -} - -static bool -do_load(const string& name, const Ice::StringSeq& args TSRMLS_DC) -{ - Profile* profile = static_cast<Profile*>(ICE_G(profile)); - - if(profile) - { - // - // A profile has already been loaded; raise Ice_ProfileAlreadyLoadedException. - // - zend_class_entry* cls = findClass("Ice_ProfileAlreadyLoadedException" TSRMLS_CC); - assert(cls); - - zval* zex; - MAKE_STD_ZVAL(zex); - if(object_init_ex(zex, cls) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return false; - } - - zend_throw_exception_object(zex TSRMLS_CC); - return false; - } - - string profileName = name; - if(profileName.empty()) - { - profileName = _defaultProfileName; - } - - // - // Compile the core types if necessary. We do this now so that the exceptions - // are available. - // - if(!findClass("Ice_Exception" TSRMLS_CC)) - { - if(zend_eval_string(const_cast<char*>(_coreTypes), 0, "__core" TSRMLS_CC) == FAILURE) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create core types:\n%s\n", _coreTypes); - return false; - } - } - - map<string, Profile*>::iterator p = _profiles.find(profileName); - if(p == _profiles.end()) - { - zend_class_entry* cls = findClass("Ice_ProfileNotFoundException" TSRMLS_CC); - assert(cls); - - zval* zex; - MAKE_STD_ZVAL(zex); - if(object_init_ex(zex, cls) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return false; - } - - // - // Set the name member. - // - zend_update_property_string(cls, zex, "name", sizeof("name") - 1, - const_cast<char*>(profileName.c_str()) TSRMLS_CC); - - zend_throw_exception_object(zex TSRMLS_CC); - return false; - } - profile = p->second; - - // - // Compile the user-defined types. - // - if(zend_eval_string(const_cast<char*>(profile->code().c_str()), 0, "__slice" TSRMLS_CC) == FAILURE) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create Slice types:\n%s\n", profile->code().c_str()); - return false; - } - - // - // Make a copy of the profile's properties, and include any command-line arguments. - // - Ice::PropertiesPtr properties = Ice::createProperties(); - properties->parseCommandLineOptions("", profile->properties()->getCommandLineOptions()); - properties->parseCommandLineOptions("", args); - ICE_G(properties) = new Ice::PropertiesPtr(properties); - - ICE_G(profile) = profile; - return true; -} - -ZEND_FUNCTION(Ice_stringVersion) -{ - if(ZEND_NUM_ARGS() != 0) - { - WRONG_PARAM_COUNT; - } - - string s = ICE_STRING_VERSION; - RETURN_STRINGL(const_cast<char*>(s.c_str()), s.length(), 1); -} - -ZEND_FUNCTION(Ice_intVersion) -{ - if(ZEND_NUM_ARGS() != 0) - { - WRONG_PARAM_COUNT; - } - - RETURN_LONG(ICE_INT_VERSION); -} - -ZEND_FUNCTION(Ice_loadProfile) -{ - 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; - } - - Ice::StringSeq args; - do_load(name, args TSRMLS_CC); -} - -ZEND_FUNCTION(Ice_loadProfileWithArgs) -{ - if(ZEND_NUM_ARGS() > 2) - { - WRONG_PARAM_COUNT; - } - - zval* zv; - char* name = ""; - int len; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|s", &zv, &name, &len) == FAILURE) - { - return; - } - - // - // Extract the command-line arguments from the array. - // - Ice::StringSeq args; - HashTable* arr = Z_ARRVAL_P(zv); - void* data; - HashPosition pos; - zend_hash_internal_pointer_reset_ex(arr, &pos); - while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) - { - zval** val = reinterpret_cast<zval**>(data); - if(Z_TYPE_PP(val) != IS_STRING) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "argument array must contain strings"); - return; - } - args.push_back(Z_STRVAL_PP(val)); - zend_hash_move_forward_ex(arr, &pos); - } - - do_load(name, args TSRMLS_CC); -} - -ZEND_FUNCTION(Ice_dumpProfile) -{ - Profile* profile = static_cast<Profile*>(ICE_G(profile)); - Ice::PropertiesPtr* properties = static_cast<Ice::PropertiesPtr*>(ICE_G(properties)); - - if(!profile) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "no profile has been loaded"); - return; - } - - ostringstream out; - out << "Ice profile: " << profile->name() << endl; - - Ice::PropertyDict props = (*properties)->getPropertiesForPrefix(""); - if(!props.empty()) - { - out << endl << "Ice configuration properties:" << endl << endl; - for(Ice::PropertyDict::iterator p = props.begin(); p != props.end(); ++p) - { - out << p->first << "=" << p->second << endl; - } - } - else - { - out << endl << "Ice configuration properties: <none>" << endl; - } - - string code = profile->code(); - if(!code.empty()) - { - out << endl << "PHP code for Slice types:" << endl << endl; - out << code; - } - else - { - out << endl << "PHP code for Slice types: <none>" << endl; - } - - string s = out.str(); - PUTS(s.c_str()); -} - -IcePHP::CodeVisitor::CodeVisitor(ostream& out, map<string, Slice::ClassDefPtr>& classes, bool suppressWarnings - TSRMLS_DC) : - _out(out), _classes(classes), _suppressWarnings(suppressWarnings) -{ -#ifdef ZTS - this->TSRMLS_C = TSRMLS_C; -#endif -} - -void -IcePHP::CodeVisitor::visitClassDecl(const Slice::ClassDeclPtr& p) -{ - Slice::ClassDefPtr def = p->definition(); - if(!def && !_suppressWarnings) - { - string scoped = p->scoped(); - php_error_docref(0 TSRMLS_CC, E_WARNING, "%s %s declared but not defined", - p->isInterface() ? "interface" : "class", scoped.c_str()); - } -} - -bool -IcePHP::CodeVisitor::visitClassDefStart(const Slice::ClassDefPtr& p) -{ - string flat = flatten(p->scoped()); - - _classes[flat] = p; - - Slice::ClassList bases = p->bases(); - Slice::ClassDefPtr base; - - if(p->isInterface()) - { - _out << "if(!interface_exists(\"" << flat << "\"))" << endl; - _out << "{" << endl; - _out << "interface " << flat; - if(!bases.empty()) - { - _out << " extends "; - for(Slice::ClassList::iterator q = bases.begin(); q != bases.end(); ++q) - { - if(q != bases.begin()) - { - _out << ","; - } - _out << flatten((*q)->scoped()); - } - } - else if(!p->isLocal()) - { - _out << " extends Ice_Object"; - } - } - else - { - _out << "if(!class_exists(\"" << flat << "\"))" << endl; - _out << "{" << endl; - if(p->isAbstract()) - { - _out << "abstract "; - } - _out << "class " << flat; - if(!bases.empty() && !bases.front()->isInterface()) - { - _out << " extends " << flatten(bases.front()->scoped()); - base = bases.front(); - bases.pop_front(); - } - else if(!p->isLocal()) - { - _out << " extends Ice_ObjectImpl"; - } - if(!bases.empty()) - { - _out << " implements "; - for(Slice::ClassList::iterator q = bases.begin(); q != bases.end(); ++q) - { - if(q != bases.begin()) - { - _out << ","; - } - _out << flatten((*q)->scoped()); - } - } - } - - _out << endl << '{' << endl; - - if(!p->isInterface()) - { - Slice::DataMemberList baseMembers; - if(base) - { - baseMembers = base->allDataMembers(); - } - - Slice::DataMemberList members = p->dataMembers(); - Slice::DataMemberList::const_iterator q; - - // - // Generate a constructor. - // - _out << "function __construct("; - for(q = baseMembers.begin(); q != baseMembers.end(); ++q) - { - if(q != baseMembers.begin()) - { - _out << ", "; - } - writeConstructorParameter(*q); - } - for(q = members.begin(); q != members.end(); ++q) - { - if(!baseMembers.empty() || q != members.begin()) - { - _out << ", "; - } - writeConstructorParameter(*q); - } - _out << ')' << endl; - _out << '{' << endl; - if(base) - { - _out << " parent::__construct("; - for(q = baseMembers.begin(); q != baseMembers.end(); ++q) - { - if(q != baseMembers.begin()) - { - _out << ", "; - } - _out << '$' << fixIdent((*q)->name()); - } - _out << ");" << endl; - } - for(q = members.begin(); q != members.end(); ++q) - { - writeConstructorAssignment(*q); - } - _out << "}" << endl; - } - - return true; -} - -void -IcePHP::CodeVisitor::visitClassDefEnd(const Slice::ClassDefPtr& p) -{ - _out << '}' << endl; - _out << '}' << endl; // interface_exists/class_exists -} - -bool -IcePHP::CodeVisitor::visitExceptionStart(const Slice::ExceptionPtr& p) -{ - string flat = flatten(p->scoped()); - Slice::ExceptionPtr base = p->base(); - - _out << "if(!class_exists(\"" << flat << "\"))" << endl; - _out << "{" << endl; - _out << "class " << flat << " extends "; - string baseName; - if(!base) - { - if(p->isLocal()) - { - baseName = "Ice_LocalException"; - } - else - { - baseName = "Ice_UserException"; - } - } - else - { - baseName = flatten(base->scoped()); - } - - _out << baseName << endl << '{' << endl; - - Slice::DataMemberList baseMembers; - if(base) - { - baseMembers = base->allDataMembers(); - } - - Slice::DataMemberList members = p->dataMembers(); - Slice::DataMemberList::const_iterator q; - - // - // Generate a constructor. - // - _out << "function __construct($_message=''"; - for(q = baseMembers.begin(); q != baseMembers.end(); ++q) - { - _out << ", "; - writeConstructorParameter(*q); - } - for(q = members.begin(); q != members.end(); ++q) - { - _out << ", "; - writeConstructorParameter(*q); - } - _out << ')' << endl; - _out << '{' << endl; - _out << " " << baseName << "::__construct($_message"; - for(q = baseMembers.begin(); q != baseMembers.end(); ++q) - { - _out << ", $" << fixIdent((*q)->name()); - } - _out << ");" << endl; - for(q = members.begin(); q != members.end(); ++q) - { - writeConstructorAssignment(*q); - } - _out << "}" << endl; - - return true; -} - -void -IcePHP::CodeVisitor::visitExceptionEnd(const Slice::ExceptionPtr& p) -{ - _out << '}' << endl; - _out << '}' << endl; // class_exists -} - -bool -IcePHP::CodeVisitor::visitStructStart(const Slice::StructPtr& p) -{ - string flat = flatten(p->scoped()); - - _out << "if(!class_exists(\"" << flat << "\"))" << endl; - _out << "{" << endl; - _out << "class " << flatten(p->scoped()) << endl; - _out << '{' << endl; - - // - // Generate a constructor. - // - Slice::DataMemberList members = p->dataMembers(); - Slice::DataMemberList::const_iterator q; - _out << "function __construct("; - for(q = members.begin(); q != members.end(); ++q) - { - if(q != members.begin()) - { - _out << ", "; - } - writeConstructorParameter(*q); - } - _out << ')' << endl; - _out << '{' << endl; - for(q = members.begin(); q != members.end(); ++q) - { - writeConstructorAssignment(*q); - } - _out << '}' << endl; - - return true; -} - -void -IcePHP::CodeVisitor::visitStructEnd(const Slice::StructPtr& p) -{ - _out << '}' << endl; - _out << '}' << endl; // class_exists -} - -void -IcePHP::CodeVisitor::visitOperation(const Slice::OperationPtr& p) -{ - string name = fixIdent(p->name()); - - Slice::ParamDeclList params = p->parameters(); - - Slice::ClassDefPtr cl = Slice::ClassDefPtr::dynamicCast(p->container()); - assert(cl); - - if(!cl->isInterface()) - { - _out << "abstract "; - } - _out << "function " << name << '('; - for(Slice::ParamDeclList::const_iterator q = params.begin(); q != params.end(); ++q) - { - Slice::ParamDeclPtr param = *q; - if(q != params.begin()) - { - _out << ", "; - } - if(param->isOutParam()) - { - _out << '&'; - } - else - { - string hint = getTypeHint(param->type()); - if(!hint.empty()) - { - _out << hint << ' '; - } - } - _out << '$' << fixIdent(param->name()); - } - _out << ");" << endl; -} - -void -IcePHP::CodeVisitor::visitDataMember(const Slice::DataMemberPtr& p) -{ - Slice::ContainedPtr cont = Slice::ContainedPtr::dynamicCast(p->container()); - assert(cont); - if(Slice::ClassDefPtr::dynamicCast(cont) && (cont->hasMetaData("protected") || p->hasMetaData("protected"))) - { - _out << "protected $" << fixIdent(p->name()) << ';' << endl; - } - else - { - _out << "public $" << fixIdent(p->name()) << ';' << endl; - } -} - -void -IcePHP::CodeVisitor::visitDictionary(const Slice::DictionaryPtr& p) -{ - Slice::TypePtr keyType = p->keyType(); - if(!isNativeKey(keyType) && !_suppressWarnings) - { - // - // TODO: Generate class. - // - string scoped = p->scoped(); - php_error_docref(0 TSRMLS_CC, E_WARNING, "skipping dictionary %s - unsupported key type", scoped.c_str()); - } -} - -void -IcePHP::CodeVisitor::visitEnum(const Slice::EnumPtr& p) -{ - string flat = flatten(p->scoped()); - - _out << "if(!class_exists(\"" << flat << "\"))" << endl; - _out << "{" << endl; - _out << "class " << flat << endl; - _out << '{' << endl; - - // - // Create a class constant for each enumerator. - // - Slice::EnumeratorList l = p->getEnumerators(); - Slice::EnumeratorList::const_iterator q; - long i; - for(q = l.begin(), i = 0; q != l.end(); ++q, ++i) - { - string name = fixIdent((*q)->name()); - _out << " const " << fixIdent((*q)->name()) << " = " << i << ';' << endl; - } - - _out << '}' << endl; - _out << '}' << endl; // class_exists -} - -void -IcePHP::CodeVisitor::visitConst(const Slice::ConstPtr& p) -{ - string flat = flatten(p->scoped()); - Slice::TypePtr type = p->type(); - string value = p->value(); - - _out << "if(!defined(\"" << flat << "\"))" << endl; - _out << "{" << endl; - _out << "define(\"" << flat << "\", "; - - Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type); - Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(type); - if(b) - { - switch(b->kind()) - { - case Slice::Builtin::KindBool: - case Slice::Builtin::KindByte: - case Slice::Builtin::KindShort: - case Slice::Builtin::KindInt: - case Slice::Builtin::KindFloat: - case Slice::Builtin::KindDouble: - _out << value; - break; - - case Slice::Builtin::KindLong: - { - IceUtil::Int64 l; - IceUtilInternal::stringToInt64(value, l); - // - // The platform's 'long' type may not be 64 bits, so we store 64-bit - // values as a string. - // - if(sizeof(IceUtil::Int64) > sizeof(long) && (l < LONG_MIN || l > LONG_MAX)) - { - _out << "\"" << value << "\";"; - } - else - { - _out << value; - } - break; - } - - case Slice::Builtin::KindString: - { - // - // Expand strings into the basic source character set. We can't use isalpha() and the like - // here because they are sensitive to the current locale. - // - static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789" - "_{}[]#()<>%:;,?*+=/^&|~!=,\\' \t"; - static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end()); - - _out << "\""; // Opening " - - ios_base::fmtflags originalFlags = _out.flags(); // Save stream state - streamsize originalWidth = _out.width(); - ostream::char_type originalFill = _out.fill(); - - for(string::const_iterator c = value.begin(); c != value.end(); ++c) - { - if(*c == '$') - { - _out << "\\$"; - } - else if(*c == '"') - { - _out << "\\\""; - } - else if(charSet.find(*c) == charSet.end()) - { - unsigned char uc = *c; // char may be signed, so make it positive - _out << "\\"; // Print as octal if not in basic source character set - _out.flags(ios_base::oct); - _out.width(3); - _out.fill('0'); - _out << static_cast<unsigned>(uc); - } - else - { - _out << *c; // Print normally if in basic source character set - } - } - - _out.fill(originalFill); // Restore stream state - _out.width(originalWidth); - _out.flags(originalFlags); - - _out << "\""; // Closing " - - break; - } - - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - assert(false); - } - } - else if(en) - { - string::size_type colon = value.rfind(':'); - if(colon != string::npos) - { - value = value.substr(colon + 1); - } - Slice::EnumeratorList l = en->getEnumerators(); - Slice::EnumeratorList::iterator q; - for(q = l.begin(); q != l.end(); ++q) - { - if((*q)->name() == value) - { - _out << flatten(en->scoped()) << "::" << fixIdent(value); - break; - } - } - } - - _out << ");" << endl; - _out << "}" << endl; // defined -} - -string -IcePHP::CodeVisitor::getTypeHint(const Slice::TypePtr& type) -{ - // - // Currently, the Zend engine does not allow an argument with a type hint to have - // a value of null, therefore we can only use type hints for structs. - // - Slice::StructPtr st = Slice::StructPtr::dynamicCast(type); - if(st) - { - return flatten(st->scoped()); - } - - return string(); -} - -string -IcePHP::CodeVisitor::getDefaultValue(const Slice::TypePtr& type) -{ - Slice::BuiltinPtr builtin = Slice::BuiltinPtr::dynamicCast(type); - if(builtin) - { - switch(builtin->kind()) - { - case Slice::Builtin::KindByte: - case Slice::Builtin::KindShort: - case Slice::Builtin::KindInt: - case Slice::Builtin::KindLong: - return "0"; - - case Slice::Builtin::KindBool: - return "false"; - - case Slice::Builtin::KindFloat: - case Slice::Builtin::KindDouble: - return "0.0"; - - case Slice::Builtin::KindString: - return "''"; - - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - return "null"; - } - } - - Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(type); - if(en) - { - // - // Use the first enumerator. - // - string flat = flatten(en->scoped()); - Slice::EnumeratorList l = en->getEnumerators(); - string name = fixIdent(l.front()->name()); - return flat + "::" + name; - } - - Slice::StructPtr str = Slice::StructPtr::dynamicCast(type); - if(str) - { - return "new " + flatten(str->scoped()) + "()"; - } - - return "null"; -} - -void -IcePHP::CodeVisitor::writeConstructorParameter(const Slice::DataMemberPtr& member) -{ - _out << '$' << fixIdent(member->name()) << '='; - // - // Structure types must be handled specially. - // - if(Slice::StructPtr::dynamicCast(member->type())) - { - // - // If a data member is a structure, we want to initialize it to a new instance of the - // structure type. However, PHP does not allow a call to "new" in the default value of - // a function argument, so we assign a marker value now and create the instance in the - // constructor body. - // - _out << "-1"; - } - else - { - _out << getDefaultValue(member->type()); - } -} - -void -IcePHP::CodeVisitor::writeConstructorAssignment(const Slice::DataMemberPtr& member) -{ - // - // Structure types are instantiated in the constructor body. - // - string name = fixIdent(member->name()); - if(Slice::StructPtr::dynamicCast(member->type())) - { - _out << " $this->" << name << " = $" << name << " == -1 ? " << getDefaultValue(member->type()) - << " : $" << name << ';' << endl; - } - else - { - _out << " $this->" << name << " = $" << name << ';' << endl; - } -} diff --git a/php/src/IcePHP/Profile.h b/php/src/IcePHP/Profile.h deleted file mode 100644 index 32ff4b241ab..00000000000 --- a/php/src/IcePHP/Profile.h +++ /dev/null @@ -1,74 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2009 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. -// -// ********************************************************************** - -#ifndef ICE_PHP_PROFILE_H -#define ICE_PHP_PROFILE_H - -#include <Config.h> - -// -// Global functions. -// -extern "C" -{ -ZEND_FUNCTION(Ice_stringVersion); -ZEND_FUNCTION(Ice_intVersion); -ZEND_FUNCTION(Ice_loadProfile); -ZEND_FUNCTION(Ice_loadProfileWithArgs); -ZEND_FUNCTION(Ice_dumpProfile); -} - -#define ICE_PHP_PROFILE_FUNCTIONS \ - ZEND_FE(Ice_stringVersion, NULL) \ - ZEND_FE(Ice_intVersion, NULL) \ - ZEND_FE(Ice_loadProfile, NULL) \ - ZEND_FE(Ice_loadProfileWithArgs, NULL) \ - ZEND_FE(Ice_dumpProfile, NULL) - -namespace IcePHP -{ - -bool profileInit(TSRMLS_D); -bool profileShutdown(TSRMLS_D); - -// -// Profile contains information about an Ice configuration. A pointer to a Profile instance -// is stored in the PHP globals (see php_ice.h) when a script invokes Ice_loadProfile(). -// -class Profile -{ -public: - - typedef std::map<std::string, Slice::ClassDefPtr> ClassMap; - - Profile(const std::string&, const std::vector<Slice::UnitPtr>&, const std::string&, const ClassMap&, - const Ice::PropertiesPtr&); - - std::string name() const; - std::string code() const; - const ClassMap& classes() const; - Ice::PropertiesPtr properties() const; - - Slice::TypePtr lookupType(const std::string&) const; - Slice::ExceptionPtr lookupException(const std::string&) const; - - void destroy(TSRMLS_D); - -private: - - std::string _name; // The profile name - std::vector<Slice::UnitPtr> _units; // The parsed Slice files - std::string _code; // PHP code generated from Slice types - ClassMap _classes; // Associates flattened type ids to their ClassDefs - Ice::PropertiesPtr _properties; // Configuration properties -}; - -} // End of namespace IcePHP - -#endif diff --git a/php/src/IcePHP/Properties.cpp b/php/src/IcePHP/Properties.cpp new file mode 100644 index 00000000000..24bba29c2c1 --- /dev/null +++ b/php/src/IcePHP/Properties.cpp @@ -0,0 +1,671 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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 <Properties.h> +#include <Util.h> + +using namespace std; +using namespace IcePHP; + +ZEND_EXTERN_MODULE_GLOBALS(ice) + +// +// Class entries represent the PHP class implementations we have registered. +// +namespace IcePHP +{ +zend_class_entry* propertiesClassEntry = 0; +} + +// +// Properties support. +// +static zend_object_handlers _handlers; + +extern "C" +{ +static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC); +static void handleFreeStorage(void* TSRMLS_DC); +static zend_object_value handleClone(zval* TSRMLS_DC); +} + +ZEND_METHOD(Ice_Properties, __construct) +{ + runtimeError("properties objects cannot be instantiated, use createProperties()" TSRMLS_CC); +} + +ZEND_METHOD(Ice_Properties, __toString) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + Ice::PropertyDict val = _this->getPropertiesForPrefix(""); + string str; + for(Ice::PropertyDict::const_iterator p = val.begin(); p != val.end(); ++p) + { + if(p != val.begin()) + { + str.append("\n"); + } + str.append(p->first + "=" + p->second); + } + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, getProperty) +{ + char* name; + int nameLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &nameLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string propName(name, nameLen); + try + { + string val = _this->getProperty(propName); + RETURN_STRINGL(STRCAST(val.c_str()), val.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, getPropertyWithDefault) +{ + char* name; + int nameLen; + char* def; + int defLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss!", &name, &nameLen, &def, &defLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string propName(name, nameLen); + string defaultValue; + if(def) + { + defaultValue = string(def, defLen); + } + + try + { + string val = _this->getPropertyWithDefault(propName, defaultValue); + RETURN_STRINGL(STRCAST(val.c_str()), val.length(), 1); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, getPropertyAsInt) +{ + char* name; + int nameLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &nameLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string propName(name, nameLen); + try + { + Ice::Int val = _this->getPropertyAsInt(propName); + RETURN_LONG(static_cast<long>(val)); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, getPropertyAsIntWithDefault) +{ + char* name; + int nameLen; + long def; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name, &nameLen, &def) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string propName(name, nameLen); + try + { + Ice::Int val = _this->getPropertyAsIntWithDefault(propName, def); + RETURN_LONG(static_cast<long>(val)); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, getPropertyAsList) +{ + char* name; + int nameLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &nameLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string propName(name, nameLen); + try + { + Ice::StringSeq val = _this->getPropertyAsList(propName); + if(!createStringArray(return_value, val TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, getPropertyAsListWithDefault) +{ + char* name; + int nameLen; + zval* def; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa!", &name, &nameLen, &def) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string propName(name, nameLen); + Ice::StringSeq defaultValue; + if(def && !extractStringArray(def, defaultValue TSRMLS_CC)) + { + RETURN_NULL(); + } + + try + { + Ice::StringSeq val = _this->getPropertyAsListWithDefault(propName, defaultValue); + if(!createStringArray(return_value, val TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, getPropertiesForPrefix) +{ + char* p; + int pLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &p, &pLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string prefix; + if(p) + { + prefix = string(p, pLen); + } + + try + { + Ice::PropertyDict val = _this->getPropertiesForPrefix(prefix); + if(!createStringMap(return_value, val TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, setProperty) +{ + char* name; + int nameLen; + char* val; + int valLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss!", &name, &nameLen, &val, &valLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string propName(name, nameLen); + string propValue; + if(val) + { + propValue = string(val, valLen); + } + + try + { + _this->setProperty(propName, propValue); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, getCommandLineOptions) +{ + if(ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + Ice::StringSeq val = _this->getCommandLineOptions(); + if(!createStringArray(return_value, val TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, parseCommandLineOptions) +{ + char* p; + int pLen; + zval* opts; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!a!", &p, &pLen, &opts) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string prefix; + if(p) + { + prefix = string(p, pLen); + } + Ice::StringSeq options; + if(opts && !extractStringArray(opts, options TSRMLS_CC)) + { + RETURN_NULL(); + } + + try + { + Ice::StringSeq val = _this->parseCommandLineOptions(prefix, options); + if(!createStringArray(return_value, val TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, parseIceCommandLineOptions) +{ + zval* opts; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!", &opts) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + Ice::StringSeq options; + if(opts && !extractStringArray(opts, options TSRMLS_CC)) + { + RETURN_NULL(); + } + + try + { + Ice::StringSeq val = _this->parseIceCommandLineOptions(options); + if(!createStringArray(return_value, val TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, load) +{ + char* f; + int fLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &f, &fLen) == FAILURE) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + string file(f, fLen); + + try + { + _this->load(file); + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +ZEND_METHOD(Ice_Properties, clone) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC); + assert(_this); + + try + { + Ice::PropertiesPtr pclone = _this->clone(); + + if(!createProperties(return_value, pclone TSRMLS_CC)) + { + RETURN_NULL(); + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + Wrapper<Ice::PropertiesPtr>* obj = Wrapper<Ice::PropertiesPtr>::create(ce TSRMLS_CC); + assert(obj); + + result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC); + result.handlers = &_handlers; + + return result; +} + +#ifdef _WIN32 +extern "C" +#endif +static void +handleFreeStorage(void* p TSRMLS_DC) +{ + Wrapper<Ice::PropertiesPtr>* obj = static_cast<Wrapper<Ice::PropertiesPtr>*>(p); + delete obj->ptr; + zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleClone(zval* zv TSRMLS_DC) +{ + zend_object_value result; + memset(&result, 0, sizeof(zend_object_value)); + + Ice::PropertiesPtr p = Wrapper<Ice::PropertiesPtr>::value(zv TSRMLS_CC); + assert(p); + + Ice::PropertiesPtr pclone = p->clone(); + + zval* clone; + MAKE_STD_ZVAL(clone); + if(!createProperties(clone, pclone TSRMLS_CC)) + { + return result; + } + + // + // 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; +} + +ZEND_FUNCTION(Ice_createProperties) +{ + zval* arglist = 0; + zval* defaultsObj = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!O!", &arglist, &defaultsObj, propertiesClassEntry) == + FAILURE) + { + RETURN_NULL(); + } + + Ice::StringSeq seq; + if(arglist && !extractStringArray(arglist, seq TSRMLS_CC)) + { + RETURN_NULL(); + } + + Ice::PropertiesPtr defaults; + if(defaultsObj && !fetchProperties(defaultsObj, defaults TSRMLS_CC)) + { + RETURN_NULL(); + } + + try + { + Ice::PropertiesPtr props = Ice::createProperties(seq, defaults); + if(!createProperties(return_value, props TSRMLS_CC)) + { + RETURN_NULL(); + } + + if(arglist && PZVAL_IS_REF(arglist)) + { + zval_dtor(arglist); + if(!createStringArray(arglist, seq TSRMLS_CC)) + { + RETURN_NULL(); + } + } + } + catch(const IceUtil::Exception& ex) + { + throwException(ex TSRMLS_CC); + RETURN_NULL(); + } +} + +// +// Predefined methods for Properties. +// +static function_entry _interfaceMethods[] = +{ + {0, 0, 0} +}; +static function_entry _classMethods[] = +{ + ZEND_ME(Ice_Properties, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) + ZEND_ME(Ice_Properties, __toString, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, getProperty, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, getPropertyWithDefault, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, getPropertyAsInt, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, getPropertyAsIntWithDefault, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, getPropertyAsList, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, getPropertyAsListWithDefault, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, getPropertiesForPrefix, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, setProperty, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, getCommandLineOptions, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, parseCommandLineOptions, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, parseIceCommandLineOptions, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, load, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Properties, clone, NULL, ZEND_ACC_PUBLIC) + {0, 0, 0} +}; + +bool +IcePHP::propertiesInit(TSRMLS_D) +{ + // + // We register an interface and a class that implements the interface. This allows + // applications to safely include the Slice-generated code for the type. + // + + // + // Register the Properties interface. + // + zend_class_entry ce; +#ifdef ICEPHP_USE_NAMESPACES + INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Properties"), _interfaceMethods); +#else + INIT_CLASS_ENTRY(ce, "Ice_Properties", _interfaceMethods); +#endif + zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC); + + // + // Register the Properties class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_Properties", _classMethods); + ce.create_object = handleAlloc; + propertiesClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + _handlers.clone_obj = handleClone; + zend_class_implements(propertiesClassEntry TSRMLS_CC, 1, interface); + + return true; +} + +bool +IcePHP::createProperties(zval* zv, const Ice::PropertiesPtr& p TSRMLS_DC) +{ + if(object_init_ex(zv, propertiesClassEntry) != SUCCESS) + { + runtimeError("unable to initialize properties object" TSRMLS_CC); + return false; + } + + Wrapper<Ice::PropertiesPtr>* obj = Wrapper<Ice::PropertiesPtr>::extract(zv TSRMLS_CC); + assert(!obj->ptr); + obj->ptr = new Ice::PropertiesPtr(p); + + return true; +} + +bool +IcePHP::fetchProperties(zval* zv, Ice::PropertiesPtr& p TSRMLS_DC) +{ + if(!ZVAL_IS_NULL(zv)) + { + if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != propertiesClassEntry) + { + invalidArgument("value is not a properties object" TSRMLS_CC); + return false; + } + p = Wrapper<Ice::PropertiesPtr>::value(zv TSRMLS_CC); + if(!p) + { + runtimeError("unable to retrieve properties object from object store" TSRMLS_CC); + return false; + } + } + return true; +} diff --git a/php/src/IcePHP/Properties.h b/php/src/IcePHP/Properties.h new file mode 100644 index 00000000000..4124ff3659e --- /dev/null +++ b/php/src/IcePHP/Properties.h @@ -0,0 +1,48 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef ICEPHP_PROPERTIES_H +#define ICEPHP_PROPERTIES_H + +#include <Config.h> + +// +// Global functions. +// +extern "C" +{ +ZEND_FUNCTION(Ice_createProperties); +} + +#define ICEPHP_PROPERTIES_FUNCTIONS \ + ZEND_FE(Ice_createProperties, NULL) + +#ifdef ICEPHP_USE_NAMESPACES +# define ICEPHP_PROPERTIES_NS_FUNCTIONS \ + ZEND_NS_FALIAS("Ice", createProperties, Ice_createProperties, NULL) +#else +# define ICEPHP_PROPERTIES_NS_FUNCTIONS +#endif + +namespace IcePHP +{ + +bool propertiesInit(TSRMLS_D); + +bool createProperties(zval*, const Ice::PropertiesPtr& TSRMLS_DC); +bool fetchProperties(zval*, Ice::PropertiesPtr& TSRMLS_DC); + +// +// Class entry. +// +extern zend_class_entry* propertiesClassEntry; + +} // End of namespace IcePHP + +#endif diff --git a/php/src/IcePHP/Proxy.cpp b/php/src/IcePHP/Proxy.cpp index 9b22aca798e..65bb3cd9e6d 100644 --- a/php/src/IcePHP/Proxy.cpp +++ b/php/src/IcePHP/Proxy.cpp @@ -7,11 +7,9 @@ // // ********************************************************************** -#include <IceUtil/DisableWarnings.h> #include <Proxy.h> -#include <Communicator.h> -#include <Marshal.h> -#include <Profile.h> +#include <Connection.h> +#include <Endpoint.h> #include <Util.h> using namespace std; @@ -22,28 +20,25 @@ 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, +// A single PHP class, 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 +// are created for proxies, because all marshaling activity is driven by the type // 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 +// In order to perform a checked or unchecked cast, the generated code 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 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 +// Naturally, there are many predefined proxy methods (e.g., ice_getIdentity, 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. +// on the proxy object. // // @@ -52,346 +47,73 @@ ZEND_EXTERN_MODULE_GLOBALS(ice) namespace IcePHP { zend_class_entry* proxyClassEntry = 0; -zend_class_entry* endpointClassEntry = 0; -zend_class_entry* connectionClassEntry = 0; } // -// Ice::ObjectPrx and Ice::Endpoint support. +// Ice::ObjectPrx support. // -static zend_object_handlers _proxyHandlers; -static zend_object_handlers _endpointHandlers; -static zend_object_handlers _connectionHandlers; +static zend_object_handlers _handlers; 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); +static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC); +static void handleFreeStorage(void* TSRMLS_DC); +static zend_object_value handleClone(zval* TSRMLS_DC); +static union _zend_function* handleGetMethod(zval**, char*, int TSRMLS_DC); +static int handleCompare(zval*, zval* TSRMLS_DC); } -static bool lookupClass(const string&, Slice::ClassDefPtr& TSRMLS_DC); +static ClassInfoPtr lookupClass(const string& 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 +class Proxy : public IceUtil::Shared { 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&); + Proxy(const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC); + ~Proxy(); - string toString() const; + bool clone(zval*, const Ice::ObjectPrx& TSRMLS_DC); + bool cloneUntyped(zval*, const Ice::ObjectPrx& TSRMLS_DC); + static bool create(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC); -private: - Ice::ObjectPrx _proxy; - Slice::ClassDefPtr _class; -#ifdef ZTS + Ice::ObjectPrx proxy; + ClassInfoPtr info; + CommunicatorInfoPtr communicator; + zval* connection; + zval* cachedConnection; +#if ZTS TSRMLS_D; #endif - zval _communicatorZval; - Ice::CommunicatorPtr _communicator; - Slice::OperationList _classOps; - map<string, OperationPtr> _ops; }; +typedef IceUtil::Handle<Proxy> ProxyPtr; } // End of namespace IcePHP -// -// Predefined methods for Ice_ObjectPrx. -// -static function_entry _proxyMethods[] = -{ - {"__construct", PHP_FN(Ice_ObjectPrx___construct), 0}, - {"__tostring", PHP_FN(Ice_ObjectPrx___tostring), 0}, - {"ice_getCommunicator", PHP_FN(Ice_ObjectPrx_ice_getCommunicator), 0}, - {"ice_toString", PHP_FN(Ice_ObjectPrx_ice_toString), 0}, - {"ice_isA", PHP_FN(Ice_ObjectPrx_ice_isA), 0}, - {"ice_ping", PHP_FN(Ice_ObjectPrx_ice_ping), 0}, - {"ice_id", PHP_FN(Ice_ObjectPrx_ice_id), 0}, - {"ice_ids", PHP_FN(Ice_ObjectPrx_ice_ids), 0}, - {"ice_getIdentity", PHP_FN(Ice_ObjectPrx_ice_getIdentity), 0}, - {"ice_newIdentity", PHP_FN(Ice_ObjectPrx_ice_identity), 0}, - {"ice_identity", PHP_FN(Ice_ObjectPrx_ice_identity), 0}, - {"ice_getContext", PHP_FN(Ice_ObjectPrx_ice_getContext), 0}, - {"ice_newContext", PHP_FN(Ice_ObjectPrx_ice_context), 0}, - {"ice_context", PHP_FN(Ice_ObjectPrx_ice_context), 0}, - {"ice_getFacet", PHP_FN(Ice_ObjectPrx_ice_getFacet), 0}, - {"ice_newFacet", PHP_FN(Ice_ObjectPrx_ice_facet), 0}, - {"ice_facet", PHP_FN(Ice_ObjectPrx_ice_facet), 0}, - {"ice_getAdapterId", PHP_FN(Ice_ObjectPrx_ice_getAdapterId), 0}, - {"ice_newAdapterId", PHP_FN(Ice_ObjectPrx_ice_adapterId), 0}, - {"ice_adapterId", PHP_FN(Ice_ObjectPrx_ice_adapterId), 0}, - {"ice_getEndpoints", PHP_FN(Ice_ObjectPrx_ice_getEndpoints), 0}, - {"ice_newEndpoints", PHP_FN(Ice_ObjectPrx_ice_endpoints), 0}, - {"ice_endpoints", PHP_FN(Ice_ObjectPrx_ice_endpoints), 0}, - {"ice_getLocatorCacheTimeout", PHP_FN(Ice_ObjectPrx_ice_getLocatorCacheTimeout), 0}, - {"ice_locatorCacheTimeout", PHP_FN(Ice_ObjectPrx_ice_locatorCacheTimeout), 0}, - {"ice_isConnectionCached", PHP_FN(Ice_ObjectPrx_ice_isConnectionCached), 0}, - {"ice_connectionCached", PHP_FN(Ice_ObjectPrx_ice_connectionCached), 0}, - {"ice_getEndpointSelection", PHP_FN(Ice_ObjectPrx_ice_getEndpointSelection), 0}, - {"ice_endpointSelection", PHP_FN(Ice_ObjectPrx_ice_endpointSelection), 0}, - {"ice_isSecure", PHP_FN(Ice_ObjectPrx_ice_isSecure), 0}, - {"ice_secure", PHP_FN(Ice_ObjectPrx_ice_secure), 0}, - {"ice_isPreferSecure", PHP_FN(Ice_ObjectPrx_ice_isPreferSecure), 0}, - {"ice_preferSecure", PHP_FN(Ice_ObjectPrx_ice_preferSecure), 0}, - {"ice_getRouter", PHP_FN(Ice_ObjectPrx_ice_getRouter), 0}, - {"ice_router", PHP_FN(Ice_ObjectPrx_ice_router), 0}, - {"ice_getLocator", PHP_FN(Ice_ObjectPrx_ice_getLocator), 0}, - {"ice_locator", PHP_FN(Ice_ObjectPrx_ice_locator), 0}, - {"ice_twoway", PHP_FN(Ice_ObjectPrx_ice_twoway), 0}, - {"ice_isTwoway", PHP_FN(Ice_ObjectPrx_ice_isTwoway), 0}, - {"ice_oneway", PHP_FN(Ice_ObjectPrx_ice_oneway), 0}, - {"ice_isOneway", PHP_FN(Ice_ObjectPrx_ice_isOneway), 0}, - {"ice_batchOneway", PHP_FN(Ice_ObjectPrx_ice_batchOneway), 0}, - {"ice_isBatchOneway", PHP_FN(Ice_ObjectPrx_ice_isBatchOneway), 0}, - {"ice_datagram", PHP_FN(Ice_ObjectPrx_ice_datagram), 0}, - {"ice_isDatagram", PHP_FN(Ice_ObjectPrx_ice_isDatagram), 0}, - {"ice_batchDatagram", PHP_FN(Ice_ObjectPrx_ice_batchDatagram), 0}, - {"ice_isBatchDatagram", PHP_FN(Ice_ObjectPrx_ice_isBatchDatagram), 0}, - {"ice_compress", PHP_FN(Ice_ObjectPrx_ice_compress), 0}, - {"ice_timeout", PHP_FN(Ice_ObjectPrx_ice_timeout), 0}, - {"ice_connectionId", PHP_FN(Ice_ObjectPrx_ice_connectionId), 0}, - {"ice_getConnection", PHP_FN(Ice_ObjectPrx_ice_getConnection), 0}, - {"ice_getCachedConnection", PHP_FN(Ice_ObjectPrx_ice_getCachedConnection), 0}, - {"ice_uncheckedCast", PHP_FN(Ice_ObjectPrx_ice_uncheckedCast), 0}, - {"ice_checkedCast", PHP_FN(Ice_ObjectPrx_ice_checkedCast), 0}, - {0, 0, 0} -}; - -// -// Predefined methods for Ice_Endpoint. -// -static function_entry _endpointMethods[] = -{ - {"__construct", PHP_FN(Ice_Endpoint___construct), 0}, - {"__tostring", PHP_FN(Ice_Endpoint___tostring), 0}, - {"toString", PHP_FN(Ice_Endpoint_toString), 0}, - {0, 0, 0} -}; - -// -// Predefined methods for Ice_Connection. -// -static function_entry _connectionMethods[] = -{ - {"__construct", PHP_FN(Ice_Connection___construct), 0}, - {"__tostring", PHP_FN(Ice_Connection___tostring), 0}, - {"close", PHP_FN(Ice_Connection_close), 0}, - {"flushBatchRequests", PHP_FN(Ice_Connection_flushBatchRequests), 0}, - {"type", PHP_FN(Ice_Connection_type), 0}, - {"timeout", PHP_FN(Ice_Connection_timeout), 0}, - {"toString", PHP_FN(Ice_Connection_toString), 0}, - {0, 0, 0} -}; - -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(0 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(0 TSRMLS_CC, E_ERROR, "unable to retrieve proxy object from object store"); - return false; - } - if(Z_OBJCE_P(zv) != proxyClassEntry) - { - php_error_docref(0 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(0 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(0 TSRMLS_CC, E_ERROR, "unable to retrieve endpoint object from object store"); - return false; - } - if(Z_OBJCE_P(zv) != endpointClassEntry) - { - php_error_docref(0 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(0 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) +ZEND_METHOD(Ice_ObjectPrx, __construct) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "Ice_ObjectPrx cannot be instantiated, use $ICE->stringToProxy()"); + runtimeError("proxies cannot be instantiated, use stringToProxy()" TSRMLS_CC); } -ZEND_FUNCTION(Ice_ObjectPrx___tostring) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - string str = _this->toString(); - RETURN_STRINGL(const_cast<char*>(str.c_str()), str.length(), 1); + string str = _this->proxy->ice_toString(); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); } catch(const IceUtil::Exception& ex) { @@ -400,242 +122,43 @@ ZEND_FUNCTION(Ice_ObjectPrx___tostring) } } -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 = 0; - - 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) +ZEND_METHOD(Ice_ObjectPrx, ice_getCommunicator) { - if(ZEND_NUM_ARGS() > 1) - { - WRONG_PARAM_COUNT; - } - - zval* arr = 0; - - 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) + if(ZEND_NUM_ARGS() > 0) { WRONG_PARAM_COUNT; } - zval* arr = 0; - - 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); - 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(); - } + _this->communicator->getZval(return_value TSRMLS_CC); } -ZEND_FUNCTION(Ice_ObjectPrx_ice_ids) +ZEND_METHOD(Ice_ObjectPrx, ice_toString) { - if(ZEND_NUM_ARGS() > 1) - { - WRONG_PARAM_COUNT; - } - - zval* arr = 0; - - 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_MN(Ice_ObjectPrx___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU); } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getIdentity) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); - createIdentity(return_value, _this->getProxy()->ice_getIdentity() TSRMLS_CC); + createIdentity(return_value, _this->proxy->ice_getIdentity() TSRMLS_CC); } -ZEND_FUNCTION(Ice_ObjectPrx_ice_identity) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); - zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC); + zend_class_entry* cls = idToClass("::Ice::Identity" TSRMLS_CC); assert(cls); zval *zid; @@ -650,8 +173,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_identity) { try { - Ice::ObjectPrx prx = _this->getProxy()->ice_identity(id); - if(!createProxy(return_value, prx TSRMLS_CC)) + if(!_this->cloneUntyped(return_value, _this->proxy->ice_identity(id) TSRMLS_CC)) { RETURN_NULL(); } @@ -664,27 +186,24 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_identity) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getContext) +ZEND_METHOD(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); -} + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); -ZEND_FUNCTION(Ice_ObjectPrx_ice_context) -{ - if(ZEND_NUM_ARGS() != 1) + if(!createStringMap(return_value, _this->proxy->ice_getContext() TSRMLS_CC)) { - WRONG_PARAM_COUNT; + RETURN_NULL(); } +} +ZEND_METHOD(Ice_ObjectPrx, ice_context) +{ zval* arr = 0; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) @@ -696,19 +215,17 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_context) // Populate the context. // Ice::Context ctx; - if(arr && !extractContext(arr, ctx TSRMLS_CC)) + if(arr && !extractStringMap(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::ObjectPrx prx = _this->getProxy()->ice_context(ctx); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_context(ctx) TSRMLS_CC)) { RETURN_NULL(); } @@ -720,21 +237,20 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_context) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getFacet) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - string facet = _this->getProxy()->ice_getFacet(); - ZVAL_STRINGL(return_value, const_cast<char*>(facet.c_str()), facet.length(), 1); + string facet = _this->proxy->ice_getFacet(); + ZVAL_STRINGL(return_value, STRCAST(facet.c_str()), facet.length(), 1); } catch(const IceUtil::Exception& ex) { @@ -743,13 +259,8 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getFacet) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_facet) +ZEND_METHOD(Ice_ObjectPrx, ice_facet) { - if(ZEND_NUM_ARGS() != 1) - { - WRONG_PARAM_COUNT; - } - char* name; int len; @@ -758,14 +269,12 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_facet) 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::ObjectPrx prx = _this->getProxy()->ice_facet(name); - if(!createProxy(return_value, prx TSRMLS_CC)) + if(!_this->cloneUntyped(return_value, _this->proxy->ice_facet(name) TSRMLS_CC)) { RETURN_NULL(); } @@ -777,21 +286,20 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_facet) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getAdapterId) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - string id = _this->getProxy()->ice_getAdapterId(); - ZVAL_STRINGL(return_value, const_cast<char*>(id.c_str()), id.length(), 1); + string id = _this->proxy->ice_getAdapterId(); + ZVAL_STRINGL(return_value, STRCAST(id.c_str()), id.length(), 1); } catch(const IceUtil::Exception& ex) { @@ -800,16 +308,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getAdapterId) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_adapterId) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); char* id; int len; @@ -821,8 +323,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_adapterId) try { - Ice::ObjectPrx prx = _this->getProxy()->ice_adapterId(id); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_adapterId(id) TSRMLS_CC)) { RETURN_NULL(); } @@ -834,20 +335,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_adapterId) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpoints) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::EndpointSeq endpoints = _this->getProxy()->ice_getEndpoints(); + Ice::EndpointSeq endpoints = _this->proxy->ice_getEndpoints(); array_init(return_value); uint idx = 0; @@ -870,16 +370,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpoints) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); zval* zv; @@ -901,7 +395,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints) if(Z_TYPE_PP(val) != IS_OBJECT) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected an element of type Ice_Endpoint"); + runtimeError("expected an element of type Ice::Endpoint" TSRMLS_CC); RETURN_NULL(); } @@ -918,8 +412,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints) try { - Ice::ObjectPrx prx = _this->getProxy()->ice_endpoints(seq); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_endpoints(seq) TSRMLS_CC)) { RETURN_NULL(); } @@ -931,20 +424,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocatorCacheTimeout) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::Int timeout = _this->getProxy()->ice_getLocatorCacheTimeout(); + Ice::Int timeout = _this->proxy->ice_getLocatorCacheTimeout(); ZVAL_LONG(return_value, static_cast<long>(timeout)); } catch(const IceUtil::Exception& ex) @@ -954,16 +446,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocatorCacheTimeout) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_locatorCacheTimeout) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); long l; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &l) != SUCCESS) @@ -973,8 +459,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locatorCacheTimeout) try { - Ice::ObjectPrx prx = _this->getProxy()->ice_locatorCacheTimeout(l); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_locatorCacheTimeout(l) TSRMLS_CC)) { RETURN_NULL(); } @@ -986,20 +471,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locatorCacheTimeout) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_isConnectionCached) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - bool b = _this->getProxy()->ice_isConnectionCached(); + bool b = _this->proxy->ice_isConnectionCached(); ZVAL_BOOL(return_value, b ? 1 : 0); } catch(const IceUtil::Exception& ex) @@ -1009,16 +493,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isConnectionCached) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionCached) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); zend_bool b; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b) != SUCCESS) @@ -1028,8 +506,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionCached) try { - Ice::ObjectPrx prx = _this->getProxy()->ice_connectionCached(b ? true : false); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_connectionCached(b ? true : false) TSRMLS_CC)) { RETURN_NULL(); } @@ -1041,20 +518,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionCached) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpointSelection) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::EndpointSelectionType type = _this->getProxy()->ice_getEndpointSelection(); + Ice::EndpointSelectionType type = _this->proxy->ice_getEndpointSelection(); ZVAL_LONG(return_value, type == Ice::Random ? 0 : 1); } catch(const IceUtil::Exception& ex) @@ -1064,16 +540,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpointSelection) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_endpointSelection) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); long l; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &l) != SUCCESS) @@ -1083,14 +553,14 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpointSelection) if(l < 0 || l > 1) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "expecting Random or Ordered"); + runtimeError("expecting Random or Ordered" TSRMLS_CC); RETURN_NULL(); } try { - Ice::ObjectPrx prx = _this->getProxy()->ice_endpointSelection(l == 0 ? Ice::Random : Ice::Ordered); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + Ice::EndpointSelectionType type = l == 0 ? Ice::Random : Ice::Ordered; + if(!_this->clone(return_value, _this->proxy->ice_endpointSelection(type) TSRMLS_CC)) { RETURN_NULL(); } @@ -1102,20 +572,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpointSelection) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_isSecure) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - bool b = _this->getProxy()->ice_isSecure(); + bool b = _this->proxy->ice_isSecure(); RETURN_BOOL(b ? 1 : 0); } catch(const IceUtil::Exception& ex) @@ -1125,16 +594,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isSecure) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_secure) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); zend_bool b; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b TSRMLS_CC) != SUCCESS) @@ -1144,8 +607,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_secure) try { - Ice::ObjectPrx prx = _this->getProxy()->ice_secure(b ? true : false); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_secure(b ? true : false) TSRMLS_CC)) { RETURN_NULL(); } @@ -1157,20 +619,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_secure) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_isPreferSecure) +ZEND_METHOD(Ice_ObjectPrx, ice_isPreferSecure) { 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - bool b = _this->getProxy()->ice_isPreferSecure(); + bool b = _this->proxy->ice_isPreferSecure(); RETURN_BOOL(b ? 1 : 0); } catch(const IceUtil::Exception& ex) @@ -1180,16 +641,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isPreferSecure) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_preferSecure) +ZEND_METHOD(Ice_ObjectPrx, ice_preferSecure) { - 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); zend_bool b; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b TSRMLS_CC) != SUCCESS) @@ -1199,8 +654,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_preferSecure) try { - Ice::ObjectPrx prx = _this->getProxy()->ice_preferSecure(b ? true : false); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_preferSecure(b ? true : false) TSRMLS_CC)) { RETURN_NULL(); } @@ -1212,31 +666,30 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_preferSecure) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getRouter) +ZEND_METHOD(Ice_ObjectPrx, ice_getRouter) { 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::RouterPrx router = _this->getProxy()->ice_getRouter(); + Ice::RouterPrx router = _this->proxy->ice_getRouter(); if(router) { - Slice::ClassDefPtr def; - if(!lookupClass("Ice::Router", def TSRMLS_CC)) + ClassInfoPtr info = lookupClass("::Ice::Router" TSRMLS_CC); + if(!info) { RETURN_NULL(); } - assert(def); + assert(info); - if(!createProxy(return_value, router, def TSRMLS_CC)) + if(!createProxy(return_value, router, info, _this->communicator TSRMLS_CC)) { RETURN_NULL(); } @@ -1253,16 +706,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getRouter) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_router) +ZEND_METHOD(Ice_ObjectPrx, ice_router) { - 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); zval* zprx; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zprx, proxyClassEntry TSRMLS_CC) != SUCCESS) @@ -1271,7 +718,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_router) } Ice::ObjectPrx proxy; - Slice::ClassDefPtr def; + ClassInfoPtr def; if(zprx && !fetchProxy(zprx, proxy, def TSRMLS_CC)) { RETURN_NULL(); @@ -1282,7 +729,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_router) { if(!def || !def->isA("::Ice::Router")) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "ice_router requires a proxy narrowed to Ice::Router"); + runtimeError("ice_router requires a proxy narrowed to Ice::Router" TSRMLS_CC); RETURN_NULL(); } router = Ice::RouterPrx::uncheckedCast(proxy); @@ -1290,8 +737,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_router) try { - Ice::ObjectPrx prx = _this->getProxy()->ice_router(router); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_router(router) TSRMLS_CC)) { RETURN_NULL(); } @@ -1303,31 +749,28 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_router) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocator) +ZEND_METHOD(Ice_ObjectPrx, ice_getLocator) { 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::LocatorPrx locator = _this->getProxy()->ice_getLocator(); + Ice::LocatorPrx locator = _this->proxy->ice_getLocator(); if(locator) { - Slice::ClassDefPtr def; - if(!lookupClass("Ice::Locator", def TSRMLS_CC)) + ClassInfoPtr info = lookupClass("::Ice::Locator" TSRMLS_CC); + if(!info) { RETURN_NULL(); } - assert(def); - - if(!createProxy(return_value, locator, def TSRMLS_CC)) + if(!createProxy(return_value, locator, info, _this->communicator TSRMLS_CC)) { RETURN_NULL(); } @@ -1344,16 +787,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocator) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_locator) +ZEND_METHOD(Ice_ObjectPrx, ice_locator) { - 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); zval* zprx; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zprx, proxyClassEntry TSRMLS_CC) != SUCCESS) @@ -1362,7 +799,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locator) } Ice::ObjectPrx proxy; - Slice::ClassDefPtr def; + ClassInfoPtr def; if(zprx && !fetchProxy(zprx, proxy, def TSRMLS_CC)) { RETURN_NULL(); @@ -1373,7 +810,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locator) { if(!def || !def->isA("::Ice::Locator")) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "ice_locator requires a proxy narrowed to Ice::Locator"); + runtimeError("ice_locator requires a proxy narrowed to Ice::Locator" TSRMLS_CC); RETURN_NULL(); } locator = Ice::LocatorPrx::uncheckedCast(proxy); @@ -1381,8 +818,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locator) try { - Ice::ObjectPrx prx = _this->getProxy()->ice_locator(locator); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_locator(locator) TSRMLS_CC)) { RETURN_NULL(); } @@ -1394,21 +830,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locator) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_twoway) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::ObjectPrx prx = _this->getProxy()->ice_twoway(); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_twoway() TSRMLS_CC)) { RETURN_NULL(); } @@ -1420,20 +854,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_twoway) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_isTwoway) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - bool b = _this->getProxy()->ice_isTwoway(); + bool b = _this->proxy->ice_isTwoway(); RETURN_BOOL(b ? 1 : 0); } catch(const IceUtil::Exception& ex) @@ -1443,21 +876,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isTwoway) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_oneway) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::ObjectPrx prx = _this->getProxy()->ice_oneway(); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_oneway() TSRMLS_CC)) { RETURN_NULL(); } @@ -1469,20 +900,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_oneway) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_isOneway) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - bool b = _this->getProxy()->ice_isOneway(); + bool b = _this->proxy->ice_isOneway(); RETURN_BOOL(b ? 1 : 0); } catch(const IceUtil::Exception& ex) @@ -1492,21 +922,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isOneway) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_batchOneway) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::ObjectPrx prx = _this->getProxy()->ice_batchOneway(); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_batchOneway() TSRMLS_CC)) { RETURN_NULL(); } @@ -1518,20 +946,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_batchOneway) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchOneway) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - bool b = _this->getProxy()->ice_isBatchOneway(); + bool b = _this->proxy->ice_isBatchOneway(); RETURN_BOOL(b ? 1 : 0); } catch(const IceUtil::Exception& ex) @@ -1541,21 +968,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchOneway) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_datagram) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::ObjectPrx prx = _this->getProxy()->ice_datagram(); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_datagram() TSRMLS_CC)) { RETURN_NULL(); } @@ -1567,20 +992,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_datagram) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_isDatagram) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - bool b = _this->getProxy()->ice_isDatagram(); + bool b = _this->proxy->ice_isDatagram(); RETURN_BOOL(b ? 1 : 0); } catch(const IceUtil::Exception& ex) @@ -1590,21 +1014,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isDatagram) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_batchDatagram) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::ObjectPrx prx = _this->getProxy()->ice_batchDatagram(); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_batchDatagram() TSRMLS_CC)) { RETURN_NULL(); } @@ -1616,20 +1038,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_batchDatagram) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchDatagram) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - bool b = _this->getProxy()->ice_isBatchDatagram(); + bool b = _this->proxy->ice_isBatchDatagram(); RETURN_BOOL(b ? 1 : 0); } catch(const IceUtil::Exception& ex) @@ -1639,16 +1060,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchDatagram) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_compress) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); zend_bool b; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b) != SUCCESS) @@ -1658,8 +1073,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_compress) try { - Ice::ObjectPrx prx = _this->getProxy()->ice_compress(b ? true : false); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_compress(b ? true : false) TSRMLS_CC)) { RETURN_NULL(); } @@ -1671,16 +1085,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_compress) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { @@ -1690,8 +1098,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout) RETURN_NULL(); } // TODO: range check? - Ice::ObjectPrx prx = _this->getProxy()->ice_timeout(l); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_timeout(l) TSRMLS_CC)) { RETURN_NULL(); } @@ -1703,16 +1110,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionId) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { @@ -1722,8 +1123,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionId) { RETURN_NULL(); } - Ice::ObjectPrx prx = _this->getProxy()->ice_connectionId(id); - if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC)) + if(!_this->clone(return_value, _this->proxy->ice_connectionId(id) TSRMLS_CC)) { RETURN_NULL(); } @@ -1735,20 +1135,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionId) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getConnection) +ZEND_METHOD(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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::ConnectionPtr con = _this->getProxy()->ice_getConnection(); + Ice::ConnectionPtr con = _this->proxy->ice_getConnection(); if(!createConnection(return_value, con TSRMLS_CC)) { RETURN_NULL(); @@ -1761,20 +1160,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getConnection) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_getCachedConnection) +ZEND_METHOD(Ice_ObjectPrx, ice_getCachedConnection) { 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); try { - Ice::ConnectionPtr con = _this->getProxy()->ice_getCachedConnection(); + Ice::ConnectionPtr con = _this->proxy->ice_getCachedConnection(); if(!con || !createConnection(return_value, con TSRMLS_CC)) { RETURN_NULL(); @@ -1787,88 +1185,28 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getCachedConnection) } } -static bool -lookupClass(const string& id, Slice::ClassDefPtr& def TSRMLS_DC) +static ClassInfoPtr +lookupClass(const string& id TSRMLS_DC) { - def = 0; - - try + ClassInfoPtr info = getClassInfoById(id TSRMLS_CC); + if(!info) { - Slice::TypePtr type; - Profile* profile = static_cast<Profile*>(ICE_G(profile)); - if(profile) - { - type = profile->lookupType(id); - } - - if(!type) + if(!id.empty() && id[id.size() - 1] == '*') { - php_error_docref(0 TSRMLS_CC, E_ERROR, "no Slice definition found for type %s", id.c_str()); - return false; + info = getClassInfoById(id.substr(0, id.size() - 1) TSRMLS_CC); } + } - Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type); - if(b && b->kind() != Slice::Builtin::KindObject && b->kind() != Slice::Builtin::KindObjectProxy) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "type %s is not a class or interface", id.c_str()); - return false; - } - - if(!b) - { - // - // Allow the use of "::Type" (ClassDecl) or "::Type*" (Proxy). - // - Slice::ClassDeclPtr decl; - Slice::ProxyPtr proxy = Slice::ProxyPtr::dynamicCast(type); - if(proxy) - { - decl = proxy->_class(); - } - else - { - decl = Slice::ClassDeclPtr::dynamicCast(type); - } - - if(!decl) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "type %s is not a class or interface", id.c_str()); - return false; - } - - if(decl->isLocal()) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "%s is a local type", id.c_str()); - return false; - } - - def = decl->definition(); - if(!def) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "%s is declared but not defined", id.c_str()); - return false; - } - - 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(0 TSRMLS_CC, E_ERROR, "the Slice definition for type %s has not been compiled", - scoped.c_str()); - return false; - } - } + if(info && !info->defined) + { + runtimeError("%s is declared but not defined" TSRMLS_CC, id.c_str()); } - catch(const IceUtil::Exception& ex) + else if(!info) { - throwException(ex TSRMLS_CC); - return false; + runtimeError("no definition found for class or interface %s" TSRMLS_CC, id.c_str()); } - return true; + return info; } static void @@ -1889,11 +1227,11 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check) int facetLen; zval* arr = 0; - if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|sa", &id, &idLen, &facet, + if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|s!a!", &id, &idLen, &facet, &facetLen, &arr) == FAILURE) { facet = 0; - if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &id, &idLen, &arr) == + if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|a!", &id, &idLen, &arr) == FAILURE) { php_error(E_ERROR, "%s() requires a type id followed by an optional facet and/or context", @@ -1902,28 +1240,27 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check) } } - 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); + ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC); + assert(_this); // // Populate the context. // Ice::Context ctx; - if(arr && !extractContext(arr, ctx TSRMLS_CC)) + if(arr && !extractStringMap(arr, ctx TSRMLS_CC)) { RETURN_NULL(); } try { - Slice::ClassDefPtr def; - if(!lookupClass(id, def TSRMLS_CC)) + ClassInfoPtr info = lookupClass(id TSRMLS_CC); + if(!info) { RETURN_NULL(); } - Ice::ObjectPrx prx = _this->getProxy(); + Ice::ObjectPrx prx = _this->proxy; if(facet) { prx = prx->ice_facet(facet); @@ -1936,19 +1273,16 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check) if(check) { - string scoped = def ? def->declaration()->scoped() : "::Ice::Object"; - // - // Verify that the object supports the requested type. We don't use id here, - // because it might contain a proxy type (e.g., "::MyClass*"). + // Verify that the object supports the requested type. // - if(!prx->ice_isA(scoped)) + if(!prx->ice_isA(info->id)) { RETURN_NULL(); } } - if(!createProxy(return_value, prx, def TSRMLS_CC)) + if(!createProxy(return_value, prx, info, _this->communicator TSRMLS_CC)) { RETURN_NULL(); } @@ -1960,601 +1294,94 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check) } } -ZEND_FUNCTION(Ice_ObjectPrx_ice_uncheckedCast) +ZEND_METHOD(Ice_ObjectPrx, ice_uncheckedCast) { do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); } -ZEND_FUNCTION(Ice_ObjectPrx_ice_checkedCast) +ZEND_METHOD(Ice_ObjectPrx, ice_checkedCast) { do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } -ZEND_FUNCTION(Ice_Endpoint___construct) -{ - php_error_docref(0 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(0 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) +IcePHP::Proxy::Proxy(const Ice::ObjectPrx& p, const ClassInfoPtr& i, const CommunicatorInfoPtr& comm TSRMLS_DC) : + proxy(p), info(i), communicator(comm), connection(0), cachedConnection(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 = 0; - argInfo[i].class_name = 0; - 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 reinterpret_cast<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(0 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(0 TSRMLS_CC, E_ERROR, "unable to get arguments"); - return; - } - - // - // Verify that the zvals for out parameters are passed by reference. + // We want to ensure that the PHP object corresponding to the communicator is + // not destroyed until after this proxy is destroyed. // - for(i = static_cast<int>(_inParams.size()); i < numParams; ++i) - { - if(!PZVAL_IS_REF(*args[i])) - { - php_error_docref(0 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 AbortMarshaling&) - { - // - // We use AbortMarshaling to escape from any nesting depth if - // a PHP exception has already been set. - // - assert(EG(exception)); - } - catch(const IceUtil::Exception& ex) - { - throwException(ex TSRMLS_CC); - } + communicator->addRef(TSRMLS_C); } -void -IcePHP::Operation::throwUserException(Ice::InputStreamPtr& is TSRMLS_DC) +IcePHP::Proxy::~Proxy() { - Slice::UnitPtr unit = _op->unit(); - - is->readBool(); // usesClasses - - string id = is->readString(); - const string origId = id; - - while(!id.empty()) + communicator->decRef(TSRMLS_C); + if(connection) { - // - // Look for a definition of this type. - // - Slice::ExceptionPtr ex = unit->lookupException(id, false); - if(ex) - { - if(ex->isLocal()) - { - php_error_docref(0 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(); - - try - { - id = is->readString(); - } - catch(Ice::UnmarshalOutOfBoundsException& ex) - { - // - // When readString raises this exception it means we've reached the last slice, - // so we set the reason member to a more helpful value. - // - ex.reason = "unknown exception type `" + origId + "'"; - throw; - } - } + zval_ptr_dtor(&connection); } - // - // 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 a 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) + if(cachedConnection) { - _classOps = _class->allOperations(); + zval_ptr_dtor(&cachedConnection); } } -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 +bool +IcePHP::Proxy::clone(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC) { - return _proxy; + return create(zv, p, info, communicator TSRMLS_CC); } -const Slice::ClassDefPtr& -IcePHP::Proxy::getClass() const +bool +IcePHP::Proxy::cloneUntyped(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC) { - return _class; + return create(zv, p, 0, communicator TSRMLS_CC); } -OperationPtr -IcePHP::Proxy::getOperation(const string& name) +bool +IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm + TSRMLS_DC) { - OperationPtr result; - - string n = lowerCase(name); - map<string, OperationPtr>::const_iterator p = _ops.find(n); - if(p == _ops.end()) + ClassInfoPtr cls = info; + if(!cls) { - 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; - } - } + cls = getClassInfoById("::Ice::Object" TSRMLS_CC); + assert(cls); } - else + + if(object_init_ex(zv, proxyClassEntry) != SUCCESS) { - result = p->second; + runtimeError("unable to initialize proxy" TSRMLS_CC); + return false; } - return result; -} + Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv TSRMLS_CC); + ProxyPtr proxy = new Proxy(p, cls, comm TSRMLS_CC); + assert(!obj->ptr); + obj->ptr = new ProxyPtr(proxy); -string -IcePHP::Proxy::toString() const -{ - return _communicator->proxyToString(_proxy); + return true; } #ifdef _WIN32 extern "C" #endif static zend_object_value -handleProxyAlloc(zend_class_entry* ce TSRMLS_DC) +handleAlloc(zend_class_entry* ce TSRMLS_DC) { zend_object_value result; - ice_object* obj = newObject(ce TSRMLS_CC); + Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::create(ce TSRMLS_CC); assert(obj); - result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleProxyFreeStorage, + result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC); - result.handlers = &_proxyHandlers; + result.handlers = &_handlers; return result; } @@ -2563,13 +1390,10 @@ handleProxyAlloc(zend_class_entry* ce TSRMLS_DC) extern "C" #endif static void -handleProxyFreeStorage(void* p TSRMLS_DC) +handleFreeStorage(void* p TSRMLS_DC) { - ice_object* obj = static_cast<ice_object*>(p); - Proxy* _this = static_cast<Proxy*>(obj->ptr); - - delete _this; - + Wrapper<ProxyPtr>* obj = static_cast<Wrapper<ProxyPtr>*>(p); + delete obj->ptr; zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); } @@ -2577,7 +1401,7 @@ handleProxyFreeStorage(void* p TSRMLS_DC) extern "C" #endif static zend_object_value -handleProxyClone(zval* zv TSRMLS_DC) +handleClone(zval* zv TSRMLS_DC) { // // Create a new object that shares a C++ proxy instance with this object. @@ -2586,22 +1410,16 @@ handleProxyClone(zval* zv TSRMLS_DC) 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); + ProxyPtr obj = Wrapper<ProxyPtr>::value(zv TSRMLS_CC); + assert(obj); zval* clone; MAKE_STD_ZVAL(clone); - if(object_init_ex(clone, IcePHP::proxyClassEntry) != SUCCESS) + if(!obj->clone(clone, obj->proxy TSRMLS_CC)) { - php_error_docref(0 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 @@ -2619,7 +1437,7 @@ handleProxyClone(zval* zv TSRMLS_DC) extern "C" #endif static union _zend_function* -handleProxyGetMethod(zval** zv, char* method, int len TSRMLS_DC) +handleGetMethod(zval** zv, char* method, int len TSRMLS_DC) { zend_function* result; @@ -2631,27 +1449,23 @@ handleProxyGetMethod(zval** zv, char* method, int len TSRMLS_DC) result = zend_get_std_object_handlers()->get_method(zv, method, len TSRMLS_CC); if(!result) { - ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(*zv TSRMLS_CC)); + Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(*zv TSRMLS_CC); assert(obj->ptr); - Proxy* _this = static_cast<Proxy*>(obj->ptr); + ProxyPtr _this = *obj->ptr; - Slice::ClassDefPtr def = _this->getClass(); - if(!def) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unknown method %s invoked on untyped proxy", method); - return 0; - } + ClassInfoPtr info = _this->info; + assert(info); - OperationPtr op = _this->getOperation(method); + OperationPtr op = info->getOperation(method); if(!op) { - string scoped = def->scoped(); - php_error_docref(0 TSRMLS_CC, E_ERROR, "unknown operation %s invoked on proxy of type %s", method, - scoped.c_str()); + // + // Returning 0 causes PHP to report an "undefined method" error. + // return 0; } - result = op->getZendFunction(); + result = op->function(); } return result; @@ -2661,21 +1475,21 @@ handleProxyGetMethod(zval** zv, char* method, int len TSRMLS_DC) extern "C" #endif static int -handleProxyCompare(zval* zobj1, zval* zobj2 TSRMLS_DC) +handleCompare(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)); + Wrapper<ProxyPtr>* obj1 = Wrapper<ProxyPtr>::extract(zobj1 TSRMLS_CC); assert(obj1->ptr); - Proxy* _this1 = static_cast<Proxy*>(obj1->ptr); - Ice::ObjectPrx prx1 = _this1->getProxy(); + ProxyPtr _this1 = *obj1->ptr; + Ice::ObjectPrx prx1 = _this1->proxy; - ice_object* obj2 = static_cast<ice_object*>(zend_object_store_get_object(zobj2 TSRMLS_CC)); + Wrapper<ProxyPtr>* obj2 = Wrapper<ProxyPtr>::extract(zobj2 TSRMLS_CC); assert(obj2->ptr); - Proxy* _this2 = static_cast<Proxy*>(obj2->ptr); - Ice::ObjectPrx prx2 = _this2->getProxy(); + ProxyPtr _this2 = *obj2->ptr; + Ice::ObjectPrx prx2 = _this2->proxy; if(prx1 == prx2) { @@ -2691,112 +1505,122 @@ handleProxyCompare(zval* zobj1, zval* zobj2 TSRMLS_DC) } } -ZEND_FUNCTION(Ice_ObjectPrx_call) +// +// Predefined methods for ObjectPrx. +// +static function_entry _proxyMethods[] = { - 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); -} + ZEND_ME(Ice_ObjectPrx, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) + ZEND_ME(Ice_ObjectPrx, __toString, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getCommunicator, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_toString, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getIdentity, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_identity, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getContext, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_context, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getFacet, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_facet, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getAdapterId, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_adapterId, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getEndpoints, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_endpoints, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getLocatorCacheTimeout, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_locatorCacheTimeout, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_isConnectionCached, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_connectionCached, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getEndpointSelection, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_endpointSelection, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_isSecure, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_secure, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_isPreferSecure, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_preferSecure, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getRouter, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_router, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getLocator, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_locator, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_twoway, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_isTwoway, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_oneway, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_isOneway, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_batchOneway, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_isBatchOneway, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_datagram, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_isDatagram, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_batchDatagram, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_isBatchDatagram, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_compress, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_timeout, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_connectionId, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getConnection, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_getCachedConnection, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_uncheckedCast, NULL, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_ObjectPrx, ice_checkedCast, NULL, ZEND_ACC_PUBLIC) + {0, 0, 0} +}; -#ifdef _WIN32 -extern "C" -#endif -static zend_object_value -handleEndpointAlloc(zend_class_entry* ce TSRMLS_DC) +bool +IcePHP::proxyInit(TSRMLS_D) { - zend_object_value result; - - ice_object* obj = newObject(ce TSRMLS_CC); - assert(obj); - - result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleEndpointFreeStorage, - 0 TSRMLS_CC); - result.handlers = &_endpointHandlers; + // + // Register the ObjectPrx class. + // + zend_class_entry ce; +#ifdef ICEPHP_USE_NAMESPACES + INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("ObjectPrx"), _proxyMethods); +#else + INIT_CLASS_ENTRY(ce, "Ice_ObjectPrx", _proxyMethods); +#endif + ce.create_object = handleAlloc; + proxyClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + //proxyClassEntry->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; + memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + _handlers.clone_obj = handleClone; + _handlers.get_method = handleGetMethod; + _handlers.compare_objects = handleCompare; - return result; + return true; } -#ifdef _WIN32 -extern "C" -#endif -static void -handleEndpointFreeStorage(void* p TSRMLS_DC) +bool +IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const CommunicatorInfoPtr& comm TSRMLS_DC) { - ice_object* obj = static_cast<ice_object*>(p); - Ice::EndpointPtr* _this = static_cast<Ice::EndpointPtr*>(obj->ptr); - - delete _this; - - zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); + return Proxy::create(zv, p, 0, comm TSRMLS_CC); } -#ifdef _WIN32 -extern "C" -#endif -static zend_object_value -handleConnectionAlloc(zend_class_entry* ce TSRMLS_DC) +bool +IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm + TSRMLS_DC) { - zend_object_value result; - - ice_object* obj = newObject(ce TSRMLS_CC); - assert(obj); - - result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleConnectionFreeStorage, - 0 TSRMLS_CC); - result.handlers = &_connectionHandlers; - - return result; + return Proxy::create(zv, p, info, comm TSRMLS_CC); } -#ifdef _WIN32 -extern "C" -#endif -static void -handleConnectionFreeStorage(void* p TSRMLS_DC) +bool +IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls TSRMLS_DC) { - ice_object* obj = static_cast<ice_object*>(p); - Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr); - - delete _this; - - zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); + CommunicatorInfoPtr comm; + return fetchProxy(zv, prx, cls, comm TSRMLS_CC); } -#ifdef _WIN32 -extern "C" -#endif -static int -handleConnectionCompare(zval* zobj1, zval* zobj2 TSRMLS_DC) +bool +IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls, CommunicatorInfoPtr& comm 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 + if(!ZVAL_IS_NULL(zv)) { - return 1; + if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != proxyClassEntry) + { + invalidArgument("value is not a proxy" TSRMLS_CC); + return false; + } + Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv TSRMLS_CC); + if(!obj) + { + runtimeError("unable to retrieve proxy object from object store" TSRMLS_CC); + return false; + } + assert(obj->ptr); + prx = (*obj->ptr)->proxy; + cls = (*obj->ptr)->info; + comm = (*obj->ptr)->communicator; } + return true; } diff --git a/php/src/IcePHP/Proxy.h b/php/src/IcePHP/Proxy.h index e99a19a0b95..99197dd6649 100644 --- a/php/src/IcePHP/Proxy.h +++ b/php/src/IcePHP/Proxy.h @@ -7,152 +7,22 @@ // // ********************************************************************** -#ifndef ICE_PHP_PROXY_H -#define ICE_PHP_PROXY_H +#ifndef ICEPHP_PROXY_H +#define ICEPHP_PROXY_H #include <Config.h> - -// -// Ice_ObjectPrx class methods. -// -extern "C" -{ -ZEND_FUNCTION(Ice_ObjectPrx___construct); -ZEND_FUNCTION(Ice_ObjectPrx___tostring); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getCommunicator); -ZEND_FUNCTION(Ice_ObjectPrx_ice_toString); -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_getIdentity); -ZEND_FUNCTION(Ice_ObjectPrx_ice_identity); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getContext); -ZEND_FUNCTION(Ice_ObjectPrx_ice_context); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getFacet); -ZEND_FUNCTION(Ice_ObjectPrx_ice_facet); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getAdapterId); -ZEND_FUNCTION(Ice_ObjectPrx_ice_adapterId); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpoints); -ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocatorCacheTimeout); -ZEND_FUNCTION(Ice_ObjectPrx_ice_locatorCacheTimeout); -ZEND_FUNCTION(Ice_ObjectPrx_ice_isConnectionCached); -ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionCached); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpointSelection); -ZEND_FUNCTION(Ice_ObjectPrx_ice_endpointSelection); -ZEND_FUNCTION(Ice_ObjectPrx_ice_isSecure); -ZEND_FUNCTION(Ice_ObjectPrx_ice_secure); -ZEND_FUNCTION(Ice_ObjectPrx_ice_isPreferSecure); -ZEND_FUNCTION(Ice_ObjectPrx_ice_preferSecure); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getRouter); -ZEND_FUNCTION(Ice_ObjectPrx_ice_router); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocator); -ZEND_FUNCTION(Ice_ObjectPrx_ice_locator); -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_compress); -ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout); -ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionId); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getConnection); -ZEND_FUNCTION(Ice_ObjectPrx_ice_getCachedConnection); -ZEND_FUNCTION(Ice_ObjectPrx_ice_uncheckedCast); -ZEND_FUNCTION(Ice_ObjectPrx_ice_checkedCast); - -ZEND_FUNCTION(Ice_Endpoint___construct); -ZEND_FUNCTION(Ice_Endpoint___tostring); -ZEND_FUNCTION(Ice_Endpoint_toString); - -ZEND_FUNCTION(Ice_Connection___construct); -ZEND_FUNCTION(Ice_Connection___tostring); -ZEND_FUNCTION(Ice_Connection_close); -ZEND_FUNCTION(Ice_Connection_flushBatchRequests); -ZEND_FUNCTION(Ice_Connection_type); -ZEND_FUNCTION(Ice_Connection_timeout); -ZEND_FUNCTION(Ice_Connection_toString); -} - -#define ICE_PHP_PROXY_FUNCTIONS \ - ZEND_FE(Ice_ObjectPrx___construct, NULL) \ - ZEND_FE(Ice_ObjectPrx___tostring, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getCommunicator, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_toString, 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_getIdentity, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_identity, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getContext, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_context, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getFacet, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_facet, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getAdapterId, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_adapterId, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getEndpoints, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_endpoints, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getLocatorCacheTimeout, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_locatorCacheTimeout, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_isConnectionCached, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_connectionCached, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getEndpointSelection, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_endpointSelection, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_isSecure, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_secure, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_isPreferSecure, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_preferSecure, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getRouter, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_router, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getLocator, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_locator, 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_compress, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_timeout, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_connectionId, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getConnection, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_getCachedConnection, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_uncheckedCast, NULL) \ - ZEND_FE(Ice_ObjectPrx_ice_checkedCast, NULL) - -#define ICE_PHP_ENDPOINT_FUNCTIONS \ - ZEND_FE(Ice_Endpoint___construct, NULL) \ - ZEND_FE(Ice_Endpoint___tostring, NULL) \ - ZEND_FE(Ice_Endpoint_toString, NULL) - -#define ICE_PHP_CONNECTION_FUNCTIONS \ - ZEND_FE(Ice_Connection___construct, NULL) \ - ZEND_FE(Ice_Connection___tostring, NULL) \ - ZEND_FE(Ice_Connection_close, NULL) \ - ZEND_FE(Ice_Connection_flushBatchRequests, NULL) \ - ZEND_FE(Ice_Connection_type, NULL) \ - ZEND_FE(Ice_Connection_timeout, NULL) \ - ZEND_FE(Ice_Connection_toString, NULL) +#include <Communicator.h> +#include <Types.h> namespace IcePHP { bool proxyInit(TSRMLS_D); -bool createProxy(zval*, const Ice::ObjectPrx& TSRMLS_DC); -bool createProxy(zval*, const Ice::ObjectPrx&, const Slice::ClassDefPtr& TSRMLS_DC); -bool fetchProxy(zval*, Ice::ObjectPrx&, Slice::ClassDefPtr& TSRMLS_DC); +bool createProxy(zval*, const Ice::ObjectPrx&, const CommunicatorInfoPtr& TSRMLS_DC); +bool createProxy(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC); +bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr& TSRMLS_DC); +bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr&, CommunicatorInfoPtr& TSRMLS_DC); // // Class entry. diff --git a/php/src/IcePHP/Types.cpp b/php/src/IcePHP/Types.cpp new file mode 100644 index 00000000000..151e4acb120 --- /dev/null +++ b/php/src/IcePHP/Types.cpp @@ -0,0 +1,2877 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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 <Types.h> +#include <Proxy.h> +#include <Util.h> +#include <IceUtil/InputUtil.h> +#include <IceUtil/OutputUtil.h> +#include <IceUtil/ScopedArray.h> +#include <Slice/PHPUtil.h> + +using namespace std; +using namespace IcePHP; +using namespace IceUtil; +using namespace IceUtilInternal; + +ZEND_EXTERN_MODULE_GLOBALS(ice) + +// +// Class entries represent the PHP class implementations we have registered. +// +namespace IcePHP +{ +zend_class_entry* typeInfoClassEntry = 0; +zend_class_entry* exceptionInfoClassEntry = 0; +} + +static zend_object_handlers _typeInfoHandlers; +static zend_object_handlers _exceptionInfoHandlers; + +extern "C" +{ +static zend_object_value handleTypeInfoAlloc(zend_class_entry* TSRMLS_DC); +static void handleTypeInfoFreeStorage(void* TSRMLS_DC); + +static zend_object_value handleExceptionInfoAlloc(zend_class_entry* TSRMLS_DC); +static void handleExceptionInfoFreeStorage(void* TSRMLS_DC); +} + +typedef map<string, ProxyInfoPtr> ProxyInfoMap; +typedef map<string, ClassInfoPtr> ClassInfoMap; +typedef map<string, ExceptionInfoPtr> ExceptionInfoMap; + +// +// getProxyInfo() +// +static IcePHP::ProxyInfoPtr +getProxyInfo(const string& id TSRMLS_DC) +{ + if(ICE_G(proxyInfoMap)) + { + ProxyInfoMap* m = reinterpret_cast<ProxyInfoMap*>(ICE_G(proxyInfoMap)); + ProxyInfoMap::iterator p = m->find(id); + if(p != m->end()) + { + return p->second; + } + } + return 0; +} + +// +// addClassInfoById() +// +static void +addClassInfoById(const ClassInfoPtr& p TSRMLS_DC) +{ + assert(!getClassInfoById(p->id TSRMLS_CC)); + + ClassInfoMap* m = reinterpret_cast<ClassInfoMap*>(ICE_G(idToClassInfoMap)); + if(!m) + { + m = new ClassInfoMap; + ICE_G(idToClassInfoMap) = m; + } + m->insert(ClassInfoMap::value_type(p->id, p)); +} + +// +// addClassInfoByName() +// +static void +addClassInfoByName(const ClassInfoPtr& p TSRMLS_DC) +{ + assert(!getClassInfoByName(p->name TSRMLS_CC)); + + ClassInfoMap* m = reinterpret_cast<ClassInfoMap*>(ICE_G(nameToClassInfoMap)); + if(!m) + { + m = new ClassInfoMap; + ICE_G(nameToClassInfoMap) = m; + } + m->insert(ClassInfoMap::value_type(p->name, p)); +} + +static ClassInfoPtr +getMostDerived(zend_class_entry* formal, zend_class_entry* cls, const ClassInfoPtr& c TSRMLS_DC) +{ + assert(checkClass(cls, formal)); + ClassInfoPtr curr = c; + + ClassInfoPtr info = getClassInfoByName(cls->name TSRMLS_CC); + if(info) + { + if(!curr || info->isA(curr->id)) + { + curr = info; + } + } + + if(cls->parent && checkClass(cls->parent, formal)) + { + curr = getMostDerived(formal, cls->parent, curr TSRMLS_CC); + } + + // + // Only check the interfaces if we don't have a base class. + // + if(!curr) + { + for(zend_uint i = 0; i < cls->num_interfaces && !info; ++i) + { + if(checkClass(cls->interfaces[i], formal)) + { + curr = getMostDerived(formal, cls->interfaces[i], curr TSRMLS_CC); + } + } + } + + return curr; +} + +// +// getClassInfoById() +// +IcePHP::ClassInfoPtr +IcePHP::getClassInfoById(const string& id TSRMLS_DC) +{ + if(ICE_G(idToClassInfoMap)) + { + ClassInfoMap* m = reinterpret_cast<ClassInfoMap*>(ICE_G(idToClassInfoMap)); + ClassInfoMap::iterator p = m->find(id); + if(p != m->end()) + { + return p->second; + } + } + return 0; +} + +// +// getClassInfoByName() +// +IcePHP::ClassInfoPtr +IcePHP::getClassInfoByName(const string& name TSRMLS_DC) +{ + if(ICE_G(nameToClassInfoMap)) + { + ClassInfoMap* m = reinterpret_cast<ClassInfoMap*>(ICE_G(nameToClassInfoMap)); + ClassInfoMap::iterator p = m->find(name); + if(p != m->end()) + { + return p->second; + } + } + return 0; +} + +// +// getExceptionInfo() +// +IcePHP::ExceptionInfoPtr +IcePHP::getExceptionInfo(const string& id TSRMLS_DC) +{ + if(ICE_G(exceptionInfoMap)) + { + ExceptionInfoMap* m = reinterpret_cast<ExceptionInfoMap*>(ICE_G(exceptionInfoMap)); + ExceptionInfoMap::iterator p = m->find(id); + if(p != m->end()) + { + return p->second; + } + } + return 0; +} + +namespace IcePHP +{ + +class ReadObjectCallback : public Ice::ReadObjectCallback +{ +public: + + ReadObjectCallback(const ClassInfoPtr&, const UnmarshalCallbackPtr&, zval*, void* TSRMLS_DC); + ~ReadObjectCallback(); + + virtual void invoke(const ::Ice::ObjectPtr&); + +private: + + ClassInfoPtr _info; + UnmarshalCallbackPtr _cb; + zval* _target; + void* _closure; +#if ZTS + TSRMLS_D; +#endif +zend_object_handle _h; +}; + +} + +// +// UnmarshalCallback implementation. +// +IcePHP::UnmarshalCallback::~UnmarshalCallback() +{ +} + +// +// TypeInfo implementation. +// +IcePHP::TypeInfo::TypeInfo() +{ +} + +bool +IcePHP::TypeInfo::usesClasses() +{ + return false; +} + +void +IcePHP::TypeInfo::unmarshaled(zval*, zval*, void* TSRMLS_DC) +{ + assert(false); +} + +void +IcePHP::TypeInfo::destroy() +{ +} + +// +// PrimitiveInfo implementation. +// +string +IcePHP::PrimitiveInfo::getId() const +{ + switch(kind) + { + case KindBool: + return "bool"; + case KindByte: + return "byte"; + case KindShort: + return "short"; + case KindInt: + return "int"; + case KindLong: + return "long"; + case KindFloat: + return "float"; + case KindDouble: + return "double"; + case KindString: + return "string"; + } + assert(false); + return string(); +} + +bool +IcePHP::PrimitiveInfo::validate(zval* zv TSRMLS_DC) +{ + switch(kind) + { + case PrimitiveInfo::KindBool: + { + if(Z_TYPE_P(zv) != IS_BOOL) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected boolean value but received %s" TSRMLS_CC, s.c_str()); + return false; + } + break; + } + case PrimitiveInfo::KindByte: + { + if(Z_TYPE_P(zv) != IS_LONG) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected byte value but received %s" TSRMLS_CC, s.c_str()); + return false; + } + long val = Z_LVAL_P(zv); + if(val < 0 || val > 255) + { + invalidArgument("value %ld is out of range for a byte" TSRMLS_CC, val); + return false; + } + break; + } + case PrimitiveInfo::KindShort: + { + if(Z_TYPE_P(zv) != IS_LONG) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected short value but received %s" TSRMLS_CC, s.c_str()); + return false; + } + long val = Z_LVAL_P(zv); + if(val < SHRT_MIN || val > SHRT_MAX) + { + invalidArgument("value %ld is out of range for a short" TSRMLS_CC, val); + return false; + } + break; + } + case PrimitiveInfo::KindInt: + { + if(Z_TYPE_P(zv) != IS_LONG) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected int value but received %s" TSRMLS_CC, s.c_str()); + return false; + } + long val = Z_LVAL_P(zv); + if(val < INT_MIN || val > INT_MAX) + { + invalidArgument("value %ld is out of range for an int" TSRMLS_CC, val); + return false; + } + break; + } + case PrimitiveInfo::KindLong: + { + // + // The platform's 'long' type may not be 64 bits, so we also accept + // a string argument for this type. + // + if(Z_TYPE_P(zv) != IS_LONG && Z_TYPE_P(zv) != IS_STRING) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected long value but received %s" TSRMLS_CC, s.c_str()); + return false; + } + Ice::Long val; + if(Z_TYPE_P(zv) == IS_LONG) + { + val = Z_LVAL_P(zv); + } + else + { + string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); + if(!IceUtilInternal::stringToInt64(sval, val)) + { + invalidArgument("invalid long value `%s'" TSRMLS_CC, Z_STRVAL_P(zv)); + return false; + } + } + break; + } + case PrimitiveInfo::KindFloat: + { + if(Z_TYPE_P(zv) != IS_DOUBLE) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected float value but received %s" TSRMLS_CC, s.c_str()); + return false; + } + break; + } + case PrimitiveInfo::KindDouble: + { + if(Z_TYPE_P(zv) != IS_DOUBLE) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected double value but received %s" TSRMLS_CC, s.c_str()); + return false; + } + break; + } + case PrimitiveInfo::KindString: + { + if(Z_TYPE_P(zv) != IS_STRING && Z_TYPE_P(zv) != IS_NULL) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected string value but received %s" TSRMLS_CC, s.c_str()); + return false; + } + break; + } + } + + return true; +} + +void +IcePHP::PrimitiveInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* TSRMLS_DC) +{ + switch(kind) + { + case PrimitiveInfo::KindBool: + { + assert(Z_TYPE_P(zv) == IS_BOOL); + os->writeBool(Z_BVAL_P(zv) ? true : false); + break; + } + case PrimitiveInfo::KindByte: + { + assert(Z_TYPE_P(zv) == IS_LONG); + long val = Z_LVAL_P(zv); + assert(val >= 0 && val <= 255); // validate() should have caught this. + os->writeByte(static_cast<Ice::Byte>(val)); + break; + } + case PrimitiveInfo::KindShort: + { + assert(Z_TYPE_P(zv) == IS_LONG); + long val = Z_LVAL_P(zv); + assert(val >= SHRT_MIN && val <= SHRT_MAX); // validate() should have caught this. + os->writeShort(static_cast<Ice::Short>(val)); + break; + } + case PrimitiveInfo::KindInt: + { + assert(Z_TYPE_P(zv) == IS_LONG); + long val = Z_LVAL_P(zv); + assert(val >= INT_MIN && val <= INT_MAX); // validate() should have caught this. + os->writeInt(static_cast<Ice::Int>(val)); + break; + } + case PrimitiveInfo::KindLong: + { + // + // The platform's 'long' type may not be 64 bits, so we also accept + // a string argument for this type. + // + assert(Z_TYPE_P(zv) == IS_LONG || Z_TYPE_P(zv) == IS_STRING); // validate() should have caught this. + Ice::Long val; + if(Z_TYPE_P(zv) == IS_LONG) + { + val = Z_LVAL_P(zv); + } + else + { + string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); + IceUtilInternal::stringToInt64(sval, val); + } + os->writeLong(val); + break; + } + case PrimitiveInfo::KindFloat: + { + assert(Z_TYPE_P(zv) == IS_DOUBLE); // validate() should have caught this. + double val = Z_DVAL_P(zv); + os->writeFloat(static_cast<Ice::Float>(val)); + break; + } + case PrimitiveInfo::KindDouble: + { + assert(Z_TYPE_P(zv) == IS_DOUBLE); // validate() should have caught this. + double val = Z_DVAL_P(zv); + os->writeDouble(val); + break; + } + case PrimitiveInfo::KindString: + { + assert(Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_NULL); // validate() should have caught this. + if(Z_TYPE_P(zv) == IS_STRING) + { + string val(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); + os->writeString(val); + } + else + { + os->writeString(string()); + } + break; + } + } +} + +void +IcePHP::PrimitiveInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, + const CommunicatorInfoPtr&, zval* target, void* closure TSRMLS_DC) +{ + zval* zv; + MAKE_STD_ZVAL(zv); + AutoDestroy destroy(zv); + + switch(kind) + { + case PrimitiveInfo::KindBool: + { + bool val = is->readBool(); + ZVAL_BOOL(zv, val ? 1 : 0); + break; + } + case PrimitiveInfo::KindByte: + { + Ice::Byte val = is->readByte(); + ZVAL_LONG(zv, val & 0xff); + break; + } + case PrimitiveInfo::KindShort: + { + Ice::Short val = is->readShort(); + ZVAL_LONG(zv, val); + break; + } + case PrimitiveInfo::KindInt: + { + Ice::Int val = is->readInt(); + ZVAL_LONG(zv, val); + break; + } + case PrimitiveInfo::KindLong: + { + Ice::Long val = is->readLong(); + + // + // The platform's 'long' type may not be 64 bits, so we store 64-bit + // values as a string. + // + if(sizeof(Ice::Long) > sizeof(long) && (val < LONG_MIN || val > LONG_MAX)) + { + string str = IceUtilInternal::int64ToString(val); + ZVAL_STRINGL(zv, STRCAST(str.c_str()), str.length(), 1); + } + else + { + ZVAL_LONG(zv, static_cast<long>(val)); + } + break; + } + case PrimitiveInfo::KindFloat: + { + Ice::Float val = is->readFloat(); + ZVAL_DOUBLE(zv, val); + break; + } + case PrimitiveInfo::KindDouble: + { + Ice::Double val = is->readDouble(); + ZVAL_DOUBLE(zv, val); + break; + } + case PrimitiveInfo::KindString: + { + string val = is->readString(); + ZVAL_STRINGL(zv, STRCAST(val.c_str()), val.length(), 1); + break; + } + } + + cb->unmarshaled(zv, target, closure TSRMLS_CC); +} + +void +IcePHP::PrimitiveInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* TSRMLS_DC) +{ + if(!validate(zv TSRMLS_CC)) + { + out << "<invalid value - expected " << getId() << ">"; + return; + } + zval tmp = *zv; + zval_copy_ctor(&tmp); + INIT_PZVAL(&tmp); + convert_to_string(&tmp); + out << Z_STRVAL(tmp); + zval_dtor(&tmp); +} + +// +// EnumInfo implementation. +// +string +IcePHP::EnumInfo::getId() const +{ + return id; +} + +bool +IcePHP::EnumInfo::validate(zval* zv TSRMLS_DC) +{ + if(Z_TYPE_P(zv) == IS_LONG) + { + Ice::StringSeq::size_type sz = static_cast<Ice::StringSeq::size_type>(Z_LVAL_P(zv)); + return sz >= 0 && sz < enumerators.size(); + } + return false; +} + +void +IcePHP::EnumInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* TSRMLS_DC) +{ + assert(Z_TYPE_P(zv) == IS_LONG); // validate() should have caught this. + int val = static_cast<int>(Z_LVAL_P(zv)); + int count = static_cast<int>(enumerators.size()); + assert(val >= 0 && val < count); // validate() should have caught this. + + if(count <= 127) + { + os->writeByte(static_cast<Ice::Byte>(val)); + } + else if(count <= 32767) + { + os->writeShort(static_cast<Ice::Short>(val)); + } + else + { + os->writeInt(val); + } +} + +void +IcePHP::EnumInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, + const CommunicatorInfoPtr&, zval* target, void* closure TSRMLS_DC) +{ + zval* zv; + ALLOC_INIT_ZVAL(zv); + AutoDestroy destroy(zv); + + int val; + int count = static_cast<int>(enumerators.size()); + if(count <= 127) + { + val = is->readByte(); + } + else if(count <= 32767) + { + val = is->readShort(); + } + else + { + val = is->readInt(); + } + + if(val < 0 || val >= count) + { + invalidArgument("enumerator %d is out of range for enum %s" TSRMLS_CC, val, id.c_str()); + throw AbortMarshaling(); + } + + ZVAL_LONG(zv, val); + cb->unmarshaled(zv, target, closure TSRMLS_CC); +} + +void +IcePHP::EnumInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* TSRMLS_DC) +{ + if(!validate(zv TSRMLS_CC)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + int val = static_cast<int>(Z_LVAL_P(zv)); + out << enumerators[val]; +} + +// +// DataMember implementation. +// +void +IcePHP::DataMember::unmarshaled(zval* zv, zval* target, void* TSRMLS_DC) +{ + assert(Z_TYPE_P(target) == IS_OBJECT); + + // + // The add_property_zval function fails if the data member has protected visibility. + // As a workaround, before calling the function we change the current scope to be that + // of the object. + // + zend_class_entry *oldScope = EG(scope); + EG(scope) = Z_OBJCE_P(target); + + // + // add_property_zval increments the refcount of zv. + // + int status = add_property_zval(target, STRCAST(name.c_str()), zv); + + EG(scope) = oldScope; // Restore the previous scope. + + if(status == FAILURE) + { + runtimeError("unable to set member `%s'" TSRMLS_CC, name.c_str()); + throw AbortMarshaling(); + } +} + +// +// StructInfo implementation. +// +string +IcePHP::StructInfo::getId() const +{ + return id; +} + +bool +IcePHP::StructInfo::validate(zval* zv TSRMLS_DC) +{ + if(Z_TYPE_P(zv) != IS_OBJECT) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected struct value of type %s but received %s" TSRMLS_CC, zce->name, s.c_str()); + return false; + } + + // + // Compare class entries. + // + zend_class_entry* ce = Z_OBJCE_P(zv); + if(ce != zce) + { + invalidArgument("expected struct value of type %s but received %s" TSRMLS_CC, zce->name, ce->name); + return false; + } + + return true; +} + +bool +IcePHP::StructInfo::usesClasses() +{ + for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) + { + if((*q)->type->usesClasses()) + { + return true; + } + } + + return false; +} + +void +IcePHP::StructInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap TSRMLS_DC) +{ + assert(Z_TYPE_P(zv) == IS_OBJECT); // validate() should have caught this. + assert(Z_OBJCE_P(zv) == zce); // validate() should have caught this. + + for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + + void* data; + if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size() + 1, &data) == FAILURE) + { + runtimeError("member `%s' of %s is not defined" TSRMLS_CC, member->name.c_str(), id.c_str()); + throw AbortMarshaling(); + } + + zval** val = reinterpret_cast<zval**>(data); + if(!member->type->validate(*val TSRMLS_CC)) + { + invalidArgument("invalid value for %s member `%s'" TSRMLS_CC, id.c_str(), member->name.c_str()); + throw AbortMarshaling(); + } + member->type->marshal(*val, os, objectMap TSRMLS_CC); + } +} + +void +IcePHP::StructInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, + const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC) +{ + zval* zv; + MAKE_STD_ZVAL(zv); + AutoDestroy destroy(zv); + + if(object_init_ex(zv, zce) != SUCCESS) + { + runtimeError("unable to initialize object of type %s" TSRMLS_CC, zce->name); + throw AbortMarshaling(); + } + + for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + member->type->unmarshal(is, member, comm, zv, 0 TSRMLS_CC); + } + + cb->unmarshaled(zv, target, closure TSRMLS_CC); +} + +void +IcePHP::StructInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC) +{ + if(!validate(zv TSRMLS_CC)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + out.sb(); + for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + + out << nl << member->name << " = "; + void* data; + if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size() + 1, &data) == SUCCESS) + { + zval** val = reinterpret_cast<zval**>(data); + member->type->print(*val, out, history TSRMLS_CC); + } + else + { + out << "<not defined>"; + } + } + out.eb(); +} + +void +IcePHP::StructInfo::destroy() +{ + for(DataMemberList::iterator p = members.begin(); p != members.end(); ++p) + { + (*p)->type->destroy(); + } + members.clear(); +} + +// +// SequenceInfo implementation. +// +string +IcePHP::SequenceInfo::getId() const +{ + return id; +} + +bool +IcePHP::SequenceInfo::validate(zval* zv TSRMLS_DC) +{ + return Z_TYPE_P(zv) == IS_NULL || Z_TYPE_P(zv) == IS_ARRAY; +} + +bool +IcePHP::SequenceInfo::usesClasses() +{ + return elementType->usesClasses(); +} + +void +IcePHP::SequenceInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap TSRMLS_DC) +{ + if(Z_TYPE_P(zv) == IS_NULL) + { + os->writeSize(0); + return; + } + + assert(Z_TYPE_P(zv) == IS_ARRAY); // validate() should have caught this. + + HashTable* arr = Z_ARRVAL_P(zv); + + Ice::Int sz = static_cast<Ice::Int>(zend_hash_num_elements(arr)); + + if(sz == 0) + { + os->writeSize(0); + return; + } + + PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType); + if(pi) + { + marshalPrimitiveSequence(pi, zv, os TSRMLS_CC); + return; + } + + HashPosition pos; + zend_hash_internal_pointer_reset_ex(arr, &pos); + + os->writeSize(sz); + + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + if(!elementType->validate(*val TSRMLS_CC)) + { + invalidArgument("invalid value for sequence element `%s'" TSRMLS_CC, id.c_str()); + throw AbortMarshaling(); + } + elementType->marshal(*val, os, objectMap TSRMLS_CC); + zend_hash_move_forward_ex(arr, &pos); + } +} + +void +IcePHP::SequenceInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, + const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC) +{ + PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType); + if(pi) + { + unmarshalPrimitiveSequence(pi, is, cb, target, closure TSRMLS_CC); + return; + } + + zval* zv; + MAKE_STD_ZVAL(zv); + array_init(zv); + AutoDestroy destroy(zv); + + Ice::Int sz = is->readSize(); + if(variableLength) + { + is->startSeq(sz, minWireSize); + } + else + { + is->checkFixedSeq(sz, minWireSize); + } + for(Ice::Int i = 0; i < sz; ++i) + { + void* cl = reinterpret_cast<void*>(i); + elementType->unmarshal(is, this, comm, zv, cl TSRMLS_CC); + if(variableLength) + { + is->checkSeq(); + is->endElement(); + } + } + if(variableLength) + { + is->endSeq(sz); + } + + cb->unmarshaled(zv, target, closure TSRMLS_CC); +} + +void +IcePHP::SequenceInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC) +{ + if(!validate(zv TSRMLS_CC)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + if(Z_TYPE_P(zv) == IS_NULL) + { + out << "{}"; + } + else + { + assert(Z_TYPE_P(zv) == IS_ARRAY); + + HashTable* arr = Z_ARRVAL_P(zv); + + HashPosition pos; + zend_hash_internal_pointer_reset_ex(arr, &pos); + + out.sb(); + + int i = 0; + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + out << nl << '[' << i << "] = "; + elementType->print(*val, out, history TSRMLS_CC); + zend_hash_move_forward_ex(arr, &pos); + ++i; + } + + out.eb(); + } +} + +void +IcePHP::SequenceInfo::unmarshaled(zval* zv, zval* target, void* closure TSRMLS_DC) +{ + assert(Z_TYPE_P(target) == IS_ARRAY); + long i = reinterpret_cast<long>(closure); + add_index_zval(target, i, zv); + Z_ADDREF_P(zv); +} + +void +IcePHP::SequenceInfo::destroy() +{ + if(elementType) + { + elementType->destroy(); + elementType = 0; + } +} + +void +IcePHP::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, zval* zv, const Ice::OutputStreamPtr& os + TSRMLS_DC) +{ + HashTable* arr = Z_ARRVAL_P(zv); + + HashPosition pos; + zend_hash_internal_pointer_reset_ex(arr, &pos); + + Ice::Int sz = static_cast<Ice::Int>(zend_hash_num_elements(arr)); + assert(sz > 0); + + switch(pi->kind) + { + case PrimitiveInfo::KindBool: + { + Ice::BoolSeq seq(sz); + Ice::Int i = 0; + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + if(!pi->validate(*val TSRMLS_CC)) + { + throw AbortMarshaling(); + } + seq[i++] = Z_BVAL_P(*val) ? true : false; + zend_hash_move_forward_ex(arr, &pos); + } + os->writeBoolSeq(seq); + break; + } + case PrimitiveInfo::KindByte: + { + Ice::ByteSeq seq(sz); + Ice::Int i = 0; + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + if(!pi->validate(*val TSRMLS_CC)) + { + throw AbortMarshaling(); + } + long l = Z_LVAL_P(*val); + assert(l >= 0 && l <= 255); + seq[i++] = static_cast<Ice::Byte>(l); + zend_hash_move_forward_ex(arr, &pos); + } + os->writeByteSeq(seq); + break; + } + case PrimitiveInfo::KindShort: + { + Ice::ShortSeq seq(sz); + Ice::Int i = 0; + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + if(!pi->validate(*val TSRMLS_CC)) + { + throw AbortMarshaling(); + } + long l = Z_LVAL_P(*val); + assert(l >= SHRT_MIN && l <= SHRT_MAX); + seq[i++] = static_cast<Ice::Short>(l); + zend_hash_move_forward_ex(arr, &pos); + } + os->writeShortSeq(seq); + break; + } + case PrimitiveInfo::KindInt: + { + Ice::IntSeq seq(sz); + Ice::Int i = 0; + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + if(!pi->validate(*val TSRMLS_CC)) + { + throw AbortMarshaling(); + } + long l = Z_LVAL_P(*val); + assert(l >= INT_MIN && l <= INT_MAX); + seq[i++] = static_cast<Ice::Int>(l); + zend_hash_move_forward_ex(arr, &pos); + } + os->writeIntSeq(seq); + break; + } + case PrimitiveInfo::KindLong: + { + Ice::LongSeq seq(sz); + Ice::Int i = 0; + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + if(!pi->validate(*val TSRMLS_CC)) + { + throw AbortMarshaling(); + } + // + // The platform's 'long' type may not be 64 bits, so we also accept + // a string argument for this type. + // + assert(Z_TYPE_P(*val) == IS_LONG || Z_TYPE_P(*val) == IS_STRING); + Ice::Long l; + if(Z_TYPE_P(*val) == IS_LONG) + { + l = Z_LVAL_P(*val); + } + else + { + string sval(Z_STRVAL_P(*val), Z_STRLEN_P(*val)); + IceUtilInternal::stringToInt64(sval, l); + } + seq[i++] = l; + zend_hash_move_forward_ex(arr, &pos); + } + os->writeLongSeq(seq); + break; + } + case PrimitiveInfo::KindFloat: + { + Ice::FloatSeq seq(sz); + Ice::Int i = 0; + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + if(!pi->validate(*val TSRMLS_CC)) + { + throw AbortMarshaling(); + } + double d = Z_DVAL_P(*val); + seq[i++] = static_cast<Ice::Float>(d); + zend_hash_move_forward_ex(arr, &pos); + } + os->writeFloatSeq(seq); + break; + } + case PrimitiveInfo::KindDouble: + { + Ice::DoubleSeq seq(sz); + Ice::Int i = 0; + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + if(!pi->validate(*val TSRMLS_CC)) + { + throw AbortMarshaling(); + } + double d = Z_DVAL_P(*val); + seq[i++] = d; + zend_hash_move_forward_ex(arr, &pos); + } + os->writeDoubleSeq(seq); + break; + } + case PrimitiveInfo::KindString: + { + Ice::StringSeq seq(sz); + Ice::Int i = 0; + void* data; + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + if(!pi->validate(*val TSRMLS_CC)) + { + throw AbortMarshaling(); + } + string s; + if(Z_TYPE_P(*val) == IS_STRING) + { + s = string(Z_STRVAL_P(*val), Z_STRLEN_P(*val)); + } + else + { + assert(Z_TYPE_P(*val) == IS_NULL); + } + seq[i++] = s; + zend_hash_move_forward_ex(arr, &pos); + } + os->writeStringSeq(seq); + break; + } + } +} + +void +IcePHP::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, const Ice::InputStreamPtr& is, + const UnmarshalCallbackPtr& cb, zval* target, void* closure TSRMLS_DC) +{ + zval* zv; + MAKE_STD_ZVAL(zv); + array_init(zv); + AutoDestroy destroy(zv); + + switch(pi->kind) + { + case PrimitiveInfo::KindBool: + { + pair<const bool*, const bool*> pr; + IceUtilInternal::ScopedArray<bool> arr(is->readBoolSeq(pr)); + for(const bool* p = pr.first; p != pr.second; ++p) + { + add_next_index_bool(zv, *p ? 1 : 0); + } + break; + } + case PrimitiveInfo::KindByte: + { + pair<const Ice::Byte*, const Ice::Byte*> pr; + is->readByteSeq(pr); + for(const Ice::Byte* p = pr.first; p != pr.second; ++p) + { + add_next_index_long(zv, *p & 0xff); + } + break; + } + case PrimitiveInfo::KindShort: + { + pair<const Ice::Short*, const Ice::Short*> pr; + IceUtilInternal::ScopedArray<Ice::Short> arr(is->readShortSeq(pr)); + for(const Ice::Short* p = pr.first; p != pr.second; ++p) + { + add_next_index_long(zv, *p); + } + break; + } + case PrimitiveInfo::KindInt: + { + pair<const Ice::Int*, const Ice::Int*> pr; + IceUtilInternal::ScopedArray<Ice::Int> arr(is->readIntSeq(pr)); + for(const Ice::Int* p = pr.first; p != pr.second; ++p) + { + add_next_index_long(zv, *p); + } + break; + } + case PrimitiveInfo::KindLong: + { + pair<const Ice::Long*, const Ice::Long*> pr; + IceUtilInternal::ScopedArray<Ice::Long> arr(is->readLongSeq(pr)); + Ice::Int i = 0; + for(const Ice::Long* p = pr.first; p != pr.second; ++p, ++i) + { + zval* val; + MAKE_STD_ZVAL(val); + // + // The platform's 'long' type may not be 64 bits, so we store 64-bit + // values as a string. + // + if(sizeof(Ice::Long) > sizeof(long) && (*p < LONG_MIN || *p > LONG_MAX)) + { + string str = IceUtilInternal::int64ToString(*p); + ZVAL_STRINGL(val, STRCAST(str.c_str()), str.length(), 1); + } + else + { + ZVAL_LONG(val, static_cast<long>(*p)); + } + add_index_zval(zv, i, val); + } + break; + } + case PrimitiveInfo::KindFloat: + { + pair<const Ice::Float*, const Ice::Float*> pr; + IceUtilInternal::ScopedArray<Ice::Float> arr(is->readFloatSeq(pr)); + Ice::Int i = 0; + for(const Ice::Float* p = pr.first; p != pr.second; ++p, ++i) + { + zval* val; + MAKE_STD_ZVAL(val); + ZVAL_DOUBLE(val, *p); + add_index_zval(zv, i, val); + } + break; + } + case PrimitiveInfo::KindDouble: + { + pair<const Ice::Double*, const Ice::Double*> pr; + IceUtilInternal::ScopedArray<Ice::Double> arr(is->readDoubleSeq(pr)); + Ice::Int i = 0; + for(const Ice::Double* p = pr.first; p != pr.second; ++p, ++i) + { + zval* val; + MAKE_STD_ZVAL(val); + ZVAL_DOUBLE(val, *p); + add_index_zval(zv, i, val); + } + break; + } + case PrimitiveInfo::KindString: + { + Ice::StringSeq seq = is->readStringSeq(); + Ice::Int i = 0; + for(Ice::StringSeq::iterator p = seq.begin(); p != seq.end(); ++p, ++i) + { + zval* val; + MAKE_STD_ZVAL(val); + ZVAL_STRINGL(val, STRCAST(p->c_str()), p->length(), 1); + add_index_zval(zv, i, val); + } + break; + } + } + + cb->unmarshaled(zv, target, closure TSRMLS_CC); +} + +// +// DictionaryInfo implementation. +// +string +IcePHP::DictionaryInfo::getId() const +{ + return id; +} + +bool +IcePHP::DictionaryInfo::validate(zval* zv TSRMLS_DC) +{ + return Z_TYPE_P(zv) == IS_NULL || Z_TYPE_P(zv) == IS_ARRAY; +} + +bool +IcePHP::DictionaryInfo::usesClasses() +{ + return valueType->usesClasses(); +} + +void +IcePHP::DictionaryInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap TSRMLS_DC) +{ + if(Z_TYPE_P(zv) == IS_NULL) + { + os->writeSize(0); + return; + } + + assert(Z_TYPE_P(zv) == IS_ARRAY); // validate() should have caught this. + + PrimitiveInfoPtr piKey = PrimitiveInfoPtr::dynamicCast(keyType); + if(!piKey || piKey->kind == PrimitiveInfo::KindFloat || piKey->kind == PrimitiveInfo::KindDouble) + { + invalidArgument("dictionary type `%s' cannot be marshaled" TSRMLS_CC, id.c_str()); + throw AbortMarshaling(); + } + + HashTable* arr = Z_ARRVAL_P(zv); + + Ice::Int sz = static_cast<Ice::Int>(zend_hash_num_elements(arr)); + os->writeSize(sz); + + if(sz == 0) + { + return; + } + + HashPosition pos; + void* data; + + zend_hash_internal_pointer_reset_ex(arr, &pos); + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + + // + // Get the key (which can be a long or a string). + // + char* keyStr; + uint keyLen; + ulong keyNum; + int hashKeyType = zend_hash_get_current_key_ex(arr, &keyStr, &keyLen, &keyNum, 0, &pos); + + // + // Store the key in a zval, so that we can reuse the PrimitiveInfo logic. + // + zval* zkey; + MAKE_STD_ZVAL(zkey); + AutoDestroy destroy(zkey); + + if(hashKeyType == HASH_KEY_IS_LONG) + { + ZVAL_LONG(zkey, keyNum); + } + else + { + ZVAL_STRINGL(zkey, keyStr, keyLen - 1, 1); + } + + // + // Convert the zval to the required type, if necessary. + // + switch(piKey->kind) + { + case PrimitiveInfo::KindBool: + { + convert_to_boolean(zkey); + break; + } + + case PrimitiveInfo::KindByte: + case PrimitiveInfo::KindShort: + case PrimitiveInfo::KindInt: + case PrimitiveInfo::KindLong: + { + if(hashKeyType == HASH_KEY_IS_STRING) + { + convert_to_long(zkey); + } + break; + } + + case PrimitiveInfo::KindString: + { + if(hashKeyType == HASH_KEY_IS_LONG) + { + convert_to_string(zkey); + } + break; + } + + case PrimitiveInfo::KindFloat: + case PrimitiveInfo::KindDouble: + assert(false); + } + + // + // Marshal the key. + // + if(!keyType->validate(zkey TSRMLS_CC)) + { + invalidArgument("invalid key in `%s' element" TSRMLS_CC, id.c_str()); + throw AbortMarshaling(); + } + keyType->marshal(zkey, os, objectMap TSRMLS_CC); + + // + // Marshal the value. + // + if(!valueType->validate(*val TSRMLS_CC)) + { + invalidArgument("invalid value in `%s' element" TSRMLS_CC, id.c_str()); + throw AbortMarshaling(); + } + valueType->marshal(*val, os, objectMap TSRMLS_CC); + + zend_hash_move_forward_ex(arr, &pos); + } +} + +void +IcePHP::DictionaryInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, + const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC) +{ + PrimitiveInfoPtr piKey = PrimitiveInfoPtr::dynamicCast(keyType); + if(!piKey || piKey->kind == PrimitiveInfo::KindFloat || piKey->kind == PrimitiveInfo::KindDouble) + { + invalidArgument("dictionary type `%s' cannot be unmarshaled" TSRMLS_CC, id.c_str()); + throw AbortMarshaling(); + } + + zval* zv; + MAKE_STD_ZVAL(zv); + array_init(zv); + AutoDestroy destroy(zv); + + KeyCallbackPtr keyCB = new KeyCallback; + + Ice::Int sz = is->readSize(); + for(Ice::Int i = 0; i < sz; ++i) + { + // + // A dictionary key cannot be a class (or contain one), so the key must be + // available immediately. + // + keyType->unmarshal(is, keyCB, comm, 0, 0 TSRMLS_CC); + assert(keyCB->key); + + // + // Allocate a callback that holds a reference to the key. + // + ValueCallbackPtr valueCB = new ValueCallback(keyCB->key TSRMLS_CC); + + // + // Pass the key to the callback. + // + valueType->unmarshal(is, valueCB, comm, zv, 0 TSRMLS_CC); + } + + cb->unmarshaled(zv, target, closure TSRMLS_CC); +} + +void +IcePHP::DictionaryInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC) +{ + if(!validate(zv TSRMLS_CC)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + if(Z_TYPE_P(zv) == IS_NULL) + { + out << "{}"; + } + else + { + HashTable* arr = Z_ARRVAL_P(zv); + HashPosition pos; + void* data; + bool first = true; + + out.sb(); + + zend_hash_internal_pointer_reset_ex(arr, &pos); + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + + // + // Get the key (which can be a long or a string). + // + char* keyStr; + uint keyLen; + ulong keyNum; + int hashKeyType = zend_hash_get_current_key_ex(arr, &keyStr, &keyLen, &keyNum, 0, &pos); + + if(first) + { + first = false; + } + else + { + out << nl; + } + out << nl << "key = "; + if(hashKeyType == HASH_KEY_IS_LONG) + { + out << keyNum; + } + else + { + out << keyStr; + } + out << nl << "value = "; + valueType->print(*val, out, history TSRMLS_CC); + + zend_hash_move_forward_ex(arr, &pos); + } + + out.eb(); + } +} + +IcePHP::DictionaryInfo::KeyCallback::KeyCallback() : + key(0) +{ +} + +IcePHP::DictionaryInfo::KeyCallback::~KeyCallback() +{ + if(key) + { + zval_ptr_dtor(&key); + } +} + +void +IcePHP::DictionaryInfo::KeyCallback::unmarshaled(zval* zv, zval*, void* TSRMLS_DC) +{ + if(key) + { + zval_ptr_dtor(&key); + } + + key = zv; + Z_ADDREF_P(key); +} + +IcePHP::DictionaryInfo::ValueCallback::ValueCallback(zval* k TSRMLS_DC) : + key(k) +{ + Z_ADDREF_P(key); +} + +IcePHP::DictionaryInfo::ValueCallback::~ValueCallback() +{ + zval_ptr_dtor(&key); +} + +void +IcePHP::DictionaryInfo::ValueCallback::unmarshaled(zval* zv, zval* target, void* TSRMLS_DC) +{ + assert(Z_TYPE_P(target) == IS_ARRAY); + + switch(Z_TYPE_P(key)) + { + case IS_LONG: + add_index_zval(target, Z_LVAL_P(key), zv); + break; + case IS_BOOL: + add_index_zval(target, Z_BVAL_P(key) ? 1 : 0, zv); + break; + case IS_STRING: + add_assoc_zval_ex(target, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, zv); + break; + default: + assert(false); + return; + } + Z_ADDREF_P(zv); +} + +void +IcePHP::DictionaryInfo::destroy() +{ + if(keyType) + { + keyType->destroy(); + keyType = 0; + } + if(valueType) + { + valueType->destroy(); + valueType = 0; + } +} + +// +// ClassInfo implementation. +// +string +IcePHP::ClassInfo::getId() const +{ + return id; +} + +bool +IcePHP::ClassInfo::validate(zval* val TSRMLS_DC) +{ + if(Z_TYPE_P(val) == IS_OBJECT) + { + return checkClass(Z_OBJCE_P(val), zce); + } + return Z_TYPE_P(val) == IS_NULL; +} + +bool +IcePHP::ClassInfo::usesClasses() +{ + return true; +} + +void +IcePHP::ClassInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap TSRMLS_DC) +{ + if(!defined) + { + runtimeError("class or interface %s is declared but not defined" TSRMLS_CC, id.c_str()); + throw AbortMarshaling(); + } + + if(Z_TYPE_P(zv) == IS_NULL) + { + os->writeObject(0); + return; + } + + assert(Z_TYPE_P(zv) == IS_OBJECT); // validate() should have caught this. + assert(checkClass(Z_OBJCE_P(zv), zce)); // validate() should have caught this. + + // + // Ice::ObjectWriter is a subclass of Ice::Object that wraps a PHP object for marshaling. + // It is possible that this PHP object has already been marshaled, therefore we first must + // check the object map to see if this object is present. If so, we use the existing ObjectWriter, + // otherwise we create a new one. The key of the map is the object's handle. + // + Ice::ObjectPtr writer; + assert(objectMap); + ObjectMap::iterator q = objectMap->find(Z_OBJ_HANDLE_P(zv)); + if(q == objectMap->end()) + { + // + // Determine the most-derived Slice type implemented by this object by scanning its + // inheritance hierarchy until we find a class or interface that we recognize. + // + ClassInfoPtr info = getMostDerived(zce, Z_OBJCE_P(zv), 0 TSRMLS_CC); + assert(info); + writer = new ObjectWriter(info, zv, objectMap TSRMLS_CC); + objectMap->insert(ObjectMap::value_type(Z_OBJ_HANDLE_P(zv), writer)); + } + else + { + writer = q->second; + } + + // + // Give the writer to the stream. The stream will eventually call write() on it. + // + os->writeObject(writer); +} + +void +IcePHP::ClassInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, + const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC) +{ + if(!defined) + { + runtimeError("class or interface %s is declared but not defined" TSRMLS_CC, id.c_str()); + throw AbortMarshaling(); + } + + is->readObject(new ReadObjectCallback(this, cb, target, closure TSRMLS_CC)); +} + +void +IcePHP::ClassInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC) +{ + if(!validate(zv TSRMLS_CC)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + if(Z_TYPE_P(zv) == IS_NULL) + { + out << "<nil>"; + } + else + { + map<unsigned int, int>::iterator q = history->objects.find(Z_OBJ_HANDLE_P(zv)); + if(q != history->objects.end()) + { + out << "<object #" << q->second << ">"; + } + else + { + out << "object #" << history->index << " (" << id << ')'; + history->objects.insert(map<unsigned int, int>::value_type(Z_OBJ_HANDLE_P(zv), history->index)); + ++history->index; + out.sb(); + printMembers(zv, out, history TSRMLS_CC); + out.eb(); + } + } +} + +void +IcePHP::ClassInfo::destroy() +{ + base = 0; + interfaces.clear(); + if(!members.empty()) + { + DataMemberList ml = members; + members.clear(); + for(DataMemberList::iterator p = ml.begin(); p != ml.end(); ++p) + { + (*p)->type->destroy(); + } + } +} + +void +IcePHP::ClassInfo::printMembers(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC) +{ + if(base) + { + base->printMembers(zv, out, history TSRMLS_CC); + } + + for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + + out << nl << member->name << " = "; + void* data; + if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size() + 1, &data) == SUCCESS) + { + zval** val = reinterpret_cast<zval**>(data); + member->type->print(*val, out, history TSRMLS_CC); + } + else + { + out << "<not defined>"; + } + } +} + +bool +IcePHP::ClassInfo::isA(const string& typeId) const +{ + if(id == typeId) + { + return true; + } + + if(base && base->isA(typeId)) + { + return true; + } + + for(ClassInfoList::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p) + { + if((*p)->isA(typeId)) + { + return true; + } + } + + return false; +} + +void +IcePHP::ClassInfo::addOperation(const string& name, const OperationPtr& op) +{ + operations.insert(OperationMap::value_type(Slice::PHP::fixIdent(name), op)); +} + +IcePHP::OperationPtr +IcePHP::ClassInfo::getOperation(const string& name) const +{ + OperationPtr op; + OperationMap::const_iterator p = operations.find(name); + if(p != operations.end()) + { + op = p->second; + } + if(!op && base) + { + op = base->getOperation(name); + } + if(!op && !interfaces.empty()) + { + for(ClassInfoList::const_iterator q = interfaces.begin(); q != interfaces.end() && !op; ++q) + { + op = (*q)->getOperation(name); + } + } + return op; +} + +// +// ProxyInfo implementation. +// +string +IcePHP::ProxyInfo::getId() const +{ + return id; +} + +bool +IcePHP::ProxyInfo::validate(zval* zv TSRMLS_DC) +{ + if(Z_TYPE_P(zv) != IS_NULL) + { + if(Z_TYPE_P(zv) != IS_OBJECT || (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) != proxyClassEntry)) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected proxy value or null but received %s" TSRMLS_CC, s.c_str()); + return false; + } + } + + return true; +} + +void +IcePHP::ProxyInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* TSRMLS_DC) +{ + if(Z_TYPE_P(zv) == IS_NULL) + { + os->writeProxy(0); + } + else + { + assert(Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == proxyClassEntry); // validate() should have caught this. + Ice::ObjectPrx proxy; + ClassInfoPtr info; + if(!fetchProxy(zv, proxy, info TSRMLS_CC)) + { + throw AbortMarshaling(); + } + if(!info->isA(id)) + { + invalidArgument("proxy is not narrowed to %s" TSRMLS_CC, id.c_str()); + throw AbortMarshaling(); + } + os->writeProxy(proxy); + } +} + +void +IcePHP::ProxyInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, + const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC) +{ + zval* zv; + MAKE_STD_ZVAL(zv); + AutoDestroy destroy(zv); + + Ice::ObjectPrx proxy = is->readProxy(); + + if(!proxy) + { + ZVAL_NULL(zv); + cb->unmarshaled(zv, target, closure TSRMLS_CC); + return; + } + + if(!cls->defined) + { + runtimeError("class or interface %s is declared but not defined" TSRMLS_CC, id.c_str()); + throw AbortMarshaling(); + } + + if(!createProxy(zv, proxy, cls, comm TSRMLS_CC)) + { + throw AbortMarshaling(); + } + cb->unmarshaled(zv, target, closure TSRMLS_CC); +} + +void +IcePHP::ProxyInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* TSRMLS_DC) +{ + if(!validate(zv TSRMLS_CC)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + if(Z_TYPE_P(zv) == IS_NULL) + { + out << "<nil>"; + } + else + { + Ice::ObjectPrx proxy; + ClassInfoPtr cls; + if(!fetchProxy(zv, proxy, cls TSRMLS_CC)) + { + return; + } + out << proxy->ice_toString(); + } +} + +void +IcePHP::ProxyInfo::destroy() +{ + cls = 0; +} + +// +// ObjectWriter implementation. +// +IcePHP::ObjectWriter::ObjectWriter(const ClassInfoPtr& info, zval* object, ObjectMap* objectMap TSRMLS_DC) : + _info(info), _object(object), _map(objectMap) +{ +#ifdef ZTS + this->TSRMLS_C = TSRMLS_C; +#endif + + Z_OBJ_HT_P(_object)->add_ref(_object TSRMLS_CC); +} + +IcePHP::ObjectWriter::~ObjectWriter() +{ + Z_OBJ_HT_P(_object)->del_ref(_object TSRMLS_CC); +} + +void +IcePHP::ObjectWriter::ice_preMarshal() +{ + string name = "ice_premarshal"; // Must be lowercase. + if(zend_hash_exists(&Z_OBJCE_P(_object)->function_table, STRCAST(name.c_str()), name.size() + 1)) + { + if(!invokeMethod(_object, name TSRMLS_CC)) + { + throw AbortMarshaling(); + } + } +} + +void +IcePHP::ObjectWriter::write(const Ice::OutputStreamPtr& os) const +{ + ClassInfoPtr info = _info; + while(info && info->id != Ice::Object::ice_staticId()) + { + os->writeTypeId(info->id); + + os->startSlice(); + for(DataMemberList::iterator q = info->members.begin(); q != info->members.end(); ++q) + { + DataMemberPtr member = *q; + + void* data; + if(zend_hash_find(Z_OBJPROP_P(_object), STRCAST(member->name.c_str()), member->name.size() + 1, &data) == + FAILURE) + { + runtimeError("member `%s' of %s is not defined" TSRMLS_CC, member->name.c_str(), _info->id.c_str()); + throw AbortMarshaling(); + } + + zval** val = reinterpret_cast<zval**>(data); + if(!member->type->validate(*val TSRMLS_CC)) + { + invalidArgument("invalid value for %s member `%s'" TSRMLS_CC, _info->id.c_str(), member->name.c_str()); + throw AbortMarshaling(); + } + member->type->marshal(*val, os, _map TSRMLS_CC); + } + os->endSlice(); + + info = info->base; + } + + // + // Marshal the Ice::Object slice. + // + os->writeTypeId(Ice::Object::ice_staticId()); + os->startSlice(); + os->writeSize(0); // For compatibility with the old AFM. + os->endSlice(); +} + +// +// ObjectReader implementation. +// +IcePHP::ObjectReader::ObjectReader(zval* object, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm TSRMLS_DC) : + _object(object), _info(info), _communicator(comm) +{ +#ifdef ZTS + this->TSRMLS_C = TSRMLS_C; +#endif + + Z_ADDREF_P(_object); +} + +IcePHP::ObjectReader::~ObjectReader() +{ + zval_ptr_dtor(&_object); +} + +void +IcePHP::ObjectReader::ice_postUnmarshal() +{ + string name = "ice_postunmarshal"; // Must be lowercase. + if(zend_hash_exists(&Z_OBJCE_P(_object)->function_table, STRCAST(name.c_str()), name.size() + 1)) + { + if(!invokeMethod(_object, name TSRMLS_CC)) + { + throw AbortMarshaling(); + } + } +} + +void +IcePHP::ObjectReader::read(const Ice::InputStreamPtr& is, bool rid) +{ + // + // Unmarshal the slices of a user-defined class. + // + ClassInfoPtr info = _info; + while(info && info->id != Ice::Object::ice_staticId()) + { + if(rid) + { + is->readTypeId(); + } + + is->startSlice(); + for(DataMemberList::iterator p = info->members.begin(); p != info->members.end(); ++p) + { + DataMemberPtr member = *p; + member->type->unmarshal(is, member, _communicator, _object, 0 TSRMLS_CC); + } + is->endSlice(); + + rid = true; + + info = info->base; + } + + // + // Unmarshal the Ice::Object slice. + // + if(rid) + { + is->readTypeId(); + } + + is->startSlice(); + // For compatibility with the old AFM. + Ice::Int sz = is->readSize(); + if(sz != 0) + { + throw Ice::MarshalException(__FILE__, __LINE__); + } + is->endSlice(); +} + +ClassInfoPtr +IcePHP::ObjectReader::getInfo() const +{ + return _info; +} + +zval* +IcePHP::ObjectReader::getObject() const +{ + return _object; +} + +// +// ReadObjectCallback implementation. +// +IcePHP::ReadObjectCallback::ReadObjectCallback(const ClassInfoPtr& info, const UnmarshalCallbackPtr& cb, + zval* target, void* closure TSRMLS_DC) : + _info(info), _cb(cb), _target(target), _closure(closure) +{ +#ifdef ZTS + this->TSRMLS_C = TSRMLS_C; +#endif + + // + // Keep a reference to the target to prevent it from being deallocated until the + // Ice object is actually read. + // + if(_target) + { + Z_ADDREF_P(_target); + } +} + +IcePHP::ReadObjectCallback::~ReadObjectCallback() +{ + if(_target) + { + zval_ptr_dtor(&_target); + } +} + +void +IcePHP::ReadObjectCallback::invoke(const Ice::ObjectPtr& p) +{ + if(p) + { + ObjectReaderPtr reader = ObjectReaderPtr::dynamicCast(p); + assert(reader); + + // + // Verify that the unmarshaled object is compatible with the formal type. + // + zval* obj = reader->getObject(); + if(!reader->getInfo()->isA(_info->id)) + { + Ice::UnexpectedObjectException ex(__FILE__, __LINE__); + ex.reason = "unmarshaled object is not an instance of " + _info->id; + ex.type = reader->getInfo()->id; + ex.expectedType = _info->id; + throw ex; + } + + _cb->unmarshaled(obj, _target, _closure TSRMLS_CC); + } + else + { + zval* zv; + MAKE_STD_ZVAL(zv); + AutoDestroy destroy(zv); + ZVAL_NULL(zv); + _cb->unmarshaled(zv, _target, _closure TSRMLS_CC); + } +} + +// +// ExceptionInfo implementation. +// +zval* +IcePHP::ExceptionInfo::unmarshal(const Ice::InputStreamPtr& is, const CommunicatorInfoPtr& comm TSRMLS_DC) +{ + zval* zv; + MAKE_STD_ZVAL(zv); + AutoDestroy destroy(zv); + + if(object_init_ex(zv, zce) != SUCCESS) + { + runtimeError("unable to initialize object of type %s" TSRMLS_CC, zce->name); + throw AbortMarshaling(); + } + + // + // NOTE: The type id for the first slice has already been read. + // + ExceptionInfoPtr info = this; + while(info) + { + is->startSlice(); + for(DataMemberList::iterator q = info->members.begin(); q != info->members.end(); ++q) + { + DataMemberPtr member = *q; + member->type->unmarshal(is, member, comm, zv, 0 TSRMLS_CC); + } + is->endSlice(); + + info = info->base; + if(info) + { + is->readString(); // Read the ID of the next slice. + } + } + + return destroy.release(); +} + +void +IcePHP::ExceptionInfo::print(zval* zv, IceUtilInternal::Output& out TSRMLS_DC) +{ + if(Z_TYPE_P(zv) != IS_OBJECT) + { + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected exception value of type %s but received %s" TSRMLS_CC, zce->name, s.c_str()); + return; + } + + // + // Compare class entries. + // + zend_class_entry* ce = Z_OBJCE_P(zv); + if(ce != zce) + { + invalidArgument("expected exception value of type %s but received %s" TSRMLS_CC, zce->name, ce->name); + return; + } + + PrintObjectHistory history; + history.index = 0; + + out << "exception " << id; + out.sb(); + printMembers(zv, out, &history TSRMLS_CC); + out.eb(); +} + +void +IcePHP::ExceptionInfo::printMembers(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC) +{ + if(base) + { + base->printMembers(zv, out, history TSRMLS_CC); + } + + for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + + out << nl << member->name << " = "; + void* data; + if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size() + 1, &data) == SUCCESS) + { + zval** val = reinterpret_cast<zval**>(data); + member->type->print(*val, out, history TSRMLS_CC); + } + else + { + out << "<not defined>"; + } + } +} + +bool +IcePHP::ExceptionInfo::isA(const string& typeId) const +{ + if(id == typeId) + { + return true; + } + + if(base && base->isA(typeId)) + { + return true; + } + + return false; +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleTypeInfoAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + Wrapper<TypeInfoPtr>* obj = Wrapper<TypeInfoPtr>::create(ce TSRMLS_CC); + assert(obj); + + result.handle = + zend_objects_store_put(obj, 0, reinterpret_cast<zend_objects_free_object_storage_t>(handleTypeInfoFreeStorage), + 0 TSRMLS_CC); + result.handlers = &_typeInfoHandlers; + + return result; +} + +#ifdef _WIN32 +extern "C" +#endif +static void +handleTypeInfoFreeStorage(void* p TSRMLS_DC) +{ + Wrapper<TypeInfoPtr>* obj = static_cast<Wrapper<TypeInfoPtr>*>(p); + delete obj->ptr; + zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); +} + +static bool +createTypeInfo(zval* zv, const TypeInfoPtr& p TSRMLS_DC) +{ + if(object_init_ex(zv, typeInfoClassEntry) != SUCCESS) + { + runtimeError("unable to initialize type" TSRMLS_CC); + return false; + } + + Wrapper<TypeInfoPtr>* ze = static_cast<Wrapper<TypeInfoPtr>*>(zend_object_store_get_object(zv TSRMLS_CC)); + assert(!ze->ptr); + ze->ptr = new TypeInfoPtr(p); + + return true; +} + +ZEND_FUNCTION(IcePHP_defineEnum) +{ + char* id; + int idLen; + zval* enumerators; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &id, &idLen, &enumerators) == FAILURE) + { + return; + } + + EnumInfoPtr type = new EnumInfo(); + type->id = id; + HashTable* arr = Z_ARRVAL_P(enumerators); + void* data; + HashPosition pos; + zend_hash_internal_pointer_reset_ex(arr, &pos); + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) + { + zval** val = reinterpret_cast<zval**>(data); + assert(Z_TYPE_PP(val) == IS_STRING); + type->enumerators.push_back(Z_STRVAL_PP(val)); + zend_hash_move_forward_ex(arr, &pos); + } + + if(!createTypeInfo(return_value, type TSRMLS_CC)) + { + RETURN_NULL(); + } +} + +static void +convertDataMembers(zval* zv, DataMemberList& l TSRMLS_DC) +{ + assert(Z_TYPE_P(zv) == IS_ARRAY); + HashTable* membersArray = Z_ARRVAL_P(zv); + void* data; + HashPosition pos; + zend_hash_internal_pointer_reset_ex(membersArray, &pos); + while(zend_hash_get_current_data_ex(membersArray, &data, &pos) != FAILURE) + { + zval** arr = reinterpret_cast<zval**>(data); + + DataMemberPtr m = new DataMember(); + zval** elem; + + assert(Z_TYPE_PP(arr) == IS_ARRAY); + HashTable* member = Z_ARRVAL_PP(arr); + assert(zend_hash_num_elements(member) == 2); + zend_hash_index_find(member, 0, reinterpret_cast<void**>(&elem)); + assert(Z_TYPE_PP(elem) == IS_STRING); + m->name = Z_STRVAL_PP(elem); + zend_hash_index_find(member, 1, reinterpret_cast<void**>(&elem)); + assert(Z_TYPE_PP(elem) == IS_OBJECT); + m->type = Wrapper<TypeInfoPtr>::value(*elem TSRMLS_CC); + l.push_back(m); + + zend_hash_move_forward_ex(membersArray, &pos); + } +} + +ZEND_FUNCTION(IcePHP_defineStruct) +{ + char* id; + int idLen; + char* name; + int nameLen; + zval* members; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssa", &id, &idLen, &name, &nameLen, &members) == FAILURE) + { + return; + } + + StructInfoPtr type = new StructInfo(); + type->id = id; + type->name = name; + convertDataMembers(members, type->members TSRMLS_CC); + type->zce = nameToClass(type->name TSRMLS_CC); + assert(type->zce); + + if(!createTypeInfo(return_value, type TSRMLS_CC)) + { + RETURN_NULL(); + } +} + +ZEND_FUNCTION(IcePHP_defineSequence) +{ + char* id; + int idLen; + zval* element; + zend_bool variableLength; + long minWireSize; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sobl", &id, &idLen, &element, &variableLength, + &minWireSize) == FAILURE) + { + return; + } + + SequenceInfoPtr type = new SequenceInfo(); + type->id = id; + type->elementType = Wrapper<TypeInfoPtr>::value(element TSRMLS_CC); + type->variableLength = variableLength ? true : false; + type->minWireSize = static_cast<int>(minWireSize); + + if(!createTypeInfo(return_value, type TSRMLS_CC)) + { + RETURN_NULL(); + } +} + +ZEND_FUNCTION(IcePHP_defineDictionary) +{ + char* id; + int idLen; + zval* key; + zval* value; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "soo", &id, &idLen, &key, &value) == FAILURE) + { + return; + } + + DictionaryInfoPtr type = new DictionaryInfo(); + type->id = id; + type->keyType = Wrapper<TypeInfoPtr>::value(key TSRMLS_CC); + type->valueType = Wrapper<TypeInfoPtr>::value(value TSRMLS_CC); + + if(!createTypeInfo(return_value, type TSRMLS_CC)) + { + RETURN_NULL(); + } +} + +ZEND_FUNCTION(IcePHP_defineProxy) +{ + zval* cls; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &cls) == FAILURE) + { + return; + } + + TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(cls TSRMLS_CC); + ClassInfoPtr c = ClassInfoPtr::dynamicCast(p); + assert(c); + + ProxyInfoPtr type = getProxyInfo(c->id TSRMLS_CC); + if(!type) + { + type = new ProxyInfo(); + type->id = c->id; + + ProxyInfoMap* m; + if(ICE_G(proxyInfoMap)) + { + m = reinterpret_cast<ProxyInfoMap*>(ICE_G(proxyInfoMap)); + } + else + { + m = new ProxyInfoMap; + ICE_G(proxyInfoMap) = m; + } + m->insert(ProxyInfoMap::value_type(type->id, type)); + } + + type->cls = c; + + if(!createTypeInfo(return_value, type TSRMLS_CC)) + { + RETURN_NULL(); + } +} + +ZEND_FUNCTION(IcePHP_declareClass) +{ + if(ZEND_NUM_ARGS() != 1) + { + WRONG_PARAM_COUNT; + } + + char* id; + int idLen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &idLen) == FAILURE) + { + return; + } + + ClassInfoPtr type = new ClassInfo(); + type->id = id; + type->defined = false; + + addClassInfoById(type TSRMLS_CC); + + if(!createTypeInfo(return_value, type TSRMLS_CC)) + { + RETURN_NULL(); + } +} + +ZEND_FUNCTION(IcePHP_defineClass) +{ + char* id; + int idLen; + char* name; + int nameLen; + zend_bool isAbstract; + zval* base; + zval* interfaces; + zval* members; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssbo!a!a!", &id, &idLen, &name, &nameLen, &isAbstract, &base, + &interfaces, &members) == FAILURE) + { + return; + } + + ClassInfoPtr type = getClassInfoById(id TSRMLS_CC); + if(!type) + { + type = new ClassInfo(); + type->id = id; + addClassInfoById(type TSRMLS_CC); + } + + type->name = name; + addClassInfoByName(type TSRMLS_CC); + + type->isAbstract = isAbstract ? true : false; + if(base) + { + TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(base TSRMLS_CC); + type->base = ClassInfoPtr::dynamicCast(p); + assert(type->base); + } + + if(interfaces) + { + HashTable* interfacesArray = Z_ARRVAL_P(interfaces); + void* data; + HashPosition pos; + zend_hash_internal_pointer_reset_ex(interfacesArray, &pos); + while(zend_hash_get_current_data_ex(interfacesArray, &data, &pos) != FAILURE) + { + zval** interfaceType = reinterpret_cast<zval**>(data); + TypeInfoPtr t = Wrapper<TypeInfoPtr>::value(*interfaceType TSRMLS_CC); + ClassInfoPtr c = ClassInfoPtr::dynamicCast(t); + assert(c); + type->interfaces.push_back(c); + zend_hash_move_forward_ex(interfacesArray, &pos); + } + } + + if(members) + { + convertDataMembers(members, type->members TSRMLS_CC); + } + + type->defined = true; + type->zce = nameToClass(type->name TSRMLS_CC); + assert(type->zce || type->id == "::Ice::LocalObject"); // LocalObject does not have a native PHP equivalent. + + if(!createTypeInfo(return_value, type TSRMLS_CC)) + { + RETURN_NULL(); + } +} + +#ifdef _WIN32 +extern "C" +#endif +static zend_object_value +handleExceptionInfoAlloc(zend_class_entry* ce TSRMLS_DC) +{ + zend_object_value result; + + Wrapper<ExceptionInfoPtr>* obj = Wrapper<ExceptionInfoPtr>::create(ce TSRMLS_CC); + assert(obj); + + result.handle = + zend_objects_store_put(obj, 0, + reinterpret_cast<zend_objects_free_object_storage_t>(handleExceptionInfoFreeStorage), 0 TSRMLS_CC); + result.handlers = &_exceptionInfoHandlers; + + return result; +} + +#ifdef _WIN32 +extern "C" +#endif +static void +handleExceptionInfoFreeStorage(void* p TSRMLS_DC) +{ + Wrapper<ExceptionInfoPtr>* obj = static_cast<Wrapper<ExceptionInfoPtr>*>(p); + delete obj->ptr; + zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC); +} + + +static bool +createExceptionInfo(zval* zv, const ExceptionInfoPtr& p TSRMLS_DC) +{ + if(object_init_ex(zv, exceptionInfoClassEntry) != SUCCESS) + { + runtimeError("unable to initialize exception info" TSRMLS_CC); + return false; + } + + Wrapper<ExceptionInfoPtr>* ze = static_cast<Wrapper<ExceptionInfoPtr>*>(zend_object_store_get_object(zv TSRMLS_CC)); + assert(!ze->ptr); + ze->ptr = new ExceptionInfoPtr(p); + + return true; +} + +ZEND_FUNCTION(IcePHP_defineException) +{ + char* id; + int idLen; + char* name; + int nameLen; + zval* base; + zval* members; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sso!a!", &id, &idLen, &name, &nameLen, &base, &members) == + FAILURE) + { + return; + } + + ExceptionInfoPtr ex = new ExceptionInfo(); + ex->id = id; + ex->name = name; + if(base) + { + ex->base = Wrapper<ExceptionInfoPtr>::value(base TSRMLS_CC); + } + if(members) + { + convertDataMembers(members, ex->members TSRMLS_CC); + } + + ex->usesClasses = false; + for(DataMemberList::iterator p = ex->members.begin(); p != ex->members.end(); ++p) + { + if(!ex->usesClasses) + { + ex->usesClasses = (*p)->type->usesClasses(); + } + } + + ex->zce = nameToClass(ex->name TSRMLS_CC); + + assert(!getExceptionInfo(ex->id TSRMLS_CC)); + + ExceptionInfoMap* m; + if(ICE_G(exceptionInfoMap)) + { + m = reinterpret_cast<ExceptionInfoMap*>(ICE_G(exceptionInfoMap)); + } + else + { + m = new ExceptionInfoMap; + ICE_G(exceptionInfoMap) = m; + } + m->insert(ExceptionInfoMap::value_type(ex->id, ex)); + + if(!createExceptionInfo(return_value, ex TSRMLS_CC)) + { + RETURN_NULL(); + } +} + +ZEND_FUNCTION(IcePHP_stringify) +{ + if(ZEND_NUM_ARGS() != 2) + { + WRONG_PARAM_COUNT; + } + + zval* v; + zval* t; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &v, &t) == FAILURE) + { + return; + } + + TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(t TSRMLS_CC); + assert(type); + + ostringstream ostr; + IceUtilInternal::Output out(ostr); + PrintObjectHistory history; + history.index = 0; + type->print(v, out, &history TSRMLS_CC); + + string str = ostr.str(); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); +} + +ZEND_FUNCTION(IcePHP_stringifyException) +{ + if(ZEND_NUM_ARGS() != 2) + { + WRONG_PARAM_COUNT; + } + + zval* v; + zval* t; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo", &v, &t) == FAILURE) + { + return; + } + + ExceptionInfoPtr ex = Wrapper<ExceptionInfoPtr>::value(t TSRMLS_CC); + assert(ex); + + ostringstream ostr; + IceUtilInternal::Output out(ostr); + ex->print(v, out TSRMLS_CC); + + string str = ostr.str(); + RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1); +} + +// +// Predefined methods for IcePHP_TypeInfo. +// +static function_entry _typeInfoMethods[] = +{ + {0, 0, 0} +}; + +// +// Predefined methods for IcePHP_ExceptionInfo. +// +static function_entry _exceptionInfoMethods[] = +{ + {0, 0, 0} +}; + +bool +IcePHP::typesInit(TSRMLS_D) +{ + zend_class_entry ce; + + // + // Register the IcePHP_TypeInfo class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_TypeInfo", _typeInfoMethods); + ce.create_object = handleTypeInfoAlloc; + typeInfoClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_typeInfoHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + + // + // Register the IcePHP_ExceptionInfo class. + // + INIT_CLASS_ENTRY(ce, "IcePHP_ExceptionInfo", _exceptionInfoMethods); + ce.create_object = handleExceptionInfoAlloc; + exceptionInfoClassEntry = zend_register_internal_class(&ce TSRMLS_CC); + memcpy(&_exceptionInfoHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + + return true; +} + +bool +IcePHP::typesRequestInit(TSRMLS_D) +{ + // + // Create the global variables for the primitive types. + // + for(int i = static_cast<int>(PrimitiveInfo::KindBool); i <= static_cast<int>(PrimitiveInfo::KindString); ++i) + { + PrimitiveInfoPtr type = new PrimitiveInfo(); + type->kind = static_cast<PrimitiveInfo::Kind>(i); + + zval* zv; + MAKE_STD_ZVAL(zv); + if(!createTypeInfo(zv, type TSRMLS_CC)) + { + zval_ptr_dtor(&zv); + return false; + } + string name = "IcePHP__t_" + type->getId(); + ZEND_SET_SYMBOL(&EG(symbol_table), const_cast<char*>(name.c_str()), zv); + } + + ICE_G(idToClassInfoMap) = 0; + ICE_G(nameToClassInfoMap) = 0; + ICE_G(proxyInfoMap) = 0; + ICE_G(exceptionInfoMap) = 0; + + return true; +} + +bool +IcePHP::typesRequestShutdown(TSRMLS_D) +{ + if(ICE_G(proxyInfoMap)) + { + ProxyInfoMap* m = static_cast<ProxyInfoMap*>(ICE_G(proxyInfoMap)); + for(ProxyInfoMap::iterator p = m->begin(); p != m->end(); ++p) + { + p->second->destroy(); + } + delete m; + } + + if(ICE_G(idToClassInfoMap)) + { + ClassInfoMap* m = static_cast<ClassInfoMap*>(ICE_G(idToClassInfoMap)); + for(ClassInfoMap::iterator p = m->begin(); p != m->end(); ++p) + { + p->second->destroy(); + } + delete m; + } + + if(ICE_G(nameToClassInfoMap)) + { + ClassInfoMap* m = static_cast<ClassInfoMap*>(ICE_G(nameToClassInfoMap)); + delete m; + } + + delete static_cast<ExceptionInfoMap*>(ICE_G(exceptionInfoMap)); + + return true; +} diff --git a/php/src/IcePHP/Types.h b/php/src/IcePHP/Types.h new file mode 100644 index 00000000000..c994201717d --- /dev/null +++ b/php/src/IcePHP/Types.h @@ -0,0 +1,465 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef ICEPHP_TYPES_H +#define ICEPHP_TYPES_H + +#include <Config.h> +#include <Communicator.h> +#include <Operation.h> +#include <Ice/Stream.h> +#include <IceUtil/OutputUtil.h> + +// +// Global functions. +// +extern "C" +{ +ZEND_FUNCTION(IcePHP_defineEnum); +ZEND_FUNCTION(IcePHP_defineStruct); +ZEND_FUNCTION(IcePHP_defineSequence); +ZEND_FUNCTION(IcePHP_defineDictionary); +ZEND_FUNCTION(IcePHP_defineProxy); +ZEND_FUNCTION(IcePHP_declareClass); +ZEND_FUNCTION(IcePHP_defineClass); +ZEND_FUNCTION(IcePHP_defineException); +ZEND_FUNCTION(IcePHP_stringify); +ZEND_FUNCTION(IcePHP_stringifyException); +} + +#define ICEPHP_TYPE_FUNCTIONS \ + ZEND_FE(IcePHP_defineEnum, NULL) \ + ZEND_FE(IcePHP_defineStruct, NULL) \ + ZEND_FE(IcePHP_defineSequence, NULL) \ + ZEND_FE(IcePHP_defineDictionary, NULL) \ + ZEND_FE(IcePHP_defineProxy, NULL) \ + ZEND_FE(IcePHP_declareClass, NULL) \ + ZEND_FE(IcePHP_defineClass, NULL) \ + ZEND_FE(IcePHP_defineException, NULL) \ + ZEND_FE(IcePHP_stringify, NULL) \ + ZEND_FE(IcePHP_stringifyException, NULL) + +namespace IcePHP +{ + +// +// This class is raised as an exception when object marshaling needs to be aborted. +// +class AbortMarshaling +{ +}; + +typedef std::map<unsigned int, Ice::ObjectPtr> ObjectMap; + +struct PrintObjectHistory +{ + int index; + std::map<unsigned int, int> objects; +}; + +// +// The delayed nature of class unmarshaling in the Ice protocol requires us to +// handle unmarshaling using a callback strategy. An instance of UnmarshalCallback +// is supplied to each type's unmarshal() member function. For all types except +// classes, the callback is invoked with the unmarshaled value before unmarshal() +// returns. For class instances, however, the callback may not be invoked until +// the stream's finished() function is called. +// +class UnmarshalCallback : public IceUtil::Shared +{ +public: + + virtual ~UnmarshalCallback(); + + // + // The unmarshaled() member function receives the unmarshaled value. The + // last two arguments are the values passed to unmarshal() for use by + // UnmarshalCallback implementations. + // + virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC) = 0; +}; +typedef IceUtil::Handle<UnmarshalCallback> UnmarshalCallbackPtr; + +// +// Base class for type information. +// +class TypeInfo : public UnmarshalCallback +{ +public: + + virtual std::string getId() const = 0; + + virtual bool validate(zval* TSRMLS_DC) = 0; + + virtual bool usesClasses(); // Default implementation returns false. + + virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC); // Default implementation is assert(false). + + virtual void destroy(); + +protected: + + TypeInfo(); + +public: + + // + // The marshal and unmarshal functions can raise Ice exceptions, and may raise + // AbortMarshaling if an error occurs. + // + virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC) = 0; + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, + zval*, void* TSRMLS_DC) = 0; + + virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC) = 0; +}; +typedef IceUtil::Handle<TypeInfo> TypeInfoPtr; + +// +// Primitive type information. +// +class PrimitiveInfo : public TypeInfo +{ +public: + + virtual std::string getId() const; + + virtual bool validate(zval* TSRMLS_DC); + + virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, + zval*, void* TSRMLS_DC); + + virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC); + + enum Kind + { + KindBool, + KindByte, + KindShort, + KindInt, + KindLong, + KindFloat, + KindDouble, + KindString + }; + + Kind kind; +}; +typedef IceUtil::Handle<PrimitiveInfo> PrimitiveInfoPtr; + +// +// Enum information. +// +class EnumInfo : public TypeInfo +{ +public: + + virtual std::string getId() const; + + virtual bool validate(zval* TSRMLS_DC); + + virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, + zval*, void* TSRMLS_DC); + + virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC); + + std::string id; + Ice::StringSeq enumerators; +}; +typedef IceUtil::Handle<EnumInfo> EnumInfoPtr; + +class DataMember : public UnmarshalCallback +{ +public: + + virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC); + + std::string name; + TypeInfoPtr type; +}; +typedef IceUtil::Handle<DataMember> DataMemberPtr; +typedef std::vector<DataMemberPtr> DataMemberList; + +// +// Struct information. +// +class StructInfo : public TypeInfo +{ +public: + + virtual std::string getId() const; + + virtual bool validate(zval* TSRMLS_DC); + + virtual bool usesClasses(); + + virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, + zval*, void* TSRMLS_DC); + + virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC); + + virtual void destroy(); + + std::string id; + std::string name; // PHP class name + DataMemberList members; + zend_class_entry* zce; +}; +typedef IceUtil::Handle<StructInfo> StructInfoPtr; + +// +// Sequence information. +// +class SequenceInfo : public TypeInfo +{ +public: + + virtual std::string getId() const; + + virtual bool validate(zval* TSRMLS_DC); + + virtual bool usesClasses(); + + virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, + zval*, void* TSRMLS_DC); + + virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC); + + virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC); + + virtual void destroy(); + + std::string id; + TypeInfoPtr elementType; + bool variableLength; + int minWireSize; + +private: + + void marshalPrimitiveSequence(const PrimitiveInfoPtr&, zval*, const Ice::OutputStreamPtr& TSRMLS_DC); + void unmarshalPrimitiveSequence(const PrimitiveInfoPtr&, const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, + zval*, void* TSRMLS_DC); +}; +typedef IceUtil::Handle<SequenceInfo> SequenceInfoPtr; + +// +// Dictionary information. +// +class DictionaryInfo : public TypeInfo +{ +public: + + virtual std::string getId() const; + + virtual bool validate(zval* TSRMLS_DC); + + virtual bool usesClasses(); + + virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, + zval*, void* TSRMLS_DC); + + virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC); + + virtual void destroy(); + + class KeyCallback : public UnmarshalCallback + { + public: + + KeyCallback(); + ~KeyCallback(); + + virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC); + + zval* key; + }; + typedef IceUtil::Handle<KeyCallback> KeyCallbackPtr; + + class ValueCallback : public UnmarshalCallback + { + public: + + ValueCallback(zval* TSRMLS_DC); + ~ValueCallback(); + + virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC); + + zval* key; + }; + typedef IceUtil::Handle<ValueCallback> ValueCallbackPtr; + + std::string id; + TypeInfoPtr keyType; + TypeInfoPtr valueType; +}; +typedef IceUtil::Handle<DictionaryInfo> DictionaryInfoPtr; + +class ExceptionInfo; +typedef IceUtil::Handle<ExceptionInfo> ExceptionInfoPtr; +typedef std::vector<ExceptionInfoPtr> ExceptionInfoList; + +class ClassInfo; +typedef IceUtil::Handle<ClassInfo> ClassInfoPtr; +typedef std::vector<ClassInfoPtr> ClassInfoList; + +typedef std::vector<TypeInfoPtr> TypeInfoList; + +class ClassInfo : public TypeInfo +{ +public: + + virtual std::string getId() const; + + virtual bool validate(zval* TSRMLS_DC); + + virtual bool usesClasses(); + + virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, + zval*, void* TSRMLS_DC); + + virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC); + + virtual void destroy(); + + void printMembers(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC); + + bool isA(const std::string&) const; + + void addOperation(const std::string&, const OperationPtr&); + OperationPtr getOperation(const std::string&) const; + + std::string id; + std::string name; // PHP class name + bool isAbstract; + ClassInfoPtr base; + ClassInfoList interfaces; + DataMemberList members; + bool defined; + zend_class_entry* zce; + + typedef std::map<std::string, OperationPtr> OperationMap; + OperationMap operations; +}; + +// +// Proxy information. +// +class ProxyInfo : public TypeInfo +{ +public: + + virtual std::string getId() const; + + virtual bool validate(zval* TSRMLS_DC); + + virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, + zval*, void* TSRMLS_DC); + + virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC); + + virtual void destroy(); + + std::string id; + ClassInfoPtr cls; +}; +typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr; + +// +// Exception information. +// +class ExceptionInfo : public IceUtil::Shared +{ +public: + + zval* unmarshal(const Ice::InputStreamPtr&, const CommunicatorInfoPtr& TSRMLS_DC); + + void print(zval*, IceUtilInternal::Output& TSRMLS_DC); + void printMembers(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC); + + bool isA(const std::string&) const; + + std::string id; + std::string name; // PHP class name + ExceptionInfoPtr base; + DataMemberList members; + bool usesClasses; + zend_class_entry* zce; +}; + +ClassInfoPtr getClassInfoById(const std::string& TSRMLS_DC); +ClassInfoPtr getClassInfoByName(const std::string& TSRMLS_DC); +ExceptionInfoPtr getExceptionInfo(const std::string& TSRMLS_DC); + +bool typesInit(TSRMLS_D); +bool typesRequestInit(TSRMLS_D); +bool typesRequestShutdown(TSRMLS_D); + +// +// ObjectWriter wraps a PHP object for marshaling. +// +class ObjectWriter : public Ice::ObjectWriter +{ +public: + + ObjectWriter(const ClassInfoPtr&, zval*, ObjectMap* TSRMLS_DC); + ~ObjectWriter(); + + virtual void ice_preMarshal(); + + virtual void write(const Ice::OutputStreamPtr&) const; + +private: + + ClassInfoPtr _info; + zval* _object; + ObjectMap* _map; +#if ZTS + TSRMLS_D; +#endif +}; + +// +// ObjectReader unmarshals the state of an Ice object. +// +class ObjectReader : public Ice::ObjectReader +{ +public: + + ObjectReader(zval*, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC); + ~ObjectReader(); + + virtual void ice_postUnmarshal(); + + virtual void read(const Ice::InputStreamPtr&, bool); + + virtual ClassInfoPtr getInfo() const; + + zval* getObject() const; + +private: + + zval* _object; + ClassInfoPtr _info; + CommunicatorInfoPtr _communicator; +#if ZTS + TSRMLS_D; +#endif +}; +typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr; + +} // End of namespace IcePHP + +#endif diff --git a/php/src/IcePHP/Util.cpp b/php/src/IcePHP/Util.cpp index 693d8a5385c..da6e282e4ff 100644 --- a/php/src/IcePHP/Util.cpp +++ b/php/src/IcePHP/Util.cpp @@ -8,86 +8,97 @@ // ********************************************************************** #include <Util.h> -#include <IceUtil/DisableWarnings.h> +#include <IceUtil/UUID.h> +#include <Slice/PHPUtil.h> #include <algorithm> #include <ctype.h> using namespace std; using namespace IcePHP; +using namespace Slice::PHP; -static string -lookupKwd(const string& name) +#ifdef _WIN32 +extern "C" +#endif +static void +dtor_wrapper(void* p) { - string lower = lowerCase(name); // PHP is case insensitive. + zval_ptr_dtor(static_cast<zval**>(p)); +} - // - // Keyword list. *Must* be kept in alphabetical order. - // - static const string keywordList[] = - { - "abstract", "and", "array", "as", "break", "case", "catch", "class", "clone", "const", "continue", "declare", - "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif", - "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "if", - "implements", "include", "include_once", "interface", "isset", "list", "new", "or", "print", "private", - "protected", "public", "require", "require_once", "return", "static", "switch", "this", "throw", "try", - "unset", "use", "var", "while", "xor" - }; - bool found = binary_search(&keywordList[0], - &keywordList[sizeof(keywordList) / sizeof(*keywordList)], - lower); - return found ? "_" + name : name; +void* +IcePHP::createWrapper(zend_class_entry* ce, size_t sz TSRMLS_DC) +{ + zend_object* obj; + zval* tmp; + + obj = static_cast<zend_object*>(emalloc(sz)); + obj->ce = ce; + obj->guards = 0; + + obj->properties = static_cast<HashTable*>(emalloc(sizeof(HashTable))); + zend_hash_init(obj->properties, 0, 0, dtor_wrapper, 0); + zend_hash_copy(obj->properties, &ce->default_properties, (copy_ctor_func_t)zval_add_ref, &tmp, sizeof(zval*)); + + return obj; } -// -// Split a scoped name into its components and return the components as a list of (unscoped) identifiers. -// -static vector<string> -splitScopedName(const string& scoped) +void* +IcePHP::extractWrapper(zval* zv TSRMLS_DC) { - assert(scoped[0] == ':'); - vector<string> ids; - string::size_type next = 0; - string::size_type pos; - while((pos = scoped.find("::", next)) != string::npos) - { - pos += 2; - if(pos != scoped.size()) - { - string::size_type endpos = scoped.find("::", pos); - if(endpos != string::npos) - { - ids.push_back(scoped.substr(pos, endpos - pos)); - } - } - next = pos; - } - if(next != scoped.size()) + if(!zv) { - ids.push_back(scoped.substr(next)); + runtimeError("method %s() must be invoked on an object" TSRMLS_CC, get_active_function_name(TSRMLS_C)); + return 0; } - else + + zend_object* obj = static_cast<zend_object*>(zend_object_store_get_object(zv TSRMLS_CC)); + if(!obj) { - ids.push_back(""); + runtimeError("no object found in %s()" TSRMLS_CC, get_active_function_name(TSRMLS_C)); + return 0; } - return ids; + return obj; +} + +zend_class_entry* +IcePHP::idToClass(const string& id TSRMLS_DC) +{ +#ifdef ICEPHP_USE_NAMESPACES + string cls = scopedToName(id, true); +#else + string cls = scopedToName(id, false); +#endif + + return nameToClass(cls TSRMLS_CC); +} + +zend_class_entry* +IcePHP::nameToClass(const string& name TSRMLS_DC) +{ + zend_class_entry** result; + if(zend_lookup_class(STRCAST(name.c_str()), name.length(), &result TSRMLS_CC) == FAILURE) + { + return 0; + } + return *result; } bool IcePHP::createIdentity(zval* zv, const Ice::Identity& id TSRMLS_DC) { - zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC); + zend_class_entry* cls = idToClass("::Ice::Identity" TSRMLS_CC); assert(cls); if(object_init_ex(zv, cls) != SUCCESS) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize Ice::Identity"); + runtimeError("unable to initialize Ice::Identity" TSRMLS_CC); return false; } - zend_update_property_string(cls, zv, "name", sizeof("name") - 1, const_cast<char*>(id.name.c_str()) TSRMLS_CC); - zend_update_property_string(cls, zv, "category", sizeof("category") - 1, - const_cast<char*>(id.category.c_str()) TSRMLS_CC); + zend_update_property_string(cls, zv, "name", sizeof("name") - 1, STRCAST(id.name.c_str()) TSRMLS_CC); + zend_update_property_string(cls, zv, "category", sizeof("category") - 1, STRCAST(id.category.c_str()) TSRMLS_CC); return true; } @@ -97,17 +108,17 @@ IcePHP::extractIdentity(zval* zv, Ice::Identity& id TSRMLS_DC) { if(Z_TYPE_P(zv) != IS_OBJECT) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "value does not contain an object"); + invalidArgument("value does not contain an object" TSRMLS_CC); return false; } - zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC); + zend_class_entry* cls = idToClass("::Ice::Identity" TSRMLS_CC); assert(cls); zend_class_entry* ce = Z_OBJCE_P(zv); if(ce != cls) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected an identity but received %s", ce->name); + invalidArgument("expected an identity but received %s" TSRMLS_CC, ce->name); return false; } @@ -118,7 +129,7 @@ IcePHP::extractIdentity(zval* zv, Ice::Identity& id TSRMLS_DC) void* nameData; if(zend_hash_find(Z_OBJPROP_P(zv), "name", sizeof("name"), &nameData) == FAILURE) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "identity value does not contain member `name'"); + invalidArgument("identity value does not contain member `name'" TSRMLS_CC); return false; } zend_hash_find(Z_OBJPROP_P(zv), "category", sizeof("category"), &categoryData); @@ -128,16 +139,14 @@ IcePHP::extractIdentity(zval* zv, Ice::Identity& id TSRMLS_DC) if(Z_TYPE_PP(nameVal) != IS_STRING) { string s = zendTypeToString(Z_TYPE_PP(nameVal)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected a string value for identity member `name' but received %s", - s.c_str()); + invalidArgument("expected a string value for identity member `name' but received %s" TSRMLS_CC, s.c_str()); return false; } if(categoryVal && Z_TYPE_PP(categoryVal) != IS_STRING && Z_TYPE_PP(categoryVal) != IS_NULL) { string s = zendTypeToString(Z_TYPE_PP(categoryVal)); - php_error_docref(0 TSRMLS_CC, E_ERROR, - "expected a string value for identity member `category' but received %s", s.c_str()); + invalidArgument("expected a string value for identity member `category' but received %s" TSRMLS_CC, s.c_str()); return false; } @@ -155,28 +164,28 @@ IcePHP::extractIdentity(zval* zv, Ice::Identity& id TSRMLS_DC) } bool -IcePHP::createContext(zval* zv, const Ice::Context& ctx TSRMLS_DC) +IcePHP::createStringMap(zval* zv, const map<string, string>& ctx TSRMLS_DC) { array_init(zv); - for(Ice::Context::const_iterator p = ctx.begin(); p != ctx.end(); ++p) + for(map<string, string>::const_iterator p = ctx.begin(); p != ctx.end(); ++p) { - zval* val; - MAKE_STD_ZVAL(val); - ZVAL_STRINGL(val, const_cast<char*>(p->second.c_str()), p->second.length(), 1); - add_assoc_zval_ex(zv, const_cast<char*>(p->first.c_str()), p->first.length() + 1, val); + if(add_assoc_stringl_ex(zv, const_cast<char*>(p->first.c_str()), p->first.length() + 1, + const_cast<char*>(p->second.c_str()), p->second.length(), 1) == FAILURE) + { + return false; + } } return true; } bool -IcePHP::extractContext(zval* zv, Ice::Context& ctx TSRMLS_DC) +IcePHP::extractStringMap(zval* zv, map<string, string>& ctx TSRMLS_DC) { if(Z_TYPE_P(zv) != IS_ARRAY) { string s = zendTypeToString(Z_TYPE_P(zv)); - php_error_docref(0 TSRMLS_CC, E_ERROR, "expected an array for the context argument but received %s", - s.c_str()); + invalidArgument("expected an associative array but received %s" TSRMLS_CC, s.c_str()); return false; } @@ -202,13 +211,13 @@ IcePHP::extractContext(zval* zv, Ice::Context& ctx TSRMLS_DC) // if(keyType != HASH_KEY_IS_STRING) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "context key must be a string"); + invalidArgument("array key must be a string" TSRMLS_CC); return false; } if(Z_TYPE_PP(val) != IS_STRING) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "context value must be a string"); + invalidArgument("array value must be a string" TSRMLS_CC); return false; } @@ -220,384 +229,288 @@ IcePHP::extractContext(zval* zv, Ice::Context& ctx TSRMLS_DC) return true; } -#ifdef _WIN32 -extern "C" -#endif -static void -dtor_wrapper(void* p) -{ - zval_ptr_dtor(static_cast<zval**>(p)); -} - -ice_object* -IcePHP::newObject(zend_class_entry* ce TSRMLS_DC) +bool +IcePHP::createStringArray(zval* zv, const Ice::StringSeq& seq TSRMLS_DC) { - ice_object* obj; - zval* tmp; - - obj = static_cast<ice_object*>(emalloc(sizeof(ice_object))); - obj->zobj.ce = ce; - obj->zobj.guards = 0; - obj->ptr = 0; - - obj->zobj.properties = static_cast<HashTable*>(emalloc(sizeof(HashTable))); - zend_hash_init(obj->zobj.properties, 0, 0, dtor_wrapper, 0); - zend_hash_copy(obj->zobj.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, &tmp, - sizeof(zval*)); + array_init(zv); + for(Ice::StringSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) + { + if(add_next_index_stringl(zv, STRCAST(p->c_str()), p->length(), 1) == FAILURE) + { + return false; + } + } - return obj; + return true; } -ice_object* -IcePHP::getObject(zval* zv TSRMLS_DC) +bool +IcePHP::extractStringArray(zval* zv, Ice::StringSeq& seq TSRMLS_DC) { - if(!zv) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "method %s() must be invoked on an object", - get_active_function_name(TSRMLS_C)); - return 0; - } - - ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC)); - if(!obj) + if(Z_TYPE_P(zv) != IS_ARRAY) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "no object found in %s()", get_active_function_name(TSRMLS_C)); - return 0; + string s = zendTypeToString(Z_TYPE_P(zv)); + invalidArgument("expected an array of strings but received %s" TSRMLS_CC, s.c_str()); + return false; } - return obj; -} + HashTable* arr = Z_ARRVAL_P(zv); + void* data; + HashPosition pos; -void -IcePHP::throwException(const IceUtil::Exception& ex TSRMLS_DC) -{ - try + zend_hash_internal_pointer_reset_ex(arr, &pos); + while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE) { - try + zval** val = reinterpret_cast<zval**>(data); + + if(Z_TYPE_PP(val) != IS_STRING) { - ex.ice_throw(); + invalidArgument("array element must be a string" TSRMLS_CC); + return false; } - catch(const Ice::TwowayOnlyException& e) - { - string name = e.ice_name(); - zend_class_entry* cls = findClassScoped(name TSRMLS_CC); - if(!cls) - { - throw; - } - zval* zex; - MAKE_STD_ZVAL(zex); - if(object_init_ex(zex, cls) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return; - } + string s(Z_STRVAL_PP(val), Z_STRLEN_PP(val)); + seq.push_back(s); - // - // Set the unknown member. - // - zend_update_property_string(cls, zex, "operation", sizeof("operation") - 1, - const_cast<char*>(e.operation.c_str()) TSRMLS_CC); + zend_hash_move_forward_ex(arr, &pos); + } - // - // Throw the exception. - // - zend_throw_exception_object(zex TSRMLS_CC); - } - catch(const Ice::UnknownException& e) - { - string name = e.ice_name(); - zend_class_entry* cls = findClassScoped(name TSRMLS_CC); - if(!cls) - { - throw; - } + return true; +} - zval* zex; - MAKE_STD_ZVAL(zex); - if(object_init_ex(zex, cls) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return; - } +static void +setStringMember(zval* obj, const string& name, const string& val TSRMLS_DC) +{ + zend_class_entry* cls = Z_OBJCE_P(obj); + assert(cls); + zend_update_property_stringl(cls, obj, const_cast<char*>(name.c_str()), static_cast<int>(name.size()), + const_cast<char*>(val.c_str()), static_cast<int>(val.size()) TSRMLS_CC); +} - // - // Set the unknown member. - // - zend_update_property_string(cls, zex, "unknown", sizeof("unknown") - 1, - const_cast<char*>(e.unknown.c_str()) TSRMLS_CC); +static bool +convertLocalException(const Ice::LocalException& ex, zval* zex TSRMLS_DC) +{ + zend_class_entry* cls = Z_OBJCE_P(zex); + assert(cls); - // - // Throw the exception. - // - zend_throw_exception_object(zex TSRMLS_CC); - } - catch(const Ice::RequestFailedException& e) + // + // Transfer data members from Ice exception to PHP object. + // + try + { + ex.ice_throw(); + } + catch(const Ice::InitializationException& e) + { + setStringMember(zex, "reason", e.reason TSRMLS_CC); + } + catch(const Ice::PluginInitializationException& e) + { + setStringMember(zex, "reason", e.reason TSRMLS_CC); + } + catch(const Ice::AlreadyRegisteredException& e) + { + setStringMember(zex, "kindOfObject", e.kindOfObject TSRMLS_CC); + setStringMember(zex, "id", e.id TSRMLS_CC); + } + catch(const Ice::NotRegisteredException& e) + { + setStringMember(zex, "kindOfObject", e.kindOfObject TSRMLS_CC); + setStringMember(zex, "id", e.id TSRMLS_CC); + } + catch(const Ice::TwowayOnlyException& e) + { + setStringMember(zex, "operation", e.operation TSRMLS_CC); + } + catch(const Ice::UnknownException& e) + { + setStringMember(zex, "unknown", e.unknown TSRMLS_CC); + } + catch(const Ice::ObjectAdapterDeactivatedException& e) + { + setStringMember(zex, "name", e.name TSRMLS_CC); + } + catch(const Ice::ObjectAdapterIdInUseException& e) + { + setStringMember(zex, "id", e.id TSRMLS_CC); + } + catch(const Ice::NoEndpointException& e) + { + setStringMember(zex, "proxy", e.proxy TSRMLS_CC); + } + catch(const Ice::EndpointParseException& e) + { + setStringMember(zex, "str", e.str TSRMLS_CC); + } + catch(const Ice::IdentityParseException& e) + { + setStringMember(zex, "str", e.str TSRMLS_CC); + } + catch(const Ice::ProxyParseException& e) + { + setStringMember(zex, "str", e.str TSRMLS_CC); + } + catch(const Ice::IllegalIdentityException& e) + { + zval* id; + MAKE_STD_ZVAL(id); + if(!createIdentity(id, e.id TSRMLS_CC)) { - string name = e.ice_name(); - zend_class_entry* cls = findClassScoped(name TSRMLS_CC); - if(!cls) - { - throw; - } - - zval* zex; - MAKE_STD_ZVAL(zex); - if(object_init_ex(zex, cls) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return; - } - - // - // Set the id member. - // - zval* id; - MAKE_STD_ZVAL(id); - if(!createIdentity(id, e.id TSRMLS_CC)) - { - return; - } - zend_update_property(cls, zex, "id", sizeof("id") - 1, id TSRMLS_CC); - - // - // Set the facet member. - // - zval* facet; - MAKE_STD_ZVAL(facet); - ZVAL_STRINGL(facet, const_cast<char*>(e.facet.c_str()), e.facet.length(), 1); - zend_update_property(cls, zex, "facet", sizeof("facet") - 1, facet TSRMLS_CC); - - // - // Set the operation member. - // - zend_update_property_string(cls, zex, "operation", sizeof("operation") - 1, - const_cast<char*>(e.operation.c_str()) TSRMLS_CC); - - // - // Throw the exception. - // - zend_throw_exception_object(zex TSRMLS_CC); + zval_ptr_dtor(&id); + return false; } - catch(const Ice::NoObjectFactoryException& e) + zend_update_property(cls, zex, "id", sizeof("id") - 1, id TSRMLS_CC); + } + catch(const Ice::RequestFailedException& e) + { + zval* id; + MAKE_STD_ZVAL(id); + if(!createIdentity(id, e.id TSRMLS_CC)) { - string name = e.ice_name(); - zend_class_entry* cls = findClassScoped(name TSRMLS_CC); - if(!cls) - { - throw; - } - - zval* zex; - MAKE_STD_ZVAL(zex); - if(object_init_ex(zex, cls) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return; - } - - // - // Set the reason member. - // - zend_update_property_string(cls, zex, "reason", sizeof("reason") - 1, - const_cast<char*>(e.reason.c_str()) TSRMLS_CC); - - // - // Set the type member. - // - zend_update_property_string(cls, zex, "type", sizeof("type") - 1, const_cast<char*>(e.type.c_str()) - TSRMLS_CC); - - // - // Throw the exception. - // - zend_throw_exception_object(zex TSRMLS_CC); + zval_ptr_dtor(&id); + return false; } - catch(const Ice::UnexpectedObjectException& e) - { - string name = e.ice_name(); - zend_class_entry* cls = findClassScoped(name TSRMLS_CC); - if(!cls) - { - throw; - } - - zval* zex; - MAKE_STD_ZVAL(zex); - if(object_init_ex(zex, cls) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return; - } + zend_update_property(cls, zex, "id", sizeof("id") - 1, id TSRMLS_CC); + setStringMember(zex, "facet", e.facet TSRMLS_CC); + setStringMember(zex, "operation", e.operation TSRMLS_CC); + } + catch(const Ice::FileException& e) + { + zend_update_property_long(cls, zex, "error", sizeof("error") - 1, e.error TSRMLS_CC); + setStringMember(zex, "path", e.path TSRMLS_CC); + } + catch(const Ice::SyscallException& e) // This must appear after all subclasses of SyscallException. + { + zend_update_property_long(cls, zex, "error", sizeof("error") - 1, e.error TSRMLS_CC); + } + catch(const Ice::DNSException& e) + { + zend_update_property_long(cls, zex, "error", sizeof("error") - 1, e.error TSRMLS_CC); + setStringMember(zex, "host", e.host TSRMLS_CC); + } + catch(const Ice::UnsupportedProtocolException& e) + { + zend_update_property_long(cls, zex, "badMajor", sizeof("badMajor") - 1, e.badMajor TSRMLS_CC); + zend_update_property_long(cls, zex, "badMinor", sizeof("badMinor") - 1, e.badMinor TSRMLS_CC); + zend_update_property_long(cls, zex, "major", sizeof("major") - 1, e.major TSRMLS_CC); + zend_update_property_long(cls, zex, "minor", sizeof("minor") - 1, e.minor TSRMLS_CC); + } + catch(const Ice::UnsupportedEncodingException& e) + { + zend_update_property_long(cls, zex, "badMajor", sizeof("badMajor") - 1, e.badMajor TSRMLS_CC); + zend_update_property_long(cls, zex, "badMinor", sizeof("badMinor") - 1, e.badMinor TSRMLS_CC); + zend_update_property_long(cls, zex, "major", sizeof("major") - 1, e.major TSRMLS_CC); + zend_update_property_long(cls, zex, "minor", sizeof("minor") - 1, e.minor TSRMLS_CC); + } + catch(const Ice::NoObjectFactoryException& e) + { + setStringMember(zex, "reason", e.reason TSRMLS_CC); + setStringMember(zex, "type", e.type TSRMLS_CC); + } + catch(const Ice::UnexpectedObjectException& e) + { + setStringMember(zex, "reason", e.reason TSRMLS_CC); + setStringMember(zex, "type", e.type TSRMLS_CC); + setStringMember(zex, "expectedType", e.expectedType TSRMLS_CC); + } + catch(const Ice::ProtocolException& e) // This must appear after all subclasses of ProtocolException. + { + setStringMember(zex, "reason", e.reason TSRMLS_CC); + } + catch(const Ice::FeatureNotSupportedException& e) + { + setStringMember(zex, "unsupportedFeature", e.unsupportedFeature TSRMLS_CC); + } + catch(const Ice::SecurityException& e) + { + setStringMember(zex, "reason", e.reason TSRMLS_CC); + } + catch(const Ice::LocalException&) + { + // + // Nothing to do. + // + } - // - // Set the reason member. - // - zend_update_property_string(cls, zex, "reason", sizeof("reason") - 1, - const_cast<char*>(e.reason.c_str()) TSRMLS_CC); - - // - // Set the type and exptected type members. - // - zend_update_property_string(cls, zex, "type", sizeof("type") - 1, const_cast<char*>(e.type.c_str()) - TSRMLS_CC); - zend_update_property_string(cls, zex, "expectedType", sizeof("expectedType") - 1, - const_cast<char*>(e.expectedType.c_str()) TSRMLS_CC); - - // - // Throw the exception. - // - zend_throw_exception_object(zex TSRMLS_CC); - } - catch(const Ice::MarshalException& e) - { - string name = e.ice_name(); - zend_class_entry* cls = findClassScoped(name TSRMLS_CC); - if(!cls) - { - throw; - } + return true; +} - zval* zex; - MAKE_STD_ZVAL(zex); - if(object_init_ex(zex, cls) != SUCCESS) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return; - } +zval* +IcePHP::convertException(const Ice::Exception& ex TSRMLS_DC) +{ + zval* zex; + MAKE_STD_ZVAL(zex); + AutoDestroy destroy(zex); - // - // Set the reason member. - // - zend_update_property_string(cls, zex, "reason", sizeof("reason") - 1, - const_cast<char*>(e.reason.c_str()) TSRMLS_CC); + ostringstream ostr; + ostr << ex; + string str = ostr.str(); - // - // Throw the exception. - // - zend_throw_exception_object(zex TSRMLS_CC); - } + try + { + ex.ice_throw(); } catch(const Ice::LocalException& e) { - zval* zex; - MAKE_STD_ZVAL(zex); - - // - // See if we have a PHP class for the exception, otherwise raise UnknownLocalException. - // - string name = e.ice_name(); - zend_class_entry* cls = findClassScoped(name TSRMLS_CC); + zend_class_entry* cls = idToClass(e.ice_name() TSRMLS_CC); if(cls) { if(object_init_ex(zex, cls) != SUCCESS) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return; + runtimeError("unable to create exception %s" TSRMLS_CC, cls->name); + return 0; + } + if(!convertLocalException(e, zex TSRMLS_CC)) + { + return 0; } } else { - cls = findClass("Ice_UnknownLocalException" TSRMLS_CC); - if(!cls) - { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to find class Ice_UnknownLocalException"); - return; - } - + cls = idToClass("Ice::UnknownLocalException" TSRMLS_CC); + assert(cls); if(object_init_ex(zex, cls) != SUCCESS) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name); - return; + runtimeError("unable to create exception %s" TSRMLS_CC, cls->name); + return 0; } - - // - // Set the unknown member. - // - ostringstream ostr; - e.ice_print(ostr); - string str = ostr.str(); - zend_update_property_string(cls, zex, "unknown", sizeof("unknown") - 1, - const_cast<char*>(str.c_str()) TSRMLS_CC); + setStringMember(zex, "unknown", str TSRMLS_CC); } - - // - // Throw the exception. - // - zend_throw_exception_object(zex TSRMLS_CC); } catch(const Ice::UserException&) { - assert(false); - } - catch(const IceUtil::Exception& e) - { - ostringstream ostr; - e.ice_print(ostr); - php_error_docref(0 TSRMLS_CC, E_ERROR, "exception: %s", ostr.str().c_str()); - } -} - -zend_class_entry* -IcePHP::findClass(const string& flat TSRMLS_DC) -{ - zend_class_entry** result; - string lower = lowerCase(flat); - if(zend_lookup_class(const_cast<char*>(lower.c_str()), lower.length(), &result TSRMLS_CC) == FAILURE) - { - return 0; - } - return *result; -} - -zend_class_entry* -IcePHP::findClassScoped(const string& scoped TSRMLS_DC) -{ - return findClass(flatten(scoped) TSRMLS_CC); -} - -string -IcePHP::lowerCase(const string& s) -{ - string result(s); - transform(result.begin(), result.end(), result.begin(), ::tolower); - return result; -} - -string -IcePHP::flatten(const string& scoped) -{ - string result = scoped; - if(result.find("::") == 0) - { - result.erase(0, 2); + zend_class_entry* cls = idToClass("Ice::UnknownUserException" TSRMLS_CC); + assert(cls); + if(object_init_ex(zex, cls) != SUCCESS) + { + runtimeError("unable to create exception %s" TSRMLS_CC, cls->name); + return 0; + } + setStringMember(zex, "unknown", str TSRMLS_CC); } - - string::size_type pos; - while((pos = result.find("::")) != string::npos) + catch(const Ice::Exception&) { - result.replace(pos, 2, "_"); + zend_class_entry* cls = idToClass("Ice::UnknownException" TSRMLS_CC); + assert(cls); + if(object_init_ex(zex, cls) != SUCCESS) + { + runtimeError("unable to create exception %s" TSRMLS_CC, cls->name); + return 0; + } + setStringMember(zex, "unknown", str TSRMLS_CC); } - return fixIdent(result); + return destroy.release(); } -string -IcePHP::fixIdent(const string& ident) +void +IcePHP::throwException(const Ice::Exception& ex TSRMLS_DC) { - if(ident[0] != ':') - { - return lookupKwd(ident); - } - vector<string> ids = splitScopedName(ident); - transform(ids.begin(), ids.end(), ids.begin(), ptr_fun(lookupKwd)); - stringstream result; - for(vector<string>::const_iterator i = ids.begin(); i != ids.end(); ++i) + zval* zex = convertException(ex TSRMLS_CC); + if(zex) { - result << "::" + *i; + zend_throw_exception_object(zex TSRMLS_CC); } - return result.str(); } std::string @@ -643,36 +556,128 @@ IcePHP::zendTypeToString(int type) return result; } -bool -IcePHP::isNativeKey(const Slice::TypePtr& type) +static void +throwError(const string& name, const string& msg TSRMLS_DC) { + zval* ex; + MAKE_STD_ZVAL(ex); + AutoDestroy destroy(ex); + + zend_class_entry* cls; + { + zend_class_entry** p; + if(zend_lookup_class(STRCAST(name.c_str()), name.size(), &p TSRMLS_CC) == FAILURE) + { + assert(false); + } + cls = *p; + } + if(object_init_ex(ex, cls) == FAILURE) + { + assert(false); + } + // - // PHP's native associative array supports only integer and string types for the key. - // For Slice dictionaries that meet this criteria, we use the native array type. + // Invoke constructor. // - Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type); - if(b) + if(!invokeMethod(ex, ZEND_CONSTRUCTOR_FUNC_NAME, msg TSRMLS_CC)) { - switch(b->kind()) - { - case Slice::Builtin::KindByte: - case Slice::Builtin::KindBool: // We allow bool even though PHP doesn't support it directly. - case Slice::Builtin::KindShort: - case Slice::Builtin::KindInt: - case Slice::Builtin::KindLong: - case Slice::Builtin::KindString: - return true; + assert(false); + } - case Slice::Builtin::KindFloat: - case Slice::Builtin::KindDouble: - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - break; - } + zend_throw_exception_object(ex TSRMLS_CC); + destroy.release(); +} + +void +IcePHP::runtimeError(const char* fmt TSRMLS_DC, ...) +{ + va_list args; + char msg[1024]; + +#if ZTS + va_start(args, TSRMLS_C); +#else + va_start(args, fmt); +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1500) + vsprintf_s(msg, fmt, args); +#else + vsprintf(msg, fmt, args); +#endif + + va_end(args); + + throwError("RuntimeException", msg TSRMLS_CC); +} + +void +IcePHP::invalidArgument(const char* fmt TSRMLS_DC, ...) +{ + va_list args; + char msg[1024]; + +#if ZTS + va_start(args, TSRMLS_C); +#else + va_start(args, fmt); +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1500) + vsprintf_s(msg, fmt, args); +#else + vsprintf(msg, fmt, args); +#endif + + va_end(args); + + throwError("InvalidArgumentException", msg TSRMLS_CC); +} + +static bool +invokeMethodHelper(zval* obj, const string& name, zval* param TSRMLS_DC) +{ + assert(zend_hash_exists(&Z_OBJCE_P(obj)->function_table, STRCAST(name.c_str()), name.size() + 1)); + zval ret, method; + INIT_ZVAL(ret); + INIT_ZVAL(method); + ZVAL_STRING(&method, STRCAST(name.c_str()), 1); + zend_uint numParams = param ? 1 : 0; + zval** params = param ? ¶m : 0; + int status = 0; + zend_try + { + status = call_user_function(0, &obj, &method, &ret, numParams, params TSRMLS_CC); + } + zend_catch + { + status = FAILURE; } + zend_end_try(); + zval_dtor(&method); + zval_dtor(&ret); + if(status == FAILURE || EG(exception)) + { + return false; + } + return true; +} - return false; +bool +IcePHP::invokeMethod(zval* obj, const string& name TSRMLS_DC) +{ + return invokeMethodHelper(obj, name, 0 TSRMLS_CC); +} + +bool +IcePHP::invokeMethod(zval* obj, const string& name, const string& arg TSRMLS_DC) +{ + zval* param; + MAKE_STD_ZVAL(param); + ZVAL_STRINGL(param, STRCAST(arg.c_str()), arg.size(), 1); + AutoDestroy destroy(param); + return invokeMethodHelper(obj, name, param TSRMLS_CC); } bool @@ -698,3 +703,34 @@ IcePHP::checkClass(zend_class_entry* ce, zend_class_entry* base) return false; } + +ZEND_FUNCTION(Ice_stringVersion) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + RETURN_STRINGL(STRCAST(ICE_STRING_VERSION), strlen(ICE_STRING_VERSION), 1); +} + +ZEND_FUNCTION(Ice_intVersion) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + RETURN_LONG(ICE_INT_VERSION); +} + +ZEND_FUNCTION(Ice_generateUUID) +{ + if(ZEND_NUM_ARGS() > 0) + { + WRONG_PARAM_COUNT; + } + + string uuid = IceUtil::generateUUID(); + RETURN_STRINGL(STRCAST(uuid.c_str()), uuid.size(), 1); +} diff --git a/php/src/IcePHP/Util.h b/php/src/IcePHP/Util.h index 2e20ee6cced..d71f31955ed 100644 --- a/php/src/IcePHP/Util.h +++ b/php/src/IcePHP/Util.h @@ -7,85 +7,122 @@ // // ********************************************************************** -#ifndef ICE_PHP_UTIL_H -#define ICE_PHP_UTIL_H +#ifndef ICEPHP_UTIL_H +#define ICEPHP_UTIL_H #include <Config.h> -namespace IcePHP +// +// Global functions. +// +extern "C" { +ZEND_FUNCTION(Ice_stringVersion); +ZEND_FUNCTION(Ice_intVersion); +ZEND_FUNCTION(Ice_generateUUID); +} + +#define ICEPHP_UTIL_FUNCTIONS \ + ZEND_FE(Ice_stringVersion, NULL) \ + ZEND_FE(Ice_intVersion, NULL) \ + ZEND_FE(Ice_generateUUID, NULL) + +#ifdef ICEPHP_USE_NAMESPACES +# define ICEPHP_UTIL_NS_FUNCTIONS \ + ZEND_NS_FALIAS("Ice", stringVersion, Ice_stringVersion, NULL) \ + ZEND_NS_FALIAS("Ice", intVersion, Ice_intVersion, NULL) \ + ZEND_NS_FALIAS("Ice", generateUUID, Ice_generateUUID, NULL) +#else +# define ICEPHP_UTIL_NS_FUNCTIONS +#endif -bool createIdentity(zval*, const Ice::Identity& TSRMLS_DC); -bool extractIdentity(zval*, Ice::Identity& TSRMLS_DC); +namespace IcePHP +{ -bool createContext(zval*, const Ice::Context& TSRMLS_DC); -bool extractContext(zval*, Ice::Context& TSRMLS_DC); +void* createWrapper(zend_class_entry*, size_t TSRMLS_DC); +void* extractWrapper(zval* TSRMLS_DC); // -// PHP wrapper for C++ objects. +// Wraps a C++ pointer inside a PHP object. // -struct ice_object +template<typename T> +struct Wrapper { zend_object zobj; - void* ptr; // For object data. + T* ptr; + + static Wrapper<T>* create(zend_class_entry* ce TSRMLS_DC) + { + Wrapper<T>* w = static_cast<Wrapper<T>*>(createWrapper(ce, sizeof(Wrapper<T>) TSRMLS_CC)); + w->ptr = 0; + return w; + } + + static Wrapper<T>* extract(zval* zv TSRMLS_DC) + { + return static_cast<Wrapper<T>*>(extractWrapper(zv TSRMLS_CC)); + } + + static T value(zval* zv TSRMLS_DC) + { + Wrapper<T>* w = extract(zv TSRMLS_CC); + if(w) + { + return *w->ptr; + } + return 0; + } }; -// -// 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* newObject(zend_class_entry* TSRMLS_DC); +zend_class_entry* idToClass(const std::string& TSRMLS_DC); +zend_class_entry* nameToClass(const std::string& TSRMLS_DC); -// -// Retrieve the ice_object given a zval. -// -ice_object* getObject(zval* TSRMLS_DC); +bool createIdentity(zval*, const Ice::Identity& TSRMLS_DC); +bool extractIdentity(zval*, Ice::Identity& TSRMLS_DC); -// -// Convert the given exception into a PHP equivalent and "throw" it. -// -void throwException(const IceUtil::Exception& TSRMLS_DC); +bool createStringMap(zval*, const std::map<std::string, std::string>& TSRMLS_DC); +bool extractStringMap(zval*, std::map<std::string, std::string>& TSRMLS_DC); + +bool createStringArray(zval*, const Ice::StringSeq& TSRMLS_DC); +bool extractStringArray(zval*, Ice::StringSeq& TSRMLS_DC); // -// Find the class entry for a flattened type name. +// Convert the given exception into its PHP equivalent. // -zend_class_entry* findClass(const std::string& TSRMLS_DC); +zval* convertException(const Ice::Exception& TSRMLS_DC); // -// Find the class entry for a scoped type with suffix. +// Convert the exception and "throw" it. // -zend_class_entry* findClassScoped(const std::string& TSRMLS_DC); +void throwException(const Ice::Exception& TSRMLS_DC); // -// Convert a string to lowercase. +// Convert a Zend type (e.g., IS_BOOL, etc.) to a string for use in error messages. // -std::string lowerCase(const std::string&); +std::string zendTypeToString(int); // -// Flatten a scoped name. Leading "::" is removed, and all remaining "::" -// are replaced with underscores. The resulting string is then escaped if it -// conflicts with a PHP keyword. +// Raise RuntimeException with the given message. // -std::string flatten(const std::string&); +void runtimeError(const char* TSRMLS_DC, ...); // -// Check the given identifier against PHP's list of reserved words. If it matches -// a reserved word, then an escaped version is returned with a leading underscore. +// Raise InvalidArgumentException with the given message. // -std::string fixIdent(const std::string&); +void invalidArgument(const char* TSRMLS_DC, ...); // -// Convert a Zend type (e.g., IS_BOOL, etc.) to a string for use in error messages. +// Invoke a method on a PHP object. The method must not take any arguments. // -std::string zendTypeToString(int); +bool invokeMethod(zval*, const std::string& TSRMLS_DC); // -// Returns true if the given type is valid for use as a key in a native PHP associative array. +// Invoke a method on a PHP object. The method must take one string argument. // -bool isNativeKey(const Slice::TypePtr&); +bool invokeMethod(zval*, const std::string&, const std::string& TSRMLS_DC); // -// Determines whether a class (or interface) inherits from a base class (or interface). +// Check inheritance. // bool checkClass(zend_class_entry*, zend_class_entry*); @@ -111,6 +148,8 @@ public: AutoDestroy(zval* zv) : _zv(zv) {} ~AutoDestroy() { if(_zv) zval_ptr_dtor(&_zv); } + zval* release() { zval* z = _zv; _zv = 0; return z; } + private: zval* _zv; }; diff --git a/php/test/Ice/Makefile b/php/test/Ice/Makefile new file mode 100644 index 00000000000..7dbd7bf554f --- /dev/null +++ b/php/test/Ice/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../.. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = binding checksum exceptions facets inheritance objects operations proxy slicing + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/php/test/Ice/Makefile.mak b/php/test/Ice/Makefile.mak new file mode 100644 index 00000000000..80bfa6388c6 --- /dev/null +++ b/php/test/Ice/Makefile.mak @@ -0,0 +1,19 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = binding checksum exceptions facets inheritance objects operations proxy slicing
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/test/Ice/binding/.gitignore b/php/test/Ice/binding/.gitignore new file mode 100644 index 00000000000..bed01730acc --- /dev/null +++ b/php/test/Ice/binding/.gitignore @@ -0,0 +1 @@ +Test.php diff --git a/php/test/Ice/binding/Client.php b/php/test/Ice/binding/Client.php index d5c709a0177..b88a1f8017d 100644 --- a/php/test/Ice/binding/Client.php +++ b/php/test/Ice/binding/Client.php @@ -15,7 +15,9 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); + +require 'Ice.php'; +require 'Test.php'; function test($b) { @@ -51,12 +53,10 @@ function deactivate($com, $adapters) } } -function allTests() +function allTests($communicator) { - global $ICE; - $ref = "communicator:default -p 12010"; - $com = $ICE->stringToProxy($ref)->ice_uncheckedCast("::Test::RemoteCommunicator"); + $com = $communicator->stringToProxy($ref)->ice_uncheckedCast("::Test::RemoteCommunicator"); echo "testing binding with single endpoint... "; flush(); @@ -430,7 +430,7 @@ function allTests() } echo "ok" . "\n"; - if(strlen($ICE->getProperty("Ice.Plugin.IceSSL")) > 0) + if(strlen($communicator->getProperties()->getProperty("Ice.Plugin.IceSSL")) > 0) { echo "testing unsecure vs. secure endpoints... "; flush(); @@ -489,6 +489,8 @@ function allTests() $com->shutdown(); } -allTests(); +$communicator = Ice_initialize(&$argv); +allTests($communicator); +$communicator->destroy(); exit(); ?> diff --git a/php/test/Ice/binding/Makefile b/php/test/Ice/binding/Makefile new file mode 100644 index 00000000000..83671f131ec --- /dev/null +++ b/php/test/Ice/binding/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Test.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/binding/Makefile.mak b/php/test/Ice/binding/Makefile.mak new file mode 100644 index 00000000000..ef0c8acea4a --- /dev/null +++ b/php/test/Ice/binding/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/binding/php.ini b/php/test/Ice/binding/php.ini deleted file mode 100644 index 8a0b2f9f6e9..00000000000 --- a/php/test/Ice/binding/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -ice.slice=Test.ice -display_startup_errors=1 diff --git a/php/test/Ice/checksum/.gitignore b/php/test/Ice/checksum/.gitignore new file mode 100644 index 00000000000..66cc0dff1cf --- /dev/null +++ b/php/test/Ice/checksum/.gitignore @@ -0,0 +1,2 @@ +CTypes.php +Test.php diff --git a/php/test/Ice/checksum/CTypes.ice b/php/test/Ice/checksum/CTypes.ice new file mode 100644 index 00000000000..f9f05a43e4c --- /dev/null +++ b/php/test/Ice/checksum/CTypes.ice @@ -0,0 +1,440 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef CLASS_ICE +#define CLASS_ICE + +module Test +{ + +// +// TEST: Same +// +const int IntConst1 = 100; + +// +// TEST: Value changed +// +const int IntConst2 = 100; + +// +// TEST: Type changed +// +const int IntConst3 = 100; + +// +// TEST: Same +// +enum Enum1 { Enum11, Enum12, Enum13 }; + +// +// TEST: Add enumerator +// +enum Enum2 { Enum21, Enum22, Enum23 }; + +// +// TEST: Remove enumerator +// +enum Enum3 { Enum31, Enum32, Enum33 }; + +// +// TEST: Change to a different type +// +enum Enum4 { Enum41, Enum42, Enum43 }; + +// +// TEST: Same +// +sequence<int> Sequence1; + +// +// TEST: Change sequence type +// +sequence<int> Sequence2; + +// +// TEST: Change to a different type +// +sequence<int> Sequence3; + +// +// TEST: Same +// +dictionary<string, int> Dictionary1; + +// +// TEST: Change key type +// +dictionary<string, int> Dictionary2; + +// +// TEST: Change value type +// +dictionary<string, int> Dictionary3; + +// +// TEST: Change to a different type +// +dictionary<string, int> Dictionary4; + +// +// TEST: Same +// +struct Struct1 +{ + string str; + bool b; +}; + +// +// TEST: Add member +// +struct Struct2 +{ + string str; + bool b; +}; + +// +// TEST: Change member type +// +struct Struct3 +{ + string str; + bool b; +}; + +// +// TEST: Remove member +// +struct Struct4 +{ + string str; + bool b; +}; + +// +// TEST: Change to a different type +// +struct Struct5 +{ + string str; + bool b; +}; + +// +// TEST: Same +// +interface Interface1 +{ +}; + +// +// TEST: Change interface to class +// +interface Interface2 +{ +}; + +// +// TEST: Add base interface +// +interface Interface3 +{ +}; + +// +// TEST: Add operation +// +interface Interface4 +{ +}; + +// +// TEST: Same +// +class EmptyClass1 +{ +}; + +// +// TEST: Add data member +// +class EmptyClass2 +{ +}; + +// +// TEST: Add operation +// +class EmptyClass3 +{ +}; + +// +// TEST: Add base class +// +class EmptyClass4 +{ +}; + +// +// TEST: Add interface +// +class EmptyClass5 +{ +}; + +// +// TEST: Same +// +class SimpleClass1 +{ + string str; + float f; +}; + +// +// TEST: Add operation +// +class SimpleClass2 +{ + string str; + float f; +}; + +// +// TEST: Rename member +// +class SimpleClass3 +{ + string str; + float f; +}; + +// +// TEST: Add member +// +class SimpleClass4 +{ + string str; + float f; +}; + +// +// TEST: Remove member +// +class SimpleClass5 +{ + string str; + float f; +}; + +// +// TEST: Reorder members +// +class SimpleClass6 +{ + string str; + float f; +}; + +// +// TEST: Change member type +// +class SimpleClass7 +{ + string str; + float f; +}; + +// +// TEST: Same +// +exception Exception1 +{ + string str; + bool b; +}; + +// +// TEST: Add member +// +exception Exception2 +{ + string str; + bool b; +}; + +// +// TEST: Change member type +// +exception Exception3 +{ + string str; + bool b; +}; + +// +// TEST: Remove member +// +exception Exception4 +{ + string str; + bool b; +}; + +// +// TEST: Add base exception +// +exception Exception5 +{ +}; + +// +// TEST: Change to a different type +// +exception Exception6 +{ + string str; + bool b; +}; + +// +// TEST: Same +// +class BaseClass1 +{ + void baseOp1(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Change return type +// +class BaseClass2 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add parameter +// +class BaseClass3 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add exception +// +class BaseClass4 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Change out parameter to in parameter +// +class BaseClass5 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Remove parameter +// +class BaseClass6 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Remove exception +// +class BaseClass7 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Remove operation +// +class BaseClass8 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add base class +// +class BaseClass9 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add interface +// +class BaseClass10 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add base class and interface +// +class BaseClass11 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Local +// +local enum LocalEnum { LocalEnum1, LocalEnum2, LocalEnum3 }; + +// +// TEST: Local +// +local sequence<string> LocalSequence; + +// +// TEST: Local +// +local dictionary<string, string> LocalDictionary; + +// +// TEST: Local +// +local struct LocalStruct +{ + string str; +}; + +// +// TEST: Local +// +local class LocalClass +{ +}; + +}; + +#endif diff --git a/php/test/Ice/checksum/Client.php b/php/test/Ice/checksum/Client.php new file mode 100755 index 00000000000..b43d5f16797 --- /dev/null +++ b/php/test/Ice/checksum/Client.php @@ -0,0 +1,95 @@ +<? +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +error_reporting(E_ALL | E_STRICT); + +if(!extension_loaded("ice")) +{ + echo "\nerror: Ice extension is not loaded.\n\n"; + exit(1); +} + +require 'Ice.php'; +require 'Test.php'; +require 'CTypes.php'; + +function test($b) +{ + if(!$b) + { + $bt = debug_backtrace(); + die("\ntest failed in ".$bt[0]["file"]." line ".$bt[0]["line"]."\n"); + } +} + +function allTests($communicator) +{ + global $Ice_sliceChecksums; + + $ref = "test:default -p 12010"; + $base = $communicator->stringToProxy($ref); + test($base); + + $checksum = Test_ChecksumPrxHelper::checkedCast($base); + test($checksum); + + // + // Verify that no checksums are present for local types. + // + echo "testing checksums... "; + flush(); + test(count($Ice_sliceChecksums) > 0); + foreach($Ice_sliceChecksums as $i => $value) + { + test(!strpos($i, "Local")); + } + + // + // Get server's Slice checksums. + // + $d = $checksum->getSliceChecksums(); + + // + // Compare the checksums. For a type FooN whose name ends in an integer N, + // we assume that the server's type does not change for N = 1, and does + // change for N > 1. + // + foreach($d as $i => $value) + { + $n = 0; + preg_match("/\\d+/", $i, $matches); + if($matches) + { + $n = (int)$matches[0]; + } + + test(isset($Ice_sliceChecksums[$i])); + + if($n <= 1) + { + test($Ice_sliceChecksums[$i] == $d[$i]); + } + else + { + test($Ice_sliceChecksums[$i] != $d[$i]); + } + } + + echo "ok\n"; + + return $checksum; +} + +$communicator = Ice_initialize(&$argv); +$checksum = allTests($communicator); +$checksum->shutdown(); +$communicator->destroy(); +exit(); +?> diff --git a/php/test/Ice/checksum/Makefile b/php/test/Ice/checksum/Makefile new file mode 100644 index 00000000000..8a0d0bc816b --- /dev/null +++ b/php/test/Ice/checksum/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Test.php CTypes.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) --checksum $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/checksum/Makefile.mak b/php/test/Ice/checksum/Makefile.mak new file mode 100644 index 00000000000..83eef33cc49 --- /dev/null +++ b/php/test/Ice/checksum/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php CTypes.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) --checksum $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/checksum/Test.ice b/php/test/Ice/checksum/Test.ice new file mode 100644 index 00000000000..cf9b2a4d554 --- /dev/null +++ b/php/test/Ice/checksum/Test.ice @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef TEST_ICE +#define TEST_ICE + +#include <Ice/SliceChecksumDict.ice> + +module Test +{ + +interface Checksum +{ + idempotent Ice::SliceChecksumDict getSliceChecksums(); + + void shutdown(); +}; + +}; + +#endif diff --git a/php/test/Ice/checksum/run.py b/php/test/Ice/checksum/run.py new file mode 100755 index 00000000000..0e1d22c8b58 --- /dev/null +++ b/php/test/Ice/checksum/run.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +TestUtil.clientServerTest(server='server/server') + +TestUtil.cleanup() diff --git a/php/test/Ice/exceptions/.gitignore b/php/test/Ice/exceptions/.gitignore new file mode 100644 index 00000000000..bed01730acc --- /dev/null +++ b/php/test/Ice/exceptions/.gitignore @@ -0,0 +1 @@ +Test.php diff --git a/php/test/Ice/exceptions/Client.php b/php/test/Ice/exceptions/Client.php index 445c5b8c023..0d69b9cd045 100644 --- a/php/test/Ice/exceptions/Client.php +++ b/php/test/Ice/exceptions/Client.php @@ -8,6 +8,9 @@ // // ********************************************************************** +require 'Ice.php'; +require 'Test.php'; + error_reporting(E_ALL | E_STRICT); if(!extension_loaded("ice")) @@ -15,7 +18,6 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); function test($b) { @@ -26,14 +28,12 @@ function test($b) } } -function allTests() +function allTests($communicator) { - global $ICE; - echo "testing stringToProxy... "; flush(); $ref = "thrower:default -p 12010"; - $base = $ICE->stringToProxy($ref); + $base = $communicator->stringToProxy($ref); test($base != null); echo "ok\n"; @@ -206,7 +206,7 @@ function allTests() echo "catching object not exist exception... "; flush(); - $id = Ice_stringToIdentity("does not exist"); + $id = $communicator->stringToIdentity("does not exist"); try { $thrower2 = $thrower->ice_identity($id)->ice_uncheckedCast("::Test::Thrower"); @@ -285,7 +285,9 @@ function allTests() return $thrower; } -$thrower = allTests(); +$communicator = Ice_initialize(&$argv); +$thrower = allTests($communicator); $thrower->shutdown(); +$communicator->destroy(); exit(); ?> diff --git a/php/test/Ice/exceptions/Makefile b/php/test/Ice/exceptions/Makefile new file mode 100644 index 00000000000..83671f131ec --- /dev/null +++ b/php/test/Ice/exceptions/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Test.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/exceptions/Makefile.mak b/php/test/Ice/exceptions/Makefile.mak new file mode 100644 index 00000000000..ef0c8acea4a --- /dev/null +++ b/php/test/Ice/exceptions/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/exceptions/php.ini b/php/test/Ice/exceptions/php.ini deleted file mode 100644 index 8a0b2f9f6e9..00000000000 --- a/php/test/Ice/exceptions/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -ice.slice=Test.ice -display_startup_errors=1 diff --git a/php/test/Ice/facets/.gitignore b/php/test/Ice/facets/.gitignore new file mode 100644 index 00000000000..bed01730acc --- /dev/null +++ b/php/test/Ice/facets/.gitignore @@ -0,0 +1 @@ +Test.php diff --git a/php/test/Ice/facets/Client.php b/php/test/Ice/facets/Client.php index f6797c06624..8c936eb7361 100644 --- a/php/test/Ice/facets/Client.php +++ b/php/test/Ice/facets/Client.php @@ -15,7 +15,9 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); + +require 'Ice.php'; +require 'Test.php'; function test($b) { @@ -26,14 +28,12 @@ function test($b) } } -function allTests() +function allTests($communicator) { - global $ICE; - echo "testing stringToProxy... "; flush(); $ref = "d:default -p 12010"; - $db = $ICE->stringToProxy($ref); + $db = $communicator->stringToProxy($ref); test($db != null); echo "ok\n"; @@ -88,7 +88,9 @@ function allTests() return $gf; } -$g = allTests(); +$communicator = Ice_initialize(&$argv); +$g = allTests($communicator); $g->shutdown(); +$communicator->destroy(); exit(); ?> diff --git a/php/test/Ice/facets/Makefile b/php/test/Ice/facets/Makefile new file mode 100644 index 00000000000..83671f131ec --- /dev/null +++ b/php/test/Ice/facets/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Test.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/facets/Makefile.mak b/php/test/Ice/facets/Makefile.mak new file mode 100644 index 00000000000..ef0c8acea4a --- /dev/null +++ b/php/test/Ice/facets/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/facets/php.ini b/php/test/Ice/facets/php.ini deleted file mode 100644 index 8a0b2f9f6e9..00000000000 --- a/php/test/Ice/facets/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -ice.slice=Test.ice -display_startup_errors=1 diff --git a/php/test/Ice/inheritance/.gitignore b/php/test/Ice/inheritance/.gitignore new file mode 100644 index 00000000000..bed01730acc --- /dev/null +++ b/php/test/Ice/inheritance/.gitignore @@ -0,0 +1 @@ +Test.php diff --git a/php/test/Ice/inheritance/Client.php b/php/test/Ice/inheritance/Client.php index d9634df6638..8a86b363cb4 100644 --- a/php/test/Ice/inheritance/Client.php +++ b/php/test/Ice/inheritance/Client.php @@ -15,7 +15,9 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); + +require 'Ice.php'; +require 'Test.php'; function test($b) { @@ -26,14 +28,12 @@ function test($b) } } -function allTests() +function allTests($communicator) { - global $ICE; - echo "testing stringToProxy... "; flush(); $ref = "initial:default -p 12010"; - $base = $ICE->stringToProxy($ref); + $base = $communicator->stringToProxy($ref); test($base != null); echo "ok\n"; @@ -235,7 +235,9 @@ function allTests() return $initial; } -$initial = allTests(); +$communicator = Ice_initialize(&$argv); +$initial = allTests($communicator); $initial->shutdown(); +$communicator->destroy(); exit(); ?> diff --git a/php/test/Ice/inheritance/Makefile b/php/test/Ice/inheritance/Makefile new file mode 100644 index 00000000000..83671f131ec --- /dev/null +++ b/php/test/Ice/inheritance/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Test.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/inheritance/Makefile.mak b/php/test/Ice/inheritance/Makefile.mak new file mode 100644 index 00000000000..ef0c8acea4a --- /dev/null +++ b/php/test/Ice/inheritance/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/inheritance/php.ini b/php/test/Ice/inheritance/php.ini deleted file mode 100644 index 8a0b2f9f6e9..00000000000 --- a/php/test/Ice/inheritance/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -ice.slice=Test.ice -display_startup_errors=1 diff --git a/php/test/Ice/objects/.gitignore b/php/test/Ice/objects/.gitignore new file mode 100644 index 00000000000..bed01730acc --- /dev/null +++ b/php/test/Ice/objects/.gitignore @@ -0,0 +1 @@ +Test.php diff --git a/php/test/Ice/objects/Client.php b/php/test/Ice/objects/Client.php index 491ae8b4656..aaf231acadd 100644 --- a/php/test/Ice/objects/Client.php +++ b/php/test/Ice/objects/Client.php @@ -15,7 +15,9 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); + +require 'Ice.php'; +require 'Test.php'; class BI extends Test_B { @@ -29,7 +31,7 @@ class BI extends Test_B return $this->_postUnmarshalInvoked; } - var $_postUnmarshalInvoked = false; + private $_postUnmarshalInvoked = false; } class CI extends Test_C @@ -44,7 +46,7 @@ class CI extends Test_C return $this->_postUnmarshalInvoked; } - var $_postUnmarshalInvoked = false; + private $_postUnmarshalInvoked = false; } class DI extends Test_D @@ -59,7 +61,7 @@ class DI extends Test_D return $this->_postUnmarshalInvoked; } - var $_postUnmarshalInvoked = false; + private $_postUnmarshalInvoked = false; } class EI extends Test_E @@ -94,6 +96,12 @@ class II extends Ice_ObjectImpl implements Test_I { } +interface Foo1 {} +interface Foo2 {} +interface Foo3 {} +class Foo4 extends Ice_ObjectImpl implements Foo3, Foo2, Foo1 {} +class Foo5 extends Foo4 implements Test_I {} + class JI extends Ice_ObjectImpl implements Test_J { } @@ -155,14 +163,12 @@ function test($b) } } -function allTests() +function allTests($communicator) { - global $ICE; - echo "testing stringToProxy... "; flush(); $ref = "initial:default -p 12010"; - $base = $ICE->stringToProxy($ref); + $base = $communicator->stringToProxy($ref); test($base != null); echo "ok\n"; @@ -329,7 +335,8 @@ function allTests() echo "setting I... "; flush(); - $initial->setI($i); + //$initial->setI($i); + $initial->setI(new Foo5); $initial->setI($j); $initial->setI($h); echo "ok\n"; @@ -337,7 +344,7 @@ function allTests() echo "testing UnexpectedObjectException... "; flush(); $ref = "uoet:default -p 12010"; - $base = $ICE->stringToProxy($ref); + $base = $communicator->stringToProxy($ref); test($base != null); $uoet = $base->ice_uncheckedCast("::Test::UnexpectedObjectExceptionTest"); test($uoet != null); @@ -360,16 +367,18 @@ function allTests() return $initial; } +$communicator = Ice_initialize(&$argv); $factory = new MyObjectFactory(); -$ICE->addObjectFactory($factory, "::Test::B"); -$ICE->addObjectFactory($factory, "::Test::C"); -$ICE->addObjectFactory($factory, "::Test::D"); -$ICE->addObjectFactory($factory, "::Test::E"); -$ICE->addObjectFactory($factory, "::Test::F"); -$ICE->addObjectFactory($factory, "::Test::I"); -$ICE->addObjectFactory($factory, "::Test::J"); -$ICE->addObjectFactory($factory, "::Test::H"); -$initial = allTests(); +$communicator->addObjectFactory($factory, "::Test::B"); +$communicator->addObjectFactory($factory, "::Test::C"); +$communicator->addObjectFactory($factory, "::Test::D"); +$communicator->addObjectFactory($factory, "::Test::E"); +$communicator->addObjectFactory($factory, "::Test::F"); +$communicator->addObjectFactory($factory, "::Test::I"); +$communicator->addObjectFactory($factory, "::Test::J"); +$communicator->addObjectFactory($factory, "::Test::H"); +$initial = allTests($communicator); $initial->shutdown(); +$communicator->destroy(); exit(); ?> diff --git a/php/test/Ice/objects/Makefile b/php/test/Ice/objects/Makefile new file mode 100644 index 00000000000..83671f131ec --- /dev/null +++ b/php/test/Ice/objects/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Test.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/objects/Makefile.mak b/php/test/Ice/objects/Makefile.mak new file mode 100644 index 00000000000..ef0c8acea4a --- /dev/null +++ b/php/test/Ice/objects/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/objects/php.ini b/php/test/Ice/objects/php.ini deleted file mode 100644 index 8a0b2f9f6e9..00000000000 --- a/php/test/Ice/objects/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -ice.slice=Test.ice -display_startup_errors=1 diff --git a/php/test/Ice/operations/.gitignore b/php/test/Ice/operations/.gitignore new file mode 100644 index 00000000000..bed01730acc --- /dev/null +++ b/php/test/Ice/operations/.gitignore @@ -0,0 +1 @@ +Test.php diff --git a/php/test/Ice/operations/Client.php b/php/test/Ice/operations/Client.php index 1a2da5ac957..0afd1dd76ce 100644 --- a/php/test/Ice/operations/Client.php +++ b/php/test/Ice/operations/Client.php @@ -15,7 +15,9 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); + +require 'Ice.php'; +require 'Test.php'; function test($b) { @@ -28,8 +30,6 @@ function test($b) function twoways($communicator, $p) { - global $ICE; - { $p->opVoid(); } @@ -103,9 +103,9 @@ function twoways($communicator, $p) { $r = $p->opMyClass($p, $c1, $c2); // TODO: Identity tests - test($c1->ice_getIdentity() == $ICE->stringToIdentity("test")); - test($c2->ice_getIdentity() == $ICE->stringToIdentity("noSuchIdentity")); - test($r->ice_getIdentity() == $ICE->stringToIdentity("test")); + test($c1->ice_getIdentity() == $communicator->stringToIdentity("test")); + test($c2->ice_getIdentity() == $communicator->stringToIdentity("noSuchIdentity")); + test($r->ice_getIdentity() == $communicator->stringToIdentity("test")); $r->opVoid(); $c1->opVoid(); try @@ -417,26 +417,26 @@ function twoways($communicator, $p) } } -function allTests() +function allTests($communicator) { - global $ICE; - $ref = "test:default -p 12010"; - $base = $ICE->stringToProxy($ref); + $base = $communicator->stringToProxy($ref); $cl = $base->ice_checkedCast("::Test::MyClass"); $derived = $cl->ice_checkedCast("::Test::MyDerivedClass"); echo "testing twoway operations... "; flush(); - twoways($ICE, $cl); - twoways($ICE, $derived); + twoways($communicator, $cl); + twoways($communicator, $derived); $derived->opDerived(); echo "ok\n"; return $cl; } -$myClass = allTests(); +$communicator = Ice_initialize(); + +$myClass = allTests($communicator); echo "testing server shutdown... "; flush(); @@ -451,5 +451,7 @@ catch(Ice_LocalException $ex) echo "ok\n"; } +$communicator->destroy(); + exit(); ?> diff --git a/php/test/Ice/operations/Makefile b/php/test/Ice/operations/Makefile new file mode 100644 index 00000000000..83671f131ec --- /dev/null +++ b/php/test/Ice/operations/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Test.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/operations/Makefile.mak b/php/test/Ice/operations/Makefile.mak new file mode 100644 index 00000000000..ef0c8acea4a --- /dev/null +++ b/php/test/Ice/operations/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/operations/php.ini b/php/test/Ice/operations/php.ini deleted file mode 100644 index 8a0b2f9f6e9..00000000000 --- a/php/test/Ice/operations/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -ice.slice=Test.ice -display_startup_errors=1 diff --git a/php/test/Ice/proxy/.gitignore b/php/test/Ice/proxy/.gitignore new file mode 100644 index 00000000000..bed01730acc --- /dev/null +++ b/php/test/Ice/proxy/.gitignore @@ -0,0 +1 @@ +Test.php diff --git a/php/test/Ice/proxy/Client.php b/php/test/Ice/proxy/Client.php index cb2ed79280f..a1606c87e90 100644 --- a/php/test/Ice/proxy/Client.php +++ b/php/test/Ice/proxy/Client.php @@ -15,7 +15,9 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); + +require 'Ice.php'; +require 'Test.php'; function test($b) { @@ -26,216 +28,214 @@ function test($b) } } -function allTests() +function allTests($communicator) { - global $ICE; - echo "testing stringToProxy... "; flush(); $ref = "test:default -p 12010"; - $base = $ICE->stringToProxy($ref); + $base = $communicator->stringToProxy($ref); test($base != null); - $b1 = $ICE->stringToProxy("test"); + $b1 = $communicator->stringToProxy("test"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getAdapterId() == "" && $b1->ice_getFacet() == ""); - $b1 = $ICE->stringToProxy("test "); + $b1 = $communicator->stringToProxy("test "); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == ""); - $b1 = $ICE->stringToProxy(" test "); + $b1 = $communicator->stringToProxy(" test "); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == ""); - $b1 = $ICE->stringToProxy(" test"); + $b1 = $communicator->stringToProxy(" test"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == ""); - $b1 = $ICE->stringToProxy("'test -f facet'"); + $b1 = $communicator->stringToProxy("'test -f facet'"); test($b1->ice_getIdentity()->name == "test -f facet" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == ""); try { - $b1 = $ICE->stringToProxy("\"test -f facet'"); + $b1 = $communicator->stringToProxy("\"test -f facet'"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex) + catch(Ice_ProxyParseException $ex) { } - $b1 = $ICE->stringToProxy("\"test -f facet\""); + $b1 = $communicator->stringToProxy("\"test -f facet\""); test($b1->ice_getIdentity()->name == "test -f facet" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == ""); - $b1 = $ICE->stringToProxy("\"test -f facet@test\""); + $b1 = $communicator->stringToProxy("\"test -f facet@test\""); test($b1->ice_getIdentity()->name == "test -f facet@test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == ""); - $b1 = $ICE->stringToProxy("\"test -f facet@test @test\""); + $b1 = $communicator->stringToProxy("\"test -f facet@test @test\""); test($b1->ice_getIdentity()->name == "test -f facet@test @test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == ""); try { - $b1 = $ICE->stringToProxy("test test"); + $b1 = $communicator->stringToProxy("test test"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex) + catch(Ice_ProxyParseException $ex) { } - $b1 = $ICE->stringToProxy("test\\040test"); + $b1 = $communicator->stringToProxy("test\\040test"); test($b1->ice_getIdentity()->name == "test test" && $b1->ice_getIdentity()->category == ""); try { - $b1 = $ICE->stringToProxy("test\\777"); + $b1 = $communicator->stringToProxy("test\\777"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_IdentityParseException $ex) + catch(Ice_IdentityParseException $ex) { } - $b1 = $ICE->stringToProxy("test\\40test"); + $b1 = $communicator->stringToProxy("test\\40test"); test($b1->ice_getIdentity()->name == "test test"); // Test some octal and hex corner cases. - $b1 = $ICE->stringToProxy("test\\4test"); + $b1 = $communicator->stringToProxy("test\\4test"); test($b1->ice_getIdentity()->name == "test\4test"); - $b1 = $ICE->stringToProxy("test\\04test"); + $b1 = $communicator->stringToProxy("test\\04test"); test($b1->ice_getIdentity()->name == "test\4test"); - $b1 = $ICE->stringToProxy("test\\004test"); + $b1 = $communicator->stringToProxy("test\\004test"); test($b1->ice_getIdentity()->name == "test\4test"); - $b1 = $ICE->stringToProxy("test\\1114test"); + $b1 = $communicator->stringToProxy("test\\1114test"); test($b1->ice_getIdentity()->name == "test\1114test"); - $b1 = $ICE->stringToProxy("test\\b\\f\\n\\r\\t\\'\\\"\\\\test"); + $b1 = $communicator->stringToProxy("test\\b\\f\\n\\r\\t\\'\\\"\\\\test"); test($b1->ice_getIdentity()->name == "test\x08\x0c\n\r\t'\"\\test" && $b1->ice_getIdentity()->category == ""); - $b1 = $ICE->stringToProxy("category/test"); + $b1 = $communicator->stringToProxy("category/test"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category" && $b1->ice_getAdapterId() == ""); - $b1 = $ICE->stringToProxy("test@adapter"); + $b1 = $communicator->stringToProxy("test@adapter"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getAdapterId() == "adapter"); try { - $b1 = $ICE->stringToProxy("id@adapter test"); + $b1 = $communicator->stringToProxy("id@adapter test"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex) + catch(Ice_ProxyParseException $ex) { } - $b1 = $ICE->stringToProxy("category/test@adapter"); + $b1 = $communicator->stringToProxy("category/test@adapter"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category" && $b1->ice_getAdapterId() == "adapter"); - $b1 = $ICE->stringToProxy("category/test@adapter:tcp"); + $b1 = $communicator->stringToProxy("category/test@adapter:tcp"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category" && $b1->ice_getAdapterId() == "adapter:tcp"); - $b1 = $ICE->stringToProxy("'category 1/test'@adapter"); + $b1 = $communicator->stringToProxy("'category 1/test'@adapter"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category 1" && $b1->ice_getAdapterId() == "adapter"); - $b1 = $ICE->stringToProxy("'category/test 1'@adapter"); + $b1 = $communicator->stringToProxy("'category/test 1'@adapter"); test($b1->ice_getIdentity()->name == "test 1" && $b1->ice_getIdentity()->category == "category" && $b1->ice_getAdapterId() == "adapter"); - $b1 = $ICE->stringToProxy("'category/test'@'adapter 1'"); + $b1 = $communicator->stringToProxy("'category/test'@'adapter 1'"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category" && $b1->ice_getAdapterId() == "adapter 1"); - $b1 = $ICE->stringToProxy("\"category \\/test@foo/test\"@adapter"); + $b1 = $communicator->stringToProxy("\"category \\/test@foo/test\"@adapter"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category /test@foo" && $b1->ice_getAdapterId() == "adapter"); - $b1 = $ICE->stringToProxy("\"category \\/test@foo/test\"@\"adapter:tcp\""); + $b1 = $communicator->stringToProxy("\"category \\/test@foo/test\"@\"adapter:tcp\""); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category /test@foo" && $b1->ice_getAdapterId() == "adapter:tcp"); - $b1 = $ICE->stringToProxy("id -f facet"); + $b1 = $communicator->stringToProxy("id -f facet"); test($b1->ice_getIdentity()->name == "id" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == "facet"); - $b1 = $ICE->stringToProxy("id -f 'facet x'"); + $b1 = $communicator->stringToProxy("id -f 'facet x'"); test($b1->ice_getIdentity()->name == "id" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == "facet x"); - $b1 = $ICE->stringToProxy("id -f \"facet x\""); + $b1 = $communicator->stringToProxy("id -f \"facet x\""); test($b1->ice_getIdentity()->name == "id" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == "facet x"); try { - $b1 = $ICE->stringToProxy("id -f \"facet x"); + $b1 = $communicator->stringToProxy("id -f \"facet x"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex) + catch(Ice_ProxyParseException $ex) { } try { - $b1 = $ICE->stringToProxy("id -f \'facet x"); + $b1 = $communicator->stringToProxy("id -f \'facet x"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex) + catch(Ice_ProxyParseException $ex) { } - $b1 = $ICE->stringToProxy("test -f facet:tcp"); + $b1 = $communicator->stringToProxy("test -f facet:tcp"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == "facet" && $b1->ice_getAdapterId() == ""); - $b1 = $ICE->stringToProxy("test -f \"facet:tcp\""); + $b1 = $communicator->stringToProxy("test -f \"facet:tcp\""); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == "facet:tcp" && $b1->ice_getAdapterId() == ""); - $b1 = $ICE->stringToProxy("test -f facet@test"); + $b1 = $communicator->stringToProxy("test -f facet@test"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == "facet" && $b1->ice_getAdapterId() == "test"); - $b1 = $ICE->stringToProxy("test -f 'facet@test'"); + $b1 = $communicator->stringToProxy("test -f 'facet@test'"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == "facet@test" && $b1->ice_getAdapterId() == ""); - $b1 = $ICE->stringToProxy("test -f 'facet@test'@test"); + $b1 = $communicator->stringToProxy("test -f 'facet@test'@test"); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getFacet() == "facet@test" && $b1->ice_getAdapterId() == "test"); try { - $b1 = $ICE->stringToProxy("test -f facet@test @test"); + $b1 = $communicator->stringToProxy("test -f facet@test @test"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex) + catch(Ice_ProxyParseException $ex) { } - $b1 = $ICE->stringToProxy("test"); + $b1 = $communicator->stringToProxy("test"); test($b1->ice_isTwoway()); - $b1 = $ICE->stringToProxy("test -t"); + $b1 = $communicator->stringToProxy("test -t"); test($b1->ice_isTwoway()); - $b1 = $ICE->stringToProxy("test -o"); + $b1 = $communicator->stringToProxy("test -o"); test($b1->ice_isOneway()); - $b1 = $ICE->stringToProxy("test -O"); + $b1 = $communicator->stringToProxy("test -O"); test($b1->ice_isBatchOneway()); - $b1 = $ICE->stringToProxy("test -d"); + $b1 = $communicator->stringToProxy("test -d"); test($b1->ice_isDatagram()); - $b1 = $ICE->stringToProxy("test -D"); + $b1 = $communicator->stringToProxy("test -D"); test($b1->ice_isBatchDatagram()); - $b1 = $ICE->stringToProxy("test"); + $b1 = $communicator->stringToProxy("test"); test(!$b1->ice_isSecure()); - $b1 = $ICE->stringToProxy("test -s"); + $b1 = $communicator->stringToProxy("test -s"); test($b1->ice_isSecure()); try { - $b1 = $ICE->stringToProxy("test:tcp@adapterId"); + $b1 = $communicator->stringToProxy("test:tcp@adapterId"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } // This is an unknown endpoint warning, not a parse exception. // //try //{ - // $b1 = $ICE->stringToProxy("test -f the:facet:tcp"); + // $b1 = $communicator->stringToProxy("test -f the:facet:tcp"); // test(false); //} - //catch(Ice_EndpointParseException $ex) //catch(Ice_UnknownLocalException $ex) + //catch(Ice_EndpointParseException $ex) //{ //} try { - $b1 = $ICE->stringToProxy("test::tcp"); + $b1 = $communicator->stringToProxy("test::tcp"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } echo "ok\n"; echo "testing propertyToProxy... "; $propertyPrefix = "Foo.Proxy"; - $ICE->setProperty($propertyPrefix, "test:default -p 12010"); - $b1 = $ICE->propertyToProxy($propertyPrefix); + $communicator->getProperties()->setProperty($propertyPrefix, "test:default -p 12010"); + $b1 = $communicator->propertyToProxy($propertyPrefix); test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" && $b1->ice_getAdapterId() == "" && $b1->ice_getFacet() == ""); @@ -247,86 +247,86 @@ function allTests() // // $property = $propertyPrefix . ".Locator"; // test(!$b1->ice_getLocator()); - // $ICE->setProperty($property, "locator:default -p 10000"); - // $b1 = $ICE->propertyToProxy($propertyPrefix); + // $communicator->getProperties()->setProperty($property, "locator:default -p 10000"); + // $b1 = $communicator->propertyToProxy($propertyPrefix); // test(!$b1->ice_getLocator()); - // $ICE->setProperty($property, ""); + // $communicator->getProperties()->setProperty($property, ""); // $property = $propertyPrefix . ".LocatorCacheTimeout"; // test($b1->ice_getLocatorCacheTimeout() == 0); - // $ICE->setProperty($property, "1"); - // $b1 = $ICE->propertyToProxy($propertyPrefix); + // $communicator->getProperties()->setProperty($property, "1"); + // $b1 = $communicator->propertyToProxy($propertyPrefix); // test($b1->ice_getLocatorCacheTimeout() == 0); - // $ICE->setProperty($property, ""); + // $communicator->getProperties()->setProperty($property, ""); // Now retest with an indirect proxy. - $ICE->setProperty($propertyPrefix, "test"); + $communicator->getProperties()->setProperty($propertyPrefix, "test"); $property = $propertyPrefix . ".Locator"; - $ICE->setProperty($property, "locator:default -p 10000"); - $b1 = $ICE->propertyToProxy($propertyPrefix); + $communicator->getProperties()->setProperty($property, "locator:default -p 10000"); + $b1 = $communicator->propertyToProxy($propertyPrefix); test($b1->ice_getLocator() && $b1->ice_getLocator()->ice_getIdentity()->name == "locator"); - $ICE->setProperty($property, ""); + $communicator->getProperties()->setProperty($property, ""); $property = $propertyPrefix . ".LocatorCacheTimeout"; test($b1->ice_getLocatorCacheTimeout() == -1); - $ICE->setProperty($property, "1"); - $b1 = $ICE->propertyToProxy($propertyPrefix); + $communicator->getProperties()->setProperty($property, "1"); + $b1 = $communicator->propertyToProxy($propertyPrefix); test($b1->ice_getLocatorCacheTimeout() == 1); - $ICE->setProperty($property, ""); + $communicator->getProperties()->setProperty($property, ""); // This cannot be tested so easily because the $property is cached - // on $ICE initialization. + // on communicator initialization. // - //$ICE->setProperty("Ice.Default.LocatorCacheTimeout", "60"); - //$b1 = $ICE->propertyToProxy($propertyPrefix); + //$communicator->getProperties()->setProperty("Ice.Default.LocatorCacheTimeout", "60"); + //$b1 = $communicator->propertyToProxy($propertyPrefix); //test($b1->ice_getLocatorCacheTimeout() == 60); - //$ICE->setProperty("Ice.Default.LocatorCacheTimeout", ""); + //$communicator->getProperties()->setProperty("Ice.Default.LocatorCacheTimeout", ""); - $ICE->setProperty($propertyPrefix, "test:default -p 12010"); + $communicator->getProperties()->setProperty($propertyPrefix, "test:default -p 12010"); $property = $propertyPrefix . ".Router"; test(!$b1->ice_getRouter()); - $ICE->setProperty($property, "router:default -p 10000"); - $b1 = $ICE->propertyToProxy($propertyPrefix); + $communicator->getProperties()->setProperty($property, "router:default -p 10000"); + $b1 = $communicator->propertyToProxy($propertyPrefix); test($b1->ice_getRouter() && $b1->ice_getRouter()->ice_getIdentity()->name == "router"); - $ICE->setProperty($property, ""); + $communicator->getProperties()->setProperty($property, ""); $property = $propertyPrefix . ".PreferSecure"; test(!$b1->ice_isPreferSecure()); - $ICE->setProperty($property, "1"); - $b1 = $ICE->propertyToProxy($propertyPrefix); + $communicator->getProperties()->setProperty($property, "1"); + $b1 = $communicator->propertyToProxy($propertyPrefix); test($b1->ice_isPreferSecure()); - $ICE->setProperty($property, ""); + $communicator->getProperties()->setProperty($property, ""); $property = $propertyPrefix . ".ConnectionCached"; test($b1->ice_isConnectionCached()); - $ICE->setProperty($property, "0"); - $b1 = $ICE->propertyToProxy($propertyPrefix); + $communicator->getProperties()->setProperty($property, "0"); + $b1 = $communicator->propertyToProxy($propertyPrefix); test(!$b1->ice_isConnectionCached()); - $ICE->setProperty($property, ""); + $communicator->getProperties()->setProperty($property, ""); $property = $propertyPrefix . ".EndpointSelection"; test($b1->ice_getEndpointSelection() == Ice_EndpointSelectionType::Random); - $ICE->setProperty($property, "Random"); - $b1 = $ICE->propertyToProxy($propertyPrefix); + $communicator->getProperties()->setProperty($property, "Random"); + $b1 = $communicator->propertyToProxy($propertyPrefix); test($b1->ice_getEndpointSelection() == Ice_EndpointSelectionType::Random); - $ICE->setProperty($property, "Ordered"); - $b1 = $ICE->propertyToProxy($propertyPrefix); + $communicator->getProperties()->setProperty($property, "Ordered"); + $b1 = $communicator->propertyToProxy($propertyPrefix); test($b1->ice_getEndpointSelection() == Ice_EndpointSelectionType::Ordered); - $ICE->setProperty($property, ""); + $communicator->getProperties()->setProperty($property, ""); //$property = $propertyPrefix . ".CollocationOptimized"; //test($b1->ice_isCollocationOptimized()); - //$ICE->setProperty($property, "0"); - //$b1 = $ICE->propertyToProxy($propertyPrefix); + //$communicator->getProperties()->setProperty($property, "0"); + //$b1 = $communicator->propertyToProxy($propertyPrefix); //test(!$b1->ice_isCollocationOptimized()); - //$ICE->setProperty($property, ""); + //$communicator->getProperties()->setProperty($property, ""); echo "ok\n"; echo "testing proxy methods... "; flush(); - test($ICE->identityToString($base->ice_identity($ICE->stringToIdentity("other"))->ice_getIdentity()) == "other"); + test($communicator->identityToString($base->ice_identity($communicator->stringToIdentity("other"))->ice_getIdentity()) == "other"); test($base->ice_facet("facet")->ice_getFacet() == "facet"); test($base->ice_adapterId("id")->ice_getAdapterId() == "id"); test($base->ice_twoway()->ice_isTwoway()); @@ -340,7 +340,7 @@ function allTests() echo "testing ice_getCommunicator... "; flush(); - test($base->ice_getCommunicator() === $ICE); + test($base->ice_getCommunicator() === $communicator); echo "ok\n"; echo "testing checked cast... "; @@ -372,138 +372,139 @@ function allTests() try { // Invalid -x option - $p = $ICE->stringToProxy("id:opaque -t 99 -v abc -x abc"); + $p = $communicator->stringToProxy("id:opaque -t 99 -v abc -x abc"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // Missing -t and -v - $p = $ICE->stringToProxy("id:opaque"); + $p = $communicator->stringToProxy("id:opaque"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // Repeated -t - $p = $ICE->stringToProxy("id:opaque -t 1 -t 1 -v abc"); + $p = $communicator->stringToProxy("id:opaque -t 1 -t 1 -v abc"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // Repeated -v - $p = $ICE->stringToProxy("id:opaque -t 1 -v abc -v abc"); + $p = $communicator->stringToProxy("id:opaque -t 1 -v abc -v abc"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // Missing -t - $p = $ICE->stringToProxy("id:opaque -v abc"); + $p = $communicator->stringToProxy("id:opaque -v abc"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // Missing -v - $p = $ICE->stringToProxy("id:opaque -t 1"); + $p = $communicator->stringToProxy("id:opaque -t 1"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // Missing arg for -t - $p = $ICE->stringToProxy("id:opaque -t -v abc"); + $p = $communicator->stringToProxy("id:opaque -t -v abc"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // Missing arg for -v - $p = $ICE->stringToProxy("id:opaque -t 1 -v"); + $p = $communicator->stringToProxy("id:opaque -t 1 -v"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // Not a number for -t - $p = $ICE->stringToProxy("id:opaque -t x -v abc"); + $p = $communicator->stringToProxy("id:opaque -t x -v abc"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // < 0 for -t - $p = $ICE->stringToProxy("id:opaque -t -1 -v abc"); + $p = $communicator->stringToProxy("id:opaque -t -1 -v abc"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } try { // Invalid char for -v - $p = $ICE->stringToProxy("id:opaque -t 99 -v x?c"); + $p = $communicator->stringToProxy("id:opaque -t 99 -v x?c"); test(false); } - catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex) + catch(Ice_EndpointParseException $ex) { } // Legal TCP endpoint expressed as opaque endpoint - $p1 = $ICE->stringToProxy("test:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA=="); - $pstr = $ICE->proxyToString($p1); + $p1 = $communicator->stringToProxy("test:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA=="); + $pstr = $communicator->proxyToString($p1); test($pstr == "test -t:tcp -h 127.0.0.1 -p 12010 -t 10000"); // Working? - if($ICE->getProperty("Ice.IPv6") == "" || $ICE->getProperty("Ice.IPv6") == "0") + if($communicator->getProperties()->getProperty("Ice.IPv6") == "" || + $communicator->getProperties()->getProperty("Ice.IPv6") == "0") { - $ssl = $ICE->getProperty("Ice.Default.Protocol") == "ssl"; + $ssl = $communicator->getProperties()->getProperty("Ice.Default.Protocol") == "ssl"; if(!$ssl) { $p1->ice_ping(); } // Two legal TCP endpoints expressed as opaque endpoints - $p1 = $ICE->stringToProxy("test:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==:opaque -t 1 -v CTEyNy4wLjAuMusuAAAQJwAAAA=="); - $pstr = $ICE->proxyToString($p1); + $p1 = $communicator->stringToProxy("test:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==:opaque -t 1 -v CTEyNy4wLjAuMusuAAAQJwAAAA=="); + $pstr = $communicator->proxyToString($p1); test($pstr == "test -t:tcp -h 127.0.0.1 -p 12010 -t 10000:tcp -h 127.0.0.2 -p 12011 -t 10000"); // // Test that an SSL endpoint and a nonsense endpoint get written // back out as an opaque endpoint. // - $p1 = $ICE->stringToProxy("test:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch"); - $pstr = $ICE->proxyToString($p1); + $p1 = $communicator->stringToProxy("test:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch"); + $pstr = $communicator->proxyToString($p1); if(!$ssl) { test($pstr == "test -t:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch"); @@ -523,8 +524,13 @@ function allTests() $p1->ice_ping(); test(false); } - catch(Ice_UnknownLocalException $ex) + catch(Ice_NoEndpointException $ex) + { + test(!$ssl); + } + catch(Ice_ConnectionRefusedException $ex) { + test($ssl); } // @@ -534,7 +540,7 @@ function allTests() // the opaque endpoints. // $p2 = $derived->_echo($p1); - $pstr = $ICE->proxyToString($p2); + $pstr = $communicator->proxyToString($p2); if(!$ssl) { test($pstr == "test -t:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch"); @@ -549,8 +555,10 @@ function allTests() return $cl; } -$myClass = allTests(); +$communicator = Ice_initialize(&$argv); +$myClass = allTests($communicator); $myClass->shutdown(); +$communicator->destroy(); exit(); ?> diff --git a/php/test/Ice/proxy/Makefile b/php/test/Ice/proxy/Makefile new file mode 100644 index 00000000000..83671f131ec --- /dev/null +++ b/php/test/Ice/proxy/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Test.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/proxy/Makefile.mak b/php/test/Ice/proxy/Makefile.mak new file mode 100644 index 00000000000..ef0c8acea4a --- /dev/null +++ b/php/test/Ice/proxy/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/proxy/Test.ice b/php/test/Ice/proxy/Test.ice index 7d47f52364b..1fc2f21aa23 100644 --- a/php/test/Ice/proxy/Test.ice +++ b/php/test/Ice/proxy/Test.ice @@ -10,18 +10,16 @@ #ifndef TEST_ICE #define TEST_ICE -#include <Ice/Router.ice> -#include <Ice/Locator.ice> -#include <Ice/Current.ice> - module Test { +dictionary<string, string> Context; + class MyClass { void shutdown(); - Ice::Context getContext(); + Context getContext(); }; class MyDerivedClass extends MyClass diff --git a/php/test/Ice/proxy/php.ini b/php/test/Ice/proxy/php.ini deleted file mode 100644 index 1fa3edc94d1..00000000000 --- a/php/test/Ice/proxy/php.ini +++ /dev/null @@ -1,4 +0,0 @@ -# The test script replaces ICE_HOME by the contents of the environment -# variable. -ice.slice=-IICE_HOME/slice -w Test.ice -display_startup_errors=1 diff --git a/php/test/Ice/slicing/Makefile b/php/test/Ice/slicing/Makefile new file mode 100644 index 00000000000..4051ad37775 --- /dev/null +++ b/php/test/Ice/slicing/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = exceptions objects + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/php/test/Ice/slicing/Makefile.mak b/php/test/Ice/slicing/Makefile.mak new file mode 100644 index 00000000000..bfce9275893 --- /dev/null +++ b/php/test/Ice/slicing/Makefile.mak @@ -0,0 +1,19 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = exceptions objects
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/test/Ice/slicing/exceptions/.gitignore b/php/test/Ice/slicing/exceptions/.gitignore new file mode 100644 index 00000000000..bed01730acc --- /dev/null +++ b/php/test/Ice/slicing/exceptions/.gitignore @@ -0,0 +1 @@ +Test.php diff --git a/php/test/Ice/slicing/exceptions/Client.php b/php/test/Ice/slicing/exceptions/Client.php index 2b739bc37fa..28c9c631936 100644 --- a/php/test/Ice/slicing/exceptions/Client.php +++ b/php/test/Ice/slicing/exceptions/Client.php @@ -6,7 +6,9 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); + +require 'Ice.php'; +require 'Test.php'; function test($b) { @@ -17,11 +19,9 @@ function test($b) } } -function allTests() +function allTests($communicator) { - global $ICE; - - $obj = $ICE->stringToProxy("Test:default -p 12010"); + $obj = $communicator->stringToProxy("Test:default -p 12010"); $test = $obj->ice_checkedCast("::Test::TestIntf"); echo "testing throwing a base exception... "; @@ -247,7 +247,9 @@ function allTests() return $test; } -$test = allTests(); +$communicator = Ice_initialize(&$argv); +$test = allTests($communicator); $test->shutdown(); +$communicator->destroy(); exit(); ?> diff --git a/php/test/Ice/slicing/exceptions/Makefile b/php/test/Ice/slicing/exceptions/Makefile new file mode 100644 index 00000000000..94ebb9296a1 --- /dev/null +++ b/php/test/Ice/slicing/exceptions/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Test.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/slicing/exceptions/Makefile.mak b/php/test/Ice/slicing/exceptions/Makefile.mak new file mode 100644 index 00000000000..43c21364d6c --- /dev/null +++ b/php/test/Ice/slicing/exceptions/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/slicing/exceptions/php.ini b/php/test/Ice/slicing/exceptions/php.ini deleted file mode 100644 index 8a0b2f9f6e9..00000000000 --- a/php/test/Ice/slicing/exceptions/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -ice.slice=Test.ice -display_startup_errors=1 diff --git a/php/test/Ice/slicing/objects/.gitignore b/php/test/Ice/slicing/objects/.gitignore new file mode 100644 index 00000000000..cde67ff9c11 --- /dev/null +++ b/php/test/Ice/slicing/objects/.gitignore @@ -0,0 +1,3 @@ +ClientPrivate.php +Forward.php +Test.php diff --git a/php/test/Ice/slicing/objects/Client.php b/php/test/Ice/slicing/objects/Client.php index 533ac71488b..0a08991bd5e 100644 --- a/php/test/Ice/slicing/objects/Client.php +++ b/php/test/Ice/slicing/objects/Client.php @@ -6,7 +6,10 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); + +require 'Ice.php'; +require 'Forward.php'; +require 'ClientPrivate.php'; function test($b) { @@ -17,11 +20,9 @@ function test($b) } } -function allTests() +function allTests($communicator) { - global $ICE; - - $obj = $ICE->stringToProxy("Test:default -p 12010"); + $obj = $communicator->stringToProxy("Test:default -p 12010"); $test = $obj->ice_checkedCast("::Test::TestIntf"); echo "testing base as Object... "; @@ -799,7 +800,9 @@ function allTests() return $test; } -$test = allTests(); +$communicator = Ice_initialize(&$argv); +$test = allTests($communicator); $test->shutdown(); +$communicator->destroy(); exit(); ?> diff --git a/php/test/Ice/slicing/objects/Makefile b/php/test/Ice/slicing/objects/Makefile new file mode 100644 index 00000000000..3188bc0d0cd --- /dev/null +++ b/php/test/Ice/slicing/objects/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = ClientPrivate.php Forward.php Test.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) -I. $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Ice/slicing/objects/Makefile.mak b/php/test/Ice/slicing/objects/Makefile.mak new file mode 100644 index 00000000000..fd3f76e1e8a --- /dev/null +++ b/php/test/Ice/slicing/objects/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = ClientPrivate.php Forward.php Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) -I. $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/slicing/objects/php.ini b/php/test/Ice/slicing/objects/php.ini deleted file mode 100644 index 45d7ad539f4..00000000000 --- a/php/test/Ice/slicing/objects/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -ice.slice=-w -I. Forward.ice ClientPrivate.ice -display_startup_errors=1 diff --git a/php/test/Makefile b/php/test/Makefile new file mode 100644 index 00000000000..39339188bdd --- /dev/null +++ b/php/test/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = .. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = Ice Slice + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/php/test/Makefile.mak b/php/test/Makefile.mak new file mode 100644 index 00000000000..a7b8d7dc641 --- /dev/null +++ b/php/test/Makefile.mak @@ -0,0 +1,19 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = Ice Slice
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/test/Slice/Makefile b/php/test/Slice/Makefile new file mode 100644 index 00000000000..5abb0e85b0f --- /dev/null +++ b/php/test/Slice/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../.. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = keyword + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/php/test/Slice/Makefile.mak b/php/test/Slice/Makefile.mak new file mode 100644 index 00000000000..ccb852a2b71 --- /dev/null +++ b/php/test/Slice/Makefile.mak @@ -0,0 +1,19 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = keyword
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/test/Slice/keyword/.gitignore b/php/test/Slice/keyword/.gitignore new file mode 100644 index 00000000000..a4492f0fe05 --- /dev/null +++ b/php/test/Slice/keyword/.gitignore @@ -0,0 +1 @@ +Key.php diff --git a/php/test/Slice/keyword/Client.php b/php/test/Slice/keyword/Client.php index f50f28fc409..fb96804944c 100644 --- a/php/test/Slice/keyword/Client.php +++ b/php/test/Slice/keyword/Client.php @@ -15,7 +15,9 @@ if(!extension_loaded("ice")) echo "\nerror: Ice extension is not loaded.\n\n"; exit(1); } -Ice_loadProfileWithArgs($argv); + +require 'Ice.php'; +require 'Key.php'; function test($b) { @@ -28,28 +30,28 @@ function test($b) class echoI extends and_echo { - function _else($a, &$b) + public function _else($a, $b) { } } class enddeclareI extends and_enddeclare { - function _else($a, &$b) + function _else($a, $b) { } + function _continue($a, $b) { } + function _do() { } } -function allTests() +function allTests($communicator) { - global $ICE; - echo "testing type names... "; flush(); $a = and_array::_as; @@ -63,11 +65,12 @@ function allTests() test($b->_throw == 0); test($b->_use == 0); test($b->_var == 0); - $c = $ICE->stringToProxy("test:tcp -p 10000")->ice_uncheckedCast("::and::function"); - $d = $ICE->stringToProxy("test:tcp -p 10000")->ice_uncheckedCast("::and::die"); - $e = $ICE->stringToProxy("test:tcp -p 10000")->ice_uncheckedCast("::and::echo"); + $p = $communicator->stringToProxy("test:tcp -p 10000"); + $c = and_functionPrxHelper::uncheckedCast($p); + $d = and_diePrxHelper::uncheckedCast($p); + $e = and_echoPrxHelper::uncheckedCast($p); $e1 = new echoI(); - $f = $ICE->stringToProxy("test:tcp -p 10000")->ice_uncheckedCast("::and::enddeclare"); + $f = and_enddeclarePrxHelper::uncheckedCast($p); $f1 = new enddeclareI(); $g = new and_endif(); $h = new and_endwhile(); @@ -76,7 +79,9 @@ function allTests() echo "ok\n"; } -allTests(); +$communicator = Ice_initialize(&$argv); +allTests($communicator); +$communicator->destroy(); exit(); ?> diff --git a/php/test/Slice/keyword/Makefile b/php/test/Slice/keyword/Makefile new file mode 100644 index 00000000000..c1fd7498cfd --- /dev/null +++ b/php/test/Slice/keyword/Makefile @@ -0,0 +1,22 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +SRCS = Key.php + +all:: $(SRCS) + +%.php: %.ice + $(SLICE2PHP) $(SLICE2PHPFLAGS) $< + +clean:: + rm -f $(SRCS) diff --git a/php/test/Slice/keyword/Makefile.mak b/php/test/Slice/keyword/Makefile.mak new file mode 100644 index 00000000000..8dca133fc19 --- /dev/null +++ b/php/test/Slice/keyword/Makefile.mak @@ -0,0 +1,22 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Key.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Slice/keyword/php.ini b/php/test/Slice/keyword/php.ini deleted file mode 100644 index 91dfdfddefd..00000000000 --- a/php/test/Slice/keyword/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -ice.slice=Key.ice -display_startup_errors=1 |