summaryrefslogtreecommitdiff
path: root/php/src
diff options
context:
space:
mode:
authorJoe George <joe@zeroc.com>2016-05-10 14:21:09 -0400
committerJoe George <joe@zeroc.com>2016-05-10 15:03:01 -0400
commita124372175471b4b536f9cacaee27d1e65af1a32 (patch)
tree76abb60a52b47110defdec1dd4e85f639ee6a65c /php/src
parentFixed issue with IE where accessing the stack from Exception.toString leads t... (diff)
downloadice-a124372175471b4b536f9cacaee27d1e65af1a32.tar.bz2
ice-a124372175471b4b536f9cacaee27d1e65af1a32.tar.xz
ice-a124372175471b4b536f9cacaee27d1e65af1a32.zip
Backport PHP7 support
Diffstat (limited to 'php/src')
-rw-r--r--php/src/Makefile7
-rw-r--r--php/src/Makefile.mak2
-rw-r--r--php/src/php5/.depend.mak (renamed from php/src/IcePHP/.depend.mak)0
-rw-r--r--php/src/php5/Communicator.cpp (renamed from php/src/IcePHP/Communicator.cpp)0
-rw-r--r--php/src/php5/Communicator.h (renamed from php/src/IcePHP/Communicator.h)0
-rw-r--r--php/src/php5/Config.h (renamed from php/src/IcePHP/Config.h)0
-rw-r--r--php/src/php5/Connection.cpp (renamed from php/src/IcePHP/Connection.cpp)0
-rw-r--r--php/src/php5/Connection.h (renamed from php/src/IcePHP/Connection.h)0
-rw-r--r--php/src/php5/Endpoint.cpp (renamed from php/src/IcePHP/Endpoint.cpp)0
-rw-r--r--php/src/php5/Endpoint.h (renamed from php/src/IcePHP/Endpoint.h)0
-rw-r--r--php/src/php5/IcePHP.rc (renamed from php/src/IcePHP/IcePHP.rc)0
-rw-r--r--php/src/php5/Init.cpp (renamed from php/src/IcePHP/Init.cpp)0
-rw-r--r--php/src/php5/Logger.cpp (renamed from php/src/IcePHP/Logger.cpp)0
-rw-r--r--php/src/php5/Logger.h (renamed from php/src/IcePHP/Logger.h)0
-rw-r--r--php/src/php5/Makefile (renamed from php/src/IcePHP/Makefile)0
-rw-r--r--php/src/php5/Makefile.mak (renamed from php/src/IcePHP/Makefile.mak)0
-rw-r--r--php/src/php5/Operation.cpp (renamed from php/src/IcePHP/Operation.cpp)0
-rw-r--r--php/src/php5/Operation.h (renamed from php/src/IcePHP/Operation.h)0
-rw-r--r--php/src/php5/Properties.cpp (renamed from php/src/IcePHP/Properties.cpp)0
-rw-r--r--php/src/php5/Properties.h (renamed from php/src/IcePHP/Properties.h)0
-rw-r--r--php/src/php5/Proxy.cpp (renamed from php/src/IcePHP/Proxy.cpp)0
-rw-r--r--php/src/php5/Proxy.h (renamed from php/src/IcePHP/Proxy.h)0
-rw-r--r--php/src/php5/Types.cpp (renamed from php/src/IcePHP/Types.cpp)0
-rw-r--r--php/src/php5/Types.h (renamed from php/src/IcePHP/Types.h)0
-rw-r--r--php/src/php5/Util.cpp (renamed from php/src/IcePHP/Util.cpp)0
-rw-r--r--php/src/php5/Util.h (renamed from php/src/IcePHP/Util.h)0
-rw-r--r--php/src/php7/.depend.mak1233
-rw-r--r--php/src/php7/Communicator.cpp1772
-rw-r--r--php/src/php7/Communicator.h60
-rw-r--r--php/src/php7/Config.h129
-rw-r--r--php/src/php7/Connection.cpp755
-rw-r--r--php/src/php7/Connection.h27
-rw-r--r--php/src/php7/Endpoint.cpp537
-rw-r--r--php/src/php7/Endpoint.h27
-rw-r--r--php/src/php7/IcePHP.rc38
-rw-r--r--php/src/php7/Init.cpp287
-rw-r--r--php/src/php7/Logger.cpp323
-rw-r--r--php/src/php7/Logger.h30
-rw-r--r--php/src/php7/Makefile39
-rw-r--r--php/src/php7/Makefile.mak67
-rw-r--r--php/src/php7/Operation.cpp875
-rw-r--r--php/src/php7/Operation.h37
-rw-r--r--php/src/php7/Properties.cpp681
-rw-r--r--php/src/php7/Properties.h38
-rw-r--r--php/src/php7/Proxy.cpp1718
-rw-r--r--php/src/php7/Proxy.h34
-rw-r--r--php/src/php7/Types.cpp3920
-rw-r--r--php/src/php7/Types.h590
-rw-r--r--php/src/php7/Util.cpp972
-rw-r--r--php/src/php7/Util.h188
50 files changed, 14384 insertions, 2 deletions
diff --git a/php/src/Makefile b/php/src/Makefile
index 7a3c951beec..f93f1c95e81 100644
--- a/php/src/Makefile
+++ b/php/src/Makefile
@@ -11,7 +11,12 @@ top_srcdir = ..
include $(top_srcdir)/config/Make.rules.php
-SUBDIRS = IcePHP
+
+ifeq ($(shell [ $$(php-config --vernum) -lt 70000 ] && echo true),true)
+SUBDIRS = php5
+else
+SUBDIRS = php7
+endif
$(EVERYTHING)::
@for subdir in $(SUBDIRS); \
diff --git a/php/src/Makefile.mak b/php/src/Makefile.mak
index 4643700e3f6..c56eac10759 100644
--- a/php/src/Makefile.mak
+++ b/php/src/Makefile.mak
@@ -11,7 +11,7 @@ top_srcdir = ..
!include $(top_srcdir)\config\Make.rules.mak.php
-SUBDIRS = IcePHP
+SUBDIRS = php5
$(EVERYTHING)::
@for %i in ( $(SUBDIRS) ) do \
diff --git a/php/src/IcePHP/.depend.mak b/php/src/php5/.depend.mak
index 811a3c85864..811a3c85864 100644
--- a/php/src/IcePHP/.depend.mak
+++ b/php/src/php5/.depend.mak
diff --git a/php/src/IcePHP/Communicator.cpp b/php/src/php5/Communicator.cpp
index 2e0e83793a7..2e0e83793a7 100644
--- a/php/src/IcePHP/Communicator.cpp
+++ b/php/src/php5/Communicator.cpp
diff --git a/php/src/IcePHP/Communicator.h b/php/src/php5/Communicator.h
index 30f07d273e1..30f07d273e1 100644
--- a/php/src/IcePHP/Communicator.h
+++ b/php/src/php5/Communicator.h
diff --git a/php/src/IcePHP/Config.h b/php/src/php5/Config.h
index 0c18832f642..0c18832f642 100644
--- a/php/src/IcePHP/Config.h
+++ b/php/src/php5/Config.h
diff --git a/php/src/IcePHP/Connection.cpp b/php/src/php5/Connection.cpp
index c4bab84d404..c4bab84d404 100644
--- a/php/src/IcePHP/Connection.cpp
+++ b/php/src/php5/Connection.cpp
diff --git a/php/src/IcePHP/Connection.h b/php/src/php5/Connection.h
index cfdaef321ae..cfdaef321ae 100644
--- a/php/src/IcePHP/Connection.h
+++ b/php/src/php5/Connection.h
diff --git a/php/src/IcePHP/Endpoint.cpp b/php/src/php5/Endpoint.cpp
index f9f0ca00c26..f9f0ca00c26 100644
--- a/php/src/IcePHP/Endpoint.cpp
+++ b/php/src/php5/Endpoint.cpp
diff --git a/php/src/IcePHP/Endpoint.h b/php/src/php5/Endpoint.h
index 1559c0a89f6..1559c0a89f6 100644
--- a/php/src/IcePHP/Endpoint.h
+++ b/php/src/php5/Endpoint.h
diff --git a/php/src/IcePHP/IcePHP.rc b/php/src/php5/IcePHP.rc
index ee77391769a..ee77391769a 100644
--- a/php/src/IcePHP/IcePHP.rc
+++ b/php/src/php5/IcePHP.rc
diff --git a/php/src/IcePHP/Init.cpp b/php/src/php5/Init.cpp
index fbb397724d8..fbb397724d8 100644
--- a/php/src/IcePHP/Init.cpp
+++ b/php/src/php5/Init.cpp
diff --git a/php/src/IcePHP/Logger.cpp b/php/src/php5/Logger.cpp
index eb911c71de7..eb911c71de7 100644
--- a/php/src/IcePHP/Logger.cpp
+++ b/php/src/php5/Logger.cpp
diff --git a/php/src/IcePHP/Logger.h b/php/src/php5/Logger.h
index c3ab3c531c0..c3ab3c531c0 100644
--- a/php/src/IcePHP/Logger.h
+++ b/php/src/php5/Logger.h
diff --git a/php/src/IcePHP/Makefile b/php/src/php5/Makefile
index 8f1f7fe3bae..8f1f7fe3bae 100644
--- a/php/src/IcePHP/Makefile
+++ b/php/src/php5/Makefile
diff --git a/php/src/IcePHP/Makefile.mak b/php/src/php5/Makefile.mak
index 2362a1d4b31..2362a1d4b31 100644
--- a/php/src/IcePHP/Makefile.mak
+++ b/php/src/php5/Makefile.mak
diff --git a/php/src/IcePHP/Operation.cpp b/php/src/php5/Operation.cpp
index 164f6003011..164f6003011 100644
--- a/php/src/IcePHP/Operation.cpp
+++ b/php/src/php5/Operation.cpp
diff --git a/php/src/IcePHP/Operation.h b/php/src/php5/Operation.h
index 91230201bc4..91230201bc4 100644
--- a/php/src/IcePHP/Operation.h
+++ b/php/src/php5/Operation.h
diff --git a/php/src/IcePHP/Properties.cpp b/php/src/php5/Properties.cpp
index 5fad58e39a8..5fad58e39a8 100644
--- a/php/src/IcePHP/Properties.cpp
+++ b/php/src/php5/Properties.cpp
diff --git a/php/src/IcePHP/Properties.h b/php/src/php5/Properties.h
index c4fa8b24e9d..c4fa8b24e9d 100644
--- a/php/src/IcePHP/Properties.h
+++ b/php/src/php5/Properties.h
diff --git a/php/src/IcePHP/Proxy.cpp b/php/src/php5/Proxy.cpp
index b86c15314c9..b86c15314c9 100644
--- a/php/src/IcePHP/Proxy.cpp
+++ b/php/src/php5/Proxy.cpp
diff --git a/php/src/IcePHP/Proxy.h b/php/src/php5/Proxy.h
index 235a427c2f5..235a427c2f5 100644
--- a/php/src/IcePHP/Proxy.h
+++ b/php/src/php5/Proxy.h
diff --git a/php/src/IcePHP/Types.cpp b/php/src/php5/Types.cpp
index 94b7cfd4e2a..94b7cfd4e2a 100644
--- a/php/src/IcePHP/Types.cpp
+++ b/php/src/php5/Types.cpp
diff --git a/php/src/IcePHP/Types.h b/php/src/php5/Types.h
index e540d49ae01..e540d49ae01 100644
--- a/php/src/IcePHP/Types.h
+++ b/php/src/php5/Types.h
diff --git a/php/src/IcePHP/Util.cpp b/php/src/php5/Util.cpp
index 2d81667eb60..2d81667eb60 100644
--- a/php/src/IcePHP/Util.cpp
+++ b/php/src/php5/Util.cpp
diff --git a/php/src/IcePHP/Util.h b/php/src/php5/Util.h
index 35b2b025c22..35b2b025c22 100644
--- a/php/src/IcePHP/Util.h
+++ b/php/src/php5/Util.h
diff --git a/php/src/php7/.depend.mak b/php/src/php7/.depend.mak
new file mode 100644
index 00000000000..811a3c85864
--- /dev/null
+++ b/php/src/php7/.depend.mak
@@ -0,0 +1,1233 @@
+
+Communicator.obj: \
+ Communicator.cpp \
+ "Communicator.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.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" \
+ "$(ice_cpp_dir)\include\IceUtil\StringUtil.h" \
+
+Connection.obj: \
+ Connection.cpp \
+ "Connection.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.h" \
+ "Endpoint.h" \
+ "Types.h" \
+ "Communicator.h" \
+ "Operation.h" \
+ "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \
+ "Util.h" \
+
+Endpoint.obj: \
+ Endpoint.cpp \
+ "Endpoint.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.h" \
+ "Util.h" \
+
+Init.obj: \
+ Init.cpp \
+ "Communicator.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.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.obj: \
+ Logger.cpp \
+ "Logger.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.h" \
+ "Util.h" \
+
+Operation.obj: \
+ Operation.cpp \
+ "Operation.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.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.obj: \
+ Properties.cpp \
+ "Properties.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.h" \
+ "Util.h" \
+
+Proxy.obj: \
+ Proxy.cpp \
+ "Proxy.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.h" \
+ "Communicator.h" \
+ "Types.h" \
+ "Operation.h" \
+ "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \
+ "Connection.h" \
+ "Endpoint.h" \
+ "Util.h" \
+
+Types.obj: \
+ Types.cpp \
+ "Types.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.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\Slice\PHPUtil.h" \
+ "$(ice_cpp_dir)\include\Slice\Parser.h" \
+
+Util.obj: \
+ Util.cpp \
+ "Util.h" \
+ "Config.h" \
+ "$(ice_cpp_dir)\include\Ice\Ice.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\Ice\Config.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Config.h" \
+ "$(ice_cpp_dir)\include\Ice\DeprecatedStringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyF.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Shared.h" \
+ "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Handle.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\Handle.h" \
+ "$(ice_cpp_dir)\include\Ice\Exception.h" \
+ "$(ice_cpp_dir)\include\Ice\Format.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamF.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObject.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \
+ "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \
+ "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Optional.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \
+ "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \
+ "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \
+ "$(ice_cpp_dir)\include\Ice\Plugin.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerF.h" \
+ "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \
+ "$(ice_cpp_dir)\include\Ice\Initialize.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Timer.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Thread.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\IceUtil\MutexProtocol.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \
+ "$(ice_cpp_dir)\include\IceUtil\Cond.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \
+ "$(ice_cpp_dir)\include\Ice\Proxy.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\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\AsyncResult.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \
+ "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \
+ "$(ice_cpp_dir)\include\Ice\InstanceF.h" \
+ "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \
+ "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \
+ "$(ice_cpp_dir)\include\Ice\Current.h" \
+ "$(ice_cpp_dir)\include\Ice\Identity.h" \
+ "$(ice_cpp_dir)\include\Ice\Version.h" \
+ "$(ice_cpp_dir)\include\Ice\BasicStream.h" \
+ "$(ice_cpp_dir)\include\Ice\Object.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \
+ "$(ice_cpp_dir)\include\Ice\Buffer.h" \
+ "$(ice_cpp_dir)\include\Ice\Protocol.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \
+ "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \
+ "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \
+ "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \
+ "$(ice_cpp_dir)\include\Ice\LocalException.h" \
+ "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\GCObject.h" \
+ "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.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\ResponseHandlerF.h" \
+ "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\Properties.h" \
+ "$(ice_cpp_dir)\include\Ice\Logger.h" \
+ "$(ice_cpp_dir)\include\Ice\LoggerUtil.h" \
+ "$(ice_cpp_dir)\include\Ice\RemoteLogger.h" \
+ "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \
+ "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectFactory.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\FacetMap.h" \
+ "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \
+ "$(ice_cpp_dir)\include\Ice\Endpoint.h" \
+ "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \
+ "$(ice_cpp_dir)\include\Ice\SlicedData.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsync.h" \
+ "$(ice_cpp_dir)\include\Ice\OutgoingAsyncF.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\ConnectionAsync.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\ProcessF.h" \
+ "$(ice_cpp_dir)\include\Ice\Router.h" \
+ "$(ice_cpp_dir)\include\Ice\DispatchInterceptor.h" \
+ "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \
+ "$(ice_cpp_dir)\include\Ice\Metrics.h" \
+ "$(ice_cpp_dir)\include\Ice\Service.h" \
+ "$(ice_cpp_dir)\include\IceUtil\UUID.h" \
+ "$(ice_cpp_dir)\include\Slice\PHPUtil.h" \
+ "$(ice_cpp_dir)\include\Slice\Parser.h" \
diff --git a/php/src/php7/Communicator.cpp b/php/src/php7/Communicator.cpp
new file mode 100644
index 00000000000..ea0e614edf3
--- /dev/null
+++ b/php/src/php7/Communicator.cpp
@@ -0,0 +1,1772 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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 <Communicator.h>
+#include <Logger.h>
+#include <Properties.h>
+#include <Proxy.h>
+#include <Types.h>
+#include <Util.h>
+#include <IceUtil/Options.h>
+#include <IceUtil/MutexPtrLock.h>
+#include <IceUtil/StringUtil.h>
+#include <IceUtil/Timer.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* communicatorClassEntry = 0;
+
+//
+// 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.
+//
+class ActiveCommunicator : public IceUtil::Shared
+{
+public:
+
+ 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
+{
+public:
+
+ CommunicatorInfoI(const ActiveCommunicatorPtr&, zval*);
+
+ virtual void getZval(zval*);
+ virtual void addRef(void);
+ virtual void decRef(void);
+
+ virtual Ice::CommunicatorPtr getCommunicator() const;
+
+ bool addObjectFactory(const std::string&, zval*);
+ bool findObjectFactory(const std::string&, zval*);
+ void destroyObjectFactories(void);
+
+ const ActiveCommunicatorPtr ac;
+ zval zv;
+ ObjectFactoryMap objectFactories;
+};
+typedef IceUtil::Handle<CommunicatorInfoI> CommunicatorInfoIPtr;
+
+//
+// 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:
+//
+// * 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;
+};
+
+class ReaperTask : public IceUtil::TimerTask
+{
+public:
+
+ virtual void runTimerTask();
+};
+
+}
+
+namespace
+{
+//
+// Communicator support.
+//
+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;
+ProfileMap _profiles;
+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;
+RegisteredCommunicatorMap _registeredCommunicators;
+IceUtil::Mutex* _registeredCommunicatorsMutex = 0;
+
+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;
+
+class Init
+{
+public:
+
+ Init()
+ {
+ _registeredCommunicatorsMutex = new IceUtil::Mutex();
+ }
+
+ ~Init()
+ {
+ delete _registeredCommunicatorsMutex;
+ _registeredCommunicatorsMutex = 0;
+ }
+};
+
+Init init;
+}
+
+extern "C"
+{
+static zend_object* handleAlloc(zend_class_entry*);
+static void handleFreeStorage(zend_object*);
+static zend_object* handleClone(zval*);
+}
+
+ZEND_METHOD(Ice_Communicator, __construct)
+{
+ runtimeError("communicators cannot be instantiated directly");
+}
+
+ZEND_METHOD(Ice_Communicator, destroy)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ //
+ // Remove all registrations.
+ //
+ {
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_registeredCommunicatorsMutex);
+ for(vector<string>::iterator p = _this->ac->ids.begin(); p != _this->ac->ids.end(); ++p)
+ {
+ _registeredCommunicators.erase(*p);
+ }
+ _this->ac->ids.clear();
+ }
+
+ //
+ // We need to destroy any object factories installed by this request.
+ //
+ _this->destroyObjectFactories();
+
+ 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);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, stringToProxy)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ char* str;
+ size_t strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &str, &strLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ string s(str, strLen);
+
+ try
+ {
+ Ice::ObjectPrx prx = _this->getCommunicator()->stringToProxy(s);
+ if(!createProxy(return_value, prx, _this))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, proxyToString)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O!"), &zv, proxyClassEntry) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ string str;
+ if(zv)
+ {
+ Ice::ObjectPrx prx;
+ ClassInfoPtr info;
+ if(!fetchProxy(zv, prx, info))
+ {
+ RETURN_NULL();
+ }
+ assert(prx);
+ str = prx->ice_toString();
+ }
+ RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, propertyToProxy)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ char* str;
+ size_t strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &str, &strLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ string s(str, strLen);
+
+ try
+ {
+ Ice::ObjectPrx prx = _this->getCommunicator()->propertyToProxy(s);
+ if(!createProxy(return_value, prx, _this))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, proxyToProperty)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ zval* zv;
+ char* str;
+ size_t strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O!s"), &zv, proxyClassEntry, &str, &strLen)
+ != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ string prefix(str, strLen);
+
+ try
+ {
+ if(zv)
+ {
+ Ice::ObjectPrx prx;
+ ClassInfoPtr info;
+ if(!fetchProxy(zv, prx, info))
+ {
+ RETURN_NULL();
+ }
+ assert(prx);
+
+ Ice::PropertyDict val = _this->getCommunicator()->proxyToProperty(prx, prefix);
+ if(!createStringMap(return_value, val))
+ {
+ RETURN_NULL();
+ }
+ }
+ else
+ {
+ array_init(return_value);
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, stringToIdentity)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ char* str;
+ size_t strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &str, &strLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ string s(str, strLen);
+
+ try
+ {
+ Ice::Identity id = _this->getCommunicator()->stringToIdentity(s);
+ if(!createIdentity(return_value, id))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, identityToString)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ zend_class_entry* identityClass = idToClass("::Ice::Identity");
+ assert(identityClass);
+
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O"), &zv, identityClass) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ Ice::Identity id;
+ if(!extractIdentity(zv, id))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ string str = _this->getCommunicator()->identityToString(id);
+ RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, addObjectFactory)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ zend_class_entry* factoryClass = idToClass("Ice::ObjectFactory");
+ assert(factoryClass);
+
+ zval* factory;
+ char* id;
+ size_t idLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("Os!"), &factory, factoryClass, &id,
+ &idLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ string type;
+ if(id)
+ {
+ type = string(id, idLen);
+ }
+
+ if(!_this->addObjectFactory(type, factory))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, findObjectFactory)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ char* id;
+ size_t idLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s!"), &id, &idLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ string type;
+ if(id)
+ {
+ type = string(id, idLen);
+ }
+
+ if(!_this->findObjectFactory(type, return_value))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, getImplicitContext)
+{
+ runtimeError("not implemented");
+}
+
+ZEND_METHOD(Ice_Communicator, getProperties)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::PropertiesPtr props = _this->getCommunicator()->getProperties();
+ if(!createProperties(return_value, props))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, getLogger)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::LoggerPtr logger = _this->getCommunicator()->getLogger();
+ if(!createLogger(return_value, logger))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+
+ZEND_METHOD(Ice_Communicator, getDefaultRouter)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::RouterPrx router = _this->getCommunicator()->getDefaultRouter();
+ if(router)
+ {
+ ClassInfoPtr info = getClassInfoById("::Ice::Router");
+ if(!info)
+ {
+ runtimeError("no definition for Ice::Router");
+ RETURN_NULL();
+ }
+ if(!createProxy(return_value, router, info, _this))
+ {
+ RETURN_NULL();
+ }
+ }
+ else
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, setDefaultRouter)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O!"), &zv, proxyClassEntry) !=
+ SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr info;
+ if(zv && !fetchProxy(zv, proxy, info))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::RouterPrx router;
+ if(proxy)
+ {
+ if(!info || !info->isA("::Ice::Router"))
+ {
+ invalidArgument("setDefaultRouter requires a proxy narrowed to Ice::Router");
+ RETURN_NULL();
+ }
+ router = Ice::RouterPrx::uncheckedCast(proxy);
+ }
+ _this->getCommunicator()->setDefaultRouter(router);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, getDefaultLocator)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::LocatorPrx locator = _this->getCommunicator()->getDefaultLocator();
+ if(locator)
+ {
+ ClassInfoPtr info = getClassInfoById("::Ice::Locator");
+ if(!info)
+ {
+ runtimeError("no definition for Ice::Locator");
+ RETURN_NULL();
+ }
+ if(!createProxy(return_value, locator, info, _this))
+ {
+ RETURN_NULL();
+ }
+ }
+ else
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, setDefaultLocator)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O!"), &zv, proxyClassEntry) !=
+ SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr info;
+ if(zv && !fetchProxy(zv, proxy, info))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::LocatorPrx locator;
+ if(proxy)
+ {
+ if(!info || !info->isA("::Ice::Locator"))
+ {
+ invalidArgument("setDefaultLocator requires a proxy narrowed to Ice::Locator");
+ RETURN_NULL();
+ }
+ locator = Ice::LocatorPrx::uncheckedCast(proxy);
+ }
+ _this->getCommunicator()->setDefaultLocator(locator);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, flushBatchRequests)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis());
+ assert(_this);
+
+ if(ZEND_NUM_ARGS() != 8)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ try
+ {
+ _this->getCommunicator()->flushBatchRequests();
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleAlloc(zend_class_entry* ce)
+{
+ Wrapper<CommunicatorInfoIPtr>* obj = Wrapper<CommunicatorInfoIPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_handlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleFreeStorage(zend_object* object)
+{
+ Wrapper<CommunicatorInfoIPtr>* obj = Wrapper<CommunicatorInfoIPtr>::fetch(object);
+ assert(obj);
+
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleClone(zval* zv)
+{
+ php_error_docref(0, E_ERROR, "communicators cannot be cloned");
+ return 0;
+}
+
+static CommunicatorInfoIPtr
+createCommunicator(zval* zv, const ActiveCommunicatorPtr& ac)
+{
+ try
+ {
+ if(object_init_ex(zv, communicatorClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize communicator object");
+ return 0;
+ }
+
+ Wrapper<CommunicatorInfoIPtr>* obj = Wrapper<CommunicatorInfoIPtr>::extract(zv);
+ 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);
+ return 0;
+ }
+}
+
+static CommunicatorInfoIPtr
+initializeCommunicator(zval* zv, Ice::StringSeq& args, bool hasArgs, const Ice::InitializationData& initData)
+{
+ try
+ {
+ Ice::CommunicatorPtr c;
+ if(hasArgs)
+ {
+ c = Ice::initialize(args, initData);
+ }
+ else
+ {
+ c = Ice::initialize(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);
+ if(!info)
+ {
+ try
+ {
+ c->destroy();
+ }
+ catch(...)
+ {
+ }
+ }
+
+ return info;
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ return 0;
+ }
+}
+
+ZEND_FUNCTION(Ice_initialize)
+{
+ if(ZEND_NUM_ARGS() > 2)
+ {
+ runtimeError("too many arguments");
+ RETURN_NULL();
+ }
+
+ zend_class_entry* initClass = idToClass("::Ice::InitializationData");
+ assert(initClass);
+
+ //
+ // 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");
+ RETURN_NULL();
+ }
+
+ Ice::StringSeq seq;
+ Ice::InitializationData initData;
+ zval* zvargs = 0;
+ zval* zvinit = 0;
+
+ //
+ // Accept the following invocations:
+ //
+ // initialize(array, InitializationData)
+ // initialize(array)
+ // initialize(InitializationData)
+ // initialize()
+ //
+ bool hasArgs = false;
+ if(ZEND_NUM_ARGS())
+ {
+ if(Z_TYPE(args[0]) == IS_ARRAY)
+ {
+ if(!extractStringArray(&args[0], seq))
+ {
+ RETURN_NULL();
+ }
+ zvargs = &args[0];
+ hasArgs = true;
+ if(ZEND_NUM_ARGS() > 1)
+ {
+ if(Z_TYPE(args[1]) != IS_OBJECT || Z_OBJCE(args[1]) != initClass)
+ {
+ string s = zendTypeToString(Z_TYPE(args[1]));
+ invalidArgument("expected InitializationData object but received %s", s.c_str());
+ RETURN_NULL();
+ }
+ zvinit = &args[1];
+ }
+ }
+ else if(Z_TYPE(args[0]) == IS_OBJECT && Z_OBJCE(args[0]) == initClass)
+ {
+ if(ZEND_NUM_ARGS() > 1)
+ {
+ runtimeError("too many arguments");
+ RETURN_NULL();
+ }
+ zvinit = &args[0];
+ }
+ else
+ {
+ string s = zendTypeToString(Z_TYPE(args[0]));
+ invalidArgument("unexpected argument type %s", s.c_str());
+ RETURN_NULL();
+ }
+ }
+
+ if(zvinit)
+ {
+ zval* data;
+ string member;
+
+ member = "properties";
+ {
+ if((data = zend_hash_str_find(Z_OBJPROP_P(zvinit), STRCAST(member.c_str()), member.size())))
+ {
+ assert(Z_TYPE_P(data) == IS_INDIRECT);
+ if(!fetchProperties(Z_INDIRECT_P(data), initData.properties))
+ {
+ RETURN_NULL();
+ }
+ }
+ }
+
+ member = "logger";
+ {
+ if((data = zend_hash_str_find(Z_OBJPROP_P(zvinit), STRCAST(member.c_str()), member.size())))
+ {
+ assert(Z_TYPE_P(data) == IS_INDIRECT);
+ if(!fetchLogger(Z_INDIRECT_P(data), initData.logger))
+ {
+ RETURN_NULL();
+ }
+ }
+ }
+ }
+
+ initData.compactIdResolver = new IdResolver();
+
+ CommunicatorInfoIPtr info = initializeCommunicator(return_value, seq, hasArgs, initData);
+ if(!info)
+ {
+ RETURN_NULL();
+ }
+
+ if(zvargs && Z_ISREF_P(zvargs))
+ {
+ zval_dtor(zvargs);
+ if(!createStringArray(zvargs, seq))
+ {
+ RETURN_NULL();
+ }
+ }
+}
+
+ZEND_FUNCTION(Ice_register)
+{
+ zval* comm;
+ char* s;
+ size_t sLen;
+ long expires = 0;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("Os|l"), &comm, communicatorClassEntry, &s,
+ &sLen, &expires) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ string id(s, sLen);
+ if(id.empty())
+ {
+ invalidArgument("communicator id cannot be empty");
+ RETURN_NULL();
+ }
+
+ CommunicatorInfoIPtr info = Wrapper<CommunicatorInfoIPtr>::value(comm);
+ assert(info);
+
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_registeredCommunicatorsMutex);
+
+ RegisteredCommunicatorMap::iterator p = _registeredCommunicators.find(id);
+ if(p != _registeredCommunicators.end())
+ {
+ if(p->second->communicator != info->getCommunicator())
+ {
+ //
+ // A different communicator is already registered with that ID.
+ //
+ RETURN_FALSE;
+ }
+ }
+ else
+ {
+ info->ac->ids.push_back(id);
+ _registeredCommunicators[id] = info->ac;
+ }
+
+ 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();
+
+ //
+ // 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_unregister)
+{
+ char* s;
+ size_t sLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &s, &sLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ string id(s, sLen);
+
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_registeredCommunicatorsMutex);
+
+ RegisteredCommunicatorMap::iterator p = _registeredCommunicators.find(id);
+ if(p == _registeredCommunicators.end())
+ {
+ //
+ // 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_find)
+{
+ char* s;
+ size_t sLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &s, &sLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ string id(s, sLen);
+
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_registeredCommunicatorsMutex);
+
+ RegisteredCommunicatorMap::iterator p = _registeredCommunicators.find(id);
+ if(p == _registeredCommunicators.end())
+ {
+ //
+ // No communicator registered with that ID.
+ //
+ RETURN_NULL();
+ }
+
+ if(p->second->expires > 0)
+ {
+ p->second->lastAccess = IceUtil::Time::now();
+ }
+
+ //
+ // 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)
+ {
+ CommunicatorMap::iterator q = m->find(p->second->communicator);
+ if(q != m->end())
+ {
+ q->second->getZval(return_value);
+ return;
+ }
+ }
+
+ if(!createCommunicator(return_value, p->second))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_getProperties)
+{
+ char* s = 0;
+ size_t sLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("|s"), &s, &sLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ string name;
+ if(s)
+ {
+ name = string(s, sLen);
+ }
+
+ ProfileMap::iterator p = _profiles.find(name);
+ if(p == _profiles.end())
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr clone = p->second->clone();
+ if(!createProperties(return_value, clone))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_identityToString)
+{
+ zend_class_entry* identityClass = idToClass("::Ice::Identity");
+ assert(identityClass);
+
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O"), &zv, identityClass) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ Ice::Identity id;
+ if(!extractIdentity(zv, id))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ string str = Ice::identityToString(id);
+ RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_stringToIdentity)
+{
+ char* str;
+ size_t strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &str, &strLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ string s(str, strLen);
+
+ try
+ {
+ Ice::Identity id = Ice::stringToIdentity(s);
+ if(!createIdentity(return_value, id))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+//
+// Necessary to suppress warnings from zend_function_entry in php-5.2
+// and INI_STR macro.
+//
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+
+//
+// Predefined methods for Communicator.
+//
+static zend_function_entry _interfaceMethods[] =
+{
+ {0, 0, 0}
+};
+static zend_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, proxyToProperty, 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}
+};
+
+static bool
+createProfile(const string& name, const string& config, const string& options)
+{
+ ProfileMap::iterator p = _profiles.find(name);
+ if(p != _profiles.end())
+ {
+ php_error_docref(0, E_WARNING, "duplicate Ice profile `%s'", 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, E_WARNING, "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, E_WARNING, "error occurred while parsing the options `%s':\n%s",
+ options.c_str(), msg.c_str());
+ return false;
+ }
+
+ properties->parseCommandLineOptions("", args);
+ }
+
+ _profiles[name] = properties;
+ return true;
+}
+
+static bool
+parseProfiles(const string& file)
+{
+ //
+ // 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
+ //
+ ifstream in(file.c_str());
+ if(!in)
+ {
+ php_error_docref(0, 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)
+ {
+ 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, E_WARNING, "invalid profile section in file %s:\n%s\n", file.c_str(),
+ line);
+ return false;
+ }
+
+ if(!name.empty())
+ {
+ createProfile(name, config, options);
+ config.clear();
+ options.clear();
+ }
+
+ 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, 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);
+
+ //
+ // Check for quotes and remove them if present
+ //
+ string::size_type qpos = IceUtilInternal::checkQuote(value);
+ if(qpos != string::npos)
+ {
+ value = value.substr(1, qpos - 1);
+ }
+ }
+
+ if(key == "config" || key == "ice.config")
+ {
+ config = value;
+ }
+ else if(key == "options" || key == "ice.options")
+ {
+ options = value;
+ }
+ else
+ {
+ php_error_docref(0, E_WARNING, "unknown profile entry in file %s:\n%s\n", file.c_str(), line);
+ }
+
+ if(name.empty())
+ {
+ php_error_docref(0, E_WARNING, "no section for profile entry in file %s:\n%s\n", file.c_str(),
+ line);
+ return false;
+ }
+ }
+ }
+
+ if(!name.empty())
+ {
+ if(!createProfile(name, config, options))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+IcePHP::communicatorInit(void)
+{
+ //
+ // 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, "Ice", "Communicator", _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Communicator", _interfaceMethods);
+#endif
+ zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC);
+
+ //
+ // Register the Communicator class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Communicator", _classMethods);
+ ce.create_object = handleAlloc;
+ communicatorClassEntry = zend_register_internal_class(&ce);
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _handlers.clone_obj = handleClone;
+ _handlers.free_obj = handleFreeStorage;
+ _handlers.offset = XtOffsetOf(Wrapper<CommunicatorInfoIPtr>, zobj);
+ zend_class_implements(communicatorClassEntry, 1, interface);
+
+ //
+ // Create the profiles from configuration settings.
+ //
+ const char* empty = "";
+ const char* config = INI_STR("ice.config"); // Needs to be a string literal!
+ if(!config)
+ {
+ config = empty;
+ }
+ const char* options = INI_STR("ice.options"); // Needs to be a string literal!
+ if(!options)
+ {
+ options = empty;
+ }
+ if(!createProfile(_defaultProfileName, config, options))
+ {
+ return false;
+ }
+
+ const char* profiles = INI_STR("ice.profiles"); // Needs to be a string literal!
+ if(!profiles)
+ {
+ profiles = empty;
+ }
+ if(strlen(profiles) > 0)
+ {
+ if(!parseProfiles(profiles))
+ {
+ return false;
+ }
+
+ if(INI_BOOL(const_cast<char*>("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(void)
+{
+ _profiles.clear();
+
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_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(void)
+{
+ ICE_G(communicatorMap) = 0;
+
+ return true;
+}
+
+bool
+IcePHP::communicatorRequestShutdown(void)
+{
+ 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();
+ }
+
+ //
+ // 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()
+{
+ //
+ // There are no more references to this communicator, so we can safely destroy it now.
+ //
+ try
+ {
+ communicator->destroy();
+ }
+ catch(...)
+ {
+ }
+}
+
+IcePHP::CommunicatorInfoI::CommunicatorInfoI(const ActiveCommunicatorPtr& c, zval* z) :
+ ac(c)
+{
+ ZVAL_COPY_VALUE(&zv, z);
+}
+
+void
+IcePHP::CommunicatorInfoI::getZval(zval* z)
+{
+ ZVAL_COPY_VALUE(z, &zv);
+ addRef();
+}
+
+void
+IcePHP::CommunicatorInfoI::addRef(void)
+{
+ Z_ADDREF_P(&zv);
+}
+
+void
+IcePHP::CommunicatorInfoI::decRef(void)
+{
+ Z_DELREF_P(&zv);
+}
+
+Ice::CommunicatorPtr
+IcePHP::CommunicatorInfoI::getCommunicator() const
+{
+ return ac->communicator;
+}
+
+bool
+IcePHP::CommunicatorInfoI::addObjectFactory(const string& id, zval* factory)
+{
+ 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;
+ }
+
+ zval zv;
+ ZVAL_COPY_VALUE(&zv, factory);
+ objectFactories.insert(ObjectFactoryMap::value_type(id, zv));
+
+ return true;
+}
+
+bool
+IcePHP::CommunicatorInfoI::findObjectFactory(const string& id, zval* zv)
+{
+ ObjectFactoryMap::iterator p = objectFactories.find(id);
+ if(p != objectFactories.end())
+ {
+ ZVAL_COPY(zv, &p->second);
+ return true;
+ }
+
+ return false;
+}
+
+void
+IcePHP::CommunicatorInfoI::destroyObjectFactories()
+{
+ for(ObjectFactoryMap::iterator p = objectFactories.begin(); p != objectFactories.end(); ++p)
+ {
+ //
+ // Invoke the destroy method on each registered PHP factory.
+ //
+ invokeMethod(&p->second, "destroy");
+ zend_clear_exception();
+ zval_ptr_dtor(&p->second);
+ }
+}
+
+IcePHP::ObjectFactoryI::ObjectFactoryI(const Ice::CommunicatorPtr& communicator) :
+ _communicator(communicator)
+{
+}
+
+Ice::ObjectPtr
+IcePHP::ObjectFactoryI::create(const string& id)
+{
+ 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;
+ ZVAL_UNDEF(&factory);
+
+ //
+ // 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())
+ {
+ ZVAL_COPY(&factory, &q->second);
+ }
+
+ //
+ // Get the type information.
+ //
+ ClassInfoPtr cls;
+ if(id == Ice::Object::ice_staticId())
+ {
+ //
+ // When the ID is that of Ice::Object, it indicates that the stream has not
+ // found a factory and is providing us an opportunity to preserve the object.
+ //
+ cls = getClassInfoById("::Ice::UnknownSlicedObject");
+ }
+ else
+ {
+ cls = getClassInfoById(id);
+ }
+
+ if(!cls)
+ {
+ return 0;
+ }
+
+ if(!Z_ISUNDEF(factory))
+ {
+ zval arg;
+ ZVAL_STRINGL(&arg, STRCAST(id.c_str()), static_cast<int>(id.length()));
+
+ zval obj;
+ ZVAL_UNDEF(&obj);
+
+ zend_try
+ {
+ zend_call_method(&factory, 0, 0, const_cast<char*>("create"), sizeof("create") - 1, &obj, 1, &arg, 0);
+
+ }
+ zend_catch
+ {
+ }
+ zend_end_try();
+
+ zval_ptr_dtor(&arg);
+
+ //
+ // Bail out if an exception has already been thrown.
+ //
+ if(Z_ISUNDEF(obj) || EG(exception))
+ {
+ throw AbortMarshaling();
+ }
+
+ AutoDestroy destroy(&obj);
+
+ if(Z_TYPE(obj) == IS_NULL)
+ {
+ return 0;
+ }
+
+ return new ObjectReader(&obj, cls, info);
+ }
+
+ //
+ // If the requested type is an abstract class, then we give up.
+ //
+ if(cls->isAbstract)
+ {
+ return 0;
+ }
+
+ //
+ // Instantiate the object.
+ //
+ zval obj;
+ ZVAL_UNDEF(&obj);
+
+ if(object_init_ex(&obj, const_cast<zend_class_entry*>(cls->zce)) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ if(!invokeMethod(&obj, ZEND_CONSTRUCTOR_FUNC_NAME))
+ {
+ throw AbortMarshaling();
+ }
+
+
+ return new ObjectReader(&obj, cls, info);
+}
+
+void
+IcePHP::ObjectFactoryI::destroy()
+{
+ _communicator = 0;
+}
+
+void
+IcePHP::ReaperTask::runTimerTask()
+{
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_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/php7/Communicator.h b/php/src/php7/Communicator.h
new file mode 100644
index 00000000000..30f07d273e1
--- /dev/null
+++ b/php/src/php7/Communicator.h
@@ -0,0 +1,60 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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_COMMUNICATOR_H
+#define ICEPHP_COMMUNICATOR_H
+
+#include <Config.h>
+#include <Ice/CommunicatorF.h>
+
+//
+// Global functions.
+//
+extern "C"
+{
+ZEND_FUNCTION(Ice_initialize);
+ZEND_FUNCTION(Ice_register);
+ZEND_FUNCTION(Ice_unregister);
+ZEND_FUNCTION(Ice_find);
+ZEND_FUNCTION(Ice_getProperties);
+ZEND_FUNCTION(Ice_identityToString);
+ZEND_FUNCTION(Ice_stringToIdentity);
+}
+
+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;
+
+ virtual Ice::CommunicatorPtr getCommunicator() const = 0;
+};
+typedef IceUtil::Handle<CommunicatorInfo> CommunicatorInfoPtr;
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/php7/Config.h b/php/src/php7/Config.h
new file mode 100644
index 00000000000..0c18832f642
--- /dev/null
+++ b/php/src/php7/Config.h
@@ -0,0 +1,129 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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_CONFIG_H
+#define ICE_PHP_CONFIG_H
+
+//
+// We need to define WIN32_LEAN_AND_MEAN to avoid redefinition errors in
+// winsock2.h. However, we can't define the macro in the Makefile because
+// a PHP header defines it without a surrounding #ifndef, so we have to
+// undefine it before including the PHP header files.
+//
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <Ice/Ice.h>
+
+#ifdef _WIN32
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+#ifdef _WIN32
+#include <crtdbg.h>
+#include <math.h>
+#endif
+
+#ifdef _WIN32
+extern "C"
+{
+#endif
+
+#ifdef _WIN32
+# pragma warning( disable : 4018) // suppress signed/unsigned mismatch in zend_execute.h (PHP 5.3.x)
+#elif defined(__GNUC__)
+# pragma GCC diagnostic warning "-Wsign-compare"
+#endif
+
+#ifdef _WIN64
+# pragma warning( disable : 4267) // suppress size_t/uint conversion warnings in zend macros for Windows x64 builds
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+# pragma GCC diagnostic warning "-Wnarrowing"
+#endif
+
+#include "php.h"
+
+#ifdef _WIN32
+# pragma warning( default : 4018)
+#endif
+
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "zend_interfaces.h"
+#include "zend_exceptions.h"
+
+#ifdef _WIN32
+}
+#endif
+
+extern zend_module_entry ice_module_entry;
+#define phpext_ice_ptr &ice_module_entry
+
+#ifdef PHP_WIN32
+#define PHP_ICE_API __declspec(dllexport)
+#else
+#define PHP_ICE_API
+#endif
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+//
+// 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);
+ZEND_RSHUTDOWN_FUNCTION(ice);
+ZEND_MINFO_FUNCTION(ice);
+
+ZEND_BEGIN_MODULE_GLOBALS(ice)
+ void* communicatorMap;
+ void* idToClassInfoMap;
+ void* compactIdToClassInfoMap;
+ void* nameToClassInfoMap;
+ void* proxyInfoMap;
+ void* exceptionInfoMap;
+ zval* unset;
+ZEND_END_MODULE_GLOBALS(ice)
+
+#ifdef ZTS
+# define ICE_G(v) TSRMG(ice_globals_id, zend_ice_globals*, v)
+#else
+# define ICE_G(v) (ice_globals.v)
+#endif
+
+#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
+
+//
+// Older versions of PHP use char* instead of const char* in many APIs.
+//
+#ifdef STRCAST
+# error "STRCAST already defined!"
+#endif
+#define STRCAST(s) const_cast<char*>(s)
+
+#endif
diff --git a/php/src/php7/Connection.cpp b/php/src/php7/Connection.cpp
new file mode 100644
index 00000000000..b1942d133c0
--- /dev/null
+++ b/php/src/php7/Connection.cpp
@@ -0,0 +1,755 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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 <Endpoint.h>
+#include <Types.h>
+#include <Util.h>
+#include <IceSSL/IceSSL.h>
+
+using namespace std;
+using namespace IcePHP;
+
+ZEND_EXTERN_MODULE_GLOBALS(ice)
+
+//
+// Class entries represent the PHP class implementations we have registered.
+//
+static zend_class_entry* connectionClassEntry = 0;
+
+static zend_class_entry* connectionInfoClassEntry = 0;
+static zend_class_entry* ipConnectionInfoClassEntry = 0;
+static zend_class_entry* tcpConnectionInfoClassEntry = 0;
+static zend_class_entry* udpConnectionInfoClassEntry = 0;
+static zend_class_entry* wsConnectionInfoClassEntry = 0;
+static zend_class_entry* sslConnectionInfoClassEntry = 0;
+static zend_class_entry* wssConnectionInfoClassEntry = 0;
+
+//
+// Ice::Connection support.
+//
+static zend_object_handlers _connectionHandlers;
+static zend_object_handlers _connectionInfoHandlers;
+
+extern "C"
+{
+static zend_object* handleConnectionAlloc(zend_class_entry*);
+static void handleConnectionFreeStorage(zend_object*);
+static int handleConnectionCompare(zval*, zval*);
+
+static zend_object* handleConnectionInfoAlloc(zend_class_entry*);
+static void handleConnectionInfoFreeStorage(zend_object*);
+}
+
+ZEND_METHOD(Ice_Connection, __construct)
+{
+ runtimeError("Connection cannot be instantiated");
+}
+
+ZEND_METHOD(Ice_Connection, __toString)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ string str = _this->toString();
+ RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, close)
+{
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ zend_bool b;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("b"), &b) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ _this->close(b ? true : false);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, getEndpoint)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ if(!createEndpoint(return_value, _this->getEndpoint()))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, flushBatchRequests)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ _this->flushBatchRequests();
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, setACM)
+{
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ zval* t;
+ zval* c;
+ zval* h;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("zzz"), &t, &c, &h) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ IceUtil::Optional<Ice::Int> timeout;
+ IceUtil::Optional<Ice::ACMClose> close;
+ IceUtil::Optional<Ice::ACMHeartbeat> heartbeat;
+
+ if(!isUnset(t))
+ {
+ if(Z_TYPE_P(t) != IS_LONG)
+ {
+ invalidArgument("value for 'timeout' argument must be Unset or an integer");
+ RETURN_NULL();
+ }
+ timeout = static_cast<Ice::Int>(Z_LVAL_P(t));
+ }
+
+ if(!isUnset(c))
+ {
+ if(Z_TYPE_P(c) != IS_LONG)
+ {
+ invalidArgument("value for 'close' argument must be Unset or an enumerator of ACMClose");
+ RETURN_NULL();
+ }
+ close = static_cast<Ice::ACMClose>(Z_LVAL_P(c));
+ }
+
+ if(!isUnset(h))
+ {
+ if(Z_TYPE_P(h) != IS_LONG)
+ {
+ invalidArgument("value for 'heartbeat' argument must be Unset or an enumerator of ACMHeartbeat");
+ RETURN_NULL();
+ }
+ heartbeat = static_cast<Ice::ACMHeartbeat>(Z_LVAL_P(h));
+ }
+
+ try
+ {
+ _this->setACM(timeout, close, heartbeat);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, getACM)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::ACM acm = _this->getACM();
+
+ zend_class_entry* acmClass = idToClass("::Ice::ACM");
+
+ if(object_init_ex(return_value, const_cast<zend_class_entry*>(acmClass)) != SUCCESS)
+ {
+ runtimeError("unable to initialize object of type %s", acmClass->name);
+ RETURN_NULL();
+ }
+
+ add_property_long(return_value, STRCAST("timeout"), static_cast<long>(acm.timeout));
+ add_property_long(return_value, STRCAST("close"), static_cast<long>(acm.close));
+ add_property_long(return_value, STRCAST("heartbeat"), static_cast<long>(acm.heartbeat));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, type)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ string str = _this->type();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length());
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, timeout)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::Int timeout = _this->timeout();
+ ZVAL_LONG(return_value, static_cast<long>(timeout));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, toString)
+{
+ ZEND_MN(Ice_Connection___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+ZEND_METHOD(Ice_Connection, getInfo)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::ConnectionInfoPtr info = _this->getInfo();
+ if(!createConnectionInfo(return_value, _this->getInfo()))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, setBufferSize)
+{
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis());
+ assert(_this);
+
+ zval* r;
+ zval* s;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("zz"), &r, &s) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ int rcvSize = static_cast<int>(Z_LVAL_P(r));
+ int sndSize = static_cast<int>(Z_LVAL_P(s));
+
+ try
+ {
+ _this->setBufferSize(rcvSize, sndSize);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleConnectionAlloc(zend_class_entry* ce)
+{
+ Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_connectionHandlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleConnectionFreeStorage(zend_object* object)
+{
+ Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::fetch(object);
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static int
+handleConnectionCompare(zval* zobj1, zval* zobj2)
+{
+ //
+ // PHP guarantees that the objects have the same class.
+ //
+
+ Ice::ConnectionPtr con1 = Wrapper<Ice::ConnectionPtr>::value(zobj1);
+ assert(con1);
+ Ice::ConnectionPtr con2 = Wrapper<Ice::ConnectionPtr>::value(zobj2);
+ assert(con2);
+
+ if(con1 == con2)
+ {
+ return 0;
+ }
+ else if(con1 < con2)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+//
+// Necessary to suppress warnings from zend_function_entry in php-5.2.
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+
+//
+// Predefined methods for Connection.
+//
+static zend_function_entry _interfaceMethods[] =
+{
+ {0, 0, 0}
+};
+static zend_function_entry _connectionClassMethods[] =
+{
+ 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, getEndpoint, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Connection, flushBatchRequests, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Connection, setACM, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Connection, getACM, 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)
+ ZEND_ME(Ice_Connection, getInfo, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Connection, setBufferSize, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+
+ZEND_METHOD(Ice_ConnectionInfo, __construct)
+{
+ runtimeError("ConnectionInfo cannot be instantiated");
+}
+
+//
+// Predefined methods for ConnectionInfo.
+//
+static zend_function_entry _connectionInfoClassMethods[] =
+{
+ ZEND_ME(Ice_ConnectionInfo, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ {0, 0, 0}
+};
+//
+// enable warning again
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic error "-Wwrite-strings"
+#endif
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleConnectionInfoAlloc(zend_class_entry* ce)
+{
+ Wrapper<Ice::ConnectionInfoPtr>* obj = Wrapper<Ice::ConnectionInfoPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_connectionInfoHandlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleConnectionInfoFreeStorage(zend_object* object)
+{
+ Wrapper<Ice::ConnectionInfoPtr>* obj = Wrapper<Ice::ConnectionInfoPtr>::fetch(object);
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+bool
+IcePHP::connectionInit(void)
+{
+ //
+ // 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, "Ice", "Connection", _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Connection", _interfaceMethods);
+#endif
+ zend_class_entry* interface = zend_register_internal_interface(&ce);
+
+ //
+ // Register the Connection class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Connection", _connectionClassMethods);
+ ce.create_object = handleConnectionAlloc;
+ connectionClassEntry = zend_register_internal_class(&ce);
+ memcpy(&_connectionHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _connectionHandlers.compare_objects = handleConnectionCompare;
+ _connectionHandlers.free_obj = handleConnectionFreeStorage;
+ _connectionHandlers.offset = XtOffsetOf(Wrapper<Ice::ConnectionPtr>, zobj);
+ zend_class_implements(connectionClassEntry, 1, interface);
+
+ //
+ // Register the ConnectionInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "ConnectionInfo", _connectionInfoClassMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_ConnectionInfo", _connectionInfoClassMethods);
+#endif
+ ce.create_object = handleConnectionInfoAlloc;
+ connectionInfoClassEntry = zend_register_internal_class(&ce);
+ memcpy(&_connectionInfoHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _connectionInfoHandlers.free_obj = handleConnectionInfoFreeStorage;
+ _connectionInfoHandlers.offset = XtOffsetOf(Wrapper<Ice::ConnectionInfoPtr>, zobj);
+ zend_declare_property_bool(connectionInfoClassEntry, STRCAST("incoming"), sizeof("incoming") - 1, 0,
+ ZEND_ACC_PUBLIC);
+ zend_declare_property_string(connectionInfoClassEntry, STRCAST("adapterName"), sizeof("adapterName") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+
+ //
+ // Register the IPConnectionInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "IPConnectionInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_IPConnectionInfo", NULL);
+#endif
+ ce.create_object = handleConnectionInfoAlloc;
+ ipConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, connectionInfoClassEntry);
+ zend_declare_property_string(ipConnectionInfoClassEntry, STRCAST("localAddress"), sizeof("localAddress") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+ zend_declare_property_long(ipConnectionInfoClassEntry, STRCAST("localPort"), sizeof("localPort") - 1, 0,
+ ZEND_ACC_PUBLIC);
+ zend_declare_property_string(ipConnectionInfoClassEntry, STRCAST("remoteAddress"), sizeof("remoteAddress") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+ zend_declare_property_long(ipConnectionInfoClassEntry, STRCAST("remotePort"), sizeof("remotePort") - 1, 0,
+ ZEND_ACC_PUBLIC);
+
+ //
+ // Register the TCPConnectionInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "TCPConnectionInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_TCPConnectionInfo", NULL);
+#endif
+ ce.create_object = handleConnectionInfoAlloc;
+ tcpConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, ipConnectionInfoClassEntry);
+
+ //
+ // Register the UDPConnectionInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "UDPConnectionInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_UDPConnectionInfo", NULL);
+#endif
+ ce.create_object = handleConnectionInfoAlloc;
+ udpConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, ipConnectionInfoClassEntry);
+ zend_declare_property_string(udpConnectionInfoClassEntry, STRCAST("mcastAddress"), sizeof("mcastAddress") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+ zend_declare_property_long(udpConnectionInfoClassEntry, STRCAST("mcastPort"), sizeof("mcastPort") - 1, 0,
+ ZEND_ACC_PUBLIC);
+
+ //
+ // Register the WSConnectionInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "WSConnectionInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_WSConnectionInfo", NULL);
+#endif
+ ce.create_object = handleConnectionInfoAlloc;
+ wsConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, ipConnectionInfoClassEntry);
+ zend_declare_property_string(wsConnectionInfoClassEntry, STRCAST("headers"), sizeof("headers") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+
+ //
+ // Register the SSLConnectionInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "SSLConnectionInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_SSLConnectionInfo", NULL);
+#endif
+ ce.create_object = handleConnectionInfoAlloc;
+ sslConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, ipConnectionInfoClassEntry);
+ zend_declare_property_string(sslConnectionInfoClassEntry, STRCAST("cipher"), sizeof("cipher") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+ zend_declare_property_string(sslConnectionInfoClassEntry, STRCAST("certs"), sizeof("certs") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+ zend_declare_property_bool(sslConnectionInfoClassEntry, STRCAST("verified"), sizeof("verified") - 1, 0,
+ ZEND_ACC_PUBLIC);
+
+ //
+ // Register the WSConnectionInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "WSSConnectionInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_WSSConnectionInfo", NULL);
+#endif
+ ce.create_object = handleConnectionInfoAlloc;
+ wssConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, sslConnectionInfoClassEntry);
+ zend_declare_property_string(wssConnectionInfoClassEntry, STRCAST("headers"), sizeof("headers") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+
+
+ return true;
+}
+
+bool
+IcePHP::createConnection(zval* zv, const Ice::ConnectionPtr& p)
+{
+ if(object_init_ex(zv, connectionClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize connection");
+ return false;
+ }
+
+ Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::extract(zv);
+ assert(obj);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::ConnectionPtr(p);
+
+ return true;
+}
+
+bool
+IcePHP::fetchConnection(zval* zv, Ice::ConnectionPtr& connection)
+{
+ 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");
+ return false;
+ }
+ Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::extract(zv);
+ if(!obj)
+ {
+ return false;
+ }
+ connection = *obj->ptr;
+ }
+ return true;
+}
+
+bool
+IcePHP::createConnectionInfo(zval* zv, const Ice::ConnectionInfoPtr& p)
+{
+ int status;
+ if(Ice::WSConnectionInfoPtr::dynamicCast(p))
+ {
+ Ice::WSConnectionInfoPtr info = Ice::WSConnectionInfoPtr::dynamicCast(p);
+ if((status = object_init_ex(zv, wsConnectionInfoClassEntry)) == SUCCESS)
+ {
+ zval zmap;
+ AutoDestroy mapDestroyer(&zmap);
+ if(createStringMap(&zmap, info->headers))
+ {
+ add_property_zval(zv, STRCAST("headers"), &zmap);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ else if(Ice::TCPConnectionInfoPtr::dynamicCast(p))
+ {
+ status = object_init_ex(zv, tcpConnectionInfoClassEntry);
+ }
+ else if(Ice::UDPConnectionInfoPtr::dynamicCast(p))
+ {
+ Ice::UDPConnectionInfoPtr info = Ice::UDPConnectionInfoPtr::dynamicCast(p);
+ if((status = object_init_ex(zv, udpConnectionInfoClassEntry)) == SUCCESS)
+ {
+ add_property_string(zv, STRCAST("mcastAddress"), const_cast<char*>(info->mcastAddress.c_str()));
+ add_property_long(zv, STRCAST("mcastPort"), static_cast<long>(info->mcastPort));
+ }
+ }
+ else if(IceSSL::WSSConnectionInfoPtr::dynamicCast(p))
+ {
+ IceSSL::WSSConnectionInfoPtr info = IceSSL::WSSConnectionInfoPtr::dynamicCast(p);
+ if((status = object_init_ex(zv, wssConnectionInfoClassEntry)) == SUCCESS)
+ {
+ zval zmap;
+ AutoDestroy mapDestroyer(&zmap);
+ if(createStringMap(&zmap, info->headers))
+ {
+ add_property_zval(zv, STRCAST("headers"), &zmap);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ else if(IceSSL::ConnectionInfoPtr::dynamicCast(p))
+ {
+ status = object_init_ex(zv, sslConnectionInfoClassEntry);
+ }
+ else if(Ice::IPConnectionInfoPtr::dynamicCast(p))
+ {
+ status = object_init_ex(zv, ipConnectionInfoClassEntry);
+ }
+ else
+ {
+ status = object_init_ex(zv, connectionInfoClassEntry);
+ }
+
+ if(status != SUCCESS)
+ {
+ runtimeError("unable to initialize connection info");
+ return false;
+ }
+
+ if(IceSSL::ConnectionInfoPtr::dynamicCast(p))
+ {
+ IceSSL::ConnectionInfoPtr info = IceSSL::ConnectionInfoPtr::dynamicCast(p);
+ add_property_string(zv, STRCAST("cipher"), const_cast<char*>(info->cipher.c_str()));
+ add_property_bool(zv, STRCAST("verified"), info->verified ? 1 : 0);
+
+ zval zarr;
+ AutoDestroy listDestroyer(&zarr);
+ if(createStringArray(&zarr, info->certs))
+ {
+ add_property_zval(zv, STRCAST("certs"), &zarr);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if(Ice::IPConnectionInfoPtr::dynamicCast(p))
+ {
+ Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(p);
+ add_property_string(zv, STRCAST("localAddress"), const_cast<char*>(info->localAddress.c_str()));
+ add_property_long(zv, STRCAST("localPort"), static_cast<long>(info->localPort));
+ add_property_string(zv, STRCAST("remoteAddress"), const_cast<char*>(info->remoteAddress.c_str()));
+ add_property_long(zv, STRCAST("remotePort"), static_cast<long>(info->remotePort));
+ }
+
+ add_property_bool(zv, STRCAST("incoming"), p->incoming ? 1 : 0);
+ add_property_string(zv, STRCAST("adapterName"), const_cast<char*>(p->adapterName.c_str()));
+ add_property_long(zv, STRCAST("rcvSize"), static_cast<long>(p->rcvSize));
+ add_property_long(zv, STRCAST("sndSize"), static_cast<long>(p->sndSize));
+
+ Wrapper<Ice::ConnectionInfoPtr>* obj = Wrapper<Ice::ConnectionInfoPtr>::extract(zv);
+ assert(obj);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::ConnectionInfoPtr(p);
+
+ return true;
+}
diff --git a/php/src/php7/Connection.h b/php/src/php7/Connection.h
new file mode 100644
index 00000000000..38ae32a56fa
--- /dev/null
+++ b/php/src/php7/Connection.h
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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(void);
+
+bool createConnection(zval*, const Ice::ConnectionPtr&);
+bool fetchConnection(zval*, Ice::ConnectionPtr&);
+
+bool createConnectionInfo(zval*, const Ice::ConnectionInfoPtr&);
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/php7/Endpoint.cpp b/php/src/php7/Endpoint.cpp
new file mode 100644
index 00000000000..31747200dc7
--- /dev/null
+++ b/php/src/php7/Endpoint.cpp
@@ -0,0 +1,537 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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>
+#include <IceSSL/EndpointInfo.h>
+
+using namespace std;
+using namespace IcePHP;
+
+ZEND_EXTERN_MODULE_GLOBALS(ice)
+
+//
+// Class entries representing the PHP class implementations we have registered.
+//
+static zend_class_entry* endpointClassEntry = 0;
+
+static zend_class_entry* endpointInfoClassEntry = 0;
+static zend_class_entry* ipEndpointInfoClassEntry = 0;
+static zend_class_entry* tcpEndpointInfoClassEntry = 0;
+static zend_class_entry* udpEndpointInfoClassEntry = 0;
+static zend_class_entry* wsEndpointInfoClassEntry = 0;
+static zend_class_entry* opaqueEndpointInfoClassEntry = 0;
+static zend_class_entry* sslEndpointInfoClassEntry = 0;
+static zend_class_entry* wssEndpointInfoClassEntry = 0;
+
+//
+// Ice::Endpoint support.
+//
+static zend_object_handlers _endpointHandlers;
+static zend_object_handlers _endpointInfoHandlers;
+
+extern "C"
+{
+static zend_object* handleEndpointAlloc(zend_class_entry*);
+static void handleEndpointFreeStorage(zend_object*);
+
+static zend_object* handleEndpointInfoAlloc(zend_class_entry*);
+static void handleEndpointInfoFreeStorage(zend_object*);
+}
+
+ZEND_METHOD(Ice_Endpoint, __construct)
+{
+ runtimeError("Endpoint cannot be instantiated");
+}
+
+ZEND_METHOD(Ice_Endpoint, __toString)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr _this = Wrapper<Ice::EndpointPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ string str = _this->toString();
+ RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Endpoint, toString)
+{
+ ZEND_MN(Ice_Endpoint___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+ZEND_METHOD(Ice_Endpoint, getInfo)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr _this = Wrapper<Ice::EndpointPtr>::value(getThis());
+ assert(_this);
+
+ if(!createEndpointInfo(return_value, _this->getInfo()))
+ {
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleEndpointAlloc(zend_class_entry* ce)
+{
+ Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_endpointHandlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleEndpointFreeStorage(zend_object* object)
+{
+ Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::fetch(object);
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+ZEND_METHOD(Ice_EndpointInfo, __construct)
+{
+ runtimeError("EndpointInfo cannot be instantiated");
+}
+
+ZEND_METHOD(Ice_EndpointInfo, type)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointInfoPtr _this = Wrapper<Ice::EndpointInfoPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ short type = static_cast<short>(_this->type());
+ RETURN_LONG(type);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_EndpointInfo, datagram)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointInfoPtr _this = Wrapper<Ice::EndpointInfoPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ RETURN_BOOL(_this->datagram() ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_EndpointInfo, secure)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointInfoPtr _this = Wrapper<Ice::EndpointInfoPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ RETURN_BOOL(_this->secure() ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleEndpointInfoAlloc(zend_class_entry* ce)
+{
+ Wrapper<Ice::EndpointInfoPtr>* obj = Wrapper<Ice::EndpointInfoPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_endpointInfoHandlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleEndpointInfoFreeStorage(zend_object* object)
+{
+ Wrapper<Ice::EndpointInfoPtr>* obj = Wrapper<Ice::EndpointInfoPtr>::fetch(object);
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+static zend_function_entry _interfaceMethods[] =
+{
+ {0, 0, 0}
+};
+
+//
+// Necessary to suppress warnings from zend_function_entry in php-5.2.
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+
+//
+// Predefined methods for Endpoint.
+//
+static zend_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, getInfo, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+
+//
+// Predefined methods for EndpointInfo.
+//
+static zend_function_entry _endpointInfoMethods[] =
+{
+ ZEND_ME(Ice_EndpointInfo, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ ZEND_ME(Ice_EndpointInfo, type, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_EndpointInfo, datagram, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_EndpointInfo, secure, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+
+//
+// enable warning again
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic error "-Wwrite-strings"
+#endif
+
+bool
+IcePHP::endpointInit(void)
+{
+ //
+ // Although the Endpoint and EndpointInfo types are defined in Slice, we need to
+ // define implementations at the time the PHP extension is loaded; we can't wait
+ // to do this until after the generated code has been loaded. Consequently, we
+ // define our own placeholder versions of the Slice types so that we can subclass
+ // them. This essentially means that the generated code for these types is ignored.
+ //
+
+ //
+ // Define the Endpoint interface.
+ //
+ zend_class_entry ce;
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "Endpoint", _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Endpoint", _interfaceMethods);
+#endif
+ zend_class_entry* endpointInterface = zend_register_internal_interface(&ce);
+
+ //
+ // Define a concrete Endpoint implementation class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Endpoint", _endpointMethods);
+ ce.create_object = handleEndpointAlloc;
+ endpointClassEntry = zend_register_internal_class(&ce);
+ memcpy(&_endpointHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _endpointHandlers.free_obj = handleEndpointFreeStorage;
+ _endpointHandlers.offset = XtOffsetOf(Wrapper<Ice::EndpointPtr>, zobj);
+ zend_class_implements(endpointClassEntry, 1, endpointInterface);
+
+ //
+ // Define the EndpointInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "EndpointInfo", _endpointInfoMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_EndpointInfo", _endpointInfoMethods);
+#endif
+ ce.create_object = handleEndpointInfoAlloc;
+ endpointInfoClassEntry = zend_register_internal_class(&ce);
+ memcpy(&_endpointInfoHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _endpointInfoHandlers.free_obj = handleEndpointInfoFreeStorage;
+ _endpointInfoHandlers.offset = XtOffsetOf(Wrapper<Ice::EndpointInfoPtr>, zobj);
+ zend_declare_property_long(endpointInfoClassEntry, STRCAST("timeout"), sizeof("timeout") - 1, 0,
+ ZEND_ACC_PUBLIC);
+ zend_declare_property_bool(endpointInfoClassEntry, STRCAST("compress"), sizeof("compress") - 1, 0,
+ ZEND_ACC_PUBLIC);
+
+ //
+ // Define the IPEndpointInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "IPEndpointInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_IPEndpointInfo", NULL);
+#endif
+ ce.create_object = handleEndpointInfoAlloc;
+ ipEndpointInfoClassEntry = zend_register_internal_class_ex(&ce, endpointInfoClassEntry);
+ zend_declare_property_string(ipEndpointInfoClassEntry, STRCAST("host"), sizeof("host") - 1, STRCAST(""),
+ ZEND_ACC_PUBLIC);
+ zend_declare_property_long(ipEndpointInfoClassEntry, STRCAST("port"), sizeof("port") - 1, 0,
+ ZEND_ACC_PUBLIC);
+ zend_declare_property_string(ipEndpointInfoClassEntry, STRCAST("sourceAddress"), sizeof("sourceAddress") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+
+ //
+ // Define the TCPEndpointInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "TCPEndpointInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_TCPEndpointInfo", NULL);
+#endif
+ ce.create_object = handleEndpointInfoAlloc;
+ tcpEndpointInfoClassEntry = zend_register_internal_class_ex(&ce, ipEndpointInfoClassEntry);
+
+ //
+ // Define the UDPEndpointInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "UDPEndpointInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_UDPEndpointInfo", NULL);
+#endif
+ ce.create_object = handleEndpointInfoAlloc;
+ udpEndpointInfoClassEntry = zend_register_internal_class_ex(&ce, ipEndpointInfoClassEntry);
+ zend_declare_property_string(udpEndpointInfoClassEntry, STRCAST("mcastInterface"), sizeof("mcastInterface") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+ zend_declare_property_long(udpEndpointInfoClassEntry, STRCAST("mcastTtl"), sizeof("mcastTtl") - 1, 0,
+ ZEND_ACC_PUBLIC);
+
+ //
+ // Define the WSEndpointInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "WSEndpointInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_WSEndpointInfo", NULL);
+#endif
+ ce.create_object = handleEndpointInfoAlloc;
+ wsEndpointInfoClassEntry = zend_register_internal_class_ex(&ce, ipEndpointInfoClassEntry);
+ zend_declare_property_string(wsEndpointInfoClassEntry, STRCAST("resource"), sizeof("resource") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+
+ //
+ // Define the OpaqueEndpointInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "OpaqueEndpointInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_OpaqueEndpointInfo", NULL);
+#endif
+ ce.create_object = handleEndpointInfoAlloc;
+ opaqueEndpointInfoClassEntry = zend_register_internal_class_ex(&ce, endpointInfoClassEntry);
+ zend_declare_property_null(opaqueEndpointInfoClassEntry, STRCAST("rawEncoding"), sizeof("rawEncoding") - 1,
+ ZEND_ACC_PUBLIC);
+ zend_declare_property_null(opaqueEndpointInfoClassEntry, STRCAST("rawBytes"), sizeof("rawBytes") - 1,
+ ZEND_ACC_PUBLIC);
+
+ //
+ // Define the SSLEndpointInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "SSLEndpointInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_SSLEndpointInfo", NULL);
+#endif
+ ce.create_object = handleEndpointInfoAlloc;
+ sslEndpointInfoClassEntry = zend_register_internal_class_ex(&ce, ipEndpointInfoClassEntry);
+
+ //
+ // Define the WSSEndpointInfo class.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "WSSEndpointInfo", NULL);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_WSSEndpointInfo", NULL);
+#endif
+ ce.create_object = handleEndpointInfoAlloc;
+ wssEndpointInfoClassEntry = zend_register_internal_class_ex(&ce, sslEndpointInfoClassEntry);
+ zend_declare_property_string(wssEndpointInfoClassEntry, STRCAST("resource"), sizeof("resource") - 1,
+ STRCAST(""), ZEND_ACC_PUBLIC);
+
+ return true;
+}
+
+bool
+IcePHP::createEndpoint(zval* zv, const Ice::EndpointPtr& p)
+{
+ if(object_init_ex(zv, endpointClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize endpoint");
+ return false;
+ }
+
+ Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::extract(zv);
+ assert(obj);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::EndpointPtr(p);
+
+ return true;
+}
+
+bool
+IcePHP::fetchEndpoint(zval* zv, Ice::EndpointPtr& endpoint)
+{
+ 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");
+ return false;
+ }
+ Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::extract(zv);
+ if(!obj)
+ {
+ return false;
+ }
+ endpoint = *obj->ptr;
+ }
+ return true;
+}
+
+bool
+IcePHP::createEndpointInfo(zval* zv, const Ice::EndpointInfoPtr& p)
+{
+ int status;
+ if(Ice::WSEndpointInfoPtr::dynamicCast(p))
+ {
+ Ice::WSEndpointInfoPtr info = Ice::WSEndpointInfoPtr::dynamicCast(p);
+ if((status = object_init_ex(zv, wsEndpointInfoClassEntry)) == SUCCESS)
+ {
+ add_property_string(zv, STRCAST("resource"), const_cast<char*>(info->resource.c_str()));
+ }
+ }
+ else if(Ice::TCPEndpointInfoPtr::dynamicCast(p))
+ {
+ status = object_init_ex(zv, tcpEndpointInfoClassEntry);
+ }
+ else if(Ice::UDPEndpointInfoPtr::dynamicCast(p))
+ {
+ Ice::UDPEndpointInfoPtr info = Ice::UDPEndpointInfoPtr::dynamicCast(p);
+ if((status = object_init_ex(zv, udpEndpointInfoClassEntry)) == SUCCESS)
+ {
+ add_property_string(zv, STRCAST("mcastInterface"), const_cast<char*>(info->mcastInterface.c_str()));
+ add_property_long(zv, STRCAST("mcastTtl"), static_cast<long>(info->mcastTtl));
+ }
+ }
+ else if(Ice::OpaqueEndpointInfoPtr::dynamicCast(p))
+ {
+ Ice::OpaqueEndpointInfoPtr info = Ice::OpaqueEndpointInfoPtr::dynamicCast(p);
+ if((status = object_init_ex(zv, opaqueEndpointInfoClassEntry)) == SUCCESS)
+ {
+ zval rawEncoding;
+ createEncodingVersion(&rawEncoding, info->rawEncoding);
+ add_property_zval(zv, STRCAST("rawEncoding"), &rawEncoding);
+ zval_ptr_dtor(&rawEncoding); // add_property_zval increased the refcount of rawEncoding
+
+ zval rawBytes;
+ array_init(&rawBytes);
+ for(Ice::ByteSeq::iterator i = info->rawBytes.begin(); i != info->rawBytes.end(); ++i)
+ {
+ add_next_index_long(&rawBytes, *i & 0xff);
+ }
+ add_property_zval(zv, STRCAST("rawBytes"), &rawBytes);
+ zval_ptr_dtor(&rawBytes); // add_property_zval increased the refcount of rawBytes
+ }
+ }
+ else if(IceSSL::WSSEndpointInfoPtr::dynamicCast(p))
+ {
+ IceSSL::WSSEndpointInfoPtr info = IceSSL::WSSEndpointInfoPtr::dynamicCast(p);
+ if((status = object_init_ex(zv, wssEndpointInfoClassEntry)) == SUCCESS)
+ {
+ add_property_string(zv, STRCAST("resource"), const_cast<char*>(info->resource.c_str()));
+ }
+ }
+ else if(IceSSL::EndpointInfoPtr::dynamicCast(p))
+ {
+ status = object_init_ex(zv, sslEndpointInfoClassEntry);
+ }
+ else if(Ice::IPEndpointInfoPtr::dynamicCast(p))
+ {
+ status = object_init_ex(zv, ipEndpointInfoClassEntry);
+ }
+ else
+ {
+ status = object_init_ex(zv, endpointInfoClassEntry);
+ }
+
+ if(status != SUCCESS)
+ {
+ runtimeError("unable to initialize endpoint info");
+ return false;
+ }
+
+ if(Ice::IPEndpointInfoPtr::dynamicCast(p))
+ {
+ Ice::IPEndpointInfoPtr info = Ice::IPEndpointInfoPtr::dynamicCast(p);
+ add_property_string(zv, STRCAST("host"), const_cast<char*>(info->host.c_str()));
+ add_property_long(zv, STRCAST("port"), static_cast<long>(info->port));
+ add_property_string(zv, STRCAST("sourceAddress"), const_cast<char*>(info->sourceAddress.c_str()));
+ }
+
+ add_property_long(zv, STRCAST("timeout"), static_cast<long>(p->timeout));
+ add_property_bool(zv, STRCAST("compress"), static_cast<long>(p->compress));
+
+ Wrapper<Ice::EndpointInfoPtr>* obj = Wrapper<Ice::EndpointInfoPtr>::extract(zv);
+ assert(obj);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::EndpointInfoPtr(p);
+
+ return true;
+}
diff --git a/php/src/php7/Endpoint.h b/php/src/php7/Endpoint.h
new file mode 100644
index 00000000000..b26a388f631
--- /dev/null
+++ b/php/src/php7/Endpoint.h
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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(void);
+
+bool createEndpoint(zval*, const Ice::EndpointPtr&);
+bool fetchEndpoint(zval*, Ice::EndpointPtr&);
+
+bool createEndpointInfo(zval*, const Ice::EndpointInfoPtr&);
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/php7/IcePHP.rc b/php/src/php7/IcePHP.rc
new file mode 100644
index 00000000000..ee77391769a
--- /dev/null
+++ b/php/src/php7/IcePHP.rc
@@ -0,0 +1,38 @@
+#include "winver.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,6,2,0
+ PRODUCTVERSION 3,6,2,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+ #define INTERNALNAME "php_iced\0"
+ #define ORIGINALFILENAME "php_iced.dll\0"
+#else
+ FILEFLAGS 0x0L
+ #define INTERNALNAME "php_ice\0"
+ #define ORIGINALFILENAME "php_ice.dll\0"
+#endif
+ FILEOS 0x4L
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "ZeroC, Inc.\0"
+ VALUE "FileDescription", "Ice for PHP Extension\0"
+ VALUE "FileVersion", "3.6.2\0"
+ VALUE "InternalName", INTERNALNAME
+ VALUE "LegalCopyright", "Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.\0"
+ VALUE "OriginalFilename", ORIGINALFILENAME
+ VALUE "ProductName", "Ice\0"
+ VALUE "ProductVersion", "3.6.2\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
diff --git a/php/src/php7/Init.cpp b/php/src/php7/Init.cpp
new file mode 100644
index 00000000000..1679703f80a
--- /dev/null
+++ b/php/src/php7/Init.cpp
@@ -0,0 +1,287 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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 <Communicator.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;
+using namespace IcePHP;
+
+ZEND_DECLARE_MODULE_GLOBALS(ice)
+
+ZEND_BEGIN_ARG_INFO_EX(Ice_initialize_arginfo, 1, ZEND_RETURN_VALUE, static_cast<zend_ulong>(-1))
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(Ice_createProperties_arginfo, 1, ZEND_RETURN_VALUE, static_cast<zend_ulong>(-1))
+ZEND_END_ARG_INFO()
+
+#define ICEPHP_COMMUNICATOR_FUNCTIONS \
+ ZEND_FE(Ice_initialize, Ice_initialize_arginfo) \
+ ZEND_FE(Ice_register, NULL) \
+ ZEND_FE(Ice_unregister, NULL) \
+ ZEND_FE(Ice_find, NULL) \
+ ZEND_FE(Ice_getProperties, NULL) \
+ ZEND_FE(Ice_identityToString, NULL) \
+ ZEND_FE(Ice_stringToIdentity, NULL)
+
+#ifdef ICEPHP_USE_NAMESPACES
+# define ICEPHP_COMMUNICATOR_NS_FUNCTIONS \
+ ZEND_NS_FALIAS("Ice", initialize, Ice_initialize, Ice_initialize_arginfo) \
+ 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) \
+ ZEND_NS_FALIAS("Ice", identityToString, Ice_identityToString, NULL) \
+ ZEND_NS_FALIAS("Ice", stringToIdentity, Ice_stringToIdentity, NULL)
+#else
+# define ICEPHP_COMMUNICATOR_NS_FUNCTIONS
+#endif
+
+#define ICEPHP_OPERATION_FUNCTIONS \
+ ZEND_FE(IcePHP_defineOperation, NULL)
+
+#define ICEPHP_PROPERTIES_FUNCTIONS \
+ ZEND_FE(Ice_createProperties, Ice_createProperties_arginfo)
+
+#ifdef ICEPHP_USE_NAMESPACES
+# define ICEPHP_PROPERTIES_NS_FUNCTIONS \
+ ZEND_NS_FALIAS("Ice", createProperties, Ice_createProperties, Ice_createProperties_arginfo)
+#else
+# define ICEPHP_PROPERTIES_NS_FUNCTIONS
+#endif
+
+#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_declareProxy, 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)
+
+#define ICEPHP_UTIL_FUNCTIONS \
+ ZEND_FE(Ice_stringVersion, NULL) \
+ ZEND_FE(Ice_intVersion, NULL) \
+ ZEND_FE(Ice_generateUUID, NULL) \
+ ZEND_FE(Ice_currentProtocol, NULL) \
+ ZEND_FE(Ice_currentProtocolEncoding, NULL) \
+ ZEND_FE(Ice_currentEncoding, NULL) \
+ ZEND_FE(Ice_protocolVersionToString, NULL) \
+ ZEND_FE(Ice_stringToProtocolVersion, NULL) \
+ ZEND_FE(Ice_encodingVersionToString, NULL) \
+ ZEND_FE(Ice_stringToEncodingVersion, 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) \
+ ZEND_NS_FALIAS("Ice", currentProtocol, Ice_currentProtocol, NULL) \
+ ZEND_NS_FALIAS("Ice", currentProtocolEncoding, Ice_currentProtocolEncoding, NULL) \
+ ZEND_NS_FALIAS("Ice", currentEncoding, Ice_currentEncoding, NULL) \
+ ZEND_NS_FALIAS("Ice", protocolVersionToString, Ice_protocolVersionToString, NULL) \
+ ZEND_NS_FALIAS("Ice", stringToProtocolVersion, Ice_stringToProtocolVersion, NULL) \
+ ZEND_NS_FALIAS("Ice", encodingVersionToString, Ice_encodingVersionToString, NULL) \
+ ZEND_NS_FALIAS("Ice", stringToEncodingVersion, Ice_stringToEncodingVersion, NULL)
+#else
+# define ICEPHP_UTIL_NS_FUNCTIONS
+#endif
+
+//
+// Necessary to suppress warnings from zend_function_entry in php-5.2.
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+
+//
+// Entries for all global functions.
+//
+zend_function_entry ice_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}
+};
+//
+// enable warning again
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic error "-Wwrite-strings"
+#endif
+
+//
+// The ice_module_entry declaration below generates lots of warnings:
+//
+// deprecated conversion from string constant to ‘char*’
+//
+// We disable them with a pragma.
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+
+zend_module_entry ice_module_entry =
+{
+ STANDARD_MODULE_HEADER,
+ "ice",
+ ice_functions,
+ ZEND_MINIT(ice),
+ ZEND_MSHUTDOWN(ice),
+ ZEND_RINIT(ice),
+ ZEND_RSHUTDOWN(ice),
+ ZEND_MINFO(ice),
+ NO_VERSION_YET,
+ STANDARD_MODULE_PROPERTIES
+};
+
+ZEND_GET_MODULE(ice)
+
+//
+// Declare initialization file entries.
+//
+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.hide_profiles", "1", PHP_INI_SYSTEM, 0)
+PHP_INI_END()
+
+extern "C"
+int initIceGlobals(zend_ice_globals* g)
+{
+ g->communicatorMap = 0;
+ g->idToClassInfoMap = 0;
+ g->compactIdToClassInfoMap = 0;
+ g->nameToClassInfoMap = 0;
+ g->proxyInfoMap = 0;
+ g->exceptionInfoMap = 0;
+ g->unset = 0;
+ return SUCCESS;
+}
+
+ZEND_MINIT_FUNCTION(ice)
+{
+ Ice::registerIceSSL(false);
+ Ice::registerIceDiscovery(false);
+ Ice::registerIceLocatorDiscovery(false);
+
+ REGISTER_INI_ENTRIES();
+ ZEND_INIT_MODULE_GLOBALS(ice, initIceGlobals, 0);
+
+ if(!communicatorInit())
+ {
+ return FAILURE;
+ }
+
+ if(!propertiesInit())
+ {
+ return FAILURE;
+ }
+
+ if(!proxyInit())
+ {
+ return FAILURE;
+ }
+
+ if(!typesInit(INIT_FUNC_ARGS_PASSTHRU))
+ {
+ return FAILURE;
+ }
+
+ if(!loggerInit())
+ {
+ return FAILURE;
+ }
+
+ if(!endpointInit())
+ {
+ return FAILURE;
+ }
+
+ if(!connectionInit())
+ {
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+ZEND_MSHUTDOWN_FUNCTION(ice)
+{
+ UNREGISTER_INI_ENTRIES();
+
+ int status = SUCCESS;
+
+ if(!communicatorShutdown())
+ {
+ status = FAILURE;
+ }
+
+ return status;
+}
+
+ZEND_RINIT_FUNCTION(ice)
+{
+ ICE_G(communicatorMap) = 0;
+
+ if(!communicatorRequestInit())
+ {
+ return FAILURE;
+ }
+
+ if(!typesRequestInit())
+ {
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+ZEND_RSHUTDOWN_FUNCTION(ice)
+{
+ if(!communicatorRequestShutdown())
+ {
+ return FAILURE;
+ }
+
+ if(!typesRequestShutdown())
+ {
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+ZEND_MINFO_FUNCTION(ice)
+{
+ php_info_print_table_start();
+ php_info_print_table_header(2, "Ice support", "enabled");
+ php_info_print_table_row(2, "Ice version", ICE_STRING_VERSION);
+ php_info_print_table_end();
+
+ DISPLAY_INI_ENTRIES();
+}
diff --git a/php/src/php7/Logger.cpp b/php/src/php7/Logger.cpp
new file mode 100644
index 00000000000..b5c9e962007
--- /dev/null
+++ b/php/src/php7/Logger.cpp
@@ -0,0 +1,323 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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* handleAlloc(zend_class_entry*);
+static void handleFreeStorage(zend_object*);
+static zend_object* handleClone(zval*);
+}
+
+ZEND_METHOD(Ice_Logger, __construct)
+{
+ runtimeError("logger objects cannot be instantiated");
+}
+
+ZEND_METHOD(Ice_Logger, __toString)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_NULL();
+}
+
+ZEND_METHOD(Ice_Logger, print)
+{
+ char* m;
+ size_t mLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &m, &mLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
+ assert(_this);
+
+ string msg(m, mLen);
+ try
+ {
+ _this->print(msg);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Logger, trace)
+{
+ char* c;
+ size_t cLen;
+ char* m;
+ size_t mLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("ss"), &c, &cLen, &m, &mLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
+ assert(_this);
+
+ string category(c, cLen);
+ string msg(m, mLen);
+ try
+ {
+ _this->trace(category, msg);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Logger, warning)
+{
+ char* m;
+ size_t mLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &m, &mLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
+ assert(_this);
+
+ string msg(m, mLen);
+ try
+ {
+ _this->warning(msg);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Logger, error)
+{
+ char* m;
+ size_t mLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &m, &mLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
+ assert(_this);
+
+ string msg(m, mLen);
+ try
+ {
+ _this->error(msg);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Logger, cloneWithPrefix)
+{
+ char* p;
+ size_t pLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &p, &pLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
+ assert(_this);
+
+ Ice::LoggerPtr clone;
+
+ string prefix(p, pLen);
+ try
+ {
+ clone = _this->cloneWithPrefix(prefix);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+
+ if(!createLogger(return_value, clone))
+ {
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleAlloc(zend_class_entry* ce)
+{
+ Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_loggerHandlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleFreeStorage(zend_object* object)
+{
+ Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::fetch(object);
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleClone(zval* zv)
+{
+ php_error_docref(0, E_ERROR, "loggers cannot be cloned");
+ return 0;
+}
+
+//
+// Necessary to suppress warnings from zend_function_entry in php-5.2.
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+
+//
+// Predefined methods for Logger.
+//
+static zend_function_entry _interfaceMethods[] =
+{
+ {0, 0, 0}
+};
+static zend_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)
+ ZEND_ME(Ice_Logger, cloneWithPrefix, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+//
+// enable warning again
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic error "-Wwrite-strings"
+#endif
+
+bool
+IcePHP::loggerInit(void)
+{
+ //
+ // 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, "Ice", "Logger", _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Logger", _interfaceMethods);
+#endif
+ zend_class_entry* interface = zend_register_internal_interface(&ce);
+
+ //
+ // Register the Logger class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Logger", _classMethods);
+ ce.create_object = handleAlloc;
+ loggerClassEntry = zend_register_internal_class(&ce);
+ memcpy(&_loggerHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _loggerHandlers.clone_obj = handleClone;
+ _loggerHandlers.free_obj = handleFreeStorage;
+ _loggerHandlers.offset = XtOffsetOf(Wrapper<Ice::LoggerPtr>, zobj);
+ zend_class_implements(loggerClassEntry, 1, interface);
+
+ return true;
+}
+
+bool
+IcePHP::createLogger(zval* zv, const Ice::LoggerPtr& p)
+{
+ if(object_init_ex(zv, loggerClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize logger object");
+ return false;
+ }
+
+ Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::extract(zv);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::LoggerPtr(p);
+
+ return true;
+}
+
+bool
+IcePHP::fetchLogger(zval* zv, Ice::LoggerPtr& p)
+{
+ if(!ZVAL_IS_NULL(zv))
+ {
+ if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != loggerClassEntry)
+ {
+ invalidArgument("value is not a logger object");
+ return false;
+ }
+ p = Wrapper<Ice::LoggerPtr>::value(zv);
+ if(!p)
+ {
+ runtimeError("unable to retrieve logger object from object store");
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/php/src/php7/Logger.h b/php/src/php7/Logger.h
new file mode 100644
index 00000000000..7ab38b6c42c
--- /dev/null
+++ b/php/src/php7/Logger.h
@@ -0,0 +1,30 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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(void);
+
+bool createLogger(zval*, const Ice::LoggerPtr&);
+bool fetchLogger(zval*, Ice::LoggerPtr&);
+
+//
+// Class entry.
+//
+extern zend_class_entry* loggerClassEntry;
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/php7/Makefile b/php/src/php7/Makefile
new file mode 100644
index 00000000000..8f1f7fe3bae
--- /dev/null
+++ b/php/src/php7/Makefile
@@ -0,0 +1,39 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2016 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 = ../..
+
+LIBNAME = $(call mkphplibname,IcePHP)
+SONAME = $(LIBNAME)
+
+TARGETS = $(libdir)/$(LIBNAME)
+
+OBJS = Communicator.o \
+ Connection.o \
+ Endpoint.o \
+ Init.o \
+ Logger.o \
+ Operation.o \
+ Properties.o \
+ Proxy.o \
+ Types.o \
+ Util.o
+
+include $(top_srcdir)/config/Make.rules.php
+
+CPPFLAGS := -I. $(CPPFLAGS) $(ICE_FLAGS) $(shell php-config --includes)
+
+LINKWITH := $(ICE_LIBS) $(CXXLIBS)
+
+$(libdir)/$(LIBNAME): $(OBJS)
+ rm -f $@
+ $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH))
+
+install:: all
+ $(call installphplib,$(libdir)/$(LIBNAME),$(DESTDIR)$(install_libdir))
diff --git a/php/src/php7/Makefile.mak b/php/src/php7/Makefile.mak
new file mode 100644
index 00000000000..2362a1d4b31
--- /dev/null
+++ b/php/src/php7/Makefile.mak
@@ -0,0 +1,67 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2016 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 = ..\..
+
+LIBNAME = php_ice$(LIBSUFFIX).lib
+DLLNAME = $(libdir)\php_ice$(LIBSUFFIX).dll
+
+TARGETS = $(LIBNAME) $(DLLNAME)
+
+OBJS = .\Communicator.obj \
+ .\Connection.obj \
+ .\Endpoint.obj \
+ .\Init.obj \
+ .\Logger.obj \
+ .\Operation.obj \
+ .\Properties.obj \
+ .\Proxy.obj \
+ .\Types.obj \
+ .\Util.obj
+
+
+#
+# Get Make.common.rules.mak to figure out CPP_COMPILER by setting it
+# to "auto"
+#
+CPP_COMPILER=auto
+
+!include $(top_srcdir)\config\Make.rules.mak.php
+
+#
+# Ensure we're using VC110
+#
+!if "$(CPP_COMPILER)" != "VC110"
+!error Invalid CPP_COMPILER setting: $(CPP_COMPILER). Must be set to VC110.
+!endif
+
+CPPFLAGS = -I. -I.. $(CPPFLAGS) $(ICE_CPPFLAGS) $(PHP_CPPFLAGS)
+
+!if "$(ARCH)" == "x86"
+CPPFLAGS = $(CPPFLAGS) -D_USE_32BIT_TIME_T
+!endif
+
+!if "$(OPTIMIZE)" != "yes"
+PDBFLAGS = /pdb:$(LIBNAME:.lib=.pdb)
+!endif
+
+LINKWITH = $(ICE_LIBS) $(PHP_LIBS) $(CXXLIBS) icediscovery$(LIBSUFFIX).lib icelocatordiscovery$(LIBSUFFIX).lib
+
+$(LIBNAME): $(DLLNAME)
+
+$(DLLNAME): $(OBJS) IcePHP.res
+ $(LINK) $(ICE_LDFLAGS) $(PHP_LDFLAGS) $(LD_DLLFLAGS) $(PDBFLAGS) $(OBJS) \
+ $(PREOUT)$(DLLNAME) $(PRELIBS)$(LINKWITH) IcePHP.res
+ move $(DLLNAME:.dll=.lib) $(LIBNAME)
+
+clean::
+ -del /q IcePHP.res
+
+install:: all
+ copy $(DLLNAME) "$(install_libdir)"
diff --git a/php/src/php7/Operation.cpp b/php/src/php7/Operation.cpp
new file mode 100644
index 00000000000..62e9ae4c30c
--- /dev/null
+++ b/php/src/php7/Operation.cpp
@@ -0,0 +1,875 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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
+{
+
+class ParamInfo : public IceUtil::Shared
+{
+public:
+
+ TypeInfoPtr type;
+ bool optional;
+ int tag;
+ int pos;
+};
+typedef IceUtil::Handle<ParamInfo> ParamInfoPtr;
+typedef list<ParamInfoPtr> ParamInfoList;
+
+//
+// Receives an out parameter or return value.
+//
+class ResultCallback : public UnmarshalCallback
+{
+public:
+
+ ResultCallback();
+ ~ResultCallback();
+
+ virtual void unmarshaled(zval*, zval*, void*);
+
+ void unset(void);
+
+ 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, Ice::FormatType, zval*, zval*, zval*, zval*
+ );
+ ~OperationI();
+
+ virtual zend_function* function();
+
+ string name; // On-the-wire name.
+ Ice::OperationMode mode;
+ Ice::OperationMode sendMode;
+ Ice::FormatType format;
+ ParamInfoList inParams;
+ ParamInfoList optionalInParams;
+ ParamInfoList outParams;
+ ParamInfoList optionalOutParams;
+ ParamInfoPtr returnType;
+ ExceptionInfoList exceptions;
+ bool sendsClasses;
+ bool returnsClasses;
+ int numParams;
+
+private:
+
+ zend_internal_function* _zendFunction;
+
+ static void convertParams(zval*, ParamInfoList&, bool&);
+ static ParamInfoPtr convertParam(zval*, int);
+ static void getArgInfo(zend_internal_arg_info&, const ParamInfoPtr&, 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&);
+
+ virtual void invoke(INTERNAL_FUNCTION_PARAMETERS) = 0;
+
+protected:
+
+ Ice::ObjectPrx _prx;
+ CommunicatorInfoPtr _communicator;
+};
+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&);
+
+protected:
+
+ OperationIPtr _op;
+
+ bool prepareRequest(int, zval*, Ice::OutputStreamPtr&, pair<const Ice::Byte*, const Ice::Byte*>&);
+ void unmarshalResults(int, zval*, zval*, const pair<const Ice::Byte*, const Ice::Byte*>&);
+ void unmarshalException(zval*, const pair<const Ice::Byte*, const Ice::Byte*>&);
+ bool validateException(const ExceptionInfoPtr&) 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&);
+
+ virtual void invoke(INTERNAL_FUNCTION_PARAMETERS);
+};
+
+class UserExceptionReaderFactoryI : public Ice::UserExceptionReaderFactory
+{
+public:
+
+ UserExceptionReaderFactoryI(const CommunicatorInfoPtr& communicator) :
+ _communicator(communicator)
+ {
+ }
+
+ virtual void createAndThrow(const string& id) const
+ {
+ ExceptionInfoPtr info = getExceptionInfo(id);
+ if(info)
+ {
+ throw ExceptionReader(_communicator, info);
+ }
+ }
+
+private:
+
+ const CommunicatorInfoPtr _communicator;
+};
+
+}
+
+//
+// ResultCallback implementation.
+//
+IcePHP::ResultCallback::ResultCallback()
+{
+ ZVAL_UNDEF(&zv);
+}
+
+IcePHP::ResultCallback::~ResultCallback()
+{
+ zval_ptr_dtor(&zv);
+}
+
+void
+IcePHP::ResultCallback::unmarshaled(zval* val, zval*, void*)
+{
+ //
+ // Copy the unmarshaled value into this result callback
+ // This increases the refcount for refcounted values and
+ // coppies non-refcound values
+ //
+ ZVAL_COPY(&zv, val);
+}
+
+void
+IcePHP::ResultCallback::unset(void)
+{
+ assignUnset(&zv);
+}
+
+//
+// OperationI implementation.
+//
+IcePHP::OperationI::OperationI(const char* n, Ice::OperationMode m, Ice::OperationMode sm, Ice::FormatType f, zval* in,
+ zval* out, zval* ret, zval* ex) :
+ name(n), mode(m), sendMode(sm), format(f), _zendFunction(0)
+{
+ //
+ // inParams
+ //
+ sendsClasses = false;
+ if(in)
+ {
+ convertParams(in, inParams, sendsClasses);
+ }
+
+ //
+ // outParams
+ //
+ returnsClasses = false;
+ if(out)
+ {
+ convertParams(out, outParams, returnsClasses);
+ }
+
+ //
+ // returnType
+ //
+ if(ret)
+ {
+ returnType = convertParam(ret, 0);
+ if(!returnsClasses)
+ {
+ returnsClasses = returnType->type->usesClasses();
+ }
+ }
+
+ numParams = static_cast<int>(inParams.size() + outParams.size());
+
+ class SortFn
+ {
+ public:
+ static bool compare(const ParamInfoPtr& lhs, const ParamInfoPtr& rhs)
+ {
+ return lhs->tag < rhs->tag;
+ }
+
+ static bool isRequired(const ParamInfoPtr& i)
+ {
+ return !i->optional;
+ }
+ };
+
+ //
+ // The inParams list represents the parameters in the order of declaration.
+ // We also need a sorted list of optional parameters.
+ //
+ ParamInfoList l = inParams;
+ copy(l.begin(), remove_if(l.begin(), l.end(), SortFn::isRequired), back_inserter(optionalInParams));
+ optionalInParams.sort(SortFn::compare);
+
+ //
+ // The outParams list represents the parameters in the order of declaration.
+ // We also need a sorted list of optional parameters. If the return value is
+ // optional, we must include it in this list.
+ //
+ l = outParams;
+ copy(l.begin(), remove_if(l.begin(), l.end(), SortFn::isRequired), back_inserter(optionalOutParams));
+ if(returnType && returnType->optional)
+ {
+ optionalOutParams.push_back(returnType);
+ }
+ optionalOutParams.sort(SortFn::compare);
+
+ //
+ // exceptions
+ //
+ if(ex)
+ {
+ HashTable* arr = Z_ARRVAL_P(ex);
+ zval* val;
+
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ ExceptionInfoPtr i = Wrapper<ExceptionInfoPtr>::value(val);
+ exceptions.push_back(i);
+ }
+ ZEND_HASH_FOREACH_END();
+ }
+}
+
+IcePHP::OperationI::~OperationI()
+{
+ if(_zendFunction)
+ {
+ delete []_zendFunction->arg_info;
+ zend_string_release(_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_internal_arg_info* argInfo = new zend_internal_arg_info[numParams];
+
+ int i = 0;
+ ParamInfoList::const_iterator p;
+ for(p = inParams.begin(); p != inParams.end(); ++p, ++i)
+ {
+ getArgInfo(argInfo[i], *p, false);
+ }
+ for(p = outParams.begin(); p != outParams.end(); ++p, ++i)
+ {
+ getArgInfo(argInfo[i], *p, true);
+ }
+
+ string fixed = fixIdent(name);
+
+ _zendFunction = static_cast<zend_internal_function*>(emalloc(sizeof(zend_internal_function)));
+ _zendFunction->type = ZEND_INTERNAL_FUNCTION;
+ _zendFunction->function_name = zend_string_init(STRCAST(fixed.c_str()), static_cast<uint32_t>(fixed.length()), 0);
+ _zendFunction->scope = proxyClassEntry;
+ _zendFunction->fn_flags = ZEND_ACC_PUBLIC;
+ _zendFunction->prototype = 0;
+ _zendFunction->num_args = static_cast<uint32_t>(numParams);
+ _zendFunction->arg_info = argInfo;
+ _zendFunction->required_num_args = _zendFunction->num_args;
+ _zendFunction->handler = ZEND_FN(IcePHP_Operation_call);
+ zend_set_function_arg_flags(reinterpret_cast<zend_function*>(_zendFunction));
+ }
+
+ return reinterpret_cast<zend_function*>(_zendFunction);
+}
+
+void
+IcePHP::OperationI::convertParams(zval* p, ParamInfoList& params, bool& usesClasses)
+{
+ assert(Z_TYPE_P(p) == IS_ARRAY);
+ HashTable* arr = Z_ARRVAL_P(p);
+ zval* val;
+ Ice::Int i = 0;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ ParamInfoPtr param = convertParam(val, i++);
+ params.push_back(param);
+ if(!param->optional && !usesClasses)
+ {
+ usesClasses = param->type->usesClasses();
+ }
+ }
+ ZEND_HASH_FOREACH_END();
+}
+
+ParamInfoPtr
+IcePHP::OperationI::convertParam(zval* p, int pos)
+{
+ assert(Z_TYPE_P(p) == IS_ARRAY);
+ HashTable* arr = Z_ARRVAL_P(p);
+ assert(zend_hash_num_elements(arr) == 3);
+
+ ParamInfoPtr param = new ParamInfo;
+
+ param->type = Wrapper<TypeInfoPtr>::value(zend_hash_index_find(arr, 0));
+
+ assert(Z_TYPE_P(zend_hash_index_find(arr, 1)) == IS_TRUE || Z_TYPE_P(zend_hash_index_find(arr, 1)) == IS_FALSE);
+ param->optional = Z_TYPE_P(zend_hash_index_find(arr, 1)) == IS_TRUE;
+
+ assert(Z_TYPE_P(zend_hash_index_find(arr, 2)) == IS_LONG);
+ param->tag = static_cast<int>(Z_LVAL_P(zend_hash_index_find(arr, 2)));
+
+ param->pos = pos;
+
+ return param;
+}
+
+void
+IcePHP::OperationI::getArgInfo(zend_internal_arg_info& arg, const ParamInfoPtr& info, bool out)
+{
+ arg.name = 0;
+ arg.class_name = 0;
+ arg.allow_null = 1;
+
+ if(!info->optional)
+ {
+ const bool isArray = SequenceInfoPtr::dynamicCast(info->type) || DictionaryInfoPtr::dynamicCast(info->type);
+ arg.type_hint = isArray ? IS_ARRAY : 0;
+
+ }
+ else
+ {
+ arg.type_hint = 0;
+ }
+
+ arg.pass_by_reference = out ? 1 : 0;
+}
+
+//
+// Invocation
+//
+IcePHP::Invocation::Invocation(const Ice::ObjectPrx& prx, const CommunicatorInfoPtr& communicator) :
+ _prx(prx), _communicator(communicator)
+{
+}
+
+//
+// TypedInvocation
+//
+IcePHP::TypedInvocation::TypedInvocation(const Ice::ObjectPrx& prx, const CommunicatorInfoPtr& communicator,
+ const OperationIPtr& op) :
+ Invocation(prx, communicator), _op(op)
+{
+}
+
+bool
+IcePHP::TypedInvocation::prepareRequest(int argc, zval* args, Ice::OutputStreamPtr& os,
+ pair<const Ice::Byte*, const Ice::Byte*>& params)
+{
+ //
+ // 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)", 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(Z_ISREF(args[i]));
+ }
+
+ if(!_op->inParams.empty())
+ {
+ try
+ {
+ //
+ // Marshal the in parameters.
+ //
+ os = Ice::createOutputStream(_communicator->getCommunicator());
+ os->startEncapsulation(_prx->ice_getEncodingVersion(), _op->format);
+
+ ObjectMap objectMap;
+ ParamInfoList::iterator p;
+
+ //
+ // Validate the supplied arguments.
+ //
+ for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ zval* arg = &args[info->pos];
+ assert(!Z_ISREF_P(arg));
+
+ if((!info->optional || !isUnset(arg)) && !info->type->validate(arg))
+ {
+ invalidArgument("invalid value for argument %d in operation `%s'", info->pos + 1,
+ _op->name.c_str());
+ return false;
+ }
+ }
+
+ //
+ // Marshal the required parameters.
+ //
+ for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ if(!info->optional)
+ {
+ zval* arg = &args[info->pos];
+ assert(!Z_ISREF_P(arg));
+
+ info->type->marshal(arg, os, &objectMap, false);
+ }
+ }
+
+ //
+ // Marshal the optional parameters.
+ //
+ for(p = _op->optionalInParams.begin(); p != _op->optionalInParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ zval* arg = &args[info->pos];
+ assert(!Z_ISREF_P(arg));
+
+ if(!isUnset(arg) && os->writeOptional(info->tag, info->type->optionalFormat()))
+ {
+ info->type->marshal(arg, os, &objectMap, true);
+ }
+ }
+
+ if(_op->sendsClasses)
+ {
+ os->writePendingObjects();
+ }
+
+ os->endEncapsulation();
+ params = os->finished();
+ }
+ catch(const AbortMarshaling&)
+ {
+ return false;
+ }
+ catch(const Ice::Exception& ex)
+ {
+ throwException(ex);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void
+IcePHP::TypedInvocation::unmarshalResults(int argc, zval* args, zval* ret,
+ const pair<const Ice::Byte*, const Ice::Byte*>& bytes)
+{
+ Ice::InputStreamPtr is = Ice::wrapInputStream(_communicator->getCommunicator(), bytes);
+
+ //
+ // Store a pointer to a local SlicedDataUtil object as the stream's closure.
+ // This is necessary to support object unmarshaling (see ObjectReader).
+ //
+ SlicedDataUtil util;
+ assert(!is->closure());
+ is->closure(&util);
+
+ is->startEncapsulation();
+
+ ParamInfoList::iterator p;
+
+ //
+ // These callbacks collect references (copies for unreferenced types) to the unmarshaled values.
+ // We copy them into the argument list *after* any pending objects have been unmarshaled.
+ //
+ ResultCallbackList outParamCallbacks;
+ ResultCallbackPtr retCallback;
+
+ outParamCallbacks.resize(_op->outParams.size());
+
+ //
+ // Unmarshal the required out parameters.
+ //
+ for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ if(!info->optional)
+ {
+ ResultCallbackPtr cb = new ResultCallback;
+ outParamCallbacks[info->pos] = cb;
+ info->type->unmarshal(is, cb, _communicator, 0, 0, false);
+ }
+ }
+
+ //
+ // Unmarshal the required return value, if any.
+ //
+ if(_op->returnType && !_op->returnType->optional)
+ {
+ retCallback = new ResultCallback;
+ _op->returnType->type->unmarshal(is, retCallback, _communicator, 0, 0, false);
+ }
+
+ //
+ // Unmarshal the optional results. This includes an optional return value.
+ //
+ for(p = _op->optionalOutParams.begin(); p != _op->optionalOutParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+
+ ResultCallbackPtr cb = new ResultCallback;
+ if(_op->returnType && info->tag == _op->returnType->tag)
+ {
+ retCallback = cb;
+ }
+ else
+ {
+ outParamCallbacks[info->pos] = cb;
+ }
+
+ if(is->readOptional(info->tag, info->type->optionalFormat()))
+ {
+ info->type->unmarshal(is, cb, _communicator, 0, 0, true);
+ }
+ else
+ {
+ cb->unset();
+ }
+ }
+
+ if(_op->returnsClasses)
+ {
+ is->readPendingObjects();
+ }
+
+ is->endEncapsulation();
+
+ util.update();
+
+ int i = static_cast<int>(_op->inParams.size());
+ for(ResultCallbackList::iterator q = outParamCallbacks.begin(); q != outParamCallbacks.end(); ++q, ++i)
+ {
+ assert(Z_ISREF(args[i]));
+
+ //
+ // We must explicitly destroy the existing contents of all zvals passed
+ // as out parameters, otherwise leaks occur.
+ //
+ zval* arg = Z_REFVAL_P(&args[i]);
+ zval_ptr_dtor(arg);
+ ZVAL_DUP(arg, &(*q)->zv);
+ }
+
+ if(_op->returnType)
+ {
+ ZVAL_DUP(ret, &retCallback->zv);
+ }
+}
+
+void
+IcePHP::TypedInvocation::unmarshalException(zval* zex, const pair<const Ice::Byte*, const Ice::Byte*>& bytes)
+{
+ Ice::InputStreamPtr is = Ice::wrapInputStream(_communicator->getCommunicator(), bytes);
+
+ //
+ // Store a pointer to a local SlicedDataUtil object as the stream's closure.
+ // This is necessary to support object unmarshaling (see ObjectReader).
+ //
+ SlicedDataUtil util;
+ assert(!is->closure());
+ is->closure(&util);
+
+ is->startEncapsulation();
+
+ try
+ {
+ Ice::UserExceptionReaderFactoryPtr factory = new UserExceptionReaderFactoryI(_communicator);
+ is->throwException(factory);
+ }
+ catch(const ExceptionReader& r)
+ {
+ is->endEncapsulation();
+
+ zval* ex = r.getException();
+ ExceptionInfoPtr info = r.getInfo();
+
+ if(validateException(info))
+ {
+ util.update();
+
+ Ice::SlicedDataPtr slicedData = r.getSlicedData();
+ if(slicedData)
+ {
+ SlicedDataUtil::setMember(ex, slicedData);
+ }
+ ZVAL_DUP(zex, ex);
+ return;
+ }
+ else
+ {
+ zval_ptr_dtor(ex);
+ Ice::UnknownUserException uue(__FILE__, __LINE__,
+ "operation raised undeclared exception `" + info->id + "'");
+ convertException(zex, uue);
+ return;
+ }
+ }
+
+ //
+ // 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");
+ convertException(zex, uue);
+}
+
+bool
+IcePHP::TypedInvocation::validateException(const ExceptionInfoPtr& info) 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) :
+ Invocation(prx, communicator), TypedInvocation(prx, communicator, op)
+{
+}
+
+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");
+ return;
+ }
+
+ Ice::OutputStreamPtr os;
+ pair<const Ice::Byte*, const Ice::Byte*> params;
+ if(!prepareRequest(ZEND_NUM_ARGS(), args, os, params))
+ {
+ return;
+ }
+
+ bool hasCtx = false;
+ Ice::Context ctx;
+ if(ZEND_NUM_ARGS() == static_cast<uint32_t>(_op->numParams) + 1)
+ {
+ if(!extractStringMap(&args[ZEND_NUM_ARGS() - 1], ctx))
+ {
+ 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(&ex, rb);
+ if(!Z_ISUNDEF(ex))
+ {
+ zend_throw_exception_object(&ex);
+ }
+ }
+ 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);
+ }
+ }
+ }
+ catch(const AbortMarshaling&)
+ {
+ }
+ catch(const Ice::Exception& ex)
+ {
+ throwException(ex);
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineOperation)
+{
+ zval* cls;
+ char* name;
+ size_t nameLen;
+ zend_long mode;
+ zend_long sendMode;
+ zend_long format;
+ zval* inParams;
+ zval* outParams;
+ zval* returnType;
+ zval* exceptions;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("osllla!a!a!a!"), &cls, &name, &nameLen,
+ &mode, &sendMode, &format, &inParams, &outParams, &returnType, &exceptions) == FAILURE)
+ {
+ return;
+ }
+
+ TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(cls);
+ ClassInfoPtr c = ClassInfoPtr::dynamicCast(type);
+ assert(c);
+
+ OperationIPtr op = new OperationI(name, static_cast<Ice::OperationMode>(mode),
+ static_cast<Ice::OperationMode>(sendMode), static_cast<Ice::FormatType>(format),
+ inParams, outParams, returnType, exceptions);
+
+ 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);
+ assert(b);
+ assert(proxy);
+ assert(cls);
+
+ OperationPtr op = cls->getOperation(get_active_function_name());
+ 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);
+ inv->invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
diff --git a/php/src/php7/Operation.h b/php/src/php7/Operation.h
new file mode 100644
index 00000000000..91230201bc4
--- /dev/null
+++ b/php/src/php7/Operation.h
@@ -0,0 +1,37 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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);
+}
+
+namespace IcePHP
+{
+
+class Operation : public IceUtil::Shared
+{
+public:
+
+ virtual zend_function* function() = 0;
+
+};
+typedef IceUtil::Handle<Operation> OperationPtr;
+
+}
+
+#endif
diff --git a/php/src/php7/Properties.cpp b/php/src/php7/Properties.cpp
new file mode 100644
index 00000000000..cfdb779e881
--- /dev/null
+++ b/php/src/php7/Properties.cpp
@@ -0,0 +1,681 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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* handleAlloc(zend_class_entry*);
+static void handleFreeStorage(zend_object*);
+static zend_object* handleClone(zval*);
+}
+
+ZEND_METHOD(Ice_Properties, __construct)
+{
+ runtimeError("properties objects cannot be instantiated, use createProperties()");
+}
+
+ZEND_METHOD(Ice_Properties, __toString)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ 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()), static_cast<int>(str.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getProperty)
+{
+ char* name;
+ size_t nameLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &name, &nameLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ assert(_this);
+
+ string propName(name, nameLen);
+ try
+ {
+ string val = _this->getProperty(propName);
+ RETURN_STRINGL(STRCAST(val.c_str()), static_cast<int>(val.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyWithDefault)
+{
+ char* name;
+ size_t nameLen;
+ char* def;
+ size_t defLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("ss!"), &name, &nameLen, &def, &defLen) ==
+ FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ 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()), static_cast<int>(val.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyAsInt)
+{
+ char* name;
+ size_t nameLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &name, &nameLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ 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);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyAsIntWithDefault)
+{
+ char* name;
+ size_t nameLen;
+ long def;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("sl"), &name, &nameLen, &def) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ 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);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyAsList)
+{
+ char* name;
+ size_t nameLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &name, &nameLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ assert(_this);
+
+ string propName(name, nameLen);
+ try
+ {
+ Ice::StringSeq val = _this->getPropertyAsList(propName);
+ if(!createStringArray(return_value, val))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyAsListWithDefault)
+{
+ char* name;
+ size_t nameLen;
+ zval* def;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("sa!"), &name, &nameLen, &def) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ assert(_this);
+
+ string propName(name, nameLen);
+ Ice::StringSeq defaultValue;
+ if(def && !extractStringArray(def, defaultValue))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::StringSeq val = _this->getPropertyAsListWithDefault(propName, defaultValue);
+ if(!createStringArray(return_value, val))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertiesForPrefix)
+{
+ char* p;
+ size_t pLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s!"), &p, &pLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ assert(_this);
+
+ string prefix;
+ if(p)
+ {
+ prefix = string(p, pLen);
+ }
+
+ try
+ {
+ Ice::PropertyDict val = _this->getPropertiesForPrefix(prefix);
+ if(!createStringMap(return_value, val))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, setProperty)
+{
+ char* name;
+ size_t nameLen;
+ char* val;
+ size_t valLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("ss!"), &name, &nameLen, &val, &valLen) ==
+ FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ 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);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getCommandLineOptions)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::StringSeq val = _this->getCommandLineOptions();
+ if(!createStringArray(return_value, val))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, parseCommandLineOptions)
+{
+ char* p;
+ size_t pLen;
+ zval* opts;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s!a!"), &p, &pLen, &opts) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ assert(_this);
+
+ string prefix;
+ if(p)
+ {
+ prefix = string(p, pLen);
+ }
+ Ice::StringSeq options;
+ if(opts && !extractStringArray(opts, options))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::StringSeq val = _this->parseCommandLineOptions(prefix, options);
+ if(!createStringArray(return_value, val))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, parseIceCommandLineOptions)
+{
+ zval* opts;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("a!"), &opts) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ assert(_this);
+
+ Ice::StringSeq options;
+ if(opts && !extractStringArray(opts, options))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::StringSeq val = _this->parseIceCommandLineOptions(options);
+ if(!createStringArray(return_value, val))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, load)
+{
+ char* f;
+ size_t fLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &f, &fLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ assert(_this);
+
+ string file(f, fLen);
+
+ try
+ {
+ _this->load(file);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, clone)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::PropertiesPtr pclone = _this->clone();
+
+ if(!createProperties(return_value, pclone))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleAlloc(zend_class_entry* ce)
+{
+ Wrapper<Ice::PropertiesPtr>* obj = Wrapper<Ice::PropertiesPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_handlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleFreeStorage(zend_object* object)
+{
+ Wrapper<Ice::PropertiesPtr>* obj = Wrapper<Ice::PropertiesPtr>::fetch(object);
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleClone(zval* zv)
+{
+ Ice::PropertiesPtr p = Wrapper<Ice::PropertiesPtr>::value(zv);
+ assert(p);
+
+ Ice::PropertiesPtr pclone = p->clone();
+
+ zval clone;
+ if(!createProperties(&clone, pclone))
+ {
+ return 0;
+ }
+
+ return Z_OBJ(clone);
+}
+
+ZEND_FUNCTION(Ice_createProperties)
+{
+ zval* arglist = 0;
+ zval* defaultsObj = 0;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("|a!O!"), &arglist, &defaultsObj,
+ propertiesClassEntry) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::StringSeq seq;
+ if(arglist && !extractStringArray(arglist, seq))
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr defaults;
+ if(defaultsObj && !fetchProperties(defaultsObj, defaults))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::PropertiesPtr props;
+ if(arglist || defaults)
+ {
+ props = Ice::createProperties(seq, defaults);
+ }
+ else
+ {
+ props = Ice::createProperties();
+ }
+
+ if(!createProperties(return_value, props))
+ {
+ RETURN_NULL();
+ }
+
+ if(arglist && Z_ISREF_P(arglist))
+ {
+ zval_dtor(arglist);
+ if(!createStringArray(arglist, seq))
+ {
+ RETURN_NULL();
+ }
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+//
+// Necessary to suppress warnings from zend_function_entry in php-5.2.
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+
+//
+// Predefined methods for Properties.
+//
+static zend_function_entry _interfaceMethods[] =
+{
+ {0, 0, 0}
+};
+static zend_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}
+};
+
+//
+// enable warning again
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic error "-Wwrite-strings"
+#endif
+
+bool
+IcePHP::propertiesInit(void)
+{
+ //
+ // 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, "Ice", "Properties", _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Properties", _interfaceMethods);
+#endif
+ zend_class_entry* interface = zend_register_internal_interface(&ce);
+
+ //
+ // Register the Properties class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Properties", _classMethods);
+ ce.create_object = handleAlloc;
+ propertiesClassEntry = zend_register_internal_class(&ce);
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _handlers.clone_obj = handleClone;
+ _handlers.free_obj = handleFreeStorage;
+ _handlers.offset = XtOffsetOf(Wrapper<Ice::PropertiesPtr>, zobj);
+ zend_class_implements(propertiesClassEntry, 1, interface);
+
+ return true;
+}
+
+bool
+IcePHP::createProperties(zval* zv, const Ice::PropertiesPtr& p)
+{
+ if(object_init_ex(zv, propertiesClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize properties object");
+ return false;
+ }
+
+ Wrapper<Ice::PropertiesPtr>* obj = Wrapper<Ice::PropertiesPtr>::extract(zv);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::PropertiesPtr(p);
+
+ return true;
+}
+
+bool
+IcePHP::fetchProperties(zval* zv, Ice::PropertiesPtr& p)
+{
+ if(!ZVAL_IS_NULL(zv))
+ {
+ if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != propertiesClassEntry)
+ {
+ invalidArgument("value is not a properties object");
+ return false;
+ }
+ p = Wrapper<Ice::PropertiesPtr>::value(zv);
+ if(!p)
+ {
+ runtimeError("unable to retrieve properties object from object store");
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/php/src/php7/Properties.h b/php/src/php7/Properties.h
new file mode 100644
index 00000000000..44584abccfd
--- /dev/null
+++ b/php/src/php7/Properties.h
@@ -0,0 +1,38 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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);
+}
+
+namespace IcePHP
+{
+
+bool propertiesInit(void);
+
+bool createProperties(zval*, const Ice::PropertiesPtr&);
+bool fetchProperties(zval*, Ice::PropertiesPtr&);
+
+//
+// Class entry.
+//
+extern zend_class_entry* propertiesClassEntry;
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/php7/Proxy.cpp b/php/src/php7/Proxy.cpp
new file mode 100644
index 00000000000..d9bb45ca0ee
--- /dev/null
+++ b/php/src/php7/Proxy.cpp
@@ -0,0 +1,1718 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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 <Proxy.h>
+#include <Connection.h>
+#include <Endpoint.h>
+#include <Util.h>
+
+using namespace std;
+using namespace IcePHP;
+
+ZEND_EXTERN_MODULE_GLOBALS(ice)
+
+//
+// Here's a brief description of how proxies are handled by this extension.
+//
+// A single PHP class, 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 type
+// definitions, not by statically-generated code.
+//
+// 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_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.
+//
+
+//
+// Class entries represent the PHP class implementations we have registered.
+//
+namespace IcePHP
+{
+zend_class_entry* proxyClassEntry = 0;
+}
+
+//
+// Ice::ObjectPrx support.
+//
+static zend_object_handlers _handlers;
+
+extern "C"
+{
+static zend_object* handleAlloc(zend_class_entry*);
+static void handleFreeStorage(zend_object*);
+static zend_object* handleClone(zval*);
+static union _zend_function* handleGetMethod(zend_object**, zend_string*, const zval*);
+static int handleCompare(zval*, zval*);
+}
+
+static ClassInfoPtr lookupClass(const string&);
+
+namespace IcePHP
+{
+
+//
+// Encapsulates proxy and type information.
+//
+class Proxy : public IceUtil::Shared
+{
+public:
+
+ Proxy(const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr&);
+ ~Proxy();
+
+ bool clone(zval*, const Ice::ObjectPrx&);
+ bool cloneUntyped(zval*, const Ice::ObjectPrx&);
+ static bool create(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr&);
+
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr info;
+ CommunicatorInfoPtr communicator;
+ zval* connection;
+ zval* cachedConnection;
+};
+typedef IceUtil::Handle<Proxy> ProxyPtr;
+
+} // End of namespace IcePHP
+
+ZEND_METHOD(Ice_ObjectPrx, __construct)
+{
+ runtimeError("proxies cannot be instantiated, use stringToProxy()");
+}
+
+ZEND_METHOD(Ice_ObjectPrx, __toString)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ string str = _this->proxy->ice_toString();
+ RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getCommunicator)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ _this->communicator->getZval(return_value);
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_toString)
+{
+ ZEND_MN(Ice_ObjectPrx___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getIdentity)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+ assert(_this->proxy);
+
+ createIdentity(return_value, _this->proxy->ice_getIdentity());
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_identity)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ zend_class_entry* cls = idToClass("::Ice::Identity");
+ assert(cls);
+
+ zval *zid;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O"), &zid, cls) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::Identity id;
+ if(extractIdentity(zid, id))
+ {
+ try
+ {
+ if(!_this->cloneUntyped(return_value, _this->proxy->ice_identity(id)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getContext)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ if(!createStringMap(return_value, _this->proxy->ice_getContext()))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_context)
+{
+ zval* arr = 0;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("a"), &arr) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ //
+ // Populate the context.
+ //
+ Ice::Context ctx;
+ if(arr && !extractStringMap(arr, ctx))
+ {
+ RETURN_NULL();
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_context(ctx)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getFacet)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ string facet = _this->proxy->ice_getFacet();
+ ZVAL_STRINGL(return_value, STRCAST(facet.c_str()), static_cast<int>(facet.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_facet)
+{
+ char* name;
+ size_t len;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &name, &len) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ if(!_this->cloneUntyped(return_value, _this->proxy->ice_facet(name)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getAdapterId)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ string id = _this->proxy->ice_getAdapterId();
+ ZVAL_STRINGL(return_value, STRCAST(id.c_str()), static_cast<int>(id.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_adapterId)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ char* id;
+ size_t len;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &id, &len) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_adapterId(id)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getEndpoints)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::EndpointSeq endpoints = _this->proxy->ice_getEndpoints();
+
+ array_init(return_value);
+ uint idx = 0;
+ for(Ice::EndpointSeq::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p, ++idx)
+ {
+ zval elem;
+ if(!createEndpoint(&elem, *p))
+ {
+ zval_ptr_dtor(&elem);
+ RETURN_NULL();
+ }
+ add_index_zval(return_value, idx, &elem);
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_endpoints)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ zval* zv;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("a"), &zv) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::EndpointSeq seq;
+
+ HashTable* arr = Z_ARRVAL_P(zv);
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(Z_TYPE_P(val) != IS_OBJECT)
+ {
+ runtimeError("expected an element of type Ice::Endpoint");
+ RETURN_NULL();
+ }
+
+ Ice::EndpointPtr endpoint;
+ if(!fetchEndpoint(val, endpoint))
+ {
+ RETURN_NULL();
+ }
+
+ seq.push_back(endpoint);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_endpoints(seq)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getLocatorCacheTimeout)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::Int timeout = _this->proxy->ice_getLocatorCacheTimeout();
+ ZVAL_LONG(return_value, static_cast<long>(timeout));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getConnectionId)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ string connectionId = _this->proxy->ice_getConnectionId();
+ ZVAL_STRINGL(return_value, STRCAST(connectionId.c_str()), static_cast<int>(connectionId.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_locatorCacheTimeout)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ long l;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("l"), &l) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_locatorCacheTimeout(l)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_isConnectionCached)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ bool b = _this->proxy->ice_isConnectionCached();
+ ZVAL_BOOL(return_value, b ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_connectionCached)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ zend_bool b;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("b"), &b) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_connectionCached(b ? true : false)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getEndpointSelection)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::EndpointSelectionType type = _this->proxy->ice_getEndpointSelection();
+ ZVAL_LONG(return_value, type == Ice::Random ? 0 : 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_endpointSelection)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ long l;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("l"), &l) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ if(l < 0 || l > 1)
+ {
+ runtimeError("expecting Random or Ordered");
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::EndpointSelectionType type = l == 0 ? Ice::Random : Ice::Ordered;
+ if(!_this->clone(return_value, _this->proxy->ice_endpointSelection(type)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_isSecure)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ bool b = _this->proxy->ice_isSecure();
+ RETURN_BOOL(b ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_secure)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ zend_bool b;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("b"), &b) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_secure(b ? true : false)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getEncodingVersion)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ if(!createEncodingVersion(return_value, _this->proxy->ice_getEncodingVersion()))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_encodingVersion)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ zend_class_entry* cls = idToClass("::Ice::EncodingVersion");
+ assert(cls);
+
+ zval *zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O"), &zv, cls) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::EncodingVersion v;
+ if(extractEncodingVersion(zv, v))
+ {
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_encodingVersion(v)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_isPreferSecure)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ bool b = _this->proxy->ice_isPreferSecure();
+ RETURN_BOOL(b ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_preferSecure)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ zend_bool b;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("b"), &b) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_preferSecure(b ? true : false)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getRouter)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::RouterPrx router = _this->proxy->ice_getRouter();
+ if(router)
+ {
+ ClassInfoPtr info = lookupClass("::Ice::Router");
+ if(!info)
+ {
+ RETURN_NULL();
+ }
+
+ assert(info);
+
+ if(!createProxy(return_value, router, info, _this->communicator))
+ {
+ RETURN_NULL();
+ }
+ }
+ else
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_router)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ zval* zprx;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O!"), &zprx, proxyClassEntry) !=
+ SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr def;
+ if(zprx && !fetchProxy(zprx, proxy, def))
+ {
+ RETURN_NULL();
+ }
+
+ Ice::RouterPrx router;
+ if(proxy)
+ {
+ if(!def || !def->isA("::Ice::Router"))
+ {
+ runtimeError("ice_router requires a proxy narrowed to Ice::Router");
+ RETURN_NULL();
+ }
+ router = Ice::RouterPrx::uncheckedCast(proxy);
+ }
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_router(router)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getLocator)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::LocatorPrx locator = _this->proxy->ice_getLocator();
+ if(locator)
+ {
+ ClassInfoPtr info = lookupClass("::Ice::Locator");
+ if(!info)
+ {
+ RETURN_NULL();
+ }
+
+ if(!createProxy(return_value, locator, info, _this->communicator))
+ {
+ RETURN_NULL();
+ }
+ }
+ else
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_locator)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ zval* zprx;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O!"), &zprx, proxyClassEntry) !=
+ SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr def;
+ if(zprx && !fetchProxy(zprx, proxy, def))
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LocatorPrx locator;
+ if(proxy)
+ {
+ if(!def || !def->isA("::Ice::Locator"))
+ {
+ runtimeError("ice_locator requires a proxy narrowed to Ice::Locator");
+ RETURN_NULL();
+ }
+ locator = Ice::LocatorPrx::uncheckedCast(proxy);
+ }
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_locator(locator)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_twoway)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_twoway()))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_isTwoway)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ bool b = _this->proxy->ice_isTwoway();
+ RETURN_BOOL(b ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_oneway)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_oneway()))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_isOneway)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ bool b = _this->proxy->ice_isOneway();
+ RETURN_BOOL(b ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_batchOneway)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_batchOneway()))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_isBatchOneway)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ bool b = _this->proxy->ice_isBatchOneway();
+ RETURN_BOOL(b ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_datagram)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_datagram()))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_isDatagram)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ bool b = _this->proxy->ice_isDatagram();
+ RETURN_BOOL(b ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_batchDatagram)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_batchDatagram()))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_isBatchDatagram)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ bool b = _this->proxy->ice_isBatchDatagram();
+ RETURN_BOOL(b ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_compress)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ zend_bool b;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("b"), &b) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ if(!_this->clone(return_value, _this->proxy->ice_compress(b ? true : false)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_timeout)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ long l;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("l"), &l) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ // TODO: range check?
+ if(!_this->clone(return_value, _this->proxy->ice_timeout(l)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_connectionId)
+{
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ char* id;
+ size_t idLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &id, &idLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ if(!_this->clone(return_value, _this->proxy->ice_connectionId(id)))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getConnection)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::ConnectionPtr con = _this->proxy->ice_getConnection();
+ if(!createConnection(return_value, con))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_getCachedConnection)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ Ice::ConnectionPtr con = _this->proxy->ice_getCachedConnection();
+ if(!con || !createConnection(return_value, con))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_flushBatchRequests)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ try
+ {
+ _this->proxy->ice_flushBatchRequests();
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETURN_NULL();
+ }
+}
+
+static ClassInfoPtr
+lookupClass(const string& id)
+{
+ ClassInfoPtr info = getClassInfoById(id);
+ if(!info)
+ {
+ if(!id.empty() && id[id.size() - 1] == '*')
+ {
+ info = getClassInfoById(id.substr(0, id.size() - 1));
+ }
+ }
+
+ if(info && !info->defined)
+ {
+ runtimeError("%s is declared but not defined", id.c_str());
+ }
+ else if(!info)
+ {
+ runtimeError("no definition found for class or interface %s", id.c_str());
+ }
+
+ return info;
+}
+
+static void
+do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
+{
+ //
+ // First argument is required and should be a scoped name. The second and third arguments
+ // are optional and represent a facet name, a context, or a facet name followed by a context.
+ //
+ if(ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 3)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ char* id;
+ size_t idLen;
+ char* facet = 0;
+ size_t facetLen;
+ zval* arr = 0;
+
+ if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), const_cast<char*>("s|s!a!"), &id,
+ &idLen, &facet, &facetLen, &arr) == FAILURE)
+ {
+ facet = 0;
+ if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), const_cast<char*>("s|a!"), &id,
+ &idLen, &arr) == FAILURE)
+ {
+ php_error(E_ERROR, "%s() requires a type id followed by an optional facet and/or context",
+ get_active_function_name());
+ return;
+ }
+ }
+
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis());
+ assert(_this);
+
+ //
+ // Populate the context.
+ //
+ Ice::Context ctx;
+ if(arr && !extractStringMap(arr, ctx))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ ClassInfoPtr info = lookupClass(id);
+ if(!info)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::ObjectPrx prx = _this->proxy;
+ if(facet)
+ {
+ prx = prx->ice_facet(facet);
+ }
+
+ if(arr)
+ {
+ prx = prx->ice_context(ctx);
+ }
+
+ if(check)
+ {
+ //
+ // Verify that the object supports the requested type.
+ //
+ if(!prx->ice_isA(info->id))
+ {
+ RETURN_NULL();
+ }
+ }
+
+ if(!createProxy(return_value, prx, info, _this->communicator))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const Ice::FacetNotExistException&)
+ {
+ // Ignore.
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ RETVAL_FALSE;
+ }
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_uncheckedCast)
+{
+ do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+ZEND_METHOD(Ice_ObjectPrx, ice_checkedCast)
+{
+ do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
+
+IcePHP::Proxy::Proxy(const Ice::ObjectPrx& p, const ClassInfoPtr& i, const CommunicatorInfoPtr& comm) :
+ proxy(p), info(i), communicator(comm), connection(0), cachedConnection(0)
+{
+ //
+ // We want to ensure that the PHP object corresponding to the communicator is
+ // not destroyed until after this proxy is destroyed.
+ //
+ communicator->addRef();
+}
+
+IcePHP::Proxy::~Proxy()
+{
+ communicator->decRef();
+ if(connection)
+ {
+ zval_ptr_dtor(connection);
+ }
+ if(cachedConnection)
+ {
+ zval_ptr_dtor(cachedConnection);
+ }
+}
+
+bool
+IcePHP::Proxy::clone(zval* zv, const Ice::ObjectPrx& p)
+{
+ return create(zv, p, info, communicator);
+}
+
+bool
+IcePHP::Proxy::cloneUntyped(zval* zv, const Ice::ObjectPrx& p)
+{
+ return create(zv, p, 0, communicator);
+}
+
+bool
+IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm
+ )
+{
+ ClassInfoPtr cls = info;
+ if(!cls)
+ {
+ cls = getClassInfoById("::Ice::Object");
+ assert(cls);
+ }
+
+ if(object_init_ex(zv, proxyClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize proxy");
+ return false;
+ }
+
+ Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv);
+ ProxyPtr proxy = new Proxy(p, cls, comm);
+ assert(!obj->ptr);
+ obj->ptr = new ProxyPtr(proxy);
+ return true;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleAlloc(zend_class_entry* ce)
+{
+ Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_handlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleFreeStorage(zend_object* object)
+{
+ Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::fetch(object);
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleClone(zval* zv)
+{
+ //
+ // Create a new object that shares a C++ proxy instance with this object.
+ //
+
+ ProxyPtr obj = Wrapper<ProxyPtr>::value(zv);
+ assert(obj);
+
+ zval clone;
+ if(!obj->clone(&clone, obj->proxy))
+ {
+ return 0;
+ }
+
+ return Z_OBJ(clone);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static union _zend_function*
+handleGetMethod(zend_object **object, zend_string *name, const zval *key )
+{
+ zend_function* result;
+ //
+ // First delegate to the standard implementation of get_method. This will find
+ // any of our predefined proxy methods. If it returns 0, then we return a
+ // function that will check the class definition.
+ //
+ result = zend_get_std_object_handlers()->get_method(object, name, key);
+ if(!result)
+ {
+ Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::fetch(*object);
+ assert(obj->ptr);
+ ProxyPtr _this = *obj->ptr;
+
+ ClassInfoPtr info = _this->info;
+ assert(info);
+
+ OperationPtr op = info->getOperation(name->val);
+ if(!op)
+ {
+ //
+ // Returning 0 causes PHP to report an "undefined method" error.
+ //
+ return 0;
+ }
+
+ result = op->function();
+ }
+
+ return result;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static int
+handleCompare(zval* zobj1, zval* zobj2)
+{
+ //
+ // PHP guarantees that the objects have the same class.
+ //
+
+ Wrapper<ProxyPtr>* obj1 = Wrapper<ProxyPtr>::extract(zobj1);
+ assert(obj1->ptr);
+ ProxyPtr _this1 = *obj1->ptr;
+ Ice::ObjectPrx prx1 = _this1->proxy;
+
+ Wrapper<ProxyPtr>* obj2 = Wrapper<ProxyPtr>::extract(zobj2);
+ assert(obj2->ptr);
+ ProxyPtr _this2 = *obj2->ptr;
+ Ice::ObjectPrx prx2 = _this2->proxy;
+
+ if(prx1 == prx2)
+ {
+ return 0;
+ }
+ else if(prx1 < prx2)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+//
+// Necessary to suppress warnings from zend_function_entry in php-5.2.
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+
+//
+// Predefined methods for ObjectPrx.
+//
+static zend_function_entry _proxyMethods[] =
+{
+ 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_getConnectionId, 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_getEncodingVersion, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_encodingVersion, 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_flushBatchRequests, 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}
+};
+
+//
+// enable warning again
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic error "-Wwrite-strings"
+#endif
+
+bool
+IcePHP::proxyInit(void)
+{
+ //
+ // Register the ObjectPrx class.
+ //
+ zend_class_entry ce;
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, "Ice", "ObjectPrx", _proxyMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_ObjectPrx", _proxyMethods);
+#endif
+ ce.create_object = handleAlloc;
+ proxyClassEntry = zend_register_internal_class(&ce);
+ //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;
+ _handlers.free_obj = handleFreeStorage;
+ _handlers.offset = XtOffsetOf(Wrapper<ProxyPtr>, zobj);
+
+ return true;
+}
+
+bool
+IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const CommunicatorInfoPtr& comm)
+{
+ return Proxy::create(zv, p, 0, comm);
+}
+
+bool
+IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm
+ )
+{
+ return Proxy::create(zv, p, info, comm);
+}
+
+bool
+IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls)
+{
+ CommunicatorInfoPtr comm;
+ return fetchProxy(zv, prx, cls, comm);
+}
+
+bool
+IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls, CommunicatorInfoPtr& comm)
+{
+ if(!ZVAL_IS_NULL(zv))
+ {
+ if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != proxyClassEntry)
+ {
+ invalidArgument("value is not a proxy");
+ return false;
+ }
+ Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv);
+ if(!obj)
+ {
+ runtimeError("unable to retrieve proxy object from object store");
+ return false;
+ }
+ assert(obj->ptr);
+ prx = (*obj->ptr)->proxy;
+ cls = (*obj->ptr)->info;
+ comm = (*obj->ptr)->communicator;
+ }
+ return true;
+}
diff --git a/php/src/php7/Proxy.h b/php/src/php7/Proxy.h
new file mode 100644
index 00000000000..771e999ea88
--- /dev/null
+++ b/php/src/php7/Proxy.h
@@ -0,0 +1,34 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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_PROXY_H
+#define ICEPHP_PROXY_H
+
+#include <Config.h>
+#include <Communicator.h>
+#include <Types.h>
+
+namespace IcePHP
+{
+
+bool proxyInit(void);
+
+bool createProxy(zval*, const Ice::ObjectPrx&, const CommunicatorInfoPtr&);
+bool createProxy(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr&);
+bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr&);
+bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr&, CommunicatorInfoPtr&);
+
+//
+// Class entry.
+//
+extern zend_class_entry* proxyClassEntry;
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/php7/Types.cpp b/php/src/php7/Types.cpp
new file mode 100644
index 00000000000..a88731f83c4
--- /dev/null
+++ b/php/src/php7/Types.cpp
@@ -0,0 +1,3920 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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>
+#include <Ice/SlicedData.h>
+
+#include <limits>
+
+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;
+
+static string _unsetGUID = "710A52F2-A014-4CB2-AF40-348D48DBCDDD";
+
+extern "C"
+{
+static zend_object* handleTypeInfoAlloc(zend_class_entry*);
+static void handleTypeInfoFreeStorage(zend_object*);
+
+static zend_object* handleExceptionInfoAlloc(zend_class_entry*);
+static void handleExceptionInfoFreeStorage(zend_object*);
+}
+
+typedef map<string, ProxyInfoPtr> ProxyInfoMap;
+typedef map<string, ClassInfoPtr> ClassInfoMap;
+typedef map<Ice::Int, ClassInfoPtr> CompactIdMap;
+typedef map<string, ExceptionInfoPtr> ExceptionInfoMap;
+
+//
+// addProxyInfo()
+//
+static void
+addProxyInfo(const ProxyInfoPtr& p)
+{
+ 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(p->id, p));
+}
+
+//
+// getProxyInfo()
+//
+static IcePHP::ProxyInfoPtr
+getProxyInfo(const string& id)
+{
+ 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;
+}
+
+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;
+};
+
+}
+
+//
+// addClassInfoById()
+//
+static void
+addClassInfoById(const ClassInfoPtr& p)
+{
+ assert(!getClassInfoById(p->id));
+
+ 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)
+{
+ assert(!getClassInfoByName(p->name));
+#ifdef ICEPHP_USE_NAMESPACES
+ assert(name[0] == '\\');
+#endif
+
+ 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
+getClassInfoByClass(zend_class_entry* cls, zend_class_entry* formal)
+{
+ //
+ // See if there's a match in our class name => ClassInfo map.
+ //
+ ClassInfoPtr info = getClassInfoByName(cls->name->val);
+
+ //
+ // Check the base class, assuming it's compatible with our formal type (if any).
+ //
+ if(!info && cls->parent && (!formal || checkClass(cls->parent, formal)))
+ {
+ info = getClassInfoByClass(cls->parent, formal);
+ }
+
+ //
+ // Check interfaces.
+ //
+ if(!info)
+ {
+ for(zend_ulong i = 0; i < cls->num_interfaces && !info; ++i)
+ {
+ if(!formal || checkClass(cls->interfaces[i], formal))
+ {
+ info = getClassInfoByClass(cls->interfaces[i], formal);
+ }
+ }
+ }
+
+ return info;
+}
+
+//
+// getClassInfoById()
+//
+IcePHP::ClassInfoPtr
+IcePHP::getClassInfoById(const string& id)
+{
+ 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)
+{
+ if(ICE_G(nameToClassInfoMap))
+ {
+ string s = name;
+
+#ifdef ICEPHP_USE_NAMESPACES
+ //
+ // PHP's class definition (zend_class_entry) does not use a leading backslash
+ // in the class name.
+ //
+ if(s[0] != '\\')
+ {
+ s.insert(0, "\\");
+ }
+#endif
+
+ ClassInfoMap* m = reinterpret_cast<ClassInfoMap*>(ICE_G(nameToClassInfoMap));
+ ClassInfoMap::iterator p = m->find(s);
+ if(p != m->end())
+ {
+ return p->second;
+ }
+ }
+ return 0;
+}
+
+//
+// getExceptionInfo()
+//
+IcePHP::ExceptionInfoPtr
+IcePHP::getExceptionInfo(const string& id)
+{
+ 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;
+}
+
+//
+// SlicedDataUtil implementation
+//
+zend_class_entry* IcePHP::SlicedDataUtil::_slicedDataType = 0;
+zend_class_entry* IcePHP::SlicedDataUtil::_sliceInfoType = 0;
+
+IcePHP::SlicedDataUtil::~SlicedDataUtil()
+{
+ //
+ // Make sure we break any cycles among the ObjectReaders in preserved slices.
+ //
+ for(set<ObjectReaderPtr>::iterator p = _readers.begin(); p != _readers.end(); ++p)
+ {
+ Ice::SlicedDataPtr slicedData = (*p)->getSlicedData();
+ for(Ice::SliceInfoSeq::const_iterator q = slicedData->slices.begin(); q != slicedData->slices.end(); ++q)
+ {
+ //
+ // Don't just call (*q)->objects.clear(), as releasing references
+ // to the objects could have unexpected side effects. We exchange
+ // the vector into a temporary and then let the temporary fall out
+ // of scope.
+ //
+ vector<Ice::ObjectPtr> tmp;
+ tmp.swap((*q)->objects);
+ }
+ }
+}
+
+void
+IcePHP::SlicedDataUtil::add(const ObjectReaderPtr& reader)
+{
+ assert(reader->getSlicedData());
+ _readers.insert(reader);
+}
+
+void
+IcePHP::SlicedDataUtil::update(void)
+{
+ for(set<ObjectReaderPtr>::iterator p = _readers.begin(); p != _readers.end(); ++p)
+ {
+ setMember((*p)->getObject(), (*p)->getSlicedData());
+ }
+}
+
+void
+IcePHP::SlicedDataUtil::setMember(zval* obj, const Ice::SlicedDataPtr& slicedData)
+{
+ //
+ // Create a PHP equivalent of the SlicedData object.
+ //
+
+ assert(slicedData);
+
+ if(!_slicedDataType)
+ {
+ _slicedDataType = idToClass("::Ice::SlicedData");
+ assert(_slicedDataType);
+ }
+ if(!_sliceInfoType)
+ {
+ _sliceInfoType = idToClass("::Ice::SliceInfo");
+ assert(_sliceInfoType);
+ }
+
+ zval sd;
+ AutoDestroy sdDestroyer(&sd);
+
+ if(object_init_ex(&sd, _slicedDataType) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ zval slices;
+ array_init(&slices);
+ AutoDestroy slicesDestroyer(&slices);
+
+ if(add_property_zval(&sd, STRCAST("slices"), &slices) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ //
+ // Translate each SliceInfo object into its PHP equivalent.
+ //
+ for(vector<Ice::SliceInfoPtr>::const_iterator p = slicedData->slices.begin(); p != slicedData->slices.end(); ++p)
+ {
+ zval slice;
+ AutoDestroy sliceDestroyer(&slice);
+
+ if(object_init_ex(&slice, _sliceInfoType) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ add_next_index_zval(&slices, &slice); // Steals a reference.
+ Z_ADDREF_P(&slice);
+
+ //
+ // typeId
+ //
+ zval typeId;
+ AutoDestroy typeIdDestroyer(&typeId);
+ ZVAL_STRINGL(&typeId, STRCAST((*p)->typeId.c_str()), static_cast<int>((*p)->typeId.size()));
+ if(add_property_zval(&slice, STRCAST("typeId"), &typeId) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ //
+ // compactId
+ //
+ zval compactId;
+ AutoDestroy compactIdDestroyer(&compactId);
+ ZVAL_LONG(&compactId, (*p)->compactId);
+ if(add_property_zval(&slice, STRCAST("compactId"), &compactId) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ //
+ // bytes
+ //
+ zval bytes;
+ array_init(&bytes);
+ AutoDestroy bytesDestroyer(&bytes);
+ for(vector<Ice::Byte>::const_iterator q = (*p)->bytes.begin(); q != (*p)->bytes.end(); ++q)
+ {
+ add_next_index_long(&bytes, *q & 0xff);
+ }
+ if(add_property_zval(&slice, STRCAST("bytes"), &bytes) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ //
+ // objects
+ //
+ zval objects;
+ array_init(&objects);
+ AutoDestroy objectsDestroyer(&objects);
+ if(add_property_zval(&slice, STRCAST("objects"), &objects) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ for(vector<Ice::ObjectPtr>::const_iterator q = (*p)->objects.begin(); q != (*p)->objects.end(); ++q)
+ {
+ //
+ // Each element in the objects list is an instance of ObjectReader that wraps a PHP object.
+ //
+ assert(*q);
+ ObjectReaderPtr r = ObjectReaderPtr::dynamicCast(*q);
+ assert(r);
+ zval* o = r->getObject();
+ assert(Z_TYPE_P(o) == IS_OBJECT); // Should be non-nil.
+ add_next_index_zval(&objects, o); // Steals a reference.
+ Z_ADDREF_P(o);
+ }
+
+ //
+ // hasOptionalMembers
+ //
+ zval hasOptionalMembers;
+ AutoDestroy hasOptionalMembersDestroyer(&hasOptionalMembers);
+ ZVAL_BOOL(&hasOptionalMembers, (*p)->hasOptionalMembers ? 1 : 0);
+ if(add_property_zval(&slice, STRCAST("hasOptionalMembers"), &hasOptionalMembers) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ //
+ // isLastSlice
+ //
+ zval isLastSlice;
+ AutoDestroy isLastSliceDestroyer(&isLastSlice);
+ ZVAL_BOOL(&isLastSlice, (*p)->isLastSlice ? 1 : 0);
+ if(add_property_zval(&slice, STRCAST("isLastSlice"), &isLastSlice) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+ }
+
+ if(add_property_zval(obj, STRCAST("_ice_slicedData"), &sd) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+}
+
+//
+// Instances of preserved class and exception types may have a data member
+// named _ice_slicedData which is an instance of the PHP class Ice_SlicedData.
+//
+Ice::SlicedDataPtr
+IcePHP::SlicedDataUtil::getMember(zval* obj, ObjectMap* objectMap)
+{
+ Ice::SlicedDataPtr slicedData;
+
+ string name = "_ice_slicedData";
+ zval* sd = zend_hash_str_find(Z_OBJPROP_P(obj), STRCAST(name.c_str()), name.size());
+ if(sd)
+ {
+ if(Z_TYPE_P(sd) != IS_NULL)
+ {
+ //
+ // The "slices" member is an array of Ice_SliceInfo objects.
+ //
+
+ zval* sl = zend_hash_str_find(Z_OBJPROP_P(sd), STRCAST("slices"), sizeof("slices") - 1);
+ assert(sl);
+ assert(Z_TYPE_P(sl) == IS_INDIRECT);
+ sl = Z_INDIRECT_P(sl);
+ assert(Z_TYPE_P(sl) == IS_ARRAY);
+
+ Ice::SliceInfoSeq slices;
+
+ HashTable* arr = Z_ARRVAL_P(sl);
+ assert(arr);
+
+ zval* s;
+
+ ZEND_HASH_FOREACH_VAL(arr, s)
+ {
+ assert(Z_OBJCE_P(s) == _sliceInfoType);
+
+ Ice::SliceInfoPtr info = new Ice::SliceInfo;
+
+ zval* typeId = zend_hash_str_find(Z_OBJPROP_P(s), STRCAST("typeId"), sizeof("typeId") - 1);
+ assert(Z_TYPE_P(typeId) == IS_INDIRECT);
+ typeId = Z_INDIRECT_P(typeId);
+ assert(typeId && Z_TYPE_P(typeId) == IS_STRING);
+ info->typeId = string(Z_STRVAL_P(typeId), Z_STRLEN_P(typeId));
+
+ zval* compactId = zend_hash_str_find(Z_OBJPROP_P(s), STRCAST("compactId"), sizeof("compactId") - 1);
+ assert(compactId && Z_TYPE_P(compactId) == IS_LONG);
+ info->compactId = static_cast<long>(Z_LVAL_P(compactId));
+
+ zval* bytes = zend_hash_str_find(Z_OBJPROP_P(s), STRCAST("bytes"), sizeof("bytes") - 1);
+ assert(Z_TYPE_P(bytes) == IS_INDIRECT);
+ bytes = Z_INDIRECT_P(bytes);
+ assert(bytes && Z_TYPE_P(bytes) == IS_ARRAY);
+ HashTable* barr = Z_ARRVAL_P(bytes);
+ zval* e;
+ info->bytes.resize(zend_hash_num_elements(barr));
+
+ vector<Ice::Byte>::size_type i = 0;
+ ZEND_HASH_FOREACH_VAL(barr, e)
+ {
+ long l = static_cast<long>(Z_LVAL_P(e));
+ assert(l >= 0 && l <= 255);
+ info->bytes[i++] = static_cast<Ice::Byte>(l);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ zval* objects = zend_hash_str_find(Z_OBJPROP_P(s), STRCAST("objects"), sizeof("objects") - 1);
+ assert(Z_TYPE_P(objects) == IS_INDIRECT);
+ objects = Z_INDIRECT_P(objects);
+ assert(objects && Z_TYPE_P(objects) == IS_ARRAY);
+ HashTable* oarr = Z_ARRVAL_P(objects);
+ zval* o;
+
+ ZEND_HASH_FOREACH_VAL(oarr, o)
+ {
+ assert(Z_TYPE_P(o) == IS_OBJECT);
+
+ Ice::ObjectPtr writer;
+
+ ObjectMap::iterator i = objectMap->find(Z_OBJ_HANDLE_P(o));
+ if(i == objectMap->end())
+ {
+ writer = new ObjectWriter(o, objectMap, 0);
+ objectMap->insert(ObjectMap::value_type(Z_OBJ_HANDLE_P(o), writer));
+ }
+ else
+ {
+ writer = i->second;
+ }
+
+ info->objects.push_back(writer);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ zval* hasOptionalMembers = zend_hash_str_find(Z_OBJPROP_P(s),
+ STRCAST("hasOptionalMembers"),
+ sizeof("hasOptionalMembers") - 1);
+
+ assert(hasOptionalMembers &&
+ (Z_TYPE_P(hasOptionalMembers) == IS_TRUE || Z_TYPE_P(hasOptionalMembers) == IS_FALSE));
+ info->hasOptionalMembers = Z_TYPE_P(hasOptionalMembers) == IS_TRUE;
+
+ zval* isLastSlice = zend_hash_str_find(Z_OBJPROP_P(s), STRCAST("isLastSlice"), sizeof("isLastSlice") - 1);
+ assert(isLastSlice && (Z_TYPE_P(isLastSlice) == IS_TRUE || Z_TYPE_P(isLastSlice) == IS_FALSE));
+ info->isLastSlice = Z_TYPE_P(isLastSlice) == IS_TRUE;
+
+ slices.push_back(info);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ slicedData = new Ice::SlicedData(slices);
+ }
+ }
+
+ return slicedData;
+}
+
+//
+// UnmarshalCallback implementation.
+//
+IcePHP::UnmarshalCallback::~UnmarshalCallback()
+{
+}
+
+//
+// TypeInfo implementation.
+//
+IcePHP::TypeInfo::TypeInfo()
+{
+}
+
+bool
+IcePHP::TypeInfo::usesClasses() const
+{
+ return false;
+}
+
+void
+IcePHP::TypeInfo::unmarshaled(zval*, zval*, void*)
+{
+ 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)
+{
+ switch(kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ if(!(Z_TYPE_P(zv) == IS_TRUE || Z_TYPE_P(zv) == IS_FALSE))
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected boolean value but received %s", 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", s.c_str());
+ return false;
+ }
+ long val = static_cast<long>(Z_LVAL_P(zv));
+ if(val < 0 || val > 255)
+ {
+ invalidArgument("value %ld is out of range for a byte", 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", s.c_str());
+ return false;
+ }
+ zend_long val = Z_LVAL_P(zv);
+ if(val < SHRT_MIN || val > SHRT_MAX)
+ {
+ invalidArgument("value %ld is out of range for a short", 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", s.c_str());
+ return false;
+ }
+ zend_long val = Z_LVAL_P(zv);
+ if(val < INT_MIN || val > INT_MAX)
+ {
+ invalidArgument("value %ld is out of range for an int", 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", s.c_str());
+ return false;
+ }
+
+ if(Z_TYPE_P(zv) != IS_LONG)
+ {
+ Ice::Long val;
+ string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
+ if(!IceUtilInternal::stringToInt64(sval, val))
+ {
+ invalidArgument("invalid long value `%s'", Z_STRVAL_P(zv));
+ return false;
+ }
+ }
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ if(Z_TYPE_P(zv) != IS_DOUBLE && Z_TYPE_P(zv) != IS_LONG)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected float value but received %s", s.c_str());
+ return false;
+ }
+ if(Z_TYPE_P(zv) == IS_DOUBLE)
+ {
+ double val = Z_DVAL_P(zv);
+ return (val <= numeric_limits<float>::max() && val >= -numeric_limits<float>::max()) ||
+#if defined(_MSC_VER) && (_MSC_VER <= 1700)
+ !_finite(val);
+#else
+ !isfinite(val);
+#endif
+ }
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ if(Z_TYPE_P(zv) != IS_DOUBLE && Z_TYPE_P(zv) != IS_LONG)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected double value but received %s", 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", s.c_str());
+ return false;
+ }
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool
+IcePHP::PrimitiveInfo::variableLength() const
+{
+ return kind == KindString;
+}
+
+int
+IcePHP::PrimitiveInfo::wireSize() const
+{
+ switch(kind)
+ {
+ case KindBool:
+ case KindByte:
+ return 1;
+ case KindShort:
+ return 2;
+ case KindInt:
+ return 4;
+ case KindLong:
+ return 8;
+ case KindFloat:
+ return 4;
+ case KindDouble:
+ return 8;
+ case KindString:
+ return 1;
+ }
+ assert(false);
+ return 0;
+}
+
+Ice::OptionalFormat
+IcePHP::PrimitiveInfo::optionalFormat() const
+{
+ switch(kind)
+ {
+ case KindBool:
+ case KindByte:
+ return Ice::OptionalFormatF1;
+ case KindShort:
+ return Ice::OptionalFormatF2;
+ case KindInt:
+ return Ice::OptionalFormatF4;
+ case KindLong:
+ return Ice::OptionalFormatF8;
+ case KindFloat:
+ return Ice::OptionalFormatF4;
+ case KindDouble:
+ return Ice::OptionalFormatF8;
+ case KindString:
+ return Ice::OptionalFormatVSize;
+ }
+
+ assert(false);
+ return Ice::OptionalFormatF1;
+}
+
+void
+IcePHP::PrimitiveInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap*, bool)
+{
+ switch(kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ assert(Z_TYPE_P(zv) == IS_TRUE || Z_TYPE_P(zv) == IS_FALSE);
+ os->write(Z_TYPE_P(zv) == IS_TRUE);
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ assert(Z_TYPE_P(zv) == IS_LONG);
+ long val = static_cast<long>(Z_LVAL_P(zv));
+ assert(val >= 0 && val <= 255); // validate() should have caught this.
+ os->write(static_cast<Ice::Byte>(val));
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ assert(Z_TYPE_P(zv) == IS_LONG);
+ long val = static_cast<long>(Z_LVAL_P(zv));
+ assert(val >= SHRT_MIN && val <= SHRT_MAX); // validate() should have caught this.
+ os->write(static_cast<Ice::Short>(val));
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ assert(Z_TYPE_P(zv) == IS_LONG);
+ long val = static_cast<long>(Z_LVAL_P(zv));
+ assert(val >= INT_MIN && val <= INT_MAX); // validate() should have caught this.
+ os->write(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 = static_cast<long>(Z_LVAL_P(zv));
+ }
+ else
+ {
+ string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
+ IceUtilInternal::stringToInt64(sval, val);
+ }
+ os->write(val);
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ Ice::Double val = 0;
+ if(Z_TYPE_P(zv) == IS_DOUBLE)
+ {
+ val = Z_DVAL_P(zv);
+ }
+ else if(Z_TYPE_P(zv) == IS_LONG)
+ {
+ val = static_cast<double>(Z_LVAL_P(zv));
+ }
+ else
+ {
+ assert(false); // validate() should have caught this.
+ }
+ os->write(static_cast<Ice::Float>(val));
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ Ice::Double val = 0;
+ if(Z_TYPE_P(zv) == IS_DOUBLE)
+ {
+ val = Z_DVAL_P(zv);
+ }
+ else if(Z_TYPE_P(zv) == IS_LONG)
+ {
+ val = static_cast<double>(Z_LVAL_P(zv));
+ }
+ else
+ {
+ assert(false); // validate() should have caught this.
+ }
+ os->write(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->write(val);
+ }
+ else
+ {
+ os->write(string());
+ }
+ break;
+ }
+ }
+}
+
+void
+IcePHP::PrimitiveInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr&, zval* target, void* closure, bool)
+{
+ zval zv;
+ AutoDestroy destroy(&zv);
+
+ switch(kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ bool val;
+ is->read(val);
+ ZVAL_BOOL(&zv, val ? 1 : 0);
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ Ice::Byte val;
+ is->read(val);
+ ZVAL_LONG(&zv, val & 0xff);
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ Ice::Short val;
+ is->read(val);
+ ZVAL_LONG(&zv, val);
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ Ice::Int val;
+ is->read(val);
+ ZVAL_LONG(&zv, val);
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ Ice::Long val;
+ is->read(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) && (val < LONG_MIN || val > LONG_MAX))
+ {
+ string str = IceUtilInternal::int64ToString(val);
+ ZVAL_STRINGL(&zv, STRCAST(str.c_str()), static_cast<int>(str.length()));
+ }
+ else
+ {
+ ZVAL_LONG(&zv, static_cast<long>(val));
+ }
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ Ice::Float val;
+ is->read(val);
+ ZVAL_DOUBLE(&zv, val);
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ Ice::Double val;
+ is->read(val);
+ ZVAL_DOUBLE(&zv, val);
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ string val;
+ is->read(val);
+ ZVAL_STRINGL(&zv, STRCAST(val.c_str()), static_cast<int>(val.length()));
+ break;
+ }
+ }
+ cb->unmarshaled(&zv, target, closure);
+}
+
+void
+IcePHP::PrimitiveInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory*)
+{
+ if(!validate(zv))
+ {
+ out << "<invalid value - expected " << getId() << ">";
+ return;
+ }
+ zval tmp;
+ ZVAL_STR(&tmp, zval_get_string(zv));
+ out << Z_STRVAL(tmp);
+}
+
+//
+// EnumInfo implementation.
+//
+IcePHP::EnumInfo::EnumInfo(const string& ident, zval* en) :
+ id(ident),
+ maxValue(0)
+{
+ HashTable* arr = Z_ARRVAL_P(en);
+ HashPosition pos;
+ zval* val;
+
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+ while((val = zend_hash_get_current_data_ex(arr, &pos)))
+ {
+ assert(Z_TYPE_P(val) == IS_STRING);
+ string name = Z_STRVAL_P(val);
+ zend_hash_move_forward_ex(arr, &pos);
+
+ val = zend_hash_get_current_data_ex(arr, &pos);
+ assert(Z_TYPE_P(val) == IS_LONG);
+ Ice::Int value = static_cast<Ice::Int>(Z_LVAL_P(val));
+ zend_hash_move_forward_ex(arr, &pos);
+
+ if(value > maxValue)
+ {
+ const_cast<int&>(maxValue) = value;
+ }
+
+ const_cast<map<Ice::Int, string>&>(enumerators)[value] = name;
+ }
+}
+
+string
+IcePHP::EnumInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::EnumInfo::validate(zval* zv)
+{
+ if(Z_TYPE_P(zv) == IS_LONG)
+ {
+ const Ice::Int l = static_cast<Ice::Int>(Z_LVAL_P(zv));
+ return l >= 0 && enumerators.find(l) != enumerators.end();
+ }
+ return false;
+}
+
+bool
+IcePHP::EnumInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IcePHP::EnumInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IcePHP::EnumInfo::optionalFormat() const
+{
+ return Ice::OptionalFormatSize;
+}
+
+void
+IcePHP::EnumInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap*, bool)
+{
+ assert(Z_TYPE_P(zv) == IS_LONG); // validate() should have caught this.
+ const Ice::Int val = static_cast<Ice::Int>(Z_LVAL_P(zv));
+ assert(val >= 0 && enumerators.find(val) != enumerators.end()); // validate() should have caught this.
+
+ os->writeEnum(val, maxValue);
+}
+
+void
+IcePHP::EnumInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr&, zval* target, void* closure, bool)
+{
+ zval zv;
+ AutoDestroy destroy(&zv);
+
+ const Ice::Int val = is->readEnum(maxValue);
+
+ if(enumerators.find(val) == enumerators.end())
+ {
+ invalidArgument("enumerator %d is out of range for enum %s", val, id.c_str());
+ throw AbortMarshaling();
+ }
+
+ ZVAL_LONG(&zv, val);
+ cb->unmarshaled(&zv, target, closure);
+}
+
+void
+IcePHP::EnumInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory*)
+{
+ if(!validate(zv))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+ const Ice::Int val = static_cast<Ice::Int>(Z_LVAL_P(zv));
+ map<Ice::Int, string>::const_iterator p = enumerators.find(val);
+ assert(p != enumerators.end());
+ out << p->second;
+}
+
+//
+// DataMember implementation.
+//
+void
+IcePHP::DataMember::unmarshaled(zval* zv, zval* target, void*)
+{
+ setMember(target, zv);
+}
+
+void
+IcePHP::DataMember::setMember(zval* target, zval* zv)
+{
+ 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'", name.c_str());
+ throw AbortMarshaling();
+ }
+}
+
+static void
+convertDataMembers(zval* zv, DataMemberList& reqMembers, DataMemberList& optMembers, bool allowOptional)
+{
+ list<DataMemberPtr> optList;
+
+ assert(Z_TYPE_P(zv) == IS_ARRAY);
+ HashTable* membersArray = Z_ARRVAL_P(zv);
+ zval* arr;
+
+ ZEND_HASH_FOREACH_VAL(membersArray, arr)
+ {
+ DataMemberPtr m = new DataMember();
+ zval* elem;
+
+ assert(Z_TYPE_P(arr) == IS_ARRAY);
+ HashTable* member = Z_ARRVAL_P(arr);
+ assert(allowOptional ? zend_hash_num_elements(member) == 4 : zend_hash_num_elements(member) == 2);
+
+ elem = zend_hash_index_find(member, 0);
+ assert(Z_TYPE_P(elem) == IS_STRING);
+ m->name = Z_STRVAL_P(elem);
+
+ elem = zend_hash_index_find(member, 1);
+ assert(Z_TYPE_P(elem) == IS_OBJECT);
+ m->type = Wrapper<TypeInfoPtr>::value(elem);
+
+ if(allowOptional)
+ {
+ elem = zend_hash_index_find(member, 2);
+ assert(Z_TYPE_P(elem) == IS_TRUE || Z_TYPE_P(elem) == IS_FALSE);
+ m->optional = Z_TYPE_P(elem) == IS_TRUE;
+
+ elem = zend_hash_index_find(member, 3);
+ assert(Z_TYPE_P(elem) == IS_LONG);
+ m->tag = static_cast<int>(Z_LVAL_P(elem));
+ }
+ else
+ {
+ m->optional = false;
+ m->tag = 0;
+ }
+
+ if(m->optional)
+ {
+ optList.push_back(m);
+ }
+ else
+ {
+ reqMembers.push_back(m);
+ }
+ }
+ ZEND_HASH_FOREACH_END();
+
+ if(allowOptional)
+ {
+ class SortFn
+ {
+ public:
+ static bool compare(const DataMemberPtr& lhs, const DataMemberPtr& rhs)
+ {
+ return lhs->tag < rhs->tag;
+ }
+ };
+
+ optList.sort(SortFn::compare);
+ copy(optList.begin(), optList.end(), back_inserter(optMembers));
+ }
+}
+
+//
+// StructInfo implementation.
+//
+IcePHP::StructInfo::StructInfo(const string& ident, const string& n, zval* m) :
+ id(ident), name(n)
+{
+ // Set to undefined
+ ZVAL_UNDEF(&_nullMarshalValue);
+
+ DataMemberList opt;
+ convertDataMembers(m, const_cast<DataMemberList&>(members), opt, false);
+ assert(opt.empty());
+ const_cast<zend_class_entry*&>(zce) = nameToClass(name);
+ assert(zce);
+
+ _variableLength = false;
+ _wireSize = 0;
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ if(!_variableLength && (*p)->type->variableLength())
+ {
+ _variableLength = true;
+ }
+ _wireSize += (*p)->type->wireSize();
+ }
+}
+
+string
+IcePHP::StructInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::StructInfo::validate(zval* zv)
+{
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ return true;
+ }
+ else if(Z_TYPE_P(zv) != IS_OBJECT)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected struct value of type %s but received %s", 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", zce->name, ce->name);
+ return false;
+ }
+
+ return true;
+}
+
+bool
+IcePHP::StructInfo::variableLength() const
+{
+ return _variableLength;
+}
+
+int
+IcePHP::StructInfo::wireSize() const
+{
+ return _wireSize;
+}
+
+Ice::OptionalFormat
+IcePHP::StructInfo::optionalFormat() const
+{
+ return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
+}
+
+bool
+IcePHP::StructInfo::usesClasses() const
+{
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ if((*p)->type->usesClasses())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+IcePHP::StructInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
+{
+ assert(Z_TYPE_P(zv) == IS_NULL || (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == zce));
+
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ if(Z_ISUNDEF(_nullMarshalValue))
+ {
+ if(object_init_ex(&_nullMarshalValue, const_cast<zend_class_entry*>(zce)) != SUCCESS)
+ {
+ runtimeError("unable to initialize object of type %s", zce->name);
+ throw AbortMarshaling();
+ }
+
+ if(!invokeMethod(&_nullMarshalValue, ZEND_CONSTRUCTOR_FUNC_NAME))
+ {
+ assert(false);
+ }
+ }
+ assert(!Z_ISUNDEF(_nullMarshalValue));
+ ZVAL_COPY_VALUE(zv, &_nullMarshalValue);
+ }
+
+ Ice::OutputStream::size_type sizePos = 0;
+ if(optional)
+ {
+ if(_variableLength)
+ {
+ sizePos = os->startSize();
+ }
+ else
+ {
+ os->writeSize(_wireSize);
+ }
+ }
+
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ zval* val = zend_hash_str_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size());
+ if(!val)
+ {
+ runtimeError("member `%s' of %s is not defined", member->name.c_str(), id.c_str());
+ throw AbortMarshaling();
+ }
+
+ if(Z_TYPE_P(val) == IS_INDIRECT)
+ {
+ val = Z_INDIRECT_P(val);
+ }
+
+ if(!member->type->validate(val))
+ {
+ invalidArgument("invalid value for %s member `%s'", id.c_str(), member->name.c_str());
+ throw AbortMarshaling();
+ }
+
+ member->type->marshal(val, os, objectMap, false);
+ }
+
+ if(optional && _variableLength)
+ {
+ os->endSize(sizePos);
+ }
+}
+
+void
+IcePHP::StructInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr& comm, zval* target, void* closure, bool optional)
+{
+ zval zv;
+ AutoDestroy destroy(&zv);
+ if(object_init_ex(&zv, const_cast<zend_class_entry*>(zce)) != SUCCESS)
+ {
+ runtimeError("unable to initialize object of type %s", zce->name);
+ throw AbortMarshaling();
+ }
+
+ if(optional)
+ {
+ if(_variableLength)
+ {
+ is->skip(4);
+ }
+ else
+ {
+ is->skipSize();
+ }
+ }
+
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ member->type->unmarshal(is, member, comm, &zv, 0, false);
+ }
+
+ cb->unmarshaled(&zv, target, closure);
+}
+
+void
+IcePHP::StructInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(!validate(zv))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ out << "<nil>";
+ }
+ else
+ {
+ out.sb();
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ out << nl << member->name << " = ";
+ zval* val = zend_hash_str_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size());
+ assert(Z_TYPE_P(val) == IS_INDIRECT);
+ val = Z_INDIRECT_P(val);
+ if(val)
+ {
+ member->type->print(val, out, history);
+ }
+ else
+ {
+ out << "<not defined>";
+ }
+ }
+ out.eb();
+ }
+}
+
+void
+IcePHP::StructInfo::destroy()
+{
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ (*p)->type->destroy();
+ }
+ const_cast<DataMemberList&>(members).clear();
+ if(!Z_ISUNDEF(_nullMarshalValue))
+ {
+ zval_ptr_dtor(&_nullMarshalValue);
+ }
+}
+
+//
+// SequenceInfo implementation.
+//
+IcePHP::SequenceInfo::SequenceInfo(const string& ident, zval* e) :
+ id(ident)
+{
+ const_cast<TypeInfoPtr&>(elementType) = Wrapper<TypeInfoPtr>::value(e);
+}
+
+string
+IcePHP::SequenceInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::SequenceInfo::validate(zval* zv)
+{
+ return Z_TYPE_P(zv) == IS_NULL || Z_TYPE_P(zv) == IS_ARRAY;
+}
+
+bool
+IcePHP::SequenceInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IcePHP::SequenceInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IcePHP::SequenceInfo::optionalFormat() const
+{
+ return elementType->variableLength() ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
+}
+
+bool
+IcePHP::SequenceInfo::usesClasses() const
+{
+ return elementType->usesClasses();
+}
+
+void
+IcePHP::SequenceInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
+{
+ Ice::Int sz = 0;
+ HashTable* arr = 0;
+
+ if(Z_TYPE_P(zv) != IS_NULL)
+ {
+ assert(Z_TYPE_P(zv) == IS_ARRAY); // validate() should have caught this.
+ arr = Z_ARRVAL_P(zv);
+ sz = static_cast<Ice::Int>(zend_hash_num_elements(arr));
+ }
+
+ Ice::OutputStream::size_type sizePos = 0;
+ if(optional)
+ {
+ if(elementType->variableLength())
+ {
+ sizePos = os->startSize();
+ }
+ else if(elementType->wireSize() > 1)
+ {
+ os->writeSize(sz == 0 ? 1 : sz * elementType->wireSize() + (sz > 254 ? 5 : 1));
+ }
+ }
+
+ if(sz == 0)
+ {
+ os->writeSize(0);
+ }
+ else
+ {
+ PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
+ if(pi)
+ {
+ marshalPrimitiveSequence(pi, zv, os);
+ return;
+ }
+
+ os->writeSize(sz);
+
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(!elementType->validate(val))
+ {
+ invalidArgument("invalid value for sequence element `%s'", id.c_str());
+ throw AbortMarshaling();
+ }
+ elementType->marshal(val, os, objectMap, false);
+ }
+ ZEND_HASH_FOREACH_END();
+ }
+
+ if(optional && elementType->variableLength())
+ {
+ os->endSize(sizePos);
+ }
+}
+
+void
+IcePHP::SequenceInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr& comm, zval* target, void* closure, bool optional)
+{
+ if(optional)
+ {
+ if(elementType->variableLength())
+ {
+ is->skip(4);
+ }
+ else if(elementType->wireSize() > 1)
+ {
+ is->skipSize();
+ }
+ }
+
+ PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
+ if(pi)
+ {
+ unmarshalPrimitiveSequence(pi, is, cb, target, closure);
+ return;
+ }
+
+ zval zv;
+ array_init(&zv);
+ AutoDestroy destroy(&zv);
+
+ Ice::Int sz = is->readSize();
+ for(Ice::Int i = 0; i < sz; ++i)
+ {
+#ifdef _MSC_VER
+# pragma warning(disable:4311)
+# pragma warning(disable:4312)
+#endif
+ void* cl = reinterpret_cast<void*>(i);
+#ifdef _MSC_VER
+# pragma warning(default:4311)
+# pragma warning(default:4312)
+#endif
+
+ elementType->unmarshal(is, this, comm, &zv, cl, false);
+ }
+
+ cb->unmarshaled(&zv, target, closure);
+}
+
+void
+IcePHP::SequenceInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(!validate(zv))
+ {
+ 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);
+
+ out.sb();
+
+ int i = 0;
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ out << nl << '[' << i << "] = ";
+ elementType->print(val, out, history);
+ ++i;
+ }
+ ZEND_HASH_FOREACH_END();
+
+ out.eb();
+ }
+}
+
+void
+IcePHP::SequenceInfo::unmarshaled(zval* zv, zval* target, void* closure)
+{
+ assert(Z_TYPE_P(target) != IS_REFERENCE);
+ assert(Z_TYPE_P(target) == IS_ARRAY);
+
+#ifdef _MSC_VER
+# pragma warning(disable:4302)
+# pragma warning(disable:4311)
+#endif
+ long i = reinterpret_cast<long>(closure);
+#ifdef _MSC_VER
+# pragma warning(default:4302)
+# pragma warning(disable:4311)
+#endif
+ add_index_zval(target, i, zv);
+ if(Z_REFCOUNTED_P(zv))
+ {
+ Z_ADDREF_P(zv);
+ }
+
+}
+
+void
+IcePHP::SequenceInfo::destroy()
+{
+ if(elementType)
+ {
+ elementType->destroy();
+ const_cast<TypeInfoPtr&>(elementType) = 0;
+ }
+}
+
+void
+IcePHP::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, zval* zv, const Ice::OutputStreamPtr& os)
+{
+ HashTable* arr = Z_ARRVAL_P(zv);
+
+ 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;
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(!pi->validate(val))
+ {
+ throw AbortMarshaling();
+ }
+ seq[i++] = Z_TYPE_P(val) == IS_TRUE;
+ }
+ ZEND_HASH_FOREACH_END();
+
+#if defined(_MSC_VER) && (_MSC_VER < 1300)
+ os->writeBoolSeq(seq);
+#else
+ os->write(seq);
+#endif
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ Ice::ByteSeq seq(sz);
+ Ice::Int i = 0;
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(!pi->validate(val))
+ {
+ throw AbortMarshaling();
+ }
+ long l = static_cast<long>(Z_LVAL_P(val));
+ assert(l >= 0 && l <= 255);
+ seq[i++] = static_cast<Ice::Byte>(l);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ Ice::ShortSeq seq(sz);
+ Ice::Int i = 0;
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(!pi->validate(val))
+ {
+ throw AbortMarshaling();
+ }
+ long l = static_cast<long>(Z_LVAL_P(val));
+ assert(l >= SHRT_MIN && l <= SHRT_MAX);
+ seq[i++] = static_cast<Ice::Short>(l);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ Ice::IntSeq seq(sz);
+ Ice::Int i = 0;
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(!pi->validate(val))
+ {
+ throw AbortMarshaling();
+ }
+ long l = static_cast<long>(Z_LVAL_P(val));
+ assert(l >= INT_MIN && l <= INT_MAX);
+ seq[i++] = static_cast<Ice::Int>(l);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ Ice::LongSeq seq(sz);
+ Ice::Int i = 0;
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(!pi->validate(val))
+ {
+ 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 = static_cast<long>(Z_LVAL_P(val));
+ }
+ else
+ {
+ string sval(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ IceUtilInternal::stringToInt64(sval, l);
+ }
+ seq[i++] = l;
+ }
+ ZEND_HASH_FOREACH_END();
+
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ Ice::FloatSeq seq(sz);
+ Ice::Int i = 0;
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(!pi->validate(val))
+ {
+ throw AbortMarshaling();
+ }
+ double d = 0;
+ if(Z_TYPE_P(val) == IS_DOUBLE)
+ {
+ d = Z_DVAL_P(val);
+ }
+ else if(Z_TYPE_P(val) == IS_LONG)
+ {
+ d = static_cast<double>(Z_LVAL_P(val));
+ }
+ else
+ {
+ assert(false); // validate() should have caught this.
+ }
+ seq[i++] = static_cast<Ice::Float>(d);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ Ice::DoubleSeq seq(sz);
+ Ice::Int i = 0;
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(!pi->validate(val))
+ {
+ throw AbortMarshaling();
+ }
+ double d = 0;
+ if(Z_TYPE_P(val) == IS_DOUBLE)
+ {
+ d = Z_DVAL_P(val);
+ }
+ else if(Z_TYPE_P(val) == IS_LONG)
+ {
+ d = static_cast<double>(Z_LVAL_P(val));
+ }
+ else
+ {
+ assert(false); // validate() should have caught this.
+ }
+ seq[i++] = d;
+ }
+ ZEND_HASH_FOREACH_END();
+
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ Ice::StringSeq seq(sz);
+ Ice::Int i = 0;
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(!pi->validate(val))
+ {
+ 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_FOREACH_END();
+
+ os->write(seq);
+ break;
+ }
+ }
+}
+
+void
+IcePHP::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, const Ice::InputStreamPtr& is,
+ const UnmarshalCallbackPtr& cb, zval* target, void* closure)
+{
+ zval zv;
+ array_init(&zv);
+ AutoDestroy destroy(&zv);
+
+ switch(pi->kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ pair<const bool*, const bool*> pr;
+ IceUtil::ScopedArray<bool> arr;
+ is->read(pr, arr);
+ 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->read(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;
+ IceUtil::ScopedArray<Ice::Short> arr;
+ is->read(pr, arr);
+ 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;
+ IceUtil::ScopedArray<Ice::Int> arr;
+ is->read(pr, arr);
+ 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;
+ IceUtil::ScopedArray<Ice::Long> arr;
+ is->read(pr, arr);
+ Ice::Int i = 0;
+ for(const Ice::Long* p = pr.first; p != pr.second; ++p, ++i)
+ {
+ 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()), static_cast<int>(str.length()));
+ }
+ 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;
+ IceUtil::ScopedArray<Ice::Float> arr;
+ is->read(pr, arr);
+ Ice::Int i = 0;
+ for(const Ice::Float* p = pr.first; p != pr.second; ++p, ++i)
+ {
+ zval val;
+ ZVAL_DOUBLE(&val, *p);
+ add_index_zval(&zv, i, &val);
+ }
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ pair<const Ice::Double*, const Ice::Double*> pr;
+ IceUtil::ScopedArray<Ice::Double> arr;
+ is->read(pr, arr);
+ Ice::Int i = 0;
+ for(const Ice::Double* p = pr.first; p != pr.second; ++p, ++i)
+ {
+ zval val;
+ ZVAL_DOUBLE(&val, *p);
+ add_index_zval(&zv, i, &val);
+ }
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ Ice::StringSeq seq;
+ is->read(seq, true);
+ Ice::Int i = 0;
+ for(Ice::StringSeq::iterator p = seq.begin(); p != seq.end(); ++p, ++i)
+ {
+ zval val;
+ ZVAL_STRINGL(&val, STRCAST(p->c_str()), static_cast<int>(p->length()));
+ add_index_zval(&zv, i, &val);
+ }
+ break;
+ }
+ }
+
+ cb->unmarshaled(&zv, target, closure);
+}
+
+//
+// DictionaryInfo implementation.
+//
+IcePHP::DictionaryInfo::DictionaryInfo(const string& ident, zval* k, zval* v) :
+ id(ident)
+{
+ const_cast<TypeInfoPtr&>(keyType) = Wrapper<TypeInfoPtr>::value(k);
+ const_cast<TypeInfoPtr&>(valueType) = Wrapper<TypeInfoPtr>::value(v);
+
+ _variableLength = keyType->variableLength() || valueType->variableLength();
+ _wireSize = keyType->wireSize() + valueType->wireSize();
+}
+
+string
+IcePHP::DictionaryInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::DictionaryInfo::validate(zval* zv)
+{
+ return Z_TYPE_P(zv) == IS_NULL || Z_TYPE_P(zv) == IS_ARRAY;
+}
+
+bool
+IcePHP::DictionaryInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IcePHP::DictionaryInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IcePHP::DictionaryInfo::optionalFormat() const
+{
+ return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
+}
+
+bool
+IcePHP::DictionaryInfo::usesClasses() const
+{
+ return valueType->usesClasses();
+}
+
+void
+IcePHP::DictionaryInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
+{
+ Ice::Int sz = 0;
+ HashTable* arr = 0;
+
+ if(Z_TYPE_P(zv) != IS_NULL)
+ {
+ assert(Z_TYPE_P(zv) == IS_ARRAY); // validate() should have caught this.
+ arr = Z_ARRVAL_P(zv);
+ sz = static_cast<Ice::Int>(zend_hash_num_elements(arr));
+ }
+
+ Ice::OutputStream::size_type sizePos = 0;
+ if(optional)
+ {
+ if(_variableLength)
+ {
+ sizePos = os->startSize();
+ }
+ else
+ {
+ os->writeSize(sz == 0 ? 1 : sz * _wireSize + (sz > 254 ? 5 : 1));
+ }
+ }
+
+ PrimitiveInfoPtr piKey = PrimitiveInfoPtr::dynamicCast(keyType);
+ EnumInfoPtr enKey = EnumInfoPtr::dynamicCast(keyType);
+ if(!enKey && (!piKey || piKey->kind == PrimitiveInfo::KindFloat || piKey->kind == PrimitiveInfo::KindDouble))
+ {
+ invalidArgument("dictionary type `%s' cannot be marshaled", id.c_str());
+ throw AbortMarshaling();
+ }
+
+ os->writeSize(sz);
+
+ if(sz > 0)
+ {
+ zend_long num_key;
+ zend_string* key;
+ zval* val;
+
+ ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, key, val)
+ {
+ //
+ // Store the key (which can be a long or a string) in a zval so that we can reuse the marshaling logic.
+ //
+ zval zkey;
+ AutoDestroy destroy(&zkey);
+
+ if(key)
+ {
+ ZVAL_STRINGL(&zkey, key->val, key->len);
+ }
+ else
+ {
+ ZVAL_LONG(&zkey, num_key);
+ }
+
+ //
+ // Convert the zval to the required type, if necessary.
+ //
+ if(piKey)
+ {
+ switch(piKey->kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ convert_to_boolean(&zkey);
+ break;
+ }
+
+ case PrimitiveInfo::KindByte:
+ case PrimitiveInfo::KindShort:
+ case PrimitiveInfo::KindInt:
+ case PrimitiveInfo::KindLong:
+ {
+ if(key) // HASH_KEY_IS_STRING
+ {
+ convert_to_long(&zkey);
+ }
+ break;
+ }
+
+ case PrimitiveInfo::KindString:
+ {
+ if(!key) // HASH_KEY_IS_LONG
+ {
+ convert_to_string(&zkey);
+ }
+ break;
+ }
+
+ case PrimitiveInfo::KindFloat:
+ case PrimitiveInfo::KindDouble:
+ assert(false);
+ }
+ }
+ else
+ {
+ if(key) // HASH_KEY_IS_STRING
+ {
+ convert_to_long(&zkey);
+ }
+ }
+
+ //
+ // Marshal the key.
+ //
+ if(!keyType->validate(&zkey))
+ {
+ invalidArgument("invalid key in `%s' element", id.c_str());
+ throw AbortMarshaling();
+ }
+ keyType->marshal(&zkey, os, objectMap, false);
+
+ //
+ // Marshal the value.
+ //
+ if(!valueType->validate(val))
+ {
+ invalidArgument("invalid value in `%s' element", id.c_str());
+ throw AbortMarshaling();
+ }
+ valueType->marshal(val, os, objectMap, false);
+ }
+ ZEND_HASH_FOREACH_END();
+ }
+
+ if(optional && _variableLength)
+ {
+ os->endSize(sizePos);
+ }
+}
+
+void
+IcePHP::DictionaryInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr& comm, zval* target, void* closure, bool optional)
+{
+ if(optional)
+ {
+ if(_variableLength)
+ {
+ is->skip(4);
+ }
+ else
+ {
+ is->skipSize();
+ }
+ }
+
+ PrimitiveInfoPtr piKey = PrimitiveInfoPtr::dynamicCast(keyType);
+ EnumInfoPtr enKey = EnumInfoPtr::dynamicCast(keyType);
+ if(!enKey && (!piKey || piKey->kind == PrimitiveInfo::KindFloat || piKey->kind == PrimitiveInfo::KindDouble))
+ {
+ invalidArgument("dictionary type `%s' cannot be unmarshaled", id.c_str());
+ throw AbortMarshaling();
+ }
+
+ zval zv;
+ array_init(&zv);
+ AutoDestroy destroy(&zv);
+
+ 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.
+ //
+ KeyCallbackPtr keyCB = new KeyCallback;
+ keyType->unmarshal(is, keyCB, comm, 0, 0, false);
+ assert(Z_TYPE(keyCB->key) != IS_UNDEF);
+
+ //
+ // Allocate a callback that holds a reference to the key.
+ //
+ ValueCallbackPtr valueCB = new ValueCallback(&keyCB->key);
+
+ //
+ // Pass the key to the callback.
+ //
+ valueType->unmarshal(is, valueCB, comm, &zv, 0, false);
+ }
+
+ cb->unmarshaled(&zv, target, closure);
+}
+
+void
+IcePHP::DictionaryInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(!validate(zv))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ out << "{}";
+ }
+ else
+ {
+ HashTable* arr = Z_ARRVAL_P(zv);
+ zval* val;
+ zend_long num_key;
+ zend_string* key;
+ bool first = true;
+
+ out.sb();
+
+ ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, key, val)
+ {
+ if(first)
+ {
+ first = false;
+ }
+ else
+ {
+ out << nl;
+ }
+ out << nl << "key = ";
+
+ if(key) // HASH_KEY_IS_STRING
+ {
+ out << key->val;
+ }
+ else // HASH_KEY_IS_LONG
+ {
+ out << num_key;
+ }
+ out << nl << "value = ";
+ valueType->print(val, out, history);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ out.eb();
+ }
+}
+
+IcePHP::DictionaryInfo::KeyCallback::KeyCallback()
+{
+ ZVAL_UNDEF(&key);
+}
+
+IcePHP::DictionaryInfo::KeyCallback::~KeyCallback()
+{
+ zval_ptr_dtor(&key);
+}
+
+void
+IcePHP::DictionaryInfo::KeyCallback::unmarshaled(zval* zv, zval*, void*)
+{
+ zval_ptr_dtor(&key);
+ ZVAL_COPY(&key, zv);
+}
+
+IcePHP::DictionaryInfo::ValueCallback::ValueCallback(zval* k)
+{
+ ZVAL_COPY_VALUE(&key, k);
+}
+
+IcePHP::DictionaryInfo::ValueCallback::~ValueCallback()
+{
+}
+
+void
+IcePHP::DictionaryInfo::ValueCallback::unmarshaled(zval* zv, zval* target, void*)
+{
+ assert(Z_TYPE_P(target) == IS_ARRAY);
+
+ switch(Z_TYPE(key))
+ {
+ case IS_LONG:
+ add_index_zval(target, Z_LVAL(key), zv);
+ break;
+ case IS_TRUE:
+ add_index_zval(target, 1, zv);
+ break;
+ case IS_FALSE:
+ add_index_zval(target, 0, zv);
+ break;
+ case IS_STRING:
+ add_assoc_zval_ex(target, Z_STRVAL(key), Z_STRLEN(key), zv);
+ break;
+ default:
+ assert(false);
+ return;
+ }
+
+ Z_TRY_ADDREF_P(zv);
+}
+
+void
+IcePHP::DictionaryInfo::destroy()
+{
+ if(keyType)
+ {
+ keyType->destroy();
+ keyType = 0;
+ }
+ if(valueType)
+ {
+ valueType->destroy();
+ valueType = 0;
+ }
+}
+
+//
+// ClassInfo implementation.
+//
+IcePHP::ClassInfo::ClassInfo(const string& ident) :
+ id(ident), compactId(-1), isAbstract(false), preserve(false), zce(0), defined(false)
+{
+}
+
+void
+IcePHP::ClassInfo::define(const string& n, Ice::Int compact, bool isAbs, bool pres, zval* b, zval* i, zval* m)
+{
+ const_cast<string&>(name) = n;
+ const_cast<Ice::Int&>(compactId) = static_cast<Ice::Int>(compact);
+ const_cast<bool&>(isAbstract) = isAbs;
+ const_cast<bool&>(preserve) = pres;
+
+ if(b)
+ {
+ TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(b);
+ const_cast<ClassInfoPtr&>(base) = ClassInfoPtr::dynamicCast(p);
+ assert(base);
+ }
+
+ if(i)
+ {
+ HashTable* interfacesArray = Z_ARRVAL_P(i);
+ zval* interfaceType;
+
+ ZEND_HASH_FOREACH_VAL(interfacesArray, interfaceType)
+ {
+ TypeInfoPtr t = Wrapper<TypeInfoPtr>::value(interfaceType);
+ ClassInfoPtr c = ClassInfoPtr::dynamicCast(t);
+ assert(c);
+ const_cast<ClassInfoList&>(interfaces).push_back(c);
+ }
+ ZEND_HASH_FOREACH_END();
+ }
+
+ if(m)
+ {
+ convertDataMembers(m, const_cast<DataMemberList&>(members), const_cast<DataMemberList&>(optionalMembers),
+ true);
+ }
+
+ const_cast<bool&>(defined) = true;
+ const_cast<zend_class_entry*&>(zce) = nameToClass(name);
+ assert(zce || id == "::Ice::LocalObject"); // LocalObject does not have a native PHP equivalent.
+}
+
+string
+IcePHP::ClassInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::ClassInfo::validate(zval* val)
+{
+ if(Z_TYPE_P(val) == IS_OBJECT)
+ {
+ return checkClass(Z_OBJCE_P(val), const_cast<zend_class_entry*>(zce));
+ }
+ return Z_TYPE_P(val) == IS_NULL;
+}
+
+bool
+IcePHP::ClassInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IcePHP::ClassInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IcePHP::ClassInfo::optionalFormat() const
+{
+ return Ice::OptionalFormatClass;
+}
+
+bool
+IcePHP::ClassInfo::usesClasses() const
+{
+ return true;
+}
+
+void
+IcePHP::ClassInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool)
+{
+ if(!defined)
+ {
+ runtimeError("class or interface %s is declared but not defined", 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), const_cast<zend_class_entry*>(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())
+ {
+ writer = new ObjectWriter(zv, objectMap, this);
+ 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, bool)
+{
+ if(!defined)
+ {
+ runtimeError("class or interface %s is declared but not defined", id.c_str());
+ throw AbortMarshaling();
+ }
+
+ is->readObject(new ReadObjectCallback(this, cb, target, closure));
+}
+
+void
+IcePHP::ClassInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(!validate(zv))
+ {
+ 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);
+ out.eb();
+ }
+ }
+}
+
+void
+IcePHP::ClassInfo::destroy()
+{
+ const_cast<ClassInfoPtr&>(base) = 0;
+ const_cast<ClassInfoList&>(interfaces).clear();
+ if(!members.empty())
+ {
+ DataMemberList ml = members;
+ const_cast<DataMemberList&>(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)
+{
+ if(base)
+ {
+ base->printMembers(zv, out, history);
+ }
+
+ DataMemberList::const_iterator q;
+
+ for(q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ out << nl << member->name << " = ";
+ zval* val = zend_hash_str_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size());
+ assert(Z_TYPE_P(val) == IS_INDIRECT);
+ val = Z_INDIRECT_P(val);
+ if(val)
+ {
+ member->type->print(val, out, history);
+ }
+ else
+ {
+ out << "<not defined>";
+ }
+ }
+
+ for(q = optionalMembers.begin(); q != optionalMembers.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ out << nl << member->name << " = ";
+ zval* val = zend_hash_str_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size());
+ assert(Z_TYPE_P(val) == IS_INDIRECT);
+ val = Z_INDIRECT_P(val);
+ if(val)
+ {
+ if(isUnset(val))
+ {
+ out << "<unset>";
+ }
+ else
+ {
+ member->type->print(val, out, history);
+ }
+ }
+ 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.
+//
+IcePHP::ProxyInfo::ProxyInfo(const string& ident) :
+ id(ident), defined(false)
+{
+}
+
+void
+IcePHP::ProxyInfo::define(const ClassInfoPtr& c)
+{
+ const_cast<ClassInfoPtr&>(cls) = c;
+ const_cast<bool&>(defined) = true;
+}
+
+string
+IcePHP::ProxyInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::ProxyInfo::validate(zval* zv)
+{
+ 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", s.c_str());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+IcePHP::ProxyInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IcePHP::ProxyInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IcePHP::ProxyInfo::optionalFormat() const
+{
+ return Ice::OptionalFormatFSize;
+}
+
+void
+IcePHP::ProxyInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap*, bool optional)
+{
+ Ice::OutputStream::size_type sizePos = 0;
+ if(optional)
+ {
+ sizePos = os->startSize();
+ }
+
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ os->write(Ice::ObjectPrx());
+ }
+ 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))
+ {
+ throw AbortMarshaling();
+ }
+ if(!info->isA(id))
+ {
+ invalidArgument("proxy is not narrowed to %s", id.c_str());
+ throw AbortMarshaling();
+ }
+ os->write(proxy);
+ }
+
+ if(optional)
+ {
+ os->endSize(sizePos);
+ }
+}
+
+void
+IcePHP::ProxyInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr& comm, zval* target, void* closure, bool optional)
+{
+ zval zv;
+ AutoDestroy destroy(&zv);
+
+ if(optional)
+ {
+ is->skip(4);
+ }
+
+ Ice::ObjectPrx proxy;
+ is->read(proxy);
+
+ if(!proxy)
+ {
+ ZVAL_NULL(&zv);
+ cb->unmarshaled(&zv, target, closure);
+ return;
+ }
+
+ if(!cls->defined)
+ {
+ runtimeError("class or interface %s is declared but not defined", id.c_str());
+ throw AbortMarshaling();
+ }
+
+ if(!createProxy(&zv, proxy, cls, comm))
+ {
+ throw AbortMarshaling();
+ }
+ cb->unmarshaled(&zv, target, closure);
+}
+
+void
+IcePHP::ProxyInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory*)
+{
+ if(!validate(zv))
+ {
+ 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))
+ {
+ return;
+ }
+ out << proxy->ice_toString();
+ }
+}
+
+void
+IcePHP::ProxyInfo::destroy()
+{
+ const_cast<ClassInfoPtr&>(cls) = 0;
+}
+
+//
+// ObjectWriter implementation.
+//
+IcePHP::ObjectWriter::ObjectWriter(zval* object, ObjectMap* objectMap, const ClassInfoPtr& formal) :
+ _map(objectMap)
+{
+ // Copy zval and increase ref count
+ ZVAL_COPY(&_object, object);
+
+ //
+ // We need to determine the most-derived Slice type supported by this object.
+ // This is typically a Slice class, but it can also be an interface.
+ //
+ // The caller may have provided a ClassInfo representing the formal type, in
+ // which case we ensure that the actual type is compatible with the formal type.
+ //
+ _info = getClassInfoByClass(Z_OBJCE_P(object), formal ? const_cast<zend_class_entry*>(formal->zce) : 0);
+ assert(_info);
+}
+
+IcePHP::ObjectWriter::~ObjectWriter()
+{
+ zval_ptr_dtor(&_object);
+}
+
+void
+IcePHP::ObjectWriter::ice_preMarshal()
+{
+ string name = "ice_premarshal"; // Must be lowercase.
+ if(zend_hash_str_exists(&Z_OBJCE_P(&_object)->function_table, STRCAST(name.c_str()), static_cast<uint>(name.size())))
+ {
+ if(!invokeMethod(&_object, name))
+ {
+ throw AbortMarshaling();
+ }
+ }
+}
+
+void
+IcePHP::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
+{
+ Ice::SlicedDataPtr slicedData;
+
+ if(_info->preserve)
+ {
+ //
+ // Retrieve the SlicedData object that we stored as a hidden member of the PHP object.
+ //
+ slicedData = SlicedDataUtil::getMember(const_cast<zval*>(&_object), const_cast<ObjectMap*>(_map));
+ }
+
+ os->startObject(slicedData);
+
+ if(_info->id != "::Ice::UnknownSlicedObject")
+ {
+ ClassInfoPtr info = _info;
+ while(info && info->id != Ice::Object::ice_staticId())
+ {
+ assert(info->base); // All classes have the Ice::Object base type.
+ const bool lastSlice = info->base->id == Ice::Object::ice_staticId();
+ os->startSlice(info->id, info->compactId, lastSlice);
+
+ writeMembers(os, info->members);
+ writeMembers(os, info->optionalMembers); // The optional members have already been sorted by tag.
+
+ os->endSlice();
+
+ info = info->base;
+ }
+ }
+
+ os->endObject();
+}
+
+void
+IcePHP::ObjectWriter::writeMembers(const Ice::OutputStreamPtr& os, const DataMemberList& members) const
+{
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ zval* val = zend_hash_str_find(Z_OBJPROP_P(const_cast<zval*>(&_object)),
+ STRCAST(member->name.c_str()), static_cast<int>(member->name.size()));
+
+ if(!val)
+ {
+ runtimeError("member `%s' of %s is not defined", member->name.c_str(), _info->id.c_str());
+ throw AbortMarshaling();
+ }
+
+ assert(Z_TYPE_P(val) == IS_INDIRECT);
+ val = Z_INDIRECT_P(val);
+
+ if(Z_TYPE_P(val) == IS_REFERENCE)
+ {
+ val = Z_REFVAL_P(val);
+ }
+
+ if(member->optional && (isUnset(val) || !os->writeOptional(member->tag, member->type->optionalFormat())))
+ {
+ continue;
+ }
+
+ if(!member->type->validate(val))
+ {
+ invalidArgument("invalid value for %s member `%s'", _info->id.c_str(), member->name.c_str());
+ throw AbortMarshaling();
+ }
+
+ member->type->marshal(val, os, _map, member->optional);
+ }
+}
+
+//
+// ObjectReader implementation.
+//
+IcePHP::ObjectReader::ObjectReader(zval* object, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm) :
+ _info(info), _communicator(comm)
+{
+ assert(Z_TYPE_P(object) == IS_OBJECT);
+ ZVAL_DUP(&_object, object);
+}
+
+IcePHP::ObjectReader::~ObjectReader()
+{
+ zval_ptr_dtor(&_object);
+}
+
+void
+IcePHP::ObjectReader::ice_postUnmarshal()
+{
+ string name = "ice_postunmarshal"; // Must be lowercase.
+ if(zend_hash_str_exists(&Z_OBJCE(_object)->function_table,
+ STRCAST(name.c_str()), static_cast<int>(name.size())))
+ {
+ if(!invokeMethod(&_object, name))
+ {
+ throw AbortMarshaling();
+ }
+ }
+}
+
+void
+IcePHP::ObjectReader::read(const Ice::InputStreamPtr& is)
+{
+ is->startObject();
+
+ const bool unknown = _info->id == "::Ice::UnknownSlicedObject";
+
+ //
+ // Unmarshal the slices of a user-defined class.
+ //
+ if(!unknown)
+ {
+ ClassInfoPtr info = _info;
+
+ while(info && info->id != Ice::Object::ice_staticId())
+ {
+ is->startSlice();
+
+ DataMemberList::const_iterator p;
+
+ for(p = info->members.begin(); p != info->members.end(); ++p)
+ {
+ DataMemberPtr member = *p;
+ member->type->unmarshal(is, member, _communicator, &_object, 0, false);
+ }
+
+ //
+ // The optional members have already been sorted by tag.
+ //
+ for(p = info->optionalMembers.begin(); p != info->optionalMembers.end(); ++p)
+ {
+ DataMemberPtr member = *p;
+ if(is->readOptional(member->tag, member->type->optionalFormat()))
+ {
+ member->type->unmarshal(is, member, _communicator, &_object, 0, true);
+ }
+ else
+ {
+ zval zv;
+ AutoDestroy destroy(&zv);
+ assignUnset(&zv);
+ member->setMember(&_object, &zv);
+ }
+ }
+
+ is->endSlice();
+
+ info = info->base;
+ }
+ }
+
+ _slicedData = is->endObject(_info->preserve);
+
+ if(_slicedData)
+ {
+ SlicedDataUtil* util = reinterpret_cast<SlicedDataUtil*>(is->closure());
+ assert(util);
+ util->add(this);
+
+ //
+ // Define the "unknownTypeId" member for an instance of UnknownSlicedObject.
+ //
+ if(unknown)
+ {
+ assert(!_slicedData->slices.empty());
+
+ const string typeId = _slicedData->slices[0]->typeId;
+ zval zv;
+ AutoDestroy typeIdDestroyer(&zv);
+ ZVAL_STRINGL(&zv, STRCAST(typeId.c_str()), static_cast<int>(typeId.size()));
+ add_property_zval(&_object, STRCAST("unknownTypeId"), &zv);
+ }
+ }
+}
+
+ClassInfoPtr
+IcePHP::ObjectReader::getInfo() const
+{
+ return _info;
+}
+
+zval*
+IcePHP::ObjectReader::getObject() const
+{
+ return const_cast<zval*>(&_object);
+}
+
+Ice::SlicedDataPtr
+IcePHP::ObjectReader::getSlicedData() const
+{
+ return _slicedData;
+}
+
+//
+// ReadObjectCallback implementation.
+//
+IcePHP::ReadObjectCallback::ReadObjectCallback(const ClassInfoPtr& info, const UnmarshalCallbackPtr& cb,
+ zval* target, void* closure) :
+ _info(info), _cb(cb), _closure(closure)
+{
+ ZVAL_NULL(&_target);
+
+ if(target)
+ {
+ assert(Z_REFCOUNTED_P(target));
+ ZVAL_COPY(&_target, target);
+ }
+}
+
+IcePHP::ReadObjectCallback::~ReadObjectCallback()
+{
+ 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);
+ }
+ else
+ {
+ zval zv;
+ AutoDestroy destroy(&zv);
+ ZVAL_NULL(&zv);
+ _cb->unmarshaled(&zv, &_target, _closure);
+ }
+}
+
+//
+// ExceptionInfo implementation.
+//
+zval*
+IcePHP::ExceptionInfo::unmarshal(const Ice::InputStreamPtr& is, const CommunicatorInfoPtr& comm)
+{
+ zval* zv = static_cast<zval*>(emalloc(sizeof(zval)));
+
+ if(object_init_ex(zv, zce) != SUCCESS)
+ {
+ runtimeError("unable to initialize object of type %s", zce->name);
+ throw AbortMarshaling();
+ }
+
+ //
+ // NOTE: The type id for the first slice has already been read.
+ //
+ ExceptionInfoPtr info = this;
+ while(info)
+ {
+ is->startSlice();
+
+ DataMemberList::iterator q;
+
+ for(q = info->members.begin(); q != info->members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ member->type->unmarshal(is, member, comm, zv, 0, false);
+ }
+
+ //
+ // The optional members have already been sorted by tag.
+ //
+ for(q = info->optionalMembers.begin(); q != info->optionalMembers.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ if(is->readOptional(member->tag, member->type->optionalFormat()))
+ {
+ member->type->unmarshal(is, member, comm, zv, 0, true);
+ }
+ else
+ {
+ zval un;
+ AutoDestroy destroy(&un);
+ assignUnset(&un);
+ member->setMember(zv, &un);
+ }
+ }
+
+ is->endSlice();
+
+ info = info->base;
+ }
+
+ return zv;
+}
+
+void
+IcePHP::ExceptionInfo::print(zval* zv, IceUtilInternal::Output& out)
+{
+ if(Z_TYPE_P(zv) != IS_OBJECT)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected exception value of type %s but received %s", 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", zce->name, ce->name);
+ return;
+ }
+
+ PrintObjectHistory history;
+ history.index = 0;
+
+ out << "exception " << id;
+ out.sb();
+ printMembers(zv, out, &history);
+ out.eb();
+}
+
+void
+IcePHP::ExceptionInfo::printMembers(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(base)
+ {
+ base->printMembers(zv, out, history);
+ }
+
+ DataMemberList::iterator q;
+
+ for(q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ out << nl << member->name << " = ";
+ zval* val = zend_hash_str_find(Z_OBJPROP_P(zv),
+ STRCAST(member->name.c_str()),
+ static_cast<int>(member->name.size()));
+ if(val)
+ {
+ member->type->print(val, out, history);
+ }
+ else
+ {
+ out << "<not defined>";
+ }
+ }
+
+ for(q = optionalMembers.begin(); q != optionalMembers.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ out << nl << member->name << " = ";
+ zval* val = zend_hash_str_find(Z_OBJPROP_P(zv),
+ STRCAST(member->name.c_str()),
+ static_cast<int>(member->name.size()));
+ if(val)
+ {
+ if(isUnset(val))
+ {
+ out << "<unset>";
+ }
+ else
+ {
+ member->type->print(val, out, history);
+ }
+ }
+ 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;
+}
+
+//
+// ExceptionReader implementation.
+//
+IcePHP::ExceptionReader::ExceptionReader(const CommunicatorInfoPtr& communicatorInfo, const ExceptionInfoPtr& info
+ ) :
+ Ice::UserExceptionReader(communicatorInfo->getCommunicator()), _communicatorInfo(communicatorInfo), _info(info)
+{
+}
+
+IcePHP::ExceptionReader::~ExceptionReader()
+ throw()
+{
+}
+
+void
+IcePHP::ExceptionReader::read(const Ice::InputStreamPtr& is) const
+{
+ is->startException();
+ const_cast<zval*&>(_ex) = _info->unmarshal(is, _communicatorInfo TSRMLS_CC);
+
+ const_cast<Ice::SlicedDataPtr&>(_slicedData) = is->endException(_info->preserve);
+}
+
+bool
+IcePHP::ExceptionReader::usesClasses() const
+{
+ return _info->usesClasses;
+}
+
+string
+IcePHP::ExceptionReader::ice_name() const
+{
+ return _info->id;
+}
+
+IcePHP::ExceptionReader*
+IcePHP::ExceptionReader::ice_clone() const
+{
+ assert(false);
+ return 0;
+}
+
+void
+IcePHP::ExceptionReader::ice_throw() const
+{
+ throw *this;
+}
+
+ExceptionInfoPtr
+IcePHP::ExceptionReader::getInfo() const
+{
+ return _info;
+}
+
+zval*
+IcePHP::ExceptionReader::getException() const
+{
+ return _ex;
+}
+
+Ice::SlicedDataPtr
+IcePHP::ExceptionReader::getSlicedData() const
+{
+ return _slicedData;
+}
+
+//
+// IdResolver
+//
+IcePHP::IdResolver::IdResolver(void)
+{
+}
+
+string
+IcePHP::IdResolver::resolve(Ice::Int id) const
+{
+ CompactIdMap* m = reinterpret_cast<CompactIdMap*>(ICE_G(compactIdToClassInfoMap));
+ if(m)
+ {
+ CompactIdMap::iterator p = m->find(id);
+ if(p != m->end())
+ {
+ return p->second->id;
+ }
+ }
+ return string();
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleTypeInfoAlloc(zend_class_entry* ce)
+{
+ Wrapper<TypeInfoPtr>* obj = Wrapper<TypeInfoPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_typeInfoHandlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleTypeInfoFreeStorage(zend_object* object)
+{
+ Wrapper<TypeInfoPtr>* obj = Wrapper<TypeInfoPtr>::fetch(object);
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+static bool
+createTypeInfo(zval* zv, const TypeInfoPtr& p)
+{
+ assert(typeInfoClassEntry);
+ if(object_init_ex(zv, typeInfoClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize type");
+ return false;
+ }
+
+ Wrapper<TypeInfoPtr>* ze = Wrapper<TypeInfoPtr>::extract(zv);
+ assert(!ze->ptr);
+ ze->ptr = new TypeInfoPtr(p);
+
+ return true;
+}
+
+ZEND_FUNCTION(IcePHP_defineEnum)
+{
+ char* id;
+ size_t idLen;
+ zval* enumerators;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("sa"), &id, &idLen, &enumerators) == FAILURE)
+ {
+ return;
+ }
+
+ EnumInfoPtr type = new EnumInfo(id, enumerators);
+
+ if(!createTypeInfo(return_value, type))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineStruct)
+{
+ char* id;
+ size_t idLen;
+ char* name;
+ size_t nameLen;
+ zval* members;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("ssa"), &id, &idLen, &name, &nameLen,
+ &members) == FAILURE)
+ {
+ return;
+ }
+
+ StructInfoPtr type = new StructInfo(id, name, members);
+
+ if(!createTypeInfo(return_value, type))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineSequence)
+{
+ char* id;
+ size_t idLen;
+ zval* element;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("so"), &id, &idLen, &element) == FAILURE)
+ {
+ assert(false);
+ return;
+ }
+
+ SequenceInfoPtr type = new SequenceInfo(id, element);
+
+ if(!createTypeInfo(return_value, type))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineDictionary)
+{
+ char* id;
+ size_t idLen;
+ zval* key;
+ zval* value;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("soo"), &id, &idLen, &key, &value) == FAILURE)
+ {
+ return;
+ }
+
+ DictionaryInfoPtr type = new DictionaryInfo(id, key, value);
+
+ if(!createTypeInfo(return_value, type))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_declareProxy)
+{
+ char* id;
+ size_t idLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &id, &idLen) == FAILURE)
+ {
+ return;
+ }
+
+ ProxyInfoPtr type = getProxyInfo(id);
+ if(!type)
+ {
+ type = new ProxyInfo(id);
+ addProxyInfo(type);
+ }
+
+ if(!createTypeInfo(return_value, type))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineProxy)
+{
+ zval* cls;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("o"), &cls) == FAILURE)
+ {
+ return;
+ }
+
+ TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(cls);
+ ClassInfoPtr c = ClassInfoPtr::dynamicCast(p);
+ assert(c);
+
+ ProxyInfoPtr type = getProxyInfo(c->id);
+ if(!type)
+ {
+ type = new ProxyInfo(c->id);
+ addProxyInfo(type);
+ }
+
+ type->define(c);
+
+ if(!createTypeInfo(return_value, type))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_declareClass)
+{
+ char* id;
+ size_t idLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &id, &idLen) == FAILURE)
+ {
+ return;
+ }
+
+ ClassInfoPtr type = getClassInfoById(id);
+ if(!type)
+ {
+ type = new ClassInfo(id);
+ addClassInfoById(type);
+ }
+
+ if(!createTypeInfo(return_value, type))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineClass)
+{
+ char* id;
+ size_t idLen;
+ char* name;
+ size_t nameLen;
+ long compactId;
+ zend_bool isAbstract;
+ zend_bool preserve;
+ zval* base;
+ zval* interfaces;
+ zval* members;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("sslbbo!a!a!"), &id, &idLen, &name, &nameLen,
+ &compactId, &isAbstract, &preserve, &base, &interfaces, &members) == FAILURE)
+ {
+ return;
+ }
+
+ ClassInfoPtr type = getClassInfoById(id);
+ if(!type)
+ {
+ type = new ClassInfo(id);
+ addClassInfoById(type);
+ }
+
+ type->define(name, static_cast<Ice::Int>(compactId), isAbstract ? true : false, preserve ? true : false, base,
+ interfaces, members);
+ addClassInfoByName(type);
+
+ CompactIdMap* m = reinterpret_cast<CompactIdMap*>(ICE_G(compactIdToClassInfoMap));
+ if(!m)
+ {
+ m = new CompactIdMap;
+ ICE_G(compactIdToClassInfoMap) = m;
+ }
+ m->insert(CompactIdMap::value_type(type->compactId, type));
+
+ if(!createTypeInfo(return_value, type))
+ {
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object*
+handleExceptionInfoAlloc(zend_class_entry* ce)
+{
+ Wrapper<ExceptionInfoPtr>* obj = Wrapper<ExceptionInfoPtr>::create(ce);
+ assert(obj);
+
+ obj->zobj.handlers = &_exceptionInfoHandlers;
+
+ return &obj->zobj;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleExceptionInfoFreeStorage(zend_object* object)
+{
+ Wrapper<ExceptionInfoPtr>* obj = Wrapper<ExceptionInfoPtr>::fetch(object);
+ delete obj->ptr;
+ zend_object_std_dtor(object);
+}
+
+
+static bool
+createExceptionInfo(zval* zv, const ExceptionInfoPtr& p)
+{
+ if(object_init_ex(zv, exceptionInfoClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize exception info");
+ return false;
+ }
+
+ Wrapper<ExceptionInfoPtr>* ze = Wrapper<ExceptionInfoPtr>::extract(zv);
+ assert(!ze->ptr);
+ ze->ptr = new ExceptionInfoPtr(p);
+
+ return true;
+}
+
+ZEND_FUNCTION(IcePHP_defineException)
+{
+ char* id;
+ size_t idLen;
+ char* name;
+ size_t nameLen;
+ zend_bool preserve;
+ zval* base;
+ zval* members;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("ssbo!a!"), &id, &idLen, &name, &nameLen,
+ &preserve, &base, &members) == FAILURE)
+ {
+ return;
+ }
+
+ ExceptionInfoPtr ex = new ExceptionInfo();
+ ex->id = id;
+ ex->name = name;
+ ex->preserve = preserve ? true : false;
+ if(base)
+ {
+ ex->base = Wrapper<ExceptionInfoPtr>::value(base);
+ }
+ if(members)
+ {
+ convertDataMembers(members, ex->members, ex->optionalMembers, true);
+ }
+
+ ex->usesClasses = false;
+
+ //
+ // Only examine the required members to see if any use classes.
+ //
+ 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);
+
+ assert(!getExceptionInfo(ex->id));
+
+ 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))
+ {
+ 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(), const_cast<char*>("zz"), &v, &t) == FAILURE)
+ {
+ return;
+ }
+
+ TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(t);
+ assert(type);
+
+ ostringstream ostr;
+ IceUtilInternal::Output out(ostr);
+ PrintObjectHistory history;
+ history.index = 0;
+ type->print(v, out, &history);
+
+ string str = ostr.str();
+ RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()));
+}
+
+ZEND_FUNCTION(IcePHP_stringifyException)
+{
+ if(ZEND_NUM_ARGS() != 2)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ zval* v;
+ zval* t;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("oo"), &v, &t) == FAILURE)
+ {
+ return;
+ }
+
+ ExceptionInfoPtr ex = Wrapper<ExceptionInfoPtr>::value(t);
+ assert(ex);
+
+ ostringstream ostr;
+ IceUtilInternal::Output out(ostr);
+ ex->print(v, out);
+
+ string str = ostr.str();
+ RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()));
+}
+
+//
+// Necessary to suppress warnings from zend_function_entry in php-5.2.
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+
+//
+// Predefined methods for IcePHP_TypeInfo.
+//
+static zend_function_entry _typeInfoMethods[] =
+{
+ {0, 0, 0}
+};
+
+//
+// Predefined methods for IcePHP_ExceptionInfo.
+//
+static zend_function_entry _exceptionInfoMethods[] =
+{
+ {0, 0, 0}
+};
+
+bool
+IcePHP::isUnset(zval* zv)
+{
+ if(Z_TYPE_P(zv) == IS_STRING)
+ {
+ return _unsetGUID == string(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
+ }
+ return false;
+}
+
+void
+IcePHP::assignUnset(zval* zv)
+{
+ ZVAL_DUP(zv, ICE_G(unset));
+}
+
+bool
+IcePHP::typesInit(INIT_FUNC_ARGS)
+{
+ 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);
+ memcpy(&_typeInfoHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _typeInfoHandlers.free_obj = handleTypeInfoFreeStorage;
+ _typeInfoHandlers.offset = XtOffsetOf(Wrapper<TypeInfoPtr>, zobj);
+
+ //
+ // Register the IcePHP_ExceptionInfo class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_ExceptionInfo", _exceptionInfoMethods);
+ ce.create_object = handleExceptionInfoAlloc;
+ exceptionInfoClassEntry = zend_register_internal_class(&ce);
+ memcpy(&_exceptionInfoHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _exceptionInfoHandlers.free_obj = handleExceptionInfoFreeStorage;
+ _exceptionInfoHandlers.offset = XtOffsetOf(Wrapper<ExceptionInfoPtr>, zobj);
+
+ REGISTER_STRING_CONSTANT("Ice_Unset", const_cast<char*>(_unsetGUID.c_str()), CONST_CS|CONST_PERSISTENT);
+#ifdef ICEPHP_USE_NAMESPACES
+ REGISTER_NS_STRING_CONSTANT("Ice", "Unset", const_cast<char*>(_unsetGUID.c_str()), CONST_CS|CONST_PERSISTENT);
+#endif
+
+ return true;
+}
+
+//
+// enable warning again
+//
+#if defined(__GNUC__)
+# pragma GCC diagnostic error "-Wwrite-strings"
+#endif
+
+bool
+IcePHP::typesRequestInit(void)
+{
+ //
+ // 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;
+ if(!createTypeInfo(&zv, type))
+ {
+ zval_ptr_dtor(&zv);
+ return false;
+ }
+ string name = "IcePHP__t_" + type->getId();
+ zend_hash_str_update(&EG(symbol_table), const_cast<char*>(name.c_str()), name.size(), &zv);
+ }
+
+ ICE_G(idToClassInfoMap) = 0;
+ ICE_G(nameToClassInfoMap) = 0;
+ ICE_G(proxyInfoMap) = 0;
+ ICE_G(exceptionInfoMap) = 0;
+
+ zval* unset = static_cast<zval*>(emalloc(sizeof(zval)));
+ ZVAL_STRINGL(unset, STRCAST(_unsetGUID.c_str()), static_cast<int>(_unsetGUID.length()));
+ ICE_G(unset) = unset;
+
+ return true;
+}
+
+bool
+IcePHP::typesRequestShutdown(void)
+{
+ 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));
+
+ zval_dtor(ICE_G(unset));
+ efree(ICE_G(unset));
+ return true;
+}
diff --git a/php/src/php7/Types.h b/php/src/php7/Types.h
new file mode 100644
index 00000000000..3a8ea345a24
--- /dev/null
+++ b/php/src/php7/Types.h
@@ -0,0 +1,590 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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_declareProxy);
+ZEND_FUNCTION(IcePHP_defineProxy);
+ZEND_FUNCTION(IcePHP_declareClass);
+ZEND_FUNCTION(IcePHP_defineClass);
+ZEND_FUNCTION(IcePHP_defineException);
+ZEND_FUNCTION(IcePHP_stringify);
+ZEND_FUNCTION(IcePHP_stringifyException);
+}
+
+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;
+
+class ObjectReader;
+typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr;
+
+//
+// This class keeps track of PHP objects (instances of Slice classes
+// and exceptions) that have preserved slices.
+//
+class SlicedDataUtil
+{
+public:
+
+ ~SlicedDataUtil();
+
+ void add(const ObjectReaderPtr&);
+
+ void update(TSRMLS_D);
+
+ static void setMember(zval*, const Ice::SlicedDataPtr& TSRMLS_DC);
+ static Ice::SlicedDataPtr getMember(zval*, ObjectMap* TSRMLS_DC);
+
+private:
+
+ std::set<ObjectReaderPtr> _readers;
+ static zend_class_entry* _slicedDataType;
+ static zend_class_entry* _sliceInfoType;
+};
+
+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*) = 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*) = 0;
+
+ virtual bool variableLength() const = 0;
+ virtual int wireSize() const = 0;
+ virtual Ice::OptionalFormat optionalFormat() const = 0;
+
+ virtual bool usesClasses() const; // Default implementation returns false.
+
+ virtual void unmarshaled(zval*, zval*, void*); // 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*, bool) = 0;
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void*, bool) = 0;
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*) = 0;
+};
+typedef IceUtil::Handle<TypeInfo> TypeInfoPtr;
+
+//
+// Primitive type information.
+//
+class PrimitiveInfo : public TypeInfo
+{
+public:
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval*);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void*, bool);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ enum Kind
+ {
+ KindBool,
+ KindByte,
+ KindShort,
+ KindInt,
+ KindLong,
+ KindFloat,
+ KindDouble,
+ KindString
+ };
+
+ Kind kind;
+};
+typedef IceUtil::Handle<PrimitiveInfo> PrimitiveInfoPtr;
+
+//
+// Enum information.
+//
+class EnumInfo : public TypeInfo
+{
+public:
+
+ EnumInfo(const std::string&, zval*);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval*);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void*, bool);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ const std::string id;
+ const std::map<Ice::Int, std::string> enumerators;
+ const Ice::Int maxValue;
+
+};
+typedef IceUtil::Handle<EnumInfo> EnumInfoPtr;
+
+class DataMember : public UnmarshalCallback
+{
+public:
+
+ virtual void unmarshaled(zval*, zval*, void*);
+
+ void setMember(zval*, zval*);
+
+ std::string name;
+ TypeInfoPtr type;
+ bool optional;
+ int tag;
+};
+typedef IceUtil::Handle<DataMember> DataMemberPtr;
+typedef std::vector<DataMemberPtr> DataMemberList;
+
+//
+// Struct information.
+//
+class StructInfo : public TypeInfo
+{
+public:
+
+ StructInfo(const std::string&, const std::string&, zval*);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval*);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual bool usesClasses() const;
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void*, bool);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void destroy();
+
+ const std::string id;
+ const std::string name; // PHP class name
+ const DataMemberList members;
+ const zend_class_entry* zce;
+
+private:
+
+ bool _variableLength;
+ int _wireSize;
+ zval _nullMarshalValue;
+};
+typedef IceUtil::Handle<StructInfo> StructInfoPtr;
+
+//
+// Sequence information.
+//
+class SequenceInfo : public TypeInfo
+{
+public:
+
+ SequenceInfo(const std::string&, zval*);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval*);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual bool usesClasses() const;
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void*, bool);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void unmarshaled(zval*, zval*, void*);
+
+ virtual void destroy();
+
+ const std::string id;
+ const TypeInfoPtr elementType;
+
+private:
+
+ void marshalPrimitiveSequence(const PrimitiveInfoPtr&, zval*, const Ice::OutputStreamPtr&);
+ void unmarshalPrimitiveSequence(const PrimitiveInfoPtr&, const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&,
+ zval*, void*);
+};
+typedef IceUtil::Handle<SequenceInfo> SequenceInfoPtr;
+
+//
+// Dictionary information.
+//
+class DictionaryInfo : public TypeInfo
+{
+public:
+
+ DictionaryInfo(const std::string&, zval*, zval*);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval*);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual bool usesClasses() const;
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void*, bool);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void destroy();
+
+ class KeyCallback : public UnmarshalCallback
+ {
+ public:
+
+ KeyCallback();
+ ~KeyCallback();
+
+ virtual void unmarshaled(zval*, zval*, void*);
+
+ zval key;
+ };
+ typedef IceUtil::Handle<KeyCallback> KeyCallbackPtr;
+
+ class ValueCallback : public UnmarshalCallback
+ {
+ public:
+
+ ValueCallback(zval*);
+ ~ValueCallback();
+
+ virtual void unmarshaled(zval*, zval*, void*);
+
+ zval key;
+ };
+ typedef IceUtil::Handle<ValueCallback> ValueCallbackPtr;
+
+ std::string id;
+ TypeInfoPtr keyType;
+ TypeInfoPtr valueType;
+
+private:
+
+ bool _variableLength;
+ int _wireSize;
+};
+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:
+
+ ClassInfo(const std::string&);
+
+ void define(const std::string&, Ice::Int, bool, bool, zval*, zval*, zval*);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval*);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual bool usesClasses() const;
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void*, bool);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void destroy();
+
+ void printMembers(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ bool isA(const std::string&) const;
+
+ void addOperation(const std::string&, const OperationPtr&);
+ OperationPtr getOperation(const std::string&) const;
+
+ const std::string id;
+ const std::string name; // PHP class name
+ const Ice::Int compactId;
+ const bool isAbstract;
+ const bool preserve;
+ const ClassInfoPtr base;
+ const ClassInfoList interfaces;
+ const DataMemberList members;
+ const DataMemberList optionalMembers;
+ const zend_class_entry* zce;
+ bool defined;
+
+ typedef std::map<std::string, OperationPtr> OperationMap;
+ OperationMap operations;
+};
+
+//
+// Proxy information.
+//
+class ProxyInfo : public TypeInfo
+{
+public:
+
+ ProxyInfo(const std::string&);
+
+ void define(const ClassInfoPtr&);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval*);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void*, bool);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void destroy();
+
+ const std::string id;
+ const ClassInfoPtr cls;
+ bool defined;
+};
+typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr;
+
+//
+// Exception information.
+//
+class ExceptionInfo : public IceUtil::Shared
+{
+public:
+
+ zval* unmarshal(const Ice::InputStreamPtr&, const CommunicatorInfoPtr&);
+
+ void print(zval*, IceUtilInternal::Output&);
+ void printMembers(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ bool isA(const std::string&) const;
+
+ std::string id;
+ std::string name; // PHP class name
+ bool preserve;
+ ExceptionInfoPtr base;
+ DataMemberList members;
+ DataMemberList optionalMembers;
+ bool usesClasses;
+ zend_class_entry* zce;
+};
+
+ClassInfoPtr getClassInfoById(const std::string&);
+ClassInfoPtr getClassInfoByName(const std::string&);
+ExceptionInfoPtr getExceptionInfo(const std::string&);
+
+bool isUnset(zval*);
+void assignUnset(zval*);
+
+bool typesInit(INIT_FUNC_ARGS);
+bool typesRequestInit(void);
+bool typesRequestShutdown(void);
+
+//
+// ObjectWriter wraps a PHP object for marshaling.
+//
+class ObjectWriter : public Ice::ObjectWriter
+{
+public:
+
+ ObjectWriter(zval*, ObjectMap*, const ClassInfoPtr&);
+ ~ObjectWriter();
+
+ virtual void ice_preMarshal();
+
+ virtual void write(const Ice::OutputStreamPtr&) const;
+
+private:
+
+ void writeMembers(const Ice::OutputStreamPtr&, const DataMemberList&) const;
+
+ zval _object;
+ ObjectMap* _map;
+ ClassInfoPtr _info;
+};
+
+//
+// ObjectReader unmarshals the state of an Ice object.
+//
+class ObjectReader : public Ice::ObjectReader
+{
+public:
+
+ ObjectReader(zval*, const ClassInfoPtr&, const CommunicatorInfoPtr&);
+ ~ObjectReader();
+
+ virtual void ice_postUnmarshal();
+
+ virtual void read(const Ice::InputStreamPtr&);
+
+ virtual ClassInfoPtr getInfo() const;
+
+ zval* getObject() const;
+
+ Ice::SlicedDataPtr getSlicedData() const;
+
+private:
+
+ zval _object;
+ ClassInfoPtr _info;
+ CommunicatorInfoPtr _communicator;
+ Ice::SlicedDataPtr _slicedData;
+};
+
+//
+// ExceptionReader creates a PHP user exception and unmarshals it.
+//
+class ExceptionReader : public Ice::UserExceptionReader
+{
+public:
+
+ ExceptionReader(const CommunicatorInfoPtr&, const ExceptionInfoPtr&);
+ ~ExceptionReader() throw();
+
+ virtual void read(const Ice::InputStreamPtr&) const;
+ virtual bool usesClasses() const;
+
+ virtual std::string ice_name() const;
+ virtual ExceptionReader* ice_clone() const;
+ virtual void ice_throw() const;
+
+ ExceptionInfoPtr getInfo() const;
+
+ zval* getException() const;
+
+ Ice::SlicedDataPtr getSlicedData() const;
+
+private:
+
+ CommunicatorInfoPtr _communicatorInfo;
+ ExceptionInfoPtr _info;
+ zval* _ex;
+ Ice::SlicedDataPtr _slicedData;
+};
+
+class IdResolver : public Ice::CompactIdResolver
+{
+public:
+
+ IdResolver(void);
+ virtual std::string resolve(Ice::Int) const;
+};
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/php7/Util.cpp b/php/src/php7/Util.cpp
new file mode 100644
index 00000000000..193f613f303
--- /dev/null
+++ b/php/src/php7/Util.cpp
@@ -0,0 +1,972 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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 <Util.h>
+#include <IceUtil/UUID.h>
+#include <Slice/PHPUtil.h>
+#include <algorithm>
+#include <ctype.h>
+
+using namespace std;
+using namespace IcePHP;
+using namespace Slice::PHP;
+
+namespace
+{
+
+bool
+getMember(zval* zv, const string& name, zval* member, int type, bool required)
+{
+ zval* val = zend_hash_str_find(Z_OBJPROP_P(zv), STRCAST(name.c_str()), name.size());
+ if(!val)
+ {
+ if(required)
+ {
+ invalidArgument("object does not contain member `%s'", name.c_str());
+ return false;
+ }
+ }
+
+ if(val)
+ {
+ assert(Z_TYPE_P(val) == IS_INDIRECT);
+ val = Z_INDIRECT_P(val);
+ if(Z_TYPE_P(val) != type)
+ {
+ string expected = zendTypeToString(type);
+ string actual = zendTypeToString(Z_TYPE_P(val));
+ invalidArgument("expected value of type %s for member `%s' but received %s", expected.c_str(),
+ name.c_str(), actual.c_str());
+ return false;
+ }
+ ZVAL_COPY_VALUE(member, val);
+ }
+ return true;
+}
+
+void
+setStringMember(zval* obj, const string& name, const string& val)
+{
+ 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())
+ );
+}
+
+template<typename T>
+bool
+getVersion(zval* zv, T& v, const char* type)
+{
+ if(Z_TYPE_P(zv) != IS_OBJECT)
+ {
+ invalidArgument("value does not contain an object");
+ return false;
+ }
+
+ zend_class_entry* cls = idToClass(type);
+ assert(cls);
+
+ zend_class_entry* ce = Z_OBJCE_P(zv);
+ if(ce != cls)
+ {
+ invalidArgument("expected an instance of %s", ce->name);
+ return false;
+ }
+
+ zval majorVal;
+ if(!getMember(zv, "major", &majorVal, IS_LONG, true))
+ {
+ return false;
+ }
+
+ zval minorVal;
+ if(!getMember(zv, "minor", &minorVal, IS_LONG, true))
+ {
+ return false;
+ }
+
+ long m;
+ m = static_cast<long>(Z_LVAL_P(&majorVal));
+ if(m < 0 || m > 255)
+ {
+ invalidArgument("version major must be a value between 0 and 255");
+ return false;
+ }
+ v.major = static_cast<Ice::Byte>(m);
+
+ m = static_cast<long>(Z_LVAL_P(&minorVal));
+ if(m < 0 || m > 255)
+ {
+ invalidArgument("version minor must be a value between 0 and 255");
+ return false;
+ }
+ v.minor = static_cast<Ice::Byte>(m);
+
+ return true;
+}
+
+template<typename T>
+bool
+createVersion(zval* zv, const T& version, const char* type)
+{
+ zend_class_entry* cls = idToClass(type);
+ assert(cls);
+
+ if(object_init_ex(zv, cls) != SUCCESS)
+ {
+ runtimeError("unable to initialize %s", cls->name);
+ return false;
+ }
+
+ zend_update_property_long(cls, zv, const_cast<char*>("major"), sizeof("major") - 1, version.major);
+ zend_update_property_long(cls, zv, const_cast<char*>("minor"), sizeof("minor") - 1, version.minor);
+
+ return true;
+}
+
+template<typename T>
+bool
+versionToString(zval* zv, zval* s, const char* type)
+{
+ T v;
+ if(!getVersion<T>(zv, v, type))
+ {
+ return false;
+ }
+
+ try
+ {
+ string str = IceInternal::versionToString<T>(v);
+ ZVAL_STRINGL(s, STRCAST(str.c_str()), static_cast<int>(str.length()));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ return false;
+ }
+
+ return true;
+}
+
+template<typename T>
+bool
+stringToVersion(const string& s, zval* zv, const char* type)
+{
+ try
+ {
+ T v = IceInternal::stringToVersion<T>(s);
+ return createVersion<T>(zv, v, type);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex);
+ }
+
+ return false;
+}
+
+char Ice_ProtocolVersion[] = "::Ice::ProtocolVersion";
+char Ice_EncodingVersion[] = "::Ice::EncodingVersion";
+
+}
+
+void*
+IcePHP::extractWrapper(zval* zv)
+{
+ if(!zv)
+ {
+ runtimeError("method %s() must be invoked on an object", get_active_function_name());
+ return 0;
+ }
+
+ zend_object* obj = Z_OBJ_P(zv);
+ if(!obj)
+ {
+ runtimeError("no object found in %s()", get_active_function_name());
+ return 0;
+ }
+
+ return obj;
+}
+
+zend_class_entry*
+IcePHP::idToClass(const string& id)
+{
+#ifdef ICEPHP_USE_NAMESPACES
+ string cls = scopedToName(id, true);
+#else
+ string cls = scopedToName(id, false);
+#endif
+
+ return nameToClass(cls);
+}
+
+zend_class_entry*
+IcePHP::nameToClass(const string& name)
+{
+ zend_class_entry* result;
+ zend_string* s = zend_string_init(STRCAST(name.c_str()), static_cast<int>(name.length()), 0);
+ result = zend_lookup_class(s);
+ zend_string_release(s);
+ return result;
+}
+
+bool
+IcePHP::createIdentity(zval* zv, const Ice::Identity& id)
+{
+ zend_class_entry* cls = idToClass("::Ice::Identity");
+ assert(cls);
+
+ if(object_init_ex(zv, cls) != SUCCESS)
+ {
+ runtimeError("unable to initialize Ice::Identity");
+ return false;
+ }
+
+ setStringMember(zv, "name", id.name);
+ setStringMember(zv, "category", id.category);
+
+ return true;
+}
+
+bool
+IcePHP::extractIdentity(zval* zv, Ice::Identity& id)
+{
+ if(Z_TYPE_P(zv) != IS_OBJECT)
+ {
+ invalidArgument("value does not contain an object");
+ return false;
+ }
+
+ zend_class_entry* cls = idToClass("::Ice::Identity");
+ assert(cls);
+
+ zend_class_entry* ce = Z_OBJCE_P(zv);
+ if(ce != cls)
+ {
+ invalidArgument("expected an identity but received %s", ce->name);
+ return false;
+ }
+
+ //
+ // Category is optional, but name is required.
+ //
+ zval categoryVal;
+ ZVAL_UNDEF(&categoryVal);
+ zval nameVal;
+
+ if(!getMember(zv, "category", &categoryVal, IS_STRING, false) ||
+ !getMember(zv, "name", &nameVal, IS_STRING, true))
+ {
+ return false;
+ }
+
+ id.name = Z_STRVAL_P(&nameVal);
+
+ if(!Z_ISUNDEF(categoryVal))
+ {
+ id.category = Z_STRVAL_P(&categoryVal);
+ }
+ else
+ {
+ id.category = "";
+ }
+
+ return true;
+}
+
+bool
+IcePHP::createStringMap(zval* zv, const map<string, string>& ctx)
+{
+ array_init(zv);
+
+ for(map<string, string>::const_iterator p = ctx.begin(); p != ctx.end(); ++p)
+ {
+ if(add_assoc_stringl_ex(zv,
+ const_cast<char*>(p->first.c_str()),
+ static_cast<uint>(p->first.length()),
+ const_cast<char*>(p->second.c_str()),
+ static_cast<uint>(p->second.length())) == FAILURE)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+IcePHP::extractStringMap(zval* zv, map<string, string>& ctx)
+{
+ if(Z_TYPE_P(zv) != IS_ARRAY)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected an associative array but received %s", s.c_str());
+ return false;
+ }
+
+ HashTable* arr = Z_ARRVAL_P(zv);
+ zend_ulong num_key;
+ zend_string* key;
+ zval* val;
+ ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, key, val)
+ {
+ if(!key)
+ {
+ invalidArgument("array key must be a string");
+ return false;
+ }
+
+ if(Z_TYPE_P(val) != IS_STRING)
+ {
+ invalidArgument("array value must be a string");
+ return false;
+ }
+
+ ctx[key->val] = Z_STRVAL_P(val);
+ (void)num_key; // Avoids error from older versions of GCC about unused variable num_key.
+ }
+ ZEND_HASH_FOREACH_END();
+
+ return true;
+}
+
+bool
+IcePHP::createStringArray(zval* zv, const Ice::StringSeq& seq)
+{
+ 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()), static_cast<uint>(p->length())) == FAILURE)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+IcePHP::extractStringArray(zval* zv, Ice::StringSeq& seq)
+{
+ if(Z_TYPE_P(zv) != IS_ARRAY)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected an array of strings but received %s", s.c_str());
+ return false;
+ }
+
+ HashTable* arr = Z_ARRVAL_P(zv);
+ zval* val;
+ ZEND_HASH_FOREACH_VAL(arr, val)
+ {
+ if(Z_TYPE_P(val) != IS_STRING)
+ {
+ invalidArgument("array element must be a string");
+ return false;
+ }
+
+ string s(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ seq.push_back(s);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ return true;
+}
+
+bool
+IcePHP::createProtocolVersion(zval* zv, const Ice::ProtocolVersion& v)
+{
+ return createVersion<Ice::ProtocolVersion>(zv, v, Ice_ProtocolVersion);
+}
+
+bool
+IcePHP::createEncodingVersion(zval* zv, const Ice::EncodingVersion& v)
+{
+ return createVersion<Ice::EncodingVersion>(zv, v, Ice_EncodingVersion);
+}
+
+bool
+IcePHP::extractEncodingVersion(zval* zv, Ice::EncodingVersion& v)
+{
+ return getVersion<Ice::EncodingVersion>(zv, v, Ice_EncodingVersion);
+}
+
+static bool
+convertLocalException(const Ice::LocalException& ex, zval* zex)
+{
+ zend_class_entry* cls = Z_OBJCE_P(zex);
+ assert(cls);
+
+ //
+ // Transfer data members from Ice exception to PHP object.
+ //
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const Ice::InitializationException& e)
+ {
+ setStringMember(zex, "reason", e.reason);
+ }
+ catch(const Ice::PluginInitializationException& e)
+ {
+ setStringMember(zex, "reason", e.reason);
+ }
+ catch(const Ice::AlreadyRegisteredException& e)
+ {
+ setStringMember(zex, "kindOfObject", e.kindOfObject);
+ setStringMember(zex, "id", e.id);
+ }
+ catch(const Ice::NotRegisteredException& e)
+ {
+ setStringMember(zex, "kindOfObject", e.kindOfObject);
+ setStringMember(zex, "id", e.id);
+ }
+ catch(const Ice::TwowayOnlyException& e)
+ {
+ setStringMember(zex, "operation", e.operation);
+ }
+ catch(const Ice::UnknownException& e)
+ {
+ setStringMember(zex, "unknown", e.unknown);
+ }
+ catch(const Ice::ObjectAdapterDeactivatedException& e)
+ {
+ setStringMember(zex, "name", e.name);
+ }
+ catch(const Ice::ObjectAdapterIdInUseException& e)
+ {
+ setStringMember(zex, "id", e.id);
+ }
+ catch(const Ice::NoEndpointException& e)
+ {
+ setStringMember(zex, "proxy", e.proxy);
+ }
+ catch(const Ice::EndpointParseException& e)
+ {
+ setStringMember(zex, "str", e.str);
+ }
+ catch(const Ice::IdentityParseException& e)
+ {
+ setStringMember(zex, "str", e.str);
+ }
+ catch(const Ice::ProxyParseException& e)
+ {
+ setStringMember(zex, "str", e.str);
+ }
+ catch(const Ice::IllegalIdentityException& e)
+ {
+ zval id;
+ if(!createIdentity(&id, e.id))
+ {
+ zval_ptr_dtor(&id);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("id"), sizeof("id") - 1, &id);
+ zval_ptr_dtor(&id);
+ }
+ catch(const Ice::RequestFailedException& e)
+ {
+ zval id;
+ if(!createIdentity(&id, e.id))
+ {
+ zval_ptr_dtor(&id);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("id"), sizeof("id") - 1, &id);
+ zval_ptr_dtor(&id);
+ setStringMember(zex, "facet", e.facet);
+ setStringMember(zex, "operation", e.operation);
+ }
+ catch(const Ice::FileException& e)
+ {
+ zend_update_property_long(cls, zex, const_cast<char*>("error"), sizeof("error") - 1, e.error);
+ setStringMember(zex, "path", e.path);
+ }
+ catch(const Ice::SyscallException& e) // This must appear after all subclasses of SyscallException.
+ {
+ zend_update_property_long(cls, zex, const_cast<char*>("error"), sizeof("error") - 1, e.error);
+ }
+ catch(const Ice::DNSException& e)
+ {
+ zend_update_property_long(cls, zex, const_cast<char*>("error"), sizeof("error") - 1, e.error);
+ setStringMember(zex, "host", e.host);
+ }
+ catch(const Ice::UnsupportedProtocolException& e)
+ {
+ zval v;
+ if(!createProtocolVersion(&v, e.bad))
+ {
+ zval_ptr_dtor(&v);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("bad"), sizeof("bad") - 1, &v);
+ zval_ptr_dtor(&v);
+
+ if(!createProtocolVersion(&v, e.supported))
+ {
+ zval_ptr_dtor(&v);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("supported"), sizeof("supported") - 1, &v);
+ zval_ptr_dtor(&v);
+ }
+ catch(const Ice::UnsupportedEncodingException& e)
+ {
+ zval v;
+ if(!createEncodingVersion(&v, e.bad))
+ {
+ zval_ptr_dtor(&v);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("bad"), sizeof("bad") - 1, &v);
+ zval_ptr_dtor(&v);
+
+ if(!createEncodingVersion(&v, e.supported))
+ {
+ zval_ptr_dtor(&v);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("supported"), sizeof("supported") - 1, &v);
+ zval_ptr_dtor(&v);
+ }
+ catch(const Ice::NoObjectFactoryException& e)
+ {
+ setStringMember(zex, "reason", e.reason);
+ setStringMember(zex, "type", e.type);
+ }
+ catch(const Ice::UnexpectedObjectException& e)
+ {
+ setStringMember(zex, "reason", e.reason);
+ setStringMember(zex, "type", e.type);
+ setStringMember(zex, "expectedType", e.expectedType);
+ }
+ catch(const Ice::ProtocolException& e) // This must appear after all subclasses of ProtocolException.
+ {
+ setStringMember(zex, "reason", e.reason);
+ }
+ catch(const Ice::FeatureNotSupportedException& e)
+ {
+ setStringMember(zex, "unsupportedFeature", e.unsupportedFeature);
+ }
+ catch(const Ice::SecurityException& e)
+ {
+ setStringMember(zex, "reason", e.reason);
+ }
+ catch(const Ice::LocalException&)
+ {
+ //
+ // Nothing to do.
+ //
+ }
+
+ return true;
+}
+
+void
+IcePHP::convertException(zval* zex, const Ice::Exception& ex)
+{
+ ZVAL_UNDEF(zex);
+
+ ostringstream ostr;
+ ostr << ex;
+ string str = ostr.str();
+
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const Ice::LocalException& e)
+ {
+ zend_class_entry* cls = idToClass(e.ice_name());
+ if(cls)
+ {
+ if(object_init_ex(zex, cls) != SUCCESS)
+ {
+ runtimeError("unable to create exception %s", cls->name);
+ return;
+ }
+ if(!convertLocalException(e, zex))
+ {
+ return;
+ }
+ }
+ else
+ {
+ cls = idToClass("Ice::UnknownLocalException");
+ assert(cls);
+ if(object_init_ex(zex, cls) != SUCCESS)
+ {
+ runtimeError("unable to create exception %s", cls->name);
+ return;
+ }
+ setStringMember(zex, "unknown", str);
+ }
+ }
+ catch(const Ice::UserException&)
+ {
+ zend_class_entry* cls = idToClass("Ice::UnknownUserException");
+ assert(cls);
+ if(object_init_ex(zex, cls) != SUCCESS)
+ {
+ runtimeError("unable to create exception %s", cls->name);
+ return;
+ }
+ setStringMember(zex, "unknown", str);
+ }
+ catch(const Ice::Exception&)
+ {
+ zend_class_entry* cls = idToClass("Ice::UnknownException");
+ assert(cls);
+ if(object_init_ex(zex, cls) != SUCCESS)
+ {
+ runtimeError("unable to create exception %s", cls->name);
+ return;
+ }
+ setStringMember(zex, "unknown", str);
+ }
+
+ return;
+}
+
+void
+IcePHP::throwException(const Ice::Exception& ex)
+{
+ zval zex;
+ convertException(&zex, ex);
+ if(!Z_ISUNDEF(zex))
+ {
+ zend_throw_exception_object(&zex);
+ }
+}
+
+std::string
+IcePHP::zendTypeToString(int type)
+{
+ string result;
+
+ switch(type)
+ {
+ case IS_NULL:
+ result = "null";
+ break;
+
+ case IS_LONG:
+ result = "long";
+ break;
+
+ case IS_DOUBLE:
+ result = "double";
+ break;
+
+ case IS_STRING:
+ result = "string";
+ break;
+
+ case IS_ARRAY:
+ result = "array";
+ break;
+
+ case IS_OBJECT:
+ result = "object";
+ break;
+
+ case IS_TRUE:
+ case IS_FALSE:
+ result = "bool";
+ break;
+
+ default:
+ result = "unknown";
+ break;
+ }
+
+ return result;
+}
+
+static void
+throwError(const string& name, const string& msg)
+{
+ if(EG(exception))
+ {
+ return;
+ }
+ zval ex;
+ // AutoDestroy destroy(&ex);
+
+ zend_class_entry* cls;
+ {
+ zend_class_entry* p;
+ zend_string* s = zend_string_init(STRCAST(name.c_str()), static_cast<int>(name.size()), 0);
+ p = zend_lookup_class(s);
+ zend_string_release(s);
+ assert(p);
+ cls = p;
+ }
+ if(object_init_ex(&ex, cls) == FAILURE)
+ {
+ assert(false);
+ }
+
+ //
+ // Invoke constructor.
+ //
+ if(!invokeMethod(&ex, ZEND_CONSTRUCTOR_FUNC_NAME, msg))
+ {
+ assert(false);
+ }
+
+ zend_throw_exception_object(&ex);
+ // destroy.release();
+}
+
+void
+IcePHP::runtimeError(const char* fmt, ...)
+{
+ va_list args;
+ char msg[1024];
+
+ va_start(args, fmt);
+
+#if defined(_MSC_VER)
+ vsprintf_s(msg, fmt, args);
+#else
+ vsprintf(msg, fmt, args);
+#endif
+
+ va_end(args);
+
+ throwError("RuntimeException", msg);
+}
+
+void
+IcePHP::invalidArgument(const char* fmt, ...)
+{
+ va_list args;
+ char msg[1024];
+
+ va_start(args, fmt);
+
+#if defined(_MSC_VER)
+ vsprintf_s(msg, fmt, args);
+#else
+ vsprintf(msg, fmt, args);
+#endif
+
+ va_end(args);
+
+ throwError("InvalidArgumentException", msg);
+}
+
+static bool
+invokeMethodHelper(zval* obj, const string& name, zval* param)
+{
+ assert(zend_hash_str_exists(&Z_OBJCE_P(obj)->function_table, STRCAST(name.c_str()), name.size()));
+ zval ret, method;
+ ZVAL_STRING(&method, STRCAST(name.c_str()));
+ uint32_t numParams = param ? 1 : 0;
+ // zval** params = param ? &param : 0;
+ int status = 0;
+ zend_try
+ {
+ status = call_user_function(0, obj, &method, &ret, numParams, param);
+ }
+ zend_catch
+ {
+ status = FAILURE;
+ }
+ zend_end_try();
+ zval_dtor(&method);
+ zval_dtor(&ret);
+ if(status == FAILURE || EG(exception))
+ {
+ return false;
+ }
+ return true;
+}
+
+bool
+IcePHP::invokeMethod(zval* obj, const string& name)
+{
+ return invokeMethodHelper(obj, name, 0);
+}
+
+bool
+IcePHP::invokeMethod(zval* obj, const string& name, const string& arg)
+{
+ zval param;
+ ZVAL_STRINGL(&param, STRCAST(arg.c_str()), static_cast<int>(arg.size()));
+ return invokeMethodHelper(obj, name, &param);
+}
+
+bool
+IcePHP::checkClass(zend_class_entry* ce, zend_class_entry* base)
+{
+ while(ce)
+ {
+ if(ce == base)
+ {
+ return true;
+ }
+
+ for(zend_ulong i = 0; i < ce->num_interfaces; ++i)
+ {
+ if(checkClass(ce->interfaces[i], base))
+ {
+ return true;
+ }
+ }
+
+ ce = ce->parent;
+ }
+
+ return false;
+}
+
+ZEND_FUNCTION(Ice_stringVersion)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_STRINGL(STRCAST(ICE_STRING_VERSION), static_cast<int>(strlen(ICE_STRING_VERSION)));
+}
+
+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()), static_cast<int>(uuid.size()));
+}
+
+ZEND_FUNCTION(Ice_currentProtocol)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ if(!createProtocolVersion(return_value, Ice::currentProtocol))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_currentProtocolEncoding)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ if(!createEncodingVersion(return_value, Ice::currentProtocolEncoding))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_currentEncoding)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ if(!createEncodingVersion(return_value, Ice::currentEncoding))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_protocolVersionToString)
+{
+ zend_class_entry* versionClass = idToClass(Ice_ProtocolVersion);
+ assert(versionClass);
+
+ zval zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O"), &zv, versionClass) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ if(!versionToString<Ice::ProtocolVersion>(&zv, return_value, Ice_ProtocolVersion))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_stringToProtocolVersion)
+{
+ char* str;
+ size_t strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &str, &strLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ string s(str, strLen);
+
+ if(!stringToVersion<Ice::ProtocolVersion>(s, return_value, Ice_ProtocolVersion))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_encodingVersionToString)
+{
+ zend_class_entry* versionClass = idToClass(Ice_EncodingVersion);
+ assert(versionClass);
+
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("O"), &zv, versionClass) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ if(!versionToString<Ice::EncodingVersion>(zv, return_value, Ice_EncodingVersion))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_stringToEncodingVersion)
+{
+ char* str;
+ size_t strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &str, &strLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ string s(str, strLen);
+
+ if(!stringToVersion<Ice::EncodingVersion>(s, return_value, Ice_EncodingVersion))
+ {
+ RETURN_NULL();
+ }
+}
diff --git a/php/src/php7/Util.h b/php/src/php7/Util.h
new file mode 100644
index 00000000000..63384679a86
--- /dev/null
+++ b/php/src/php7/Util.h
@@ -0,0 +1,188 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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_UTIL_H
+#define ICEPHP_UTIL_H
+
+#include <Config.h>
+
+//
+// Global functions.
+//
+extern "C"
+{
+ZEND_FUNCTION(Ice_stringVersion);
+ZEND_FUNCTION(Ice_intVersion);
+ZEND_FUNCTION(Ice_generateUUID);
+ZEND_FUNCTION(Ice_currentProtocol);
+ZEND_FUNCTION(Ice_currentProtocolEncoding);
+ZEND_FUNCTION(Ice_currentEncoding);
+ZEND_FUNCTION(Ice_protocolVersionToString);
+ZEND_FUNCTION(Ice_stringToProtocolVersion);
+ZEND_FUNCTION(Ice_encodingVersionToString);
+ZEND_FUNCTION(Ice_stringToEncodingVersion);
+}
+
+namespace IcePHP
+{
+
+void* createWrapper(zend_class_entry*, size_t);
+void* extractWrapper(zval*);
+
+//
+// Wraps a C++ pointer inside a PHP object.
+//
+template<typename T>
+struct Wrapper
+{
+ T* ptr;
+
+ static Wrapper<T>* create(zend_class_entry* ce)
+ {
+ Wrapper<T>* w = static_cast<Wrapper<T>*>(ecalloc(1, sizeof(Wrapper<T>) + zend_object_properties_size(ce)));
+
+ zend_object_std_init(&w->zobj, ce);
+ object_properties_init(&w->zobj, ce);
+
+ w->ptr = 0;
+ return w;
+ }
+
+ static Wrapper<T>* extract(zval* zv)
+ {
+ return reinterpret_cast<Wrapper<T>*>(reinterpret_cast<char *>(extractWrapper(zv)) - XtOffsetOf(Wrapper<T>, zobj));
+ }
+
+ static Wrapper<T>* fetch(zend_object* object)
+ {
+ return reinterpret_cast<Wrapper<T>*>(reinterpret_cast<char *>(object) - XtOffsetOf(Wrapper<T>, zobj));
+ }
+
+ static T value(zval* zv)
+ {
+ Wrapper<T>* w = extract(zv);
+ if(w)
+ {
+ return *w->ptr;
+ }
+ return 0;
+ }
+
+ // This must be last element in the struct
+ zend_object zobj;
+};
+
+zend_class_entry* idToClass(const std::string&);
+zend_class_entry* nameToClass(const std::string&);
+
+bool createIdentity(zval*, const Ice::Identity&);
+bool extractIdentity(zval*, Ice::Identity&);
+
+bool createStringMap(zval*, const std::map<std::string, std::string>&);
+bool extractStringMap(zval*, std::map<std::string, std::string>&);
+
+bool createStringArray(zval*, const Ice::StringSeq&);
+bool extractStringArray(zval*, Ice::StringSeq&);
+
+//
+// Create a PHP instance of Ice_ProtocolVersion.
+//
+bool createProtocolVersion(zval*, const Ice::ProtocolVersion&);
+
+//
+// Create a PHP instance of Ice_EncodingVersion.
+//
+bool createEncodingVersion(zval*, const Ice::EncodingVersion&);
+
+//
+// Extracts the members of an encoding version.
+//
+bool extractEncodingVersion(zval*, Ice::EncodingVersion&);
+
+//
+// Convert the given exception into its PHP equivalent.
+//
+void convertException(zval*, const Ice::Exception&);
+
+//
+// Convert the exception and "throw" it.
+//
+void throwException(const Ice::Exception&);
+
+//
+// Convert a Zend type (e.g., IS_BOOL, etc.) to a string for use in error messages.
+//
+std::string zendTypeToString(int);
+
+//
+// Raise RuntimeException with the given message.
+//
+void runtimeError(const char*, ...);
+
+//
+// Raise InvalidArgumentException with the given message.
+//
+void invalidArgument(const char*, ...);
+
+//
+// Invoke a method on a PHP object. The method must not take any arguments.
+//
+bool invokeMethod(zval*, const std::string&);
+
+//
+// Invoke a method on a PHP object. The method must take one string argument.
+//
+bool invokeMethod(zval*, const std::string&, const std::string&);
+
+//
+// Check inheritance.
+//
+bool checkClass(zend_class_entry*, zend_class_entry*);
+
+//
+// Exception-safe efree.
+//
+class AutoEfree
+{
+public:
+ AutoEfree(void* p) : _p(p) {}
+ ~AutoEfree() { efree(_p); }
+
+private:
+ void* _p;
+};
+
+//
+// Exception-safe zval destroy.
+//
+class AutoDestroy
+{
+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;
+};
+
+class AutoReleaseString
+{
+public:
+ AutoReleaseString(zend_string* s) : _s(s) {}
+ ~AutoReleaseString() { if(_s) zend_string_release(_s); }
+
+private:
+ zend_string* _s;
+};
+
+} // End of namespace IcePHP
+
+#endif