summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2009-06-23 17:47:58 -0700
committerMark Spruiell <mes@zeroc.com>2009-06-23 17:47:58 -0700
commita2e794a1366fcd71f04496c206869ffa158547ac (patch)
tree4c9d6554f3dc658aeaa76892aeecfc3d7eb56b61
parentAdd x64 configurations to C++ projects (diff)
downloadice-a2e794a1366fcd71f04496c206869ffa158547ac.tar.bz2
ice-a2e794a1366fcd71f04496c206869ffa158547ac.tar.xz
ice-a2e794a1366fcd71f04496c206869ffa158547ac.zip
PHP changes:
- static translation - more traditional language mapping (multiple communicators, etc.) - support for registered (persistent) communicators - support for PHP namespaces (PHP 5.3 or later)
-rw-r--r--CHANGES53
-rw-r--r--RELEASE_NOTES360
-rw-r--r--cpp/include/Slice/PHPUtil.h50
-rw-r--r--cpp/src/Makefile1
-rw-r--r--cpp/src/Makefile.mak1
-rw-r--r--cpp/src/Slice/.depend1
-rw-r--r--cpp/src/Slice/Makefile1
-rw-r--r--cpp/src/Slice/Makefile.mak1
-rw-r--r--cpp/src/Slice/PHPUtil.cpp155
-rw-r--r--cpp/src/slice2php/.depend1
-rw-r--r--cpp/src/slice2php/Main.cpp1677
-rw-r--r--cpp/src/slice2php/Makefile31
-rw-r--r--cpp/src/slice2php/Makefile.mak60
-rw-r--r--cpp/src/slice2php/Slice2PHP.rc34
-rw-r--r--distribution/src/rpm/ice.spec41
-rw-r--r--distribution/src/unix/README.Linux-RPM23
-rw-r--r--distribution/src/windows/vc60/doc/README.txt72
-rw-r--r--java/src/IceSSL/PasswordCallback.java2
-rw-r--r--php/INSTALL103
-rw-r--r--php/Makefile8
-rw-r--r--php/Makefile.mak2
-rwxr-xr-xphp/allTests.py1
-rw-r--r--php/bin/.gitignore1
-rw-r--r--php/config/Make.rules43
-rw-r--r--php/config/Make.rules.mak60
-rw-r--r--php/demo/Glacier2/Makefile21
-rw-r--r--php/demo/Glacier2/Makefile.mak19
-rw-r--r--php/demo/Glacier2/hello/.gitignore1
-rw-r--r--php/demo/Glacier2/hello/Hello.ice24
-rw-r--r--php/demo/Glacier2/hello/Makefile22
-rw-r--r--php/demo/Glacier2/hello/Makefile.mak22
-rw-r--r--php/demo/Glacier2/hello/README90
-rw-r--r--php/demo/Glacier2/hello/config.glacier223
-rw-r--r--php/demo/Glacier2/hello/login.php105
-rw-r--r--php/demo/Glacier2/hello/session.php99
-rw-r--r--php/demo/Ice/Makefile21
-rw-r--r--php/demo/Ice/Makefile.mak19
-rw-r--r--php/demo/Ice/hello/.gitignore1
-rw-r--r--php/demo/Ice/hello/Makefile22
-rw-r--r--php/demo/Ice/hello/Makefile.mak22
-rw-r--r--php/demo/Ice/hello/README39
-rw-r--r--php/demo/Ice/hello/client.php (renamed from php/demo/Ice/hello/hello.php)9
-rw-r--r--php/demo/Ice/value/.gitignore1
-rw-r--r--php/demo/Ice/value/Client.php11
-rw-r--r--php/demo/Ice/value/Client_ns.php191
-rw-r--r--php/demo/Ice/value/Makefile22
-rw-r--r--php/demo/Ice/value/Makefile.mak22
-rw-r--r--php/demo/Ice/value/php.ini19
-rw-r--r--php/demo/Makefile21
-rw-r--r--php/demo/Makefile.mak19
-rw-r--r--php/lib/.gitignore7
-rw-r--r--php/lib/Glacier2.php13
-rw-r--r--php/lib/Ice.php177
-rw-r--r--php/lib/IceBox.php12
-rw-r--r--php/lib/IceGrid.php19
-rw-r--r--php/lib/IcePatch2.php12
-rw-r--r--php/lib/IceStorm.php12
-rw-r--r--php/lib/Ice_ns.php186
-rw-r--r--php/lib/Makefile142
-rw-r--r--php/lib/Makefile.mak123
-rw-r--r--php/src/IcePHP/.depend10
-rw-r--r--php/src/IcePHP/Communicator.cpp1651
-rw-r--r--php/src/IcePHP/Communicator.h88
-rw-r--r--php/src/IcePHP/Config.h42
-rw-r--r--php/src/IcePHP/Connection.cpp304
-rw-r--r--php/src/IcePHP/Connection.h30
-rw-r--r--php/src/IcePHP/Endpoint.cpp500
-rw-r--r--php/src/IcePHP/Endpoint.h30
-rw-r--r--php/src/IcePHP/Init.cpp96
-rw-r--r--php/src/IcePHP/Logger.cpp278
-rw-r--r--php/src/IcePHP/Logger.h30
-rw-r--r--php/src/IcePHP/Makefile14
-rw-r--r--php/src/IcePHP/Makefile.mak17
-rw-r--r--php/src/IcePHP/Marshal.cpp2305
-rw-r--r--php/src/IcePHP/Marshal.h83
-rw-r--r--php/src/IcePHP/Operation.cpp711
-rw-r--r--php/src/IcePHP/Operation.h40
-rw-r--r--php/src/IcePHP/Profile.cpp1617
-rw-r--r--php/src/IcePHP/Profile.h74
-rw-r--r--php/src/IcePHP/Properties.cpp671
-rw-r--r--php/src/IcePHP/Properties.h48
-rw-r--r--php/src/IcePHP/Proxy.cpp1994
-rw-r--r--php/src/IcePHP/Proxy.h146
-rw-r--r--php/src/IcePHP/Types.cpp2877
-rw-r--r--php/src/IcePHP/Types.h465
-rw-r--r--php/src/IcePHP/Util.cpp874
-rw-r--r--php/src/IcePHP/Util.h121
-rw-r--r--php/test/Ice/Makefile21
-rw-r--r--php/test/Ice/Makefile.mak19
-rw-r--r--php/test/Ice/binding/.gitignore1
-rw-r--r--php/test/Ice/binding/Client.php16
-rw-r--r--php/test/Ice/binding/Makefile22
-rw-r--r--php/test/Ice/binding/Makefile.mak22
-rw-r--r--php/test/Ice/binding/php.ini2
-rw-r--r--php/test/Ice/checksum/.gitignore2
-rw-r--r--php/test/Ice/checksum/CTypes.ice440
-rwxr-xr-xphp/test/Ice/checksum/Client.php95
-rw-r--r--php/test/Ice/checksum/Makefile22
-rw-r--r--php/test/Ice/checksum/Makefile.mak22
-rw-r--r--php/test/Ice/checksum/Test.ice27
-rwxr-xr-xphp/test/Ice/checksum/run.py25
-rw-r--r--php/test/Ice/exceptions/.gitignore1
-rw-r--r--php/test/Ice/exceptions/Client.php16
-rw-r--r--php/test/Ice/exceptions/Makefile22
-rw-r--r--php/test/Ice/exceptions/Makefile.mak22
-rw-r--r--php/test/Ice/exceptions/php.ini2
-rw-r--r--php/test/Ice/facets/.gitignore1
-rw-r--r--php/test/Ice/facets/Client.php14
-rw-r--r--php/test/Ice/facets/Makefile22
-rw-r--r--php/test/Ice/facets/Makefile.mak22
-rw-r--r--php/test/Ice/facets/php.ini2
-rw-r--r--php/test/Ice/inheritance/.gitignore1
-rw-r--r--php/test/Ice/inheritance/Client.php14
-rw-r--r--php/test/Ice/inheritance/Makefile22
-rw-r--r--php/test/Ice/inheritance/Makefile.mak22
-rw-r--r--php/test/Ice/inheritance/php.ini2
-rw-r--r--php/test/Ice/objects/.gitignore1
-rw-r--r--php/test/Ice/objects/Client.php47
-rw-r--r--php/test/Ice/objects/Makefile22
-rw-r--r--php/test/Ice/objects/Makefile.mak22
-rw-r--r--php/test/Ice/objects/php.ini2
-rw-r--r--php/test/Ice/operations/.gitignore1
-rw-r--r--php/test/Ice/operations/Client.php28
-rw-r--r--php/test/Ice/operations/Makefile22
-rw-r--r--php/test/Ice/operations/Makefile.mak22
-rw-r--r--php/test/Ice/operations/php.ini2
-rw-r--r--php/test/Ice/proxy/.gitignore1
-rw-r--r--php/test/Ice/proxy/Client.php282
-rw-r--r--php/test/Ice/proxy/Makefile22
-rw-r--r--php/test/Ice/proxy/Makefile.mak22
-rw-r--r--php/test/Ice/proxy/Test.ice8
-rw-r--r--php/test/Ice/proxy/php.ini4
-rw-r--r--php/test/Ice/slicing/Makefile21
-rw-r--r--php/test/Ice/slicing/Makefile.mak19
-rw-r--r--php/test/Ice/slicing/exceptions/.gitignore1
-rw-r--r--php/test/Ice/slicing/exceptions/Client.php14
-rw-r--r--php/test/Ice/slicing/exceptions/Makefile22
-rw-r--r--php/test/Ice/slicing/exceptions/Makefile.mak22
-rw-r--r--php/test/Ice/slicing/exceptions/php.ini2
-rw-r--r--php/test/Ice/slicing/objects/.gitignore3
-rw-r--r--php/test/Ice/slicing/objects/Client.php15
-rw-r--r--php/test/Ice/slicing/objects/Makefile22
-rw-r--r--php/test/Ice/slicing/objects/Makefile.mak22
-rw-r--r--php/test/Ice/slicing/objects/php.ini2
-rw-r--r--php/test/Makefile21
-rw-r--r--php/test/Makefile.mak19
-rw-r--r--php/test/Slice/Makefile21
-rw-r--r--php/test/Slice/Makefile.mak19
-rw-r--r--php/test/Slice/keyword/.gitignore1
-rw-r--r--php/test/Slice/keyword/Client.php27
-rw-r--r--php/test/Slice/keyword/Makefile22
-rw-r--r--php/test/Slice/keyword/Makefile.mak22
-rw-r--r--php/test/Slice/keyword/php.ini2
-rw-r--r--py/bin/.gitignore1
-rw-r--r--rb/bin/.gitignore1
-rw-r--r--rb/ruby/Ice.rb2
-rwxr-xr-xscripts/TestUtil.py43
157 files changed, 14053 insertions, 7208 deletions
diff --git a/CHANGES b/CHANGES
index 48acb5e3684..ea652a5db25 100644
--- a/CHANGES
+++ b/CHANGES
@@ -105,7 +105,7 @@ noted.
prepended by '--', warnings by '-!' and errors by '!!'.
- All permutations of Ice.initialize() will now recognize the value of
- ICE_CONFIG envirnment variable as long as an already created
+ the ICE_CONFIG environment variable as long as an already created
property set has not been passed in the InitializationData or an
Ice.Config argument/property has not been set. Previously if the
no argument version of initialize was used, ICE_CONFIG was ignored
@@ -180,9 +180,9 @@ Java Changes
source and writes them through to the corresponding APIs in the
generated code.
-- Ice.jar and Freeze.jar now include source files. This allows
- IDEs such Eclipse to browse the Ice source code and to display
- javadoc comments.
+- Ice.jar and Freeze.jar now include source files. This allows IDEs
+ such as Eclipse to browse the Ice source code and to display javadoc
+ comments.
- The following APIs are deprecated and will be removed in a future
release.
@@ -269,6 +269,51 @@ Ruby Changes
PHP Changes
===========
+- Added slice2php and removed dynamic Slice translation.
+
+- Added support for PHP namespaces (requires PHP 5.3 or later).
+
+- Added ability to create and destroy communicators. Use the function
+ Ice_initialize (\Ice\initialize) to create a communicator. By
+ default, all communicators created during a page request are
+ destroyed automatically at the end of the request.
+
+- Added ability to register a communicator for use in a subsequent
+ page request. Three new functions are provided:
+
+ * Ice_register (\Ice\register)
+ * Ice_unregister (\Ice\unregister)
+ * Ice_find (\Ice\find)
+
+- Added a demo (in Glacier2/hello) that shows how to register and
+ use the same communicator instance for multiple page requests in a
+ PHP session.
+
+- Added support for all Slice local exceptions.
+
+- The INI settings are now used to configure property sets that a
+ script can use to initialize a communicator. The ice.slice directive
+ is no longer supported.
+
+- Added the function Ice_createProperties().
+
+- Now generating minimal proxy classes to simplify downcasting.
+
+- Removed the "$ICE" global variable.
+
+- Removed the following methods:
+
+ $ICE->setProperty()
+ $ICE->getProperty()
+
+- Removed the following functions:
+
+ Ice_stringToIdentity()
+ Ice_identityToString()
+ Ice_loadProfile()
+ Ice_loadProfileWithArgs()
+ Ice_dumpProfile()
+
======================================================================
Changes since version 3.3.0
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 41fb6d3c815..3b0064712a8 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -26,6 +26,7 @@ Table of Contents
2. Upgrading your application from Ice 3.3
- Java language mapping changes
- Changes to the Java API for Freeze maps
+ - PHP changes
3. Upgrading your application from Ice 3.2 or earlier releases
- Compatibility
- Migrating IceStorm databases
@@ -611,11 +612,366 @@ Note that, given the uncertain nature of Java finalizers, it is quite
likely that the remaining finalizers will not be executed.
+PHP changes
+===========
+The Ice extension for PHP has undergone many changes in this release.
+The subsections below describe these changes in detail.
-Old
-===
+Static translation
+------------------
+
+In prior releases, Slice files were deployed with the application and
+loaded at Web server startup by the Ice extension. Before each page
+request, the extension directed the PHP interpreter to parse the code
+that was generated from the Slice definitions.
+
+In this release, Slice files must be translated using a new compiler
+(slice2php). This change offers several advantages:
+
+* Applications may have more opportunities to improve performance
+ through the use of opcode caching.
+
+* It is no longer necessary to restart the Web server when you make
+ changes to your Slice definitions, which is especially useful during
+ development.
+
+* Errors in your Slice files can now be discovered in your development
+ environment, rather than waiting until the Web server reports a
+ failure and then reviewing the server log to determine the problem.
+
+* The development process becomes simpler because you can easily
+ examine the generated code if you have questions about the API or
+ language mapping rules.
+
+* PHP scripts can now use all of the Ice local exceptions. In prior
+ releases, only a subset of the local exception types were available,
+ and all others were mapped to Ice_UnknownLocalException. See the
+ section "Local exceptions" below for more information.
+
+All of the Slice files for Ice and Ice services are translated during
+an Ice build and available for inclusion in your application. At a
+minimum, you must include the file Ice.php:
+
+// PHP
+require 'Ice.php';
+
+Ice.php contains definitions for core Ice types and includes a minimal
+set of generated files. To use an Ice service such as IceStorm,
+include the appropriate generated file:
+
+// PHP
+require 'Ice.php';
+require 'IceStorm/IceStorm.php';
+
+
+Deployment
+----------
+
+With the transition to static code generation, you no longer need to
+deploy Slice files with your application. Instead, you will need to
+deploy the PHP code generated from your Slice definitions, along with
+Ice.php, the generated code for the Ice core, and the generated code
+for any Ice services your application might use.
+
+
+Communicators
+-------------
+
+In prior releases, each PHP page request could access a single Ice
+communicator via the $ICE global variable. The configuration of this
+communicator was derived from the profile that the script loaded via
+the Ice_loadProfile function. The communicator was created on demand
+when $ICE was first used and destroyed automatically at the end of the
+page request.
+
+In this release, a PHP script must create its own communicator using
+an API that is similar to other Ice language mappings:
+
+ function Ice_initialize()
+ function Ice_initialize($args)
+ function Ice_initialize($initData)
+ function Ice_initialize($args, $initData)
+
+Ice_initialize creates a new communicator using the configuration
+provided in the optional arguments. $args is an array of strings
+representing command-line options, and $initData is an instance of
+Ice_InitializationData.
+
+An application that requires no configuration can initialize a
+communicator as follows:
+
+// PHP
+$communicator = Ice_initialize();
+
+More elaborate configuration scenarios are described in the section
+"Configuration" below.
+
+A script may optionally destroy its communicator:
+
+// PHP
+$communicator->destroy();
+
+At the completion of a page request, Ice by default automatically
+destroys any communicator that was not explicitly destroyed.
+
+
+Registered communicators
+------------------------
+
+Applications may benefit from the ability to use a communicator
+instance in multiple page requests. Reusing a communicator allows the
+application to minimize the overhead associated with the communicator
+lifecycle, including such activities as opening and closing
+connections to Ice servers.
+
+This release includes new APIs for registering a communicator in order
+to prevent Ice from destroying it automatically at the completion of a
+page request. For example, a session-based application can create a
+communicator, establish a Glacier2 session, and register the
+communicator. In subsequent page requests, the PHP session can
+retrieve its communicator instance and continue using the Glacier2
+session.
+
+The Ice manual provides more information on this feature, and a new
+sample program can be found in Glacier2/hello.
+
+
+Configuration
+-------------
+
+Prior releases supported four INI settings in PHP's configuration
+file:
+
+ * ice.config
+ * ice.options
+ * ice.profiles
+ * ice.slice
+
+The ice.slice directive is no longer supported since Slice definitions
+are now compiled statically. The remaining options are still supported
+but their semantics are slightly different. They no longer represent
+the configuration of a communicator; instead, they define property
+sets that a script can retrieve and use to initialize a communicator.
+
+The global INI directives ice.config and ice.options configure the
+default property set. The ice.profiles directive can optionally
+nominate a separate file that defines any number of named profiles,
+each of which configures a property set.
+
+As before, the profiles use an INI file syntax:
+
+[Name1]
+config=file1
+options="--Ice.Trace.Network=2 ..."
+
+[Name2]
+config=file2
+options="--Ice.Trace.Locator=1 ..."
+
+A new directive, ice.hide_profiles, overwrites the value of the
+ice.profiles directive as a security measure. This directive has
+a default value of 1, meaning it is enabled by default.
+
+A script can obtain a property set using the new function
+Ice_getProperties. Called without an argument (or with an empty
+string), the function returns the default property set:
+
+// PHP
+$props = Ice_getProperties();
+
+Alternatively, you can pass the name of the desired profile:
+
+// PHP
+$props = Ice_getProperties("Name1");
+
+The returned object is an instance of Ice_Properties, which supports
+the standard Ice API.
+
+For users migrating from an earlier release, you can replace a call to
+Ice_loadProfile as follows:
+
+// PHP - Old API
+Ice_loadProfile('Name1');
+
+// PHP - New API
+$initData = new Ice_InitializationData;
+$initData->properties = Ice_getProperties('Name1');
+$ICE = Ice_initialize($initData);
+
+(Note that it is not necessary to use the symbol $ICE for your
+communicator. However, using this symbol may ease your migration to
+this release.)
+
+Ice_loadProfile also installed the PHP definitions corresponding to
+your Slice types. In this release you will need to add 'require'
+statements to include your generated code.
+
+Finally, if you wish to manually configure a communicator, you can
+create a property set using Ice_createProperties:
+
+ function Ice_createProperties($args=null, $defaultProperties=null)
+
+$args is an array of strings representing command-line options, and
+$defaultProperties is an instance of Ice_Properties that supplies
+default values for properties.
+
+As an example, an application can configure a communicator as shown
+below:
+
+// PHP
+$initData = new Ice_InitializationData;
+$initData->properties = Ice_createProperties();
+$initData->properties->setProperty("Ice.Trace.Network", "1");
+...
+$ICE = Ice_initialize($initData);
+
+
+Namespaces
+----------
+
+This release includes optional support for PHP namespaces, which was
+introduced in PHP 5.3. Support for PHP namespaces is disabled by
+default; to enable it, you must build the Ice extension from source
+code with USE_NAMESPACES=yes (see Make.rules or Make.rules.mak in
+the php/config subdirectory). Note that the extension only supports
+one mapping style at a time; installing a namespace-enabled version
+of the extension requires all Ice applications on the target Web
+server to use namespaces.
+
+With namespace support enabled, you must modify your script to
+include a different version of the core Ice types:
+
+// PHP
+require 'Ice_ns.php'; // Namespace version of Ice.php
+
+You must also recompile your Slice files using the -n option to
+generate namespace-compatible code:
+
+% slice2php -n MySliceFile.ice
+
+This mapping translates Slice modules into PHP namespaces instead of
+using the "flattened" (underscore) naming scheme. For example,
+Ice_Properties becomes \Ice\Properties in the namespace mapping.
+However, applications can still refer to global Ice functions by their
+traditional names (such as Ice_initialize) or by their namespace
+equivalents (\Ice\initialize).
+
+
+Local exceptions
+----------------
+
+As mentioned earlier, prior releases of Ice for PHP only supported a
+limited subset of the standard local exceptions (refer to
+Ice/LocalException.ice for the definitions of these exceptions).
+An occurrence of an unsupported local exception was mapped to
+Ice_UnknownLocalException.
+
+This release adds support for all local exceptions, which allows an
+application to more easily react to certain types of errors:
+
+// PHP
+try
+{
+ $proxy->sayHello();
+}
+catch(Ice_ConnectionLostException $ex)
+{
+ // Handle connection loss
+}
+catch(Ice_LocalException $ex)
+{
+ // Handle other errors
+}
+
+This change represents a potential backward compatibility issue:
+applications that previously caught Ice_UnknownLocalException may
+need to be modified to catch the intended exception instead.
+
+
+Downcasting
+-----------
+
+In prior releases, to downcast a proxy you had to invoke the
+ice_checkedCast or ice_uncheckedCast method on a proxy and supply
+a type ID:
+
+// PHP
+$hello = $proxy->ice_checkedCast("::Demo::Hello");
+
+This API is likely to cause run-time errors because no validation is
+performed on the type ID string. For example, renaming the Hello
+interface to Greeting requires that you not only change all
+occurrences of Demo_Hello to Demo_Greeting, but also fix any type IDs
+that your code might have embedded. The PHP interpreter does not
+provide any assistance if you forget to make this change, and you will
+only discover it when that particular line of code is executed and
+fails.
+
+To improve this situation, a minimal class is now generated for each
+proxy type. The purpose of this class is to supply checkedCast and
+uncheckedCast static methods:
+
+class Demo_HelloPrx
+{
+ public static function checkedCast($proxy, $facetOrCtx=null,
+ $ctx=null);
+
+ public static function uncheckedCast($proxy, $facet=null);
+}
+
+Now your application can downcast a proxy as follows:
+
+// PHP
+$hello = Demo_HelloPrx::checkedCast($proxy);
+
+You can continue to use ice_checkedCast and ice_uncheckedCast but we
+recommend migrating your application to the new methods.
+
+
+Other API changes
+-----------------
+
+This section describes additional changes to the Ice API in this
+release:
+
+- The global variable $ICE is no longer defined. An application must
+ now initialize its own communicator as described above in the
+ "Communicators" section.
+
+- Removed the following communicator methods:
+
+ $ICE->setProperty()
+ $ICE->getProperty()
+
+ The equivalent methods are:
+
+ $communicator->getProperties()->setProperty()
+ $communicator->getProperties()->getProperty()
+
+- Removed the following global functions:
+
+ Ice_stringToIdentity()
+ Ice_identityToString()
+
+ The equivalent methods are:
+
+ $communicator->stringToIdentity()
+ $communicator->identityToString()
+
+- These functions have also been removed:
+
+ Ice_loadProfile()
+ Ice_loadProfileWithArgs()
+ Ice_dumpProfile()
+
+ Refer to the "Configuration" section above for more information.
+
+
+================
+OLD
+================
Since Ice 3.3.1 maintains binary compatibility with Ice 3.3.0, it is
not necessary for you to recompile your Slice files or your program
diff --git a/cpp/include/Slice/PHPUtil.h b/cpp/include/Slice/PHPUtil.h
new file mode 100644
index 00000000000..82aadabcebb
--- /dev/null
+++ b/cpp/include/Slice/PHPUtil.h
@@ -0,0 +1,50 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef SLICE_PHP_UTIL_H
+#define SLICE_PHP_UTIL_H
+
+#include <Slice/Parser.h>
+
+namespace Slice
+{
+namespace PHP
+{
+
+//
+// Convert a scoped name into a PHP name.
+//
+SLICE_API std::string scopedToName(const std::string&, bool);
+
+//
+// Check the given identifier against PHP's list of reserved words. If it matches
+// a reserved word, then an escaped version is returned with a leading underscore.
+//
+SLICE_API std::string fixIdent(const std::string&);
+
+//
+// Get the fully-qualified name of the given definition. If a suffix is provided,
+// it is prepended to the definition's unqualified name. If the nameSuffix
+// is provided, it is appended to the container's name.
+//
+// COMPILERFIX: MSVC 6 seems to have a problem with const std::string
+// = std::string(), const std::string = std::string().
+//
+SLICE_API std::string getAbsolute(const Slice::ContainedPtr&, bool, const std::string& = "", const std::string& = "");
+
+//
+// Since PHP uses the backslash character as the namespace separator, we have
+// to escape backslash characters when they appear in a string literal.
+//
+SLICE_API std::string escapeName(const std::string&);
+
+}
+}
+
+#endif
diff --git a/cpp/src/Makefile b/cpp/src/Makefile
index bacd29aa623..dc712a58868 100644
--- a/cpp/src/Makefile
+++ b/cpp/src/Makefile
@@ -19,6 +19,7 @@ SUBDIRS = IceUtil \
slice2freezej \
slice2docbook \
slice2java \
+ slice2php \
slice2py \
slice2rb \
slice2html \
diff --git a/cpp/src/Makefile.mak b/cpp/src/Makefile.mak
index 4014fa2c454..b04fc8c7082 100644
--- a/cpp/src/Makefile.mak
+++ b/cpp/src/Makefile.mak
@@ -19,6 +19,7 @@ SUBDIRS = IceUtil \
slice2freezej \
slice2docbook \
slice2java \
+ slice2php \
slice2py \
slice2rb \
slice2html \
diff --git a/cpp/src/Slice/.depend b/cpp/src/Slice/.depend
index 158e40d9aa2..e6ac78b7e95 100644
--- a/cpp/src/Slice/.depend
+++ b/cpp/src/Slice/.depend
@@ -9,6 +9,7 @@ Checksum$(OBJEXT): Checksum.cpp $(includedir)/Slice/Checksum.h $(includedir)/Sli
PythonUtil$(OBJEXT): PythonUtil.cpp $(includedir)/Slice/PythonUtil.h $(includedir)/Slice/Parser.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/IceUtil/OutputUtil.h $(includedir)/Slice/Checksum.h $(includedir)/Slice/Util.h $(includedir)/IceUtil/IceUtil.h $(includedir)/IceUtil/AbstractMutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/Cache.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/CountDownLatch.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/CtrlCHandler.h $(includedir)/IceUtil/Functional.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/RWRecMutex.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/RecMutex.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/UUID.h $(includedir)/IceUtil/Unicode.h $(includedir)/IceUtil/StringUtil.h $(includedir)/IceUtil/InputUtil.h
DotNetNames$(OBJEXT): DotNetNames.cpp $(includedir)/Slice/DotNetNames.h
RubyUtil$(OBJEXT): RubyUtil.cpp $(includedir)/Slice/RubyUtil.h $(includedir)/Slice/Parser.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/IceUtil/OutputUtil.h $(includedir)/Slice/Checksum.h $(includedir)/Slice/Util.h $(includedir)/IceUtil/Functional.h $(includedir)/IceUtil/InputUtil.h
+PHPUtil$(OBJEXT): PHPUtil.cpp $(includedir)/Slice/PHPUtil.h $(includedir)/Slice/Parser.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h
Util$(OBJEXT): Util.cpp $(includedir)/Slice/Util.h $(includedir)/Slice/Parser.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/IceUtil/Unicode.h $(includedir)/IceUtil/FileUtil.h $(includedir)/IceUtil/StringUtil.h
FileTracker$(OBJEXT): FileTracker.cpp $(includedir)/Slice/FileTracker.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Slice/Parser.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h
MD5$(OBJEXT): MD5.cpp ../Slice/MD5.h $(includedir)/IceUtil/Config.h ../Slice/MD5I.h
diff --git a/cpp/src/Slice/Makefile b/cpp/src/Slice/Makefile
index 7232e2fe64a..0cf15556efc 100644
--- a/cpp/src/Slice/Makefile
+++ b/cpp/src/Slice/Makefile
@@ -26,6 +26,7 @@ OBJS = Scanner.o \
PythonUtil.o \
DotNetNames.o \
RubyUtil.o \
+ PHPUtil.o \
Util.o \
FileTracker.o \
MD5.o \
diff --git a/cpp/src/Slice/Makefile.mak b/cpp/src/Slice/Makefile.mak
index dd76c272482..22f42d8e30b 100644
--- a/cpp/src/Slice/Makefile.mak
+++ b/cpp/src/Slice/Makefile.mak
@@ -25,6 +25,7 @@ OBJS = Scanner.obj \
PythonUtil.obj \
DotNetNames.obj \
RubyUtil.obj \
+ PHPUtil.obj \
Util.obj \
FileTracker.obj \
MD5.obj \
diff --git a/cpp/src/Slice/PHPUtil.cpp b/cpp/src/Slice/PHPUtil.cpp
new file mode 100644
index 00000000000..e8794a37360
--- /dev/null
+++ b/cpp/src/Slice/PHPUtil.cpp
@@ -0,0 +1,155 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Slice/PHPUtil.h>
+
+using namespace std;
+using namespace Slice;
+
+static string
+lowerCase(const string& s)
+{
+ string result(s);
+ transform(result.begin(), result.end(), result.begin(), ::tolower);
+ return result;
+}
+
+static string
+lookupKwd(const string& name)
+{
+ string lower = lowerCase(name); // PHP is case insensitive.
+
+ //
+ // Keyword list. *Must* be kept in alphabetical order.
+ //
+ static const string keywordList[] =
+ {
+ "abstract", "and", "array", "as", "break", "case", "catch", "class", "clone", "const", "continue", "declare",
+ "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif",
+ "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "if",
+ "implements", "include", "include_once", "interface", "isset", "list", "new", "or", "print", "private",
+ "protected", "public", "require", "require_once", "return", "static", "switch", "this", "throw", "try",
+ "unset", "use", "var", "while", "xor"
+ };
+ bool found = binary_search(&keywordList[0],
+ &keywordList[sizeof(keywordList) / sizeof(*keywordList)],
+ lower);
+ return found ? "_" + name : name;
+}
+
+//
+// Split a scoped name into its components and return the components as a list of (unscoped) identifiers.
+//
+static vector<string>
+splitScopedName(const string& scoped)
+{
+ assert(scoped[0] == ':');
+ vector<string> ids;
+ string::size_type next = 0;
+ string::size_type pos;
+ while((pos = scoped.find("::", next)) != string::npos)
+ {
+ pos += 2;
+ if(pos != scoped.size())
+ {
+ string::size_type endpos = scoped.find("::", pos);
+ if(endpos != string::npos)
+ {
+ ids.push_back(scoped.substr(pos, endpos - pos));
+ }
+ }
+ next = pos;
+ }
+ if(next != scoped.size())
+ {
+ ids.push_back(scoped.substr(next));
+ }
+ else
+ {
+ ids.push_back("");
+ }
+
+ return ids;
+}
+
+string
+Slice::PHP::scopedToName(const string& scoped, bool ns)
+{
+ string result;
+ if(ns)
+ {
+ result = fixIdent(scoped);
+ if(result.find("::") == 0)
+ {
+ result.replace(0, 2, "\\");
+ }
+
+ string::size_type pos;
+ while((pos = result.find("::")) != string::npos)
+ {
+ result.replace(pos, 2, "\\");
+ }
+ }
+ else
+ {
+ string str = scoped;
+ if(str.find("::") == 0)
+ {
+ str.erase(0, 2);
+ }
+
+ string::size_type pos;
+ while((pos = str.find("::")) != string::npos)
+ {
+ str.replace(pos, 2, "_");
+ }
+
+ result = fixIdent(str);
+ }
+
+ return result;
+}
+
+string
+Slice::PHP::fixIdent(const string& ident)
+{
+ if(ident[0] != ':')
+ {
+ return lookupKwd(ident);
+ }
+ vector<string> ids = splitScopedName(ident);
+ transform(ids.begin(), ids.end(), ids.begin(), ptr_fun(lookupKwd));
+ stringstream result;
+ for(vector<string>::const_iterator i = ids.begin(); i != ids.end(); ++i)
+ {
+ result << "::" + *i;
+ }
+ return result.str();
+}
+
+string
+Slice::PHP::getAbsolute(const ContainedPtr& cont, bool ns, const string& prefix, const string& suffix)
+{
+ return scopedToName(cont->scope() + prefix + cont->name() + suffix, ns);
+}
+
+string
+Slice::PHP::escapeName(const string& name)
+{
+ string result = name;
+
+ string::size_type pos = 0;
+ while((pos = result.find("\\", pos)) != string::npos)
+ {
+ result.insert(pos, "\\");
+ pos += 2;
+ }
+
+ return result;
+}
diff --git a/cpp/src/slice2php/.depend b/cpp/src/slice2php/.depend
new file mode 100644
index 00000000000..4e49f990dad
--- /dev/null
+++ b/cpp/src/slice2php/.depend
@@ -0,0 +1 @@
+Main$(OBJEXT): Main.cpp $(includedir)/IceUtil/DisableWarnings.h $(includedir)/IceUtil/CtrlCHandler.h $(includedir)/IceUtil/Config.h $(includedir)/IceUtil/Exception.h $(includedir)/IceUtil/IceUtil.h $(includedir)/IceUtil/AbstractMutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/Cache.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/CountDownLatch.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Functional.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/RWRecMutex.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/RecMutex.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/UUID.h $(includedir)/IceUtil/Unicode.h $(includedir)/IceUtil/InputUtil.h $(includedir)/IceUtil/Options.h $(includedir)/IceUtil/OutputUtil.h $(includedir)/IceUtil/StringUtil.h $(includedir)/Slice/Checksum.h $(includedir)/Slice/Parser.h $(includedir)/Slice/Preprocessor.h $(includedir)/Slice/FileTracker.h $(includedir)/Slice/PHPUtil.h $(includedir)/Slice/Util.h
diff --git a/cpp/src/slice2php/Main.cpp b/cpp/src/slice2php/Main.cpp
new file mode 100644
index 00000000000..9ad5e42935e
--- /dev/null
+++ b/cpp/src/slice2php/Main.cpp
@@ -0,0 +1,1677 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/DisableWarnings.h>
+#include <IceUtil/CtrlCHandler.h>
+#include <IceUtil/IceUtil.h>
+#include <IceUtil/InputUtil.h>
+#include <IceUtil/Options.h>
+#include <IceUtil/OutputUtil.h>
+#include <IceUtil/StringUtil.h>
+#include <IceUtil/StaticMutex.h>
+#include <Slice/Checksum.h>
+#include <Slice/Preprocessor.h>
+#include <Slice/FileTracker.h>
+#include <Slice/PHPUtil.h>
+#include <Slice/Util.h>
+#include <cstring>
+#include <climits>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#include <direct.h>
+#endif
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+using namespace std;
+using namespace Slice;
+using namespace Slice::PHP;
+using namespace IceUtil;
+using namespace IceUtilInternal;
+
+//
+// CodeVisitor generates the PHP mapping for a translation unit.
+//
+class CodeVisitor : public ParserVisitor
+{
+public:
+
+ CodeVisitor(IceUtilInternal::Output&, bool);
+
+ virtual void visitClassDecl(const ClassDeclPtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitConst(const ConstPtr&);
+
+private:
+
+ void startNamespace(const ContainedPtr&);
+ void endNamespace();
+
+ //
+ // Return the PHP name for the given Slice type. When using namespaces,
+ // this name is a relative (unqualified) name, otherwise this name is the
+ // flattened absolute name.
+ //
+ string getName(const ContainedPtr&, const string& = string());
+
+ //
+ // Return the PHP variable for the given object's type.
+ //
+ string getTypeVar(const ContainedPtr&, const string& = string());
+
+ //
+ // Emit the array for a Slice type.
+ //
+ void writeType(const TypePtr&);
+
+ //
+ // Write a default value for a given type.
+ //
+ void writeDefaultValue(const TypePtr&);
+
+ struct MemberInfo
+ {
+ string fixedName;
+ TypePtr type;
+ bool inherited;
+ StringList metaData;
+ };
+ typedef list<MemberInfo> MemberInfoList;
+
+ //
+ // Write a member assignment statement for a constructor.
+ //
+ void writeAssign(const MemberInfo&);
+
+ //
+ // Convert an operation mode into a string.
+ //
+ string getOperationMode(Slice::Operation::Mode, bool);
+
+ void collectClassMembers(const ClassDefPtr&, MemberInfoList&, bool);
+ void collectExceptionMembers(const ExceptionPtr&, MemberInfoList&, bool);
+
+ Output& _out;
+ bool _ns; // Using namespaces?
+ list<string> _moduleStack; // TODO: Necessary?
+ set<string> _classHistory; // TODO: Necessary?
+};
+
+//
+// CodeVisitor implementation.
+//
+CodeVisitor::CodeVisitor(Output& out, bool ns) :
+ _out(out), _ns(ns)
+{
+}
+
+void
+CodeVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ //
+ // Handle forward declarations.
+ //
+ string scoped = p->scoped();
+ string abs = getAbsolute(p, _ns);
+ if(_classHistory.count(scoped) == 0)
+ {
+ startNamespace(p);
+
+ string type = getTypeVar(p);
+ _out << sp << nl << "if(!isset(" << type << "))";
+ _out << sb;
+ _out << nl << type << " = IcePHP_declareClass('" << scoped << "');";
+ if(!p->isLocal())
+ {
+ _out << nl << type << "Prx = IcePHP_defineProxy(" << type << ");";
+ }
+ _out << eb;
+
+ endNamespace();
+
+ _classHistory.insert(scoped); // Avoid redundant declarations.
+ }
+}
+
+bool
+CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ string scoped = p->scoped();
+ string name = getName(p);
+ string type = getTypeVar(p);
+ string abs = getAbsolute(p, _ns);
+ string prxName = getName(p, "Prx");
+ string prxType = getTypeVar(p, "Prx");
+ string prxAbs = getAbsolute(p, _ns, "", "Prx");
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+ OperationList ops = p->operations();
+ OperationList::iterator oli;
+ DataMemberList members = p->dataMembers();
+ bool isInterface = p->isInterface();
+ bool isAbstract = isInterface || p->allOperations().size() > 0; // Don't use isAbstract() - see bug 3739
+
+ startNamespace(p);
+
+ //
+ // Define the class.
+ //
+ if(isInterface)
+ {
+ _out << sp << nl << "if(!interface_exists('" << escapeName(abs) << "'))";
+ _out << sb;
+ _out << nl << "interface " << name;
+ if(!bases.empty())
+ {
+ _out << " extends ";
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ if(q != bases.begin())
+ {
+ _out << ", ";
+ }
+ _out << getAbsolute(*q, _ns);
+ }
+ }
+ _out << sb;
+ for(oli = ops.begin(); oli != ops.end(); ++oli)
+ {
+ _out << nl << "public function " << fixIdent((*oli)->name()) << '(';
+ ParamDeclList params = (*oli)->parameters();
+ for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q)
+ {
+ if(q != params.begin())
+ {
+ _out << ", ";
+ }
+ _out << '$' << fixIdent((*q)->name());
+ }
+ _out << ");";
+ }
+ _out << eb;
+ }
+ else
+ {
+ _out << sp << nl << "if(!class_exists('" << escapeName(abs) << "'))";
+ _out << sb;
+ _out << nl;
+ if(isAbstract)
+ {
+ _out << "abstract ";
+ }
+ _out << "class " << name;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ bases.pop_front();
+ }
+ if(base)
+ {
+ _out << " extends " << getAbsolute(base, _ns);
+ }
+ else
+ {
+ if(!p->isLocal())
+ {
+ _out << " extends " << scopedToName("::Ice::ObjectImpl", _ns);
+ }
+ }
+ if(!bases.empty())
+ {
+ _out << " implements ";
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ if(q != bases.begin())
+ {
+ _out << ", ";
+ }
+ _out << getAbsolute(*q, _ns);
+ }
+ }
+
+ _out << sb;
+
+ //
+ // __construct
+ //
+ _out << nl << "public function __construct(";
+ MemberInfoList allMembers;
+ collectClassMembers(p, allMembers, false);
+ if(!allMembers.empty())
+ {
+ for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(q != allMembers.begin())
+ {
+ _out << ", ";
+ }
+ _out << '$' << q->fixedName << '=';
+ writeDefaultValue(q->type);
+ }
+ }
+ _out << ")";
+ _out << sb;
+ if(base)
+ {
+ _out << nl << "parent::__construct(";
+ int count = 0;
+ for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(q->inherited)
+ {
+ if(count)
+ {
+ _out << ", ";
+ }
+ _out << '$' << q->fixedName;
+ ++count;
+ }
+ }
+ _out << ");";
+ }
+ {
+ for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(!q->inherited)
+ {
+ writeAssign(*q);
+ }
+ }
+ }
+ _out << eb;
+
+ if(!ops.empty())
+ {
+ _out << sp;
+ for(oli = ops.begin(); oli != ops.end(); ++oli)
+ {
+ _out << nl << "abstract public function " << fixIdent((*oli)->name()) << '(';
+ ParamDeclList params = (*oli)->parameters();
+ for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q)
+ {
+ if(q != params.begin())
+ {
+ _out << ", ";
+ }
+ _out << '$' << fixIdent((*q)->name());
+ }
+ _out << ");";
+ }
+ }
+
+ if(!p->isLocal())
+ {
+ //
+ // ice_staticId
+ //
+ _out << sp << nl << "public static function ice_staticId()";
+ _out << sb;
+ _out << nl << "return '" << scoped << "';";
+ _out << eb;
+ }
+
+ //
+ // __toString
+ //
+ _out << sp << nl << "public function __toString()";
+ _out << sb;
+ _out << nl << "global " << type << ';';
+ _out << nl << "return IcePHP_stringify($this, " << type << ");";
+ _out << eb;
+
+ if(!members.empty())
+ {
+ _out << sp;
+ bool isProtected = p->hasMetaData("protected");
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ _out << nl;
+ if(isProtected || (*q)->hasMetaData("protected"))
+ {
+ _out << "protected ";
+ }
+ else
+ {
+ _out << "public ";
+ }
+ _out << "$" << fixIdent((*q)->name()) << ";";
+ }
+ }
+
+ _out << eb; // End of class.
+ }
+
+ //
+ // Define the proxy class.
+ //
+ if(!p->isLocal())
+ {
+ _out << sp << nl << "class " << prxName << "Helper";
+ _out << sb;
+
+ _out << sp << nl << "public static function checkedCast($proxy, $facetOrCtx=null, $ctx=null)";
+ _out << sb;
+ _out << nl << "return $proxy->ice_checkedCast('" << scoped << "', $facetOrCtx, $ctx);";
+ _out << eb;
+
+ _out << sp << nl << "public static function uncheckedCast($proxy, $facet=null)";
+ _out << sb;
+ _out << nl << "return $proxy->ice_uncheckedCast('" << scoped << "', $facet);";
+ _out << eb;
+
+ _out << eb;
+ }
+
+ if(_classHistory.count(scoped) == 0 && p->canBeCyclic())
+ {
+ //
+ // Emit a forward declaration for the class in case a data member refers to this type.
+ //
+ _out << sp << nl << type << " = IcePHP_declareClass('" << scoped << "');";
+ }
+
+ //
+ // Emit the type information.
+ //
+ _out << sp << nl << type << " = IcePHP_defineClass('" << scoped << "', '" << escapeName(abs) << "', "
+ << (isAbstract ? "true" : "false") << ", ";
+ if(!base)
+ {
+ _out << "$Ice__t_Object";
+ }
+ else
+ {
+ _out << getTypeVar(base);
+ }
+ _out << ", ";
+ //
+ // Interfaces
+ //
+ if(!bases.empty())
+ {
+ _out << "array(";
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ if(q != bases.begin())
+ {
+ _out << ", ";
+ }
+ _out << getTypeVar(*q);
+ }
+ _out << ')';
+ }
+ else
+ {
+ _out << "null";
+ }
+ _out << ", ";
+ //
+ // Members
+ //
+ // Data members are represented as an array:
+ //
+ // ('MemberName', MemberType)
+ //
+ // where MemberType is either a primitive type constant (T_INT, etc.) or the id of a constructed type.
+ //
+ if(!members.empty())
+ {
+ _out << "array(";
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ if(q != members.begin())
+ {
+ _out << ',' << nl;
+ }
+ _out.inc();
+ _out << nl << "array('" << fixIdent((*q)->name()) << "', ";
+ writeType((*q)->type());
+ _out << ')';
+ _out.dec();
+ }
+ _out << ')';
+ }
+ else
+ {
+ _out << "null";
+ }
+ _out << ");";
+
+ if(!p->isLocal())
+ {
+ _out << sp << nl << prxType << " = IcePHP_defineProxy(" << type << ");";
+
+ //
+ // Define each operation. The arguments to IcePHP_defineOperation are:
+ //
+ // $ClassType, 'opName', Mode, SendMode, (InParams), (OutParams), ReturnType, (Exceptions)
+ //
+ // where InParams and OutParams are arrays of type descriptions, and Exceptions
+ // is an array of exception type ids.
+ //
+ if(!ops.empty())
+ {
+ _out << sp;
+ for(oli = ops.begin(); oli != ops.end(); ++oli)
+ {
+ ParamDeclList params = (*oli)->parameters();
+ ParamDeclList::iterator t;
+ int count;
+
+ _out << nl << "IcePHP_defineOperation(" << type << ", '" << (*oli)->name() << "', "
+ << getOperationMode((*oli)->mode(), _ns) << ", " << getOperationMode((*oli)->sendMode(), _ns)
+ << ", ";
+ for(t = params.begin(), count = 0; t != params.end(); ++t)
+ {
+ if(!(*t)->isOutParam())
+ {
+ if(count == 0)
+ {
+ _out << "array(";
+ }
+ else if(count > 0)
+ {
+ _out << ", ";
+ }
+ writeType((*t)->type());
+ ++count;
+ }
+ }
+ if(count > 0)
+ {
+ _out << ')';
+ }
+ else
+ {
+ _out << "null";
+ }
+ _out << ", ";
+ for(t = params.begin(), count = 0; t != params.end(); ++t)
+ {
+ if((*t)->isOutParam())
+ {
+ if(count == 0)
+ {
+ _out << "array(";
+ }
+ else if(count > 0)
+ {
+ _out << ", ";
+ }
+ writeType((*t)->type());
+ ++count;
+ }
+ }
+ if(count > 0)
+ {
+ _out << ')';
+ }
+ else
+ {
+ _out << "null";
+ }
+ _out << ", ";
+ TypePtr returnType = (*oli)->returnType();
+ if(returnType)
+ {
+ writeType(returnType);
+ }
+ else
+ {
+ _out << "null";
+ }
+ _out << ", ";
+ ExceptionList exceptions = (*oli)->throws();
+ if(!exceptions.empty())
+ {
+ _out << "array(";
+ for(ExceptionList::iterator u = exceptions.begin(); u != exceptions.end(); ++u)
+ {
+ if(u != exceptions.begin())
+ {
+ _out << ", ";
+ }
+ _out << getTypeVar(*u);
+ }
+ _out << ')';
+ }
+ else
+ {
+ _out << "null";
+ }
+ _out << ");";
+ }
+ }
+ }
+
+ _out << eb;
+
+ endNamespace();
+
+ if(_classHistory.count(scoped) == 0)
+ {
+ _classHistory.insert(scoped); // Avoid redundant declarations.
+ }
+
+ return false;
+}
+
+bool
+CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ string scoped = p->scoped();
+ string name = getName(p);
+ string type = getTypeVar(p);
+ string abs = getAbsolute(p, _ns);
+
+ startNamespace(p);
+
+ _out << sp << nl << "if(!class_exists('" << escapeName(abs) << "'))";
+ _out << sb;
+ _out << nl << "class " << name << " extends ";
+ ExceptionPtr base = p->base();
+ string baseName;
+ if(base)
+ {
+ baseName = getAbsolute(base, _ns);
+ _out << baseName;
+ }
+ else if(p->isLocal())
+ {
+ _out << scopedToName("::Ice::LocalException", _ns);
+ }
+ else
+ {
+ _out << scopedToName("::Ice::UserException", _ns);
+ }
+ _out << sb;
+
+ DataMemberList members = p->dataMembers();
+ DataMemberList::iterator dmli;
+
+ //
+ // __construct
+ //
+ _out << nl << "public function __construct(";
+ MemberInfoList allMembers;
+ collectExceptionMembers(p, allMembers, false);
+ if(!allMembers.empty())
+ {
+ for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(q != allMembers.begin())
+ {
+ _out << ", ";
+ }
+ _out << '$' << q->fixedName << '=';
+ writeDefaultValue(q->type);
+ }
+ }
+ _out << ")";
+ _out << sb;
+ if(base)
+ {
+ _out << nl << "parent::__construct(";
+ int count = 0;
+ for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(q->inherited)
+ {
+ if(count)
+ {
+ _out << ", ";
+ }
+ _out << '$' << q->fixedName;
+ ++count;
+ }
+ }
+ _out << ");";
+ }
+ for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(!q->inherited)
+ {
+ writeAssign(*q);
+ }
+ }
+ _out << eb;
+
+ //
+ // ice_name
+ //
+ _out << sp << nl << "public function ice_name()";
+ _out << sb;
+ _out << nl << "return '" << scoped.substr(2) << "';";
+ _out << eb;
+
+ //
+ // __toString
+ //
+ _out << sp << nl << "public function __toString()";
+ _out << sb;
+ _out << nl << "global " << type << ';';
+ _out << nl << "return IcePHP_stringifyException($this, " << type << ");";
+ _out << eb;
+
+ if(!members.empty())
+ {
+ _out << sp;
+ for(dmli = members.begin(); dmli != members.end(); ++dmli)
+ {
+ _out << nl << "public $" << fixIdent((*dmli)->name()) << ";";
+ }
+ }
+
+ _out << eb;
+
+ //
+ // Emit the type information.
+ //
+ _out << sp << nl << type << " = IcePHP_defineException('" << scoped << "', '" << escapeName(abs) << "', ";
+ if(!base)
+ {
+ _out << "null";
+ }
+ else
+ {
+ _out << getTypeVar(base);
+ }
+ _out << ", ";
+ //
+ // Data members are represented as an array:
+ //
+ // ('MemberName', MemberType)
+ //
+ // where MemberType is either a primitive type constant (T_INT, etc.) or the id of a constructed type.
+ //
+ if(!members.empty())
+ {
+ _out << "array(";
+ for(dmli = members.begin(); dmli != members.end(); ++dmli)
+ {
+ if(dmli != members.begin())
+ {
+ _out << ',' << nl;
+ }
+ _out.inc();
+ _out << nl << "array('" << fixIdent((*dmli)->name()) << "', ";
+ writeType((*dmli)->type());
+ _out << ')';
+ _out.dec();
+ }
+ _out << ')';
+ }
+ else
+ {
+ _out << "null";
+ }
+ _out << ");";
+
+ _out << eb;
+
+ endNamespace();
+
+ return false;
+}
+
+bool
+CodeVisitor::visitStructStart(const StructPtr& p)
+{
+ string scoped = p->scoped();
+ string name = getName(p);
+ string type = getTypeVar(p);
+ string abs = getAbsolute(p, _ns);
+ MemberInfoList memberList;
+ MemberInfoList::iterator r;
+
+ {
+ DataMemberList members = p->dataMembers();
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ memberList.push_back(MemberInfo());
+ memberList.back().fixedName = fixIdent((*q)->name());
+ memberList.back().type = (*q)->type();
+ memberList.back().metaData = (*q)->getMetaData();
+ }
+ }
+
+ startNamespace(p);
+
+ _out << sp << nl << "if(!class_exists('" << escapeName(abs) << "'))";
+ _out << sb;
+
+ _out << nl << "class " << name;
+ _out << sb;
+ _out << nl << "public function __construct(";
+ for(r = memberList.begin(); r != memberList.end(); ++r)
+ {
+ if(r != memberList.begin())
+ {
+ _out << ", ";
+ }
+ _out << '$' << r->fixedName << '=';
+ writeDefaultValue(r->type);
+ }
+ _out << ")";
+ _out << sb;
+ for(r = memberList.begin(); r != memberList.end(); ++r)
+ {
+ writeAssign(*r);
+ }
+ _out << eb;
+
+ //
+ // __toString
+ //
+ _out << sp << nl << "public function __toString()";
+ _out << sb;
+ _out << nl << "global " << type << ';';
+ _out << nl << "return IcePHP_stringify($this, " << type << ");";
+ _out << eb;
+
+ if(!memberList.empty())
+ {
+ _out << sp;
+ for(r = memberList.begin(); r != memberList.end(); ++r)
+ {
+ _out << nl << "public $" << r->fixedName << ';';
+ }
+ }
+
+ _out << eb;
+
+ //
+ // Emit the type information.
+ //
+ _out << sp << nl << type << " = IcePHP_defineStruct('" << scoped << "', '" << escapeName(abs) << "', array(";
+ //
+ // Data members are represented as an array:
+ //
+ // ('MemberName', MemberType)
+ //
+ // where MemberType is either a primitive type constant (T_INT, etc.) or the id of a constructed type.
+ //
+ for(r = memberList.begin(); r != memberList.end(); ++r)
+ {
+ if(r != memberList.begin())
+ {
+ _out << ", ";
+ }
+ _out.inc();
+ _out << nl << "array('" << r->fixedName << "', ";
+ writeType(r->type);
+ _out << ')';
+ _out.dec();
+ }
+ _out << "));";
+
+ _out << eb;
+
+ endNamespace();
+
+ return false;
+}
+
+void
+CodeVisitor::visitSequence(const SequencePtr& p)
+{
+ string type = getTypeVar(p);
+ TypePtr content = p->type();
+
+ startNamespace(p);
+
+ //
+ // Emit the type information.
+ //
+ string scoped = p->scoped();
+ _out << sp << nl << "if(!isset(" << type << "))";
+ _out << sb;
+ _out << nl << type << " = IcePHP_defineSequence('" << scoped << "', ";
+ writeType(content);
+ _out << ", ";
+ if(content->isVariableLength())
+ {
+ _out << "true";
+ }
+ else
+ {
+ _out << "false";
+ }
+ _out << ", " << content->minWireSize() << ");";
+ _out << eb;
+
+ endNamespace();
+}
+
+void
+CodeVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ string type = getTypeVar(p);
+
+ startNamespace(p);
+
+ //
+ // Emit the type information.
+ //
+ string scoped = p->scoped();
+ _out << sp << nl << "if(!isset(" << type << "))";
+ _out << sb;
+ _out << nl << type << " = IcePHP_defineDictionary('" << scoped << "', ";
+ writeType(p->keyType());
+ _out << ", ";
+ writeType(p->valueType());
+ _out << ");";
+ _out << eb;
+
+ endNamespace();
+}
+
+void
+CodeVisitor::visitEnum(const EnumPtr& p)
+{
+ string scoped = p->scoped();
+ string name = getName(p);
+ string type = getTypeVar(p);
+ string abs = getAbsolute(p, _ns);
+ EnumeratorList enums = p->getEnumerators();
+ EnumeratorList::iterator q;
+ long i;
+
+ startNamespace(p);
+
+ _out << sp << nl << "if(!class_exists('" << escapeName(abs) << "'))";
+ _out << sb;
+ _out << nl << "class " << name;
+ _out << sb;
+
+ for(q = enums.begin(), i = 0; q != enums.end(); ++q, ++i)
+ {
+ string fixedEnum = fixIdent((*q)->name());
+ ostringstream idx;
+ idx << i;
+ _out << nl << "const " << fixedEnum << " = " << idx.str() << ';';
+ }
+
+ _out << eb;
+
+ //
+ // Emit the type information.
+ //
+ _out << sp << nl << type << " = IcePHP_defineEnum('" << scoped << "', array(";
+ for(q = enums.begin(); q != enums.end(); ++q)
+ {
+ if(q != enums.begin())
+ {
+ _out << ", ";
+ }
+ _out << "'" << (*q)->name() << "'";
+ }
+ _out << "));";
+
+ _out << eb;
+
+ endNamespace();
+}
+
+void
+CodeVisitor::visitConst(const ConstPtr& p)
+{
+ string name = getName(p);
+ string type = getTypeVar(p);
+ string abs = getAbsolute(p, _ns);
+ string value = p->value();
+ Slice::TypePtr valueType = p->type();
+
+ startNamespace(p);
+
+ _out << sp << nl << "if(!defined('" << escapeName(abs) << "'))";
+ _out << sb;
+ _out << sp << nl << "define('" << name << "', ";
+
+ Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(valueType);
+ Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(valueType);
+ if(b)
+ {
+ switch(b->kind())
+ {
+ case Slice::Builtin::KindBool:
+ case Slice::Builtin::KindByte:
+ case Slice::Builtin::KindShort:
+ case Slice::Builtin::KindInt:
+ case Slice::Builtin::KindFloat:
+ case Slice::Builtin::KindDouble:
+ {
+ _out << value;
+ break;
+ }
+ case Slice::Builtin::KindLong:
+ {
+ IceUtil::Int64 l;
+ IceUtilInternal::stringToInt64(value, l);
+ //
+ // The platform's 'long' type may not be 64 bits, so we store 64-bit
+ // values as a string.
+ //
+ if(sizeof(IceUtil::Int64) > sizeof(long) && (l < LONG_MIN || l > LONG_MAX))
+ {
+ _out << "'" << value << "'";
+ }
+ else
+ {
+ _out << value;
+ }
+ break;
+ }
+
+ case Slice::Builtin::KindString:
+ {
+ //
+ // Expand strings into the basic source character set. We can't use isalpha() and the like
+ // here because they are sensitive to the current locale.
+ //
+ static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789"
+ "_{}[]#()<>%:;.?*+-/^&|~!=, '";
+ static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end());
+
+ _out << "\""; // Opening "
+
+ for(string::const_iterator c = value.begin(); c != value.end(); ++c)
+ {
+ switch(*c)
+ {
+ case '$':
+ {
+ _out << "\\$";
+ break;
+ }
+ case '"':
+ {
+ _out << "\\\"";
+ break;
+ }
+ case '\\':
+ {
+ _out << "\\\\";
+ break;
+ }
+ case '\r':
+ {
+ _out << "\\r";
+ break;
+ }
+ case '\n':
+ {
+ _out << "\\n";
+ break;
+ }
+ case '\t':
+ {
+ _out << "\\t";
+ break;
+ }
+ case '\b':
+ {
+ _out << "\\b";
+ break;
+ }
+ case '\f':
+ {
+ _out << "\\f";
+ break;
+ }
+ default:
+ {
+ if(charSet.find(*c) == charSet.end())
+ {
+ unsigned char uc = *c; // Char may be signed, so make it positive.
+ stringstream s;
+ s << "\\"; // Print as octal if not in basic source character set.
+ s.flags(ios_base::oct);
+ s.width(3);
+ s.fill('0');
+ s << static_cast<unsigned>(uc);
+ _out << s.str();
+ }
+ else
+ {
+ _out << *c; // Print normally if in basic source character set.
+ }
+ break;
+ }
+ }
+ }
+
+ _out << "\""; // Closing "
+ break;
+ }
+
+ case Slice::Builtin::KindObject:
+ case Slice::Builtin::KindObjectProxy:
+ case Slice::Builtin::KindLocalObject:
+ assert(false);
+ }
+ }
+ else if(en)
+ {
+ string::size_type colon = value.rfind(':');
+ if(colon != string::npos)
+ {
+ value = value.substr(colon + 1);
+ }
+ Slice::EnumeratorList l = en->getEnumerators();
+ Slice::EnumeratorList::iterator q;
+ for(q = l.begin(); q != l.end(); ++q)
+ {
+ if((*q)->name() == value)
+ {
+ _out << getAbsolute(en, _ns) << "::" << fixIdent(value);
+ break;
+ }
+ }
+ }
+ else
+ {
+ assert(false); // Unknown const type.
+ }
+
+ _out << ");";
+ _out << eb;
+
+ endNamespace();
+}
+
+void
+CodeVisitor::startNamespace(const ContainedPtr& cont)
+{
+ if(_ns)
+ {
+ string scope = cont->scope();
+ scope = scope.substr(2); // Removing leading '::'
+ scope = scope.substr(0, scope.length() - 2); // Removing trailing '::'
+ _out << sp << nl << "namespace " << scopedToName(scope, true);
+ _out << sb;
+ }
+}
+
+void
+CodeVisitor::endNamespace()
+{
+ if(_ns)
+ {
+ _out << eb;
+ }
+}
+
+string
+CodeVisitor::getTypeVar(const ContainedPtr& p, const string& suffix)
+{
+ return "$" + getAbsolute(p, false, "_t_", suffix);
+}
+
+string
+CodeVisitor::getName(const ContainedPtr& p, const string& suffix)
+{
+ if(_ns)
+ {
+ return fixIdent(p->name() + suffix);
+ }
+ else
+ {
+ return getAbsolute(p, false, "", suffix);
+ }
+}
+
+void
+CodeVisitor::writeType(const TypePtr& p)
+{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindBool:
+ {
+ _out << "$IcePHP__t_bool";
+ break;
+ }
+ case Builtin::KindByte:
+ {
+ _out << "$IcePHP__t_byte";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ _out << "$IcePHP__t_short";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ _out << "$IcePHP__t_int";
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ _out << "$IcePHP__t_long";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ _out << "$IcePHP__t_float";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ _out << "$IcePHP__t_double";
+ break;
+ }
+ case Builtin::KindString:
+ {
+ _out << "$IcePHP__t_string";
+ break;
+ }
+ case Builtin::KindObject:
+ {
+ _out << "$Ice__t_Object";
+ break;
+ }
+ case Builtin::KindObjectProxy:
+ {
+ _out << "$Ice__t_ObjectPrx";
+ break;
+ }
+ case Builtin::KindLocalObject:
+ {
+ _out << "$Ice__t_LocalObject";
+ break;
+ }
+ }
+ return;
+ }
+
+ ProxyPtr prx = ProxyPtr::dynamicCast(p);
+ if(prx)
+ {
+ _out << getTypeVar(prx->_class(), "Prx");
+ return;
+ }
+
+ ContainedPtr cont = ContainedPtr::dynamicCast(p);
+ assert(cont);
+ _out << getTypeVar(cont);
+}
+
+void
+CodeVisitor::writeDefaultValue(const TypePtr& p)
+{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindBool:
+ {
+ _out << "false";
+ break;
+ }
+ case Builtin::KindByte:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ {
+ _out << "0";
+ break;
+ }
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ {
+ _out << "0.0";
+ break;
+ }
+ case Builtin::KindString:
+ {
+ _out << "''";
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ _out << "null";
+ break;
+ }
+ }
+ return;
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(p);
+ if(en)
+ {
+ EnumeratorList enums = en->getEnumerators();
+ _out << getAbsolute(en, _ns) << "::" << fixIdent(enums.front()->name());
+ return;
+ }
+
+ //
+ // PHP does not allow the following construct:
+ //
+ // function foo($theStruct=new MyStructType)
+ //
+ // Instead we use null as the default value and allocate an instance in
+ // the constructor.
+ //
+ StructPtr st = StructPtr::dynamicCast(p);
+ if(st)
+ {
+ _out << "null";
+ return;
+ }
+
+ _out << "null";
+}
+
+void
+CodeVisitor::writeAssign(const MemberInfo& info)
+{
+ StructPtr st = StructPtr::dynamicCast(info.type);
+ if(st)
+ {
+ _out << nl << "$this->" << info.fixedName << " = is_null($" << info.fixedName << ") ? new "
+ << getAbsolute(st, _ns) << " : $" << info.fixedName << ';';
+ }
+ else
+ {
+ _out << nl << "$this->" << info.fixedName << " = $" << info.fixedName << ';';
+ }
+}
+
+string
+CodeVisitor::getOperationMode(Slice::Operation::Mode mode, bool ns)
+{
+ ostringstream ostr;
+ ostr << static_cast<int>(mode);
+ return ostr.str();
+}
+
+void
+CodeVisitor::collectClassMembers(const ClassDefPtr& p, MemberInfoList& allMembers, bool inherited)
+{
+ ClassList bases = p->bases();
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ collectClassMembers(bases.front(), allMembers, true);
+ }
+
+ DataMemberList members = p->dataMembers();
+
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ MemberInfo m;
+ m.fixedName = fixIdent((*q)->name());
+ m.type = (*q)->type();
+ m.inherited = inherited;
+ m.metaData = (*q)->getMetaData();
+ allMembers.push_back(m);
+ }
+}
+
+void
+CodeVisitor::collectExceptionMembers(const ExceptionPtr& p, MemberInfoList& allMembers, bool inherited)
+{
+ ExceptionPtr base = p->base();
+ if(base)
+ {
+ collectExceptionMembers(base, allMembers, true);
+ }
+
+ DataMemberList members = p->dataMembers();
+
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ MemberInfo m;
+ m.fixedName = fixIdent((*q)->name());
+ m.type = (*q)->type();
+ m.inherited = inherited;
+ m.metaData = (*q)->getMetaData();
+ allMembers.push_back(m);
+ }
+}
+
+static void
+generate(const UnitPtr& un, bool all, bool checksum, bool ns, const vector<string>& includePaths, Output& out)
+{
+ if(!all)
+ {
+ vector<string> paths = includePaths;
+ for(vector<string>::iterator p = paths.begin(); p != paths.end(); ++p)
+ {
+ *p = fullPath(*p);
+ }
+
+ StringList includes = un->includeFiles();
+ if(!includes.empty())
+ {
+ if(ns)
+ {
+ out << sp;
+ out << nl << "namespace";
+ out << sb;
+ }
+ for(StringList::const_iterator q = includes.begin(); q != includes.end(); ++q)
+ {
+ string file = changeInclude(*q, paths);
+ out << nl << "require '" << file << ".php';";
+ }
+ if(ns)
+ {
+ out << eb;
+ }
+ }
+ }
+
+ CodeVisitor codeVisitor(out, ns);
+ un->visit(&codeVisitor, false);
+
+ if(checksum)
+ {
+ ChecksumMap checksums = createChecksums(un);
+ if(!checksums.empty())
+ {
+ out << sp;
+ if(ns)
+ {
+ out << "namespace"; // Global namespace.
+ out << sb;
+ }
+ for(ChecksumMap::const_iterator p = checksums.begin(); p != checksums.end(); ++p)
+ {
+ out << nl << "$Ice_sliceChecksums[\"" << p->first << "\"] = \"";
+ ostringstream str;
+ str.flags(ios_base::hex);
+ str.fill('0');
+ for(vector<unsigned char>::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ str << (int)(*q);
+ }
+ out << str.str() << "\";";
+ }
+ if(ns)
+ {
+ out << eb;
+ }
+ }
+ }
+
+ out << nl; // Trailing newline.
+}
+
+static void
+printHeader(IceUtilInternal::Output& out)
+{
+ static const char* header =
+"// **********************************************************************\n"
+"//\n"
+"// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.\n"
+"//\n"
+"// This copy of Ice is licensed to you under the terms described in the\n"
+"// ICE_LICENSE file included in this distribution.\n"
+"//\n"
+"// **********************************************************************\n"
+ ;
+
+ out << header;
+ out << "\n// Ice version " << ICE_STRING_VERSION;
+}
+
+static IceUtil::StaticMutex _mutex = ICE_STATIC_MUTEX_INITIALIZER;
+static bool _interrupted = false;
+
+void
+interruptedCallback(int signal)
+{
+ IceUtil::StaticMutex::Lock lock(_mutex);
+
+ _interrupted = true;
+}
+
+void
+usage(const char* n)
+{
+ cerr << "Usage: " << n << " [options] slice-files...\n";
+ cerr <<
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ "-DNAME Define NAME as 1.\n"
+ "-DNAME=DEF Define NAME as DEF.\n"
+ "-UNAME Remove any definition for NAME.\n"
+ "-IDIR Put DIR in the include file search path.\n"
+ "-E Print preprocessor output on stdout.\n"
+ "--output-dir DIR Create files in the directory DIR.\n"
+ "-d, --debug Print debug messages.\n"
+ "--ice Permit `Ice' prefix (for building Ice source code only)\n"
+ "--all Generate code for Slice definitions in included files.\n"
+ "--checksum Generate checksums for Slice definitions.\n"
+ "-n, --namespace Use PHP namespaces (requires PHP 5.3.0 or later).\n"
+ ;
+}
+
+int
+main(int argc, char* argv[])
+{
+ IceUtilInternal::Options opts;
+ opts.addOpt("h", "help");
+ opts.addOpt("v", "version");
+ opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
+ opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
+ opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
+ opts.addOpt("E");
+ opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg);
+ opts.addOpt("d", "debug");
+ opts.addOpt("", "ice");
+ opts.addOpt("", "all");
+ opts.addOpt("", "checksum");
+ opts.addOpt("n", "namespace");
+
+ vector<string> args;
+ try
+ {
+#if defined(__BCPLUSPLUS__) && (__BCPLUSPLUS__ >= 0x0600)
+ IceUtil::DummyBCC dummy;
+#endif
+ args = opts.parse(argc, (const char**)argv);
+ }
+ catch(const IceUtilInternal::BadOptException& e)
+ {
+ cerr << argv[0] << ": error: " << e.reason << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if(opts.isSet("help"))
+ {
+ usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+
+ if(opts.isSet("version"))
+ {
+ cerr << ICE_STRING_VERSION << endl;
+ return EXIT_SUCCESS;
+ }
+
+ vector<string> cppArgs;
+ vector<string> optargs = opts.argVec("D");
+ vector<string>::const_iterator i;
+ for(i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs.push_back("-D" + *i);
+ }
+
+ optargs = opts.argVec("U");
+ for(i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs.push_back("-U" + *i);
+ }
+
+ vector<string> includePaths = opts.argVec("I");
+ for(i = includePaths.begin(); i != includePaths.end(); ++i)
+ {
+ cppArgs.push_back("-I" + Preprocessor::normalizeIncludePath(*i));
+ }
+
+ bool preprocess = opts.isSet("E");
+
+ string output = opts.optArg("output-dir");
+
+ bool debug = opts.isSet("debug");
+
+ bool ice = opts.isSet("ice");
+
+ bool all = opts.isSet("all");
+
+ bool checksum = opts.isSet("checksum");
+
+ bool ns = opts.isSet("namespace");
+
+ if(args.empty())
+ {
+ getErrorStream() << argv[0] << ": error: no input file" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ int status = EXIT_SUCCESS;
+
+ IceUtil::CtrlCHandler ctrlCHandler;
+ ctrlCHandler.setCallback(interruptedCallback);
+
+ for(i = args.begin(); i != args.end(); ++i)
+ {
+ Preprocessor icecpp(argv[0], *i, cppArgs);
+ FILE* cppHandle = icecpp.preprocess(false);
+
+ if(cppHandle == 0)
+ {
+ return EXIT_FAILURE;
+ }
+
+ if(preprocess)
+ {
+ char buf[4096];
+ while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL)
+ {
+ if(fputs(buf, stdout) == EOF)
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ if(!icecpp.close())
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ UnitPtr u = Unit::createUnit(false, all, ice);
+ int parseStatus = u->parse(*i, cppHandle, debug);
+
+ if(!icecpp.close())
+ {
+ u->destroy();
+ return EXIT_FAILURE;
+ }
+
+ if(parseStatus == EXIT_FAILURE)
+ {
+ status = EXIT_FAILURE;
+ }
+ else
+ {
+ string base = icecpp.getBaseName();
+ string::size_type pos = base.find_last_of("/\\");
+ if(pos != string::npos)
+ {
+ base.erase(0, pos + 1);
+ }
+
+ string file = base + ".php";
+ if(!output.empty())
+ {
+ file = output + '/' + file;
+ }
+
+ try
+ {
+ IceUtilInternal::Output out;
+ out.open(file.c_str());
+ if(!out)
+ {
+ ostringstream os;
+ os << "cannot open`" << file << "': " << strerror(errno);
+ throw FileException(__FILE__, __LINE__, os.str());
+ }
+ FileTracker::instance()->addFile(file);
+
+ out << "<?php\n";
+ printHeader(out);
+ out << "\n// Generated from file `" << base << ".ice'\n";
+
+ //
+ // Generate the PHP mapping.
+ //
+ generate(u, all, checksum, ns, includePaths, out);
+
+ out << "?>\n";
+ out.close();
+ }
+ catch(const Slice::FileException& ex)
+ {
+ // If a file could not be created, then cleanup any
+ // created files.
+ FileTracker::instance()->cleanup();
+ u->destroy();
+ getErrorStream() << argv[0] << ": error: " << ex.reason() << endl;
+ return EXIT_FAILURE;
+ }
+ catch(const string& err)
+ {
+ FileTracker::instance()->cleanup();
+ getErrorStream() << argv[0] << ": error: " << err << endl;
+ status = EXIT_FAILURE;
+ }
+ }
+
+ u->destroy();
+ }
+
+ {
+ IceUtil::StaticMutex::Lock lock(_mutex);
+
+ if(_interrupted)
+ {
+ FileTracker::instance()->cleanup();
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ return status;
+}
diff --git a/cpp/src/slice2php/Makefile b/cpp/src/slice2php/Makefile
new file mode 100644
index 00000000000..5c7d5cdffb5
--- /dev/null
+++ b/cpp/src/slice2php/Makefile
@@ -0,0 +1,31 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+NAME = $(top_srcdir)/bin/slice2php
+
+TARGETS = $(NAME)
+
+OBJS = Main.o
+
+SRCS = $(OBJS:.o=.cpp)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(NAME): $(OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) -lSlice $(BASELIBS) $(MCPP_RPATH_LINK)
+
+install:: all
+ $(call installprogram,$(NAME),$(install_bindir))
+
+include .depend
diff --git a/cpp/src/slice2php/Makefile.mak b/cpp/src/slice2php/Makefile.mak
new file mode 100644
index 00000000000..3f1d6bf9be1
--- /dev/null
+++ b/cpp/src/slice2php/Makefile.mak
@@ -0,0 +1,60 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+NAME = $(top_srcdir)\bin\slice2php.exe
+
+TARGETS = $(NAME)
+
+OBJS = Main.obj
+
+SRCS = $(OBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I. $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(GENERATE_PDB)" == "yes"
+PDBFLAGS = /pdb:$(NAME:.exe=.pdb)
+!endif
+
+!if "$(BCPLUSPLUS)" == "yes"
+RES_FILE = ,, Slice2PHP.res
+!else
+RES_FILE = Slice2PHP.res
+!endif
+
+$(NAME): $(OBJS) Slice2PHP.res
+ $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(OBJS) $(SETARGV) $(PREOUT)$@ $(PRELIBS)slice$(LIBSUFFIX).lib \
+ $(BASELIBS) $(RES_FILE)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+clean::
+ del /q $(NAME:.exe=.*)
+ del /q Slice2PHP.res
+
+install:: all
+ copy $(NAME) $(install_bindir)
+
+
+!if "$(BCPLUSPLUS)" == "yes" && "$(OPTIMIZE)" != "yes"
+
+install:: all
+ copy $(NAME:.exe=.tds) $(install_bindir)
+
+!elseif "$(GENERATE_PDB)" == "yes"
+
+install:: all
+ copy $(NAME:.exe=.pdb) $(install_bindir)
+
+!endif
+
+!include .depend
diff --git a/cpp/src/slice2php/Slice2PHP.rc b/cpp/src/slice2php/Slice2PHP.rc
new file mode 100644
index 00000000000..31db7dfc054
--- /dev/null
+++ b/cpp/src/slice2php/Slice2PHP.rc
@@ -0,0 +1,34 @@
+#include "winver.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,3,1,0
+ PRODUCTVERSION 3,3,1,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE VFT_APP
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "ZeroC, Inc.\0"
+ VALUE "FileDescription", "Slice To Python Translator\0"
+ VALUE "FileVersion", "3.3.1\0"
+ VALUE "InternalName", "slice2py\0"
+ VALUE "LegalCopyright", "Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.\0"
+ VALUE "OriginalFilename", "slice2py.exe\0"
+ VALUE "ProductName", "Ice\0"
+ VALUE "ProductVersion", "3.3.1\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
diff --git a/distribution/src/rpm/ice.spec b/distribution/src/rpm/ice.spec
index 5c62063e7a3..e3ed4cdb93e 100644
--- a/distribution/src/rpm/ice.spec
+++ b/distribution/src/rpm/ice.spec
@@ -247,9 +247,16 @@ Tools for developing Ice applications in Python.
%package php
Summary: The Ice runtime for PHP
Group: System Environment/Libraries
-Requires: ice = %{version}-%{release}
+Requires: ice-libs = %{version}-%{release}
%description php
The Ice runtime for PHP.
+
+%package php-devel
+Summary: Tools for developing Ice applications in PHP
+Group: Development/Tools
+Requires: ice-php = %{version}-%{release}
+%description php-devel
+Tools for developing Ice applications in PHP.
%endif
@@ -283,7 +290,7 @@ make %{makeopts} OPTIMIZE=yes embedded_runpath_prefix=""
%endif
#
-# We build java5 all the time, since we include the GUI and
+# We build java all the time, since we include the GUI and
# ant-ice.jar in a non-noarch package.
#
cd $RPM_BUILD_DIR/Ice-%{version}/java
@@ -291,11 +298,7 @@ export CLASSPATH=`build-classpath db-%{dbversion} jgoodies-forms-%{formsversion}
JGOODIES_FORMS=`find-jar jgoodies-forms-%{formsversion}`
JGOODIES_LOOKS=`find-jar jgoodies-looks-%{looksversion}`
-ant -Dice.mapping=java5 -Dbuild.suffix=java5 -Djgoodies.forms=$JGOODIES_FORMS -Djgoodies.looks=$JGOODIES_LOOKS jar
-
-%ifarch noarch
-ant -Dice.mapping=java2 -Dbuild.suffix=java2 jar
-%endif
+ant -Djgoodies.forms=$JGOODIES_FORMS -Djgoodies.looks=$JGOODIES_LOOKS jar
#
# We build mono all the time because we include iceboxnet.exe in an
@@ -360,14 +363,18 @@ make prefix=$RPM_BUILD_ROOT install
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/php.d
cp -p $RPM_BUILD_DIR/Ice-rpmbuild-%{version}/ice.ini $RPM_BUILD_ROOT%{_sysconfdir}/php.d
mkdir -p $RPM_BUILD_ROOT%{_libdir}/php/modules
-mv $RPM_BUILD_ROOT/%_lib/IcePHP.so $RPM_BUILD_ROOT%{_libdir}/php/modules
+mv $RPM_BUILD_ROOT/php/IcePHP.so $RPM_BUILD_ROOT%{_libdir}/php/modules
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/php
+mv $RPM_BUILD_ROOT/php/* $RPM_BUILD_ROOT%{_datadir}/php
%endif
%if "%{dist}" == ".sles10"
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/php5/conf.d
cp -p $RPM_BUILD_DIR/Ice-rpmbuild-%{version}/ice.ini $RPM_BUILD_ROOT%{_sysconfdir}/php5/conf.d
mkdir -p $RPM_BUILD_ROOT%{_libdir}/php5/extensions
-mv $RPM_BUILD_ROOT/%_lib/IcePHP.so $RPM_BUILD_ROOT%{_libdir}/php5/extensions
+mv $RPM_BUILD_ROOT/php/IcePHP.so $RPM_BUILD_ROOT%{_libdir}/php5/extensions
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/php5
+mv $RPM_BUILD_ROOT/php/* $RPM_BUILD_ROOT%{_datadir}/php5
%endif
#
@@ -386,7 +393,7 @@ rm -f $RPM_BUILD_ROOT%{_bindir}/slice2rb
# IceGridGUI
#
mkdir -p $RPM_BUILD_ROOT%{_javadir}
-cp -p $RPM_BUILD_DIR/Ice-%{version}/java/libjava5/IceGridGUI.jar $RPM_BUILD_ROOT%{_javadir}/IceGridGUI-%{version}.jar
+cp -p $RPM_BUILD_DIR/Ice-%{version}/java/lib/IceGridGUI.jar $RPM_BUILD_ROOT%{_javadir}/IceGridGUI-%{version}.jar
ln -s IceGridGUI-%{version}.jar $RPM_BUILD_ROOT%{_javadir}/IceGridGUI.jar
cp -p $RPM_BUILD_DIR/Ice-%{version}/java/bin/icegridgui.rpm $RPM_BUILD_ROOT%{_bindir}/icegridgui
mkdir -p $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}-%{version}/help
@@ -395,7 +402,7 @@ cp -Rp $RPM_BUILD_DIR/Ice-%{version}/java/resources/IceGridAdmin $RPM_BUILD_ROOT
#
# ant-ice.jar
#
-cp -p $RPM_BUILD_DIR/Ice-%{version}/java/libjava5/ant-ice.jar $RPM_BUILD_ROOT%{_javadir}/ant-ice-%{version}.jar
+cp -p $RPM_BUILD_DIR/Ice-%{version}/java/lib/ant-ice.jar $RPM_BUILD_ROOT%{_javadir}/ant-ice-%{version}.jar
ln -s ant-ice-%{version}.jar $RPM_BUILD_ROOT%{_javadir}/ant-ice.jar
@@ -468,14 +475,11 @@ cp -p $RPM_BUILD_DIR/Ice-rpmbuild-%{version}/SOURCES.Linux $RPM_BUILD_ROOT%{_def
# Java install (using jpackage conventions)
#
cd $RPM_BUILD_DIR/Ice-%{version}/java
-ant -Dice.mapping=java5 -Dbuild.suffix=java5 -Dprefix=$RPM_BUILD_ROOT install
-ant -Dice.mapping=java2 -Dbuild.suffix=java2 -Dprefix=$RPM_BUILD_ROOT install
+ant -Dprefix=$RPM_BUILD_ROOT install
mkdir -p $RPM_BUILD_ROOT%{_javadir}
mv $RPM_BUILD_ROOT/lib/Ice.jar $RPM_BUILD_ROOT%{_javadir}/Ice-%{version}.jar
ln -s Ice-%{version}.jar $RPM_BUILD_ROOT%{_javadir}/Ice.jar
-mv $RPM_BUILD_ROOT/lib/java2/Ice.jar $RPM_BUILD_ROOT%{_javadir}/Ice-java2-%{version}.jar
-ln -s Ice-java2-%{version}.jar $RPM_BUILD_ROOT%{_javadir}/Ice-java2.jar
%if %{mono}
@@ -568,8 +572,6 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-, root, root, -)
%{_javadir}/Ice-%{version}.jar
%{_javadir}/Ice.jar
-%{_javadir}/Ice-java2-%{version}.jar
-%{_javadir}/Ice-java2.jar
%endif
#
@@ -775,6 +777,7 @@ fi
%files php
%defattr(-, root, root, -)
+%{_datadir}/Ice-%{version}/php
%if "%{dist}" == ".rhel4" || "%{dist}" == ".rhel5"
%{_libdir}/php/modules/IcePHP.so
@@ -785,6 +788,10 @@ fi
%{_libdir}/php5/extensions
%config(noreplace) %{_sysconfdir}/php5/conf.d/ice.ini
%endif
+
+%files php-devel
+%defattr(-, root, root, -)
+%{_bindir}/slice2php
%endif
diff --git a/distribution/src/unix/README.Linux-RPM b/distribution/src/unix/README.Linux-RPM
index a7ffe53ec0b..43fe36beaab 100644
--- a/distribution/src/unix/README.Linux-RPM
+++ b/distribution/src/unix/README.Linux-RPM
@@ -183,6 +183,29 @@ You can verify that the Ice extension is installed properly by
examining the output of the "php -m" command, or by calling the
phpinfo() function from a script.
+Your application will also need to include at least some of the Ice
+for PHP run-time source files (installed in /usr/share/Ice-@ver@/php).
+To make these files available to your application, you can either
+modify PHP's include path or copy the necessary files to a directory
+that is already in the interpreter's include path. You can determine
+the current include path by executing the following command:
+
+% php -i | grep include_path
+
+If you want to make the Ice run-time files available to all PHP
+applications on the host, you can modify the include_path setting in
+php.ini to add the installation directory:
+
+include_path = /usr/share/Ice-@ver@/php:...
+
+Another option is to modify the include path from within your
+script prior to including any Ice run-time file:
+
+// PHP
+ini_set('include_path',
+ ini_get('include_path') . PATH_SEPARATOR . '/usr/share/Ice-@ver@/php')
+require 'Ice.php'; // Load the core Ice run time definitions.
+
On SuSE Linux Enterprise Server 10, you need to install php5 version
5.1.2-29.22 or greater (as long as the greater version maintains
binary compatibility). Note that php5 5.1.2-29.22 is not binary
diff --git a/distribution/src/windows/vc60/doc/README.txt b/distribution/src/windows/vc60/doc/README.txt
index 59a29befc26..6efa6faaadd 100644
--- a/distribution/src/windows/vc60/doc/README.txt
+++ b/distribution/src/windows/vc60/doc/README.txt
@@ -24,7 +24,7 @@ development tools to build Ice applications:
- in C++, using Visual Studio 6.0
- in Ruby, using Ruby 1.8.6
- - in PHP, using PHP 5.2.6
+ - in PHP, using PHP 5.2.10
If you want to develop Ice applications in another programming
language, or with another C++ compiler, please download the
@@ -200,22 +200,17 @@ OpenSSL, such as C++ and Python.
Running the PHP demos
---------------------
-Two PHP demos are provided in the demophp directory.
+PHP demos are provided in the demophp directory.
-To run the PHP demos, you need PHP 5.2.6. It can be downloaded from:
+You will need PHP 5.2.10 to run the demos. It can be downloaded from:
http://www.php.net/downloads.php
-The example in demophp\Ice\hello demonstrates the use of the Ice
-extension for PHP in a dynamic Web page, whereas the example in
-demophp\Ice\value requires PHP's command line interpreter. Both
-examples require that an Ice server be available; a matching server
-from any of the other language mappings can be used. A README file is
-provided in each of the example directories.
-
-Note that you must modify the php.ini files in each demo directory to
-match your PHP installation and ensure that the Ice extension for PHP
-is loaded properly.
+The examples in demophp\Ice\hello and demophp\Glacier2\hello
+demonstrate using the Ice extension for PHP in a dynamic Web page,
+whereas the example in demophp\Ice\value requires PHP's command-line
+interpreter. A README file is provided in each of the example
+directories.
Using IcePHP with Apache
@@ -338,44 +333,27 @@ appropriate changes as you follow the instructions.
for Apache to fail at startup are missing DLLs (see step 4) or
insufficient access rights (see step 5).
-7) Apache's executable has a relatively small default stack size. You
- can determine its current stack size with the following commands:
-
- > cd \Program Files\Apache Software Foundation\Apache2.2\bin
- > dumpbin /all httpd.exe | find "stack"
-
- The relevant output line is shown below:
-
- 40000 size of stack reserve
-
- The default size is 0x40000 (262,144) bytes, which is too small to
- effectively use the Ice extension. Attempting to load even a
- trivial Slice file causes Apache to fail during startup with a
- stack overflow error.
-
- To increase the stack size, make sure that the Apache service is
- not running and use the editbin utility to modify the executable.
- Note that the new stack size is given in decimal:
-
- > editbin /stack:1048576 httpd.exe
-
- Now execute dumpbin again to verify that the change was made:
-
- > dumpbin /all httpd.exe | find "stack"
-
- The new output line is shown below:
+7) Your application will also need to include at least some of the Ice
+ for PHP run-time source files (installed in C:\Ice\php). To make
+ these files available to your application, you can either modify
+ PHP's include path or copy the necessary files to a directory that
+ is already in the interpreter's include path. You can determine the
+ current include path by loading the phpinfo.php page in your
+ browser and searching for an entry named "include_path".
- 100000 size of stack reserve
+ If you want to make the Ice run-time files available to all PHP
+ applications on the host, you can modify the include_path setting
+ in php.ini to add the installation directory:
-8) In order to load Slice definitions for a PHP script, you must
- modify php.ini and then restart Apache. For example, the "hello"
- demo in C:\Ice\demophp\Ice\hello requires the following addition to
- php.ini:
+ include_path = C:\Ice\php;...
- ice.slice = C:\Ice\demophp\Ice\hello\Hello.ice
+ Another option is to modify the include path from within your
+ script prior to including any Ice run-time file:
- Be aware that specifying a relative path for a Slice file means
- the path is relative to the Apache installation directory.
+ // PHP
+ ini_set('include_path',
+ ini_get('include_path') . PATH_SEPARATOR . 'C:/Ice/php')
+ require 'Ice.php'; // Load the core Ice run time definitions.
Binary compatibility
diff --git a/java/src/IceSSL/PasswordCallback.java b/java/src/IceSSL/PasswordCallback.java
index 9fc76d6e59f..192fe9299cd 100644
--- a/java/src/IceSSL/PasswordCallback.java
+++ b/java/src/IceSSL/PasswordCallback.java
@@ -23,7 +23,7 @@ public interface PasswordCallback
* @param alias The value of the property <code>IceSSL.Alias</code>, if that
* property is set; <code>null</code>, otherwise.
* @return The password for the key. The return value must not be <code>null</code>.
- *
+ *
**/
char[] getPassword(String alias);
diff --git a/php/INSTALL b/php/INSTALL
index c9219093343..4a29d76358f 100644
--- a/php/INSTALL
+++ b/php/INSTALL
@@ -6,7 +6,7 @@ Requirements
* 5.1.2 (SLES 10)
* 5.1.6 (RHEL)
- * 5.2.6 (source builds)
+ * 5.2.x or 5.3.x (source builds)
You can download PHP from
@@ -32,7 +32,8 @@ Follow the steps below to build Ice for PHP:
2. Edit config/Make.rules and review the build settings. For example,
you may want to enable OPTIMIZE. If your PHP installation resides
in a non-standard location, modify the PHP_HOME setting to contain
- the installation directory.
+ the installation directory. If you are using PHP 5.3 or later and
+ wish to use PHP namespaces, set USE_NAMESPACES=yes.
3. If you have not built Ice for C++ from the cpp subdirectory, then
set the ICE_HOME environment variable to the directory containing
@@ -53,20 +54,20 @@ Building PHP with the Ice extension (Windows)
======================================================================
Compiling PHP from source code on Windows is a tedious process,
-therefore we recommend that you download the binary distribution
-for PHP and use it along with the precompiled dynamic Ice extension
-included in the Ice installer for Visual C++ 6.0.
+therefore we recommend that you download a binary distribution of PHP
+and use it along with the precompiled dynamic Ice extension included
+in the Ice installer for Visual C++ 6.0 (VC6).
If you prefer to build the Ice extension yourself, you must first
understand the C run time dependency issues. Specifically, the Ice
extension must use the same C run time as PHP5. Since the binary
distribution of PHP5 available from php.net depends on the Visual C++
6.0 run time DLL (MSVCRT), you must also build the Ice extension using
-Visual C++ 6.0 if you want to use Ice with this PHP distribution. This
-is why the precompiled Ice extension is included in the Ice installer
-for Visual C++ 6.0, as attempting to use an Ice extension that was
-built with a newer compiler together with the binary PHP distribution
-results in undefined behavior.
+VC6 if you want to use Ice with this PHP distribution. This is why the
+precompiled Ice extension is included in the Ice installer for VC6, as
+attempting to use an Ice extension that was built with a newer
+compiler together with the binary PHP distribution results in
+undefined behavior.
To use a later version of Visual C++, you must obtain (or build) PHP5
with the desired compiler, and use the same compiler to build the Ice
@@ -79,7 +80,15 @@ Follow these instructions to build the Ice extension:
the distribution.
2) Download and extract the PHP5 sources (Ice for PHP requires the PHP
- header files).
+ header files). If you are using PHP 5.3, change to the PHP5 source
+ directory and run the following commands:
+
+ > buildconf
+ > configure
+
+ You do not need to actually build PHP from source, but these two
+ steps are necessary to generate header files that are required by
+ the Ice extension.
3) Open a command window.
@@ -97,14 +106,17 @@ Follow these instructions to build the Ice extension:
necessary changes. In particular, you may need to change the values
of PHP_HOME and PHP_BIN_HOME to refer to your PHP source and binary
installations, respectively. If you compiled PHP from source, you
- should also review the setting of PHP_LIBDIR.
+ should also review the setting of PHP_LIBDIR. If you are using PHP
+ 5.3 or later and wish to use PHP namespaces, set
+ USE_NAMESPACES=yes. Finally, if you are using a non-thread-safe PHP
+ installation, set PHP_ZTS=no.
7) Start NMAKE:
nmake /f Makefile.mak
8) Upon successful completion, the Ice for PHP extension is created as
- bin\php_ice.dll (Release) or bin\php_iced.dll (Debug).
+ lib\php_ice.dll (Release) or lib\php_iced.dll (Debug).
======================================================================
@@ -216,8 +228,9 @@ Dependencies
PHP will need to be able to locate the Ice run-time libraries "Ice",
"Slice", "IceUtil" and "bzip2" (Windows) or "libbz2" (Unix). On
-Windows, the STLport library is also necessary. In general, these
-libraries must reside in a directory of the user's PATH.
+Windows, the STLport library is also necessary when using VC6. In
+general, these libraries must reside in a directory of the user's
+PATH.
For Web servers, the libraries may need to reside in a system
directory. For example, on Linux you can add the directory containing
@@ -244,14 +257,33 @@ will also need access to the shared libraries for IceSSL and OpenSSL.
======================================================================
+Source Files
+======================================================================
+
+In addition to the binary Ice extension module, you will also need to
+make the Ice for PHP source files available to your scripts. These
+files are located in the "lib" subdirectory and consist of the Ice run
+time definitions (Ice.php or Ice_ns.php) along with PHP source files
+generated from the Slice files included in the Ice distribution.
+
+The Ice extension makes no assumptions about the location of these
+files, so you can install them anywhere you like. For example, you can
+simply include them in the same directory as your application scripts.
+Alternatively, if you prefer to install them in a common directory,
+you may need to modify PHP's include_path directive so that the PHP
+interpreter is able to locate these files.
+
+
+======================================================================
Permissions
======================================================================
The Web server normally runs in a special user account that may not
-necessarily have access to the Ice extension, its dependent libraries,
-and other resources such as Ice configuration files, Slice files, and
-PHP scripts. It is very important that you review the permissions of
-these files and verify that the Web server has sufficient access.
+necessarily have access to the Ice extension, its dependent libraries
+and PHP source files, and other resources such as Ice configuration
+and your application scripts. It is very important that you review the
+permissions of these files and verify that the Web server has
+sufficient access.
For example, on Windows the Apache server typically runs as a service
in the "Local System" account. You will need to modify the access
@@ -273,39 +305,6 @@ accessible.
======================================================================
-Apache Notes (Windows)
-======================================================================
-
-Apache's executable has a relatively small default stack size. You can
-determine its current stack size with the following commands:
-
- cd \Program Files\Apache Software Foundation\Apache2.2\bin
- dumpbin /all httpd.exe | find "stack"
-
-The relevant output line is shown below:
-
- 40000 size of stack reserve
-
-The default size is 0x40000 bytes, which is too small to effectively
-use the Ice extension. Attempting to load even a trivial Slice file
-causes Apache to fail during startup with a stack overflow error.
-
-To increase the stack size, use the editbin utility. Note that the
-new stack size is given in decimal:
-
- editbin /stack:1048576 httpd.exe
-
-Now execute dumpbin again to verify that the change was made:
-
- dumpbin /all httpd.exe | find "stack"
-
-The new output line is shown below:
-
- 100000 size of stack reserve
-
-
-
-======================================================================
SELinux Notes
======================================================================
diff --git a/php/Makefile b/php/Makefile
index dd86d998f1a..e11c52fcf3e 100644
--- a/php/Makefile
+++ b/php/Makefile
@@ -11,13 +11,13 @@ top_srcdir = .
include $(top_srcdir)/config/Make.rules
-SUBDIRS = src
+SUBDIRS = src lib demo test
install:: install-common
- @if test ! -d $(install_libdir) ; \
+ @if test ! -d $(install_phpdir) ; \
then \
- echo "Creating $(install_libdir)..." ; \
- $(call mkdir,$(install_libdir)) ; \
+ echo "Creating $(install_phpdir)..." ; \
+ $(call mkdir,$(install_phpdir)) ; \
fi
$(EVERYTHING)::
diff --git a/php/Makefile.mak b/php/Makefile.mak
index 152ad0dc3d6..ac141432a40 100644
--- a/php/Makefile.mak
+++ b/php/Makefile.mak
@@ -11,7 +11,7 @@ top_srcdir = .
!include $(top_srcdir)\config\Make.rules.mak
-SUBDIRS = src
+SUBDIRS = src lib demo test
install:: install-common
@if not exist $(install_libdir) \
diff --git a/php/allTests.py b/php/allTests.py
index 8267c7a7a10..90bcfe96d79 100755
--- a/php/allTests.py
+++ b/php/allTests.py
@@ -29,6 +29,7 @@ tests = [
("Ice/exceptions", ["core"]),
("Ice/inheritance", ["core"]),
("Ice/binding", ["core"]),
+ ("Ice/checksum", ["core"]),
("Ice/facets", ["core"]),
("Ice/objects", ["core"]),
("Ice/slicing/exceptions", ["core"]),
diff --git a/php/bin/.gitignore b/php/bin/.gitignore
deleted file mode 100644
index 39af5887579..00000000000
--- a/php/bin/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-# Dummy file, so that git retains this otherwise empty directory.
diff --git a/php/config/Make.rules b/php/config/Make.rules
index 89715f202d6..d6a6f58885e 100644
--- a/php/config/Make.rules
+++ b/php/config/Make.rules
@@ -39,6 +39,12 @@ embedded_runpath_prefix ?= /opt/Ice-$(VERSION_MAJOR).$(VERSION_MINOR)
#
#
+# Determines whether the extension uses PHP namespaces (requires
+# PHP 5.3 or later).
+#
+#USE_NAMESPACES ?= yes
+
+#
# If you've built PHP yourself then set PHP_HOME to contain the
# installation directory; the rest of the PHP-related settings
# should be correct.
@@ -85,7 +91,7 @@ PHP_FLAGS ?= -I$(PHP_INCLUDE_DIR) -I$(PHP_INCLUDE_DIR)/main -I$(PHP_INCLUDE_DIR)
#
ice_language = php
ice_require_cpp = yes
-slice_translator = slice2cpp
+slice_translator = slice2php
ifeq ($(shell test -f $(top_srcdir)/config/Make.common.rules && echo 0),0)
include $(top_srcdir)/config/Make.common.rules
@@ -94,7 +100,8 @@ else
endif
libdir = $(top_srcdir)/lib
-install_libdir = $(prefix)/$(libsubdir)
+install_phpdir = $(prefix)/php
+install_libdir = $(prefix)/php
#
# Platform specific definitions
@@ -104,7 +111,7 @@ ifeq ($(shell test -f $(top_srcdir)/config/Make.rules.$(UNAME) && echo 0),0)
else
configdir = $(top_srcdir)/../cpp/config
endif
-include $(configdir)/Make.rules.$(UNAME)
+include $(configdir)/Make.rules.$(UNAME)
ifdef ice_src_dist
ifeq ($(ice_cpp_dir), $(ice_dir)/cpp)
@@ -121,13 +128,29 @@ endif
ICE_LIBS = $(ICE_LIB_DIR) -lIce -lSlice -lIceUtil
ifneq ($(embedded_runpath_prefix),)
- runpath_libdir := $(embedded_runpath_prefix)/lib$(lp64suffix)
+ runpath_libdir := $(embedded_runpath_prefix)/lib$(lp64suffix)
endif
CPPFLAGS =
ICECPPFLAGS = -I$(slicedir)
+SLICE2PHPFLAGS = $(ICECPPFLAGS)
LDFLAGS = $(LDPLATFORMFLAGS) $(CXXFLAGS) -L$(libdir)
+ifeq ("$(USE_NAMESPACES)","yes")
+ CPPFLAGS := $(CPPFLAGS) -DICEPHP_USE_NAMESPACES
+ SLICE2PHPFLAGS := $(SLICE2PHPFLAGS) -n
+endif
+
+ifdef ice_src_dist
+ ifeq ($(ice_cpp_dir), $(ice_dir)/cpp)
+ SLICE2PHP = $(ice_cpp_dir)/bin/slice2php
+ else
+ SLICE2PHP = $(ice_cpp_dir)/$(binsubdir)/slice2php
+ endif
+else
+ SLICE2PHP = $(ice_dir)/$(binsubdir)/slice2php
+endif
+
ifeq ($(installphplib),)
installphplib = $(INSTALL) $(1) $(2); \
chmod a+rx $(2)/$(notdir $(1))
@@ -141,10 +164,14 @@ mkphplibname = $(subst lib,,$(call mklibname,$(1)))
EVERYTHING = all depend clean install
.SUFFIXES:
-.SUFFIXES: .cpp .o .py
+.SUFFIXES: .cpp .o .py .php
all:: $(SRCS)
+%.php: $(SDIR)/%.ice
+ rm -f $(*F).php
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
.cpp.o:
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
@@ -154,11 +181,7 @@ clean::
all:: $(SRCS) $(TARGETS)
-depend:: $(SRCS) $(SLICE_SRCS)
- -rm -f .depend
- if test -n "$(SRCS)" ; then \
- $(CXX) -DMAKEDEPEND -M $(CXXFLAGS) $(CPPFLAGS) $(SRCS) | $(ice_dir)/config/makedepend.py >> .depend; \
- fi
+depend::
ifneq ($(TEMPLATE_REPOSITORY),)
clean::
diff --git a/php/config/Make.rules.mak b/php/config/Make.rules.mak
index 515f5a9b8ec..37f2889f75b 100644
--- a/php/config/Make.rules.mak
+++ b/php/config/Make.rules.mak
@@ -23,17 +23,25 @@ OPTIMIZE = yes
#
# Specify your C++ compiler. Supported values are:
-# VC60
+# VC60, VC90, VC90_EXPRESS
#
!if "$(CPP_COMPILER)" == ""
CPP_COMPILER = VC60
!endif
#
+# Determines whether the extension uses PHP namespaces (requires
+# PHP 5.3 or later).
+#
+!if "$(USE_NAMESPACES)" == ""
+USE_NAMESPACES = no
+!endif
+
+#
# Set PHP_HOME to your PHP source directory.
#
!if "$(PHP_HOME)" == ""
-PHP_HOME = C:\php-5.2.6
+PHP_HOME = C:\php-5.2.9
!endif
#
@@ -44,6 +52,13 @@ PHP_BIN_HOME = C:\Program Files\PHP
!endif
#
+# Set PHP_ZTS to "no" (or comment it out) to disable Zend Thread Safety.
+#
+!if "$(PHP_ZTS)" == ""
+PHP_ZTS = yes
+!endif
+
+#
# STLPort is required if using MSVC++ 6.0. Change if STLPort
# is located in a different location.
#
@@ -65,7 +80,7 @@ STLPORT_HOME = C:\Ice-$(VERSION)-ThirdParty-VC60
#
ice_language = php
ice_require_cpp = yes
-slice_translator = slice2cpp.exe
+slice_translator = slice2php.exe
!if exist ($(top_srcdir)\..\config\Make.common.rules.mak)
!include $(top_srcdir)\..\config\Make.common.rules.mak
@@ -73,11 +88,11 @@ slice_translator = slice2cpp.exe
!include $(top_srcdir)\config\Make.common.rules.mak
!endif
-bindir = $(top_srcdir)\bin
libdir = $(top_srcdir)\lib
-install_bindir = $(prefix)\bin
+install_phpdir = $(prefix)\php
+install_libdir = $(prefix)\php
-!if "$(CPP_COMPILER)" != "VC60"
+!if "$(CPP_COMPILER)" != "VC60" && "$(CPP_COMPILER)" != "VC90" && "$(CPP_COMPILER)" != "VC90_EXPRESS"
!error Invalid setting for CPP_COMPILER: $(CPP_COMPILER)
!endif
@@ -110,24 +125,49 @@ ICE_LDFLAGS = /LIBPATH:"$(ice_dir)\lib"
slicedir = $(ice_dir)\slice
+!if "$(PHP_ZTS)" == "yes"
+PHP_LIB_PREFIX = php5ts
+!else
+PHP_LIB_PREFIX = php5
+!endif
+
!if "$(OPTIMIZE)" != "yes"
PHP_LDFLAGS = /LIBPATH:"$(PHP_BIN_HOME)"
-PHP_LIBS = php5ts_debug.lib
+PHP_LIBS = $(PHP_LIB_PREFIX)_debug.lib
PHP_ZEND_DEBUG = 1
!else
PHP_LDFLAGS = /LIBPATH:"$(PHP_BIN_HOME)\dev"
-PHP_LIBS = php5ts.lib
+PHP_LIBS = $(PHP_LIB_PREFIX).lib
PHP_ZEND_DEBUG = 0
!endif
-PHP_CPPFLAGS = -I"$(PHP_HOME)" -I"$(PHP_HOME)\main" -I"$(PHP_HOME)\TSRM" -I"$(PHP_HOME)\Zend" -DPHP_WIN32 -DZEND_WIN32 -DZEND_DEBUG=$(PHP_ZEND_DEBUG) -DZTS -DWIN32
+PHP_CPPFLAGS = -I"$(PHP_HOME)" -I"$(PHP_HOME)\main" -I"$(PHP_HOME)\TSRM" -I"$(PHP_HOME)\Zend" -DPHP_WIN32 -DZEND_WIN32 -DZEND_DEBUG=$(PHP_ZEND_DEBUG) -DWIN32
+!if "$(PHP_ZTS)" == "yes"
+PHP_CPPFLAGS = $(PHP_CPPFLAGS) -DZTS
+!endif
ICECPPFLAGS = -I$(slicedir)
+SLICE2PHPFLAGS = $(ICECPPFLAGS)
+
+!if "$(USE_NAMESPACES)" == "yes"
+CPPFLAGS = $(CPPFLAGS) -DICEPHP_USE_NAMESPACES
+SLICE2PHPFLAGS = $(SLICE2PHPFLAGS) -n
+!endif
+
+!if "$(ice_src_dist)" != ""
+!if "$(ice_cpp_dir)" == "$(ice_dir)\cpp"
+SLICE2PHP = "$(ice_cpp_dir)\bin\slice2php.exe"
+!else
+SLICE2PHP = "$(ice_cpp_dir)\bin$(x64suffix)\slice2php.exe"
+!endif
+!else
+SLICE2PHP = "$(ice_dir)\bin$(x64suffix)\slice2php.exe"
+!endif
EVERYTHING = all clean install
.SUFFIXES:
-.SUFFIXES: .cpp .obj .rb
+.SUFFIXES: .cpp .obj .php
all:: $(SRCS)
diff --git a/php/demo/Glacier2/Makefile b/php/demo/Glacier2/Makefile
new file mode 100644
index 00000000000..c3e3118ecf4
--- /dev/null
+++ b/php/demo/Glacier2/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = hello
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/php/demo/Glacier2/Makefile.mak b/php/demo/Glacier2/Makefile.mak
new file mode 100644
index 00000000000..02303e64b28
--- /dev/null
+++ b/php/demo/Glacier2/Makefile.mak
@@ -0,0 +1,19 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = hello
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/demo/Glacier2/hello/.gitignore b/php/demo/Glacier2/hello/.gitignore
new file mode 100644
index 00000000000..0b9d5a958ca
--- /dev/null
+++ b/php/demo/Glacier2/hello/.gitignore
@@ -0,0 +1 @@
+Hello.php
diff --git a/php/demo/Glacier2/hello/Hello.ice b/php/demo/Glacier2/hello/Hello.ice
new file mode 100644
index 00000000000..bcaed6ad877
--- /dev/null
+++ b/php/demo/Glacier2/hello/Hello.ice
@@ -0,0 +1,24 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef HELLO_ICE
+#define HELLO_ICE
+
+module Demo
+{
+
+interface Hello
+{
+ idempotent void sayHello(int delay);
+ void shutdown();
+};
+
+};
+
+#endif
diff --git a/php/demo/Glacier2/hello/Makefile b/php/demo/Glacier2/hello/Makefile
new file mode 100644
index 00000000000..99d7b9d48a9
--- /dev/null
+++ b/php/demo/Glacier2/hello/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Hello.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/demo/Glacier2/hello/Makefile.mak b/php/demo/Glacier2/hello/Makefile.mak
new file mode 100644
index 00000000000..9cb7c656975
--- /dev/null
+++ b/php/demo/Glacier2/hello/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Hello.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/demo/Glacier2/hello/README b/php/demo/Glacier2/hello/README
new file mode 100644
index 00000000000..7e6b55cd922
--- /dev/null
+++ b/php/demo/Glacier2/hello/README
@@ -0,0 +1,90 @@
+This directory contains a PHP/HTML application that demonstrates how
+a PHP session can register an Ice communicator and use it in
+subsequent page requests.
+
+To use the application, a user must first log in by providing any
+username and password combination (see login.php). Clicking the
+'Login' button causes the application to create a communicator,
+establish a Glacier2 session, and redirect the user to the session
+page (see session.php). From this page the user can invoke the
+'sayHello' operation on a hello server via the Glacier2 session.
+
+NOTE: As explained in the Ice manual, the ability to register a
+communicator for use by a PHP session is only useful when the
+session's page requests are serviced by the same web server process.
+In order to use this demo effectively, you may need to modify your
+Web server configuration (e.g., to use a single persistent process).
+Non-persistent Web server models (e.g., CGI) cannot be used with this
+demo.
+
+Follow these steps to install the demo:
+
+1) Install the Ice extension and run-time files as described in the
+ top-level INSTALL or README file that accompanied your Ice
+ distribution. Restart the Web server if necessary.
+
+2) Install the following files in your Web server's document
+ directory:
+
+ * login.php
+ * session.php
+ * Hello.php
+
+ The file Hello.php is generated from Hello.ice when you run make or
+ nmake in this directory. Verify that the files have appropriate
+ access rights.
+
+3) In a command window on the Web server host, start a Glacier2 router
+ using the configuration file provided in this directory:
+
+ % glacier2router --Ice.Config=config.glacier2
+
+4) In a separate command window on the same host, start a hello
+ server. You can use a server from any Ice language mapping.
+
+5) Start a Web browser and open the login.php page to begin using the
+ demo. Note that the Glacier2 configuration uses a session timeout
+ of 30 seconds.
+
+If you want to run the Glacier2 router on a different host than the
+Web server, you will need to modify the router's endpoint in
+config.glacier2 and login.php. To run the hello server on a different
+host, modify the endpoint in session.php.
+
+
+======================================================================
+SELinux Notes
+======================================================================
+
+SELinux augments the traditional Unix permissions with a number of
+new features. In particular, SELinux can prevent the httpd daemon from
+opening network connections and reading files without the proper
+SELinux types.
+
+If you suspect that your IcePHP application does not work due to
+SELinux restrictions, we recommend that you first try it with SELinux
+disabled. As root, run:
+
+# setenforce 0
+
+to disable SELinux until the next reboot of your computer.
+
+If you want to run httpd with IcePHP and SELinux enabled, you must do
+the following:
+
+- Allow httpd to open network connections:
+
+ # setsebool httpd_can_network_connect=1
+
+ (add the -P option to make this setting persistent across reboots)
+
+- Make sure any .ice file used by your PHP scripts can be read by
+ httpd. The enclosing directory also needs to be accessible. For
+ example:
+
+ # chcon -R -t httpd_sys_content_t /opt/MyApp/slice
+
+For more information on SELinux in Red Hat Enterprise Linux 4, refer
+to the link below:
+
+ http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/selinux-guide/
diff --git a/php/demo/Glacier2/hello/config.glacier2 b/php/demo/Glacier2/hello/config.glacier2
new file mode 100644
index 00000000000..f57636d73ed
--- /dev/null
+++ b/php/demo/Glacier2/hello/config.glacier2
@@ -0,0 +1,23 @@
+#
+# Set the Glacier2 instance name.
+#
+Glacier2.InstanceName=DemoGlacier2
+
+#
+# The client-visible endpoint of Glacier2. This should be an endpoint
+# visible from the public Internet, and it should typically be secure.
+#
+Glacier2.Client.Endpoints=tcp -p 4063 -h 127.0.0.1
+
+#
+# For this demo, we use the null permissions verifier. This permissions
+# verifier allows any user-id / password combination.
+#
+Glacier2.PermissionsVerifier=DemoGlacier2/NullPermissionsVerifier
+
+#
+# The timeout for inactive sessions. If any client session is inactive
+# for longer than this value, the session expires and is removed. The
+# unit is seconds.
+#
+Glacier2.SessionTimeout=30
diff --git a/php/demo/Glacier2/hello/login.php b/php/demo/Glacier2/hello/login.php
new file mode 100644
index 00000000000..fae442f3b4d
--- /dev/null
+++ b/php/demo/Glacier2/hello/login.php
@@ -0,0 +1,105 @@
+<HTML>
+<HEAD>
+<TITLE>Session Demo - Login</TITLE>
+</HEAD>
+
+<BODY>
+<H1>Session Demo - Login</H1>
+
+<?php
+require 'Ice.php';
+require 'Glacier2.php';
+
+session_start();
+
+try
+{
+ //
+ // Check for an existing session.
+ //
+ $ICE = Ice_find(session_id());
+ if(isset($_SESSION['authenticated']) || $ICE != null)
+ {
+ unset($_SESSION['authenticated']);
+ Ice_unregister(session_id());
+ echo "<P><HR><I>Destroyed previous session.</I><HR></P>\n";
+ }
+
+ //
+ // Generate a new session ID.
+ //
+ session_regenerate_id();
+
+ if(isset($_POST["submitted"]))
+ {
+ //
+ // Initialize a communicator using the default properties.
+ //
+ $initData = new Ice_InitializationData;
+ $initData->properties = Ice_createProperties();
+ $initData->properties->setProperty("Ice.Default.Router", "DemoGlacier2/router:tcp -p 4063 -h 127.0.0.1");
+ $ICE = Ice_initialize($initData);
+
+ try
+ {
+ //
+ // Verify that we are using a Glacier2 router.
+ //
+ $router = Glacier2_RouterPrxHelper::checkedCast($ICE->getDefaultRouter());
+ if($router == null)
+ {
+ echo "<P><HR><B>Configured router is not a Glacier2 router.</B><HR></P>\n";
+ die();
+ }
+
+ $user = "";
+ $password = "";
+
+ if(isset($_POST["user"]))
+ {
+ $user = $_POST["user"];
+ }
+ if(isset($_POST["password"]))
+ {
+ $password = $_POST["password"];
+ }
+
+ if(isset($_POST["login"]))
+ {
+ $router->createSession($user, $password);
+ $_SESSION['authenticated'] = 'true';
+ Ice_register($ICE, session_id(), session_cache_expire());
+ header("Location: session.php"); // Redirect.
+ exit();
+ }
+ }
+ catch(Glacier2_PermissionDeniedException $ex)
+ {
+ echo "<P><HR><B>Login failure: " . $ex->reason . "</B><HR></P>\n";
+ }
+ }
+}
+catch(Ice_LocalException $ex)
+{
+ echo "<P><HR><B>\n";
+ echo "<PRE>\n";
+ print_r($ex);
+ echo "</PRE>\n";
+ echo "</B><HR></P>\n";
+}
+?>
+
+ <P>
+ <FORM method="POST" action="<?php echo basename($_SERVER["PHP_SELF"]); ?>">
+ <P>This demo accepts any username / password combination.</P>
+ <P>
+ Username: <INPUT type="text" size="12" name="user"><BR>
+ <BR>
+ Password: <INPUT type="text" size="12" name="password"><BR>
+ </P>
+ <P>
+ <INPUT type="hidden" name="submitted" value="yes">
+ <INPUT type="submit" name="login" value="Login">
+ </FORM>
+</BODY>
+</HTML>
diff --git a/php/demo/Glacier2/hello/session.php b/php/demo/Glacier2/hello/session.php
new file mode 100644
index 00000000000..fae291ae0ac
--- /dev/null
+++ b/php/demo/Glacier2/hello/session.php
@@ -0,0 +1,99 @@
+<HTML>
+<HEAD>
+<TITLE>Session Demo</TITLE>
+</HEAD>
+
+<BODY>
+
+<H1>Session Demo</H1>
+
+<?php
+require 'Ice.php';
+require 'Glacier2.php';
+require 'Hello.php';
+
+session_start();
+
+try
+{
+ //
+ // Attempt to retrieve the communicator that was registered in login.php
+ // for the session ID.
+ //
+ $ICE = Ice_find(session_id());
+ if(!isset($_SESSION['authenticated']) || $ICE == null)
+ {
+ echo "<P><HR><B>\n";
+ echo "No active session found. Visit the <a href=\"login.php\">login</a> page to proceed.\n";
+ echo "</B><HR></P>\n";
+ exit();
+ }
+
+ if(isset($_POST["submitted"]))
+ {
+ if(isset($_POST["sayHello"]))
+ {
+ $hello = Demo_HelloPrxHelper::uncheckedCast($ICE->stringToProxy("hello:tcp -p 10000"));
+ $hello->sayHello(0);
+ echo "<P><HR><I>Success.</I><HR></P>\n";
+ }
+ elseif(isset($_POST["logout"]))
+ {
+ try
+ {
+ $router = Glacier2_RouterPrxHelper::uncheckedCast($ICE->getDefaultRouter());
+ $router->destroySession();
+ }
+ catch(Ice_ConnectionLostException $ex)
+ {
+ //
+ // This exception is expected when the session is destroyed.
+ //
+ }
+ catch(Glacier2_SessionNotExistException $ex)
+ {
+ //
+ // This exception is expected if the session has expired.
+ //
+ }
+ catch(Exception $ex)
+ {
+ // Ignore.
+ }
+ unset($_SESSION['authenticated']);
+ Ice_unregister(session_id());
+ echo "<P><HR><B>\n";
+ echo "Session destroyed. Visit the <a href=\"login.php\">login</a> page to proceed.\n";
+ echo "</B><HR></P>\n";
+ exit();
+ }
+ }
+}
+catch(Ice_Exception $ex)
+{
+ echo "<P><HR><B>\n";
+ echo "<PRE>\n";
+ print_r($ex);
+ echo "</PRE>\n";
+ echo "</P>\n";
+ echo "<P>\n";
+ echo "Visit the <a href=\"login.php\">login</a> page to proceed.\n";
+ echo "</B><HR></P>\n";
+ unset($_SESSION['authenticated']);
+ Ice_unregister(session_id());
+ exit();
+}
+?>
+
+ <P>
+ <FORM method="POST" action="<?php echo basename($_SERVER["PHP_SELF"]); ?>">
+ <P>Click <B>Say Hello</B> to invoke on the server and keep the session alive.
+ Click <B>Logout</B> to destroy the session.</P>
+ </P>
+ <P>
+ <INPUT type="hidden" name="submitted" value="yes">
+ <INPUT type="submit" name="sayHello" value="Say Hello">
+ <INPUT type="submit" name="logout" value="Logout">
+ </FORM>
+</BODY>
+</HTML>
diff --git a/php/demo/Ice/Makefile b/php/demo/Ice/Makefile
new file mode 100644
index 00000000000..2c1a13bfebe
--- /dev/null
+++ b/php/demo/Ice/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = hello value
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/php/demo/Ice/Makefile.mak b/php/demo/Ice/Makefile.mak
new file mode 100644
index 00000000000..2dee4965246
--- /dev/null
+++ b/php/demo/Ice/Makefile.mak
@@ -0,0 +1,19 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = hello value
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/demo/Ice/hello/.gitignore b/php/demo/Ice/hello/.gitignore
new file mode 100644
index 00000000000..0b9d5a958ca
--- /dev/null
+++ b/php/demo/Ice/hello/.gitignore
@@ -0,0 +1 @@
+Hello.php
diff --git a/php/demo/Ice/hello/Makefile b/php/demo/Ice/hello/Makefile
new file mode 100644
index 00000000000..99d7b9d48a9
--- /dev/null
+++ b/php/demo/Ice/hello/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Hello.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/demo/Ice/hello/Makefile.mak b/php/demo/Ice/hello/Makefile.mak
new file mode 100644
index 00000000000..9cb7c656975
--- /dev/null
+++ b/php/demo/Ice/hello/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Hello.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/demo/Ice/hello/README b/php/demo/Ice/hello/README
index 7c3e5a50d8c..001e75d23c0 100644
--- a/php/demo/Ice/hello/README
+++ b/php/demo/Ice/hello/README
@@ -1,32 +1,29 @@
This directory contains a PHP/HTML implementation of the Ice hello
-client. The procedure for installing this script depends on your Web
-server environment. For example, if you're using PHP as a Web server
-module, then you'll need to install this script in your document root
-directory.
+client.
-Alternatively, if you're using CGI, then you will need to make this
-script executable, add a line at the top of the script to indicate the
-path to the PHP CGI binary, and copy the script to your cgi-bin
-directory. On Unix platforms, the line at the top of the file should
-look something like the one below, where /opt/php5 is the PHP5
-installation directory:
+Follow these steps to install the demo:
-#! /opt/php5/bin/php
+1) Install the Ice extension and run-time files as described in the
+ top-level INSTALL or README file that accompanied your Ice
+ distribution. Restart the Web server if necessary.
-Next, the PHP configuration must be modified to load the Slice
-definitions required by this example. In php.ini, set this directive:
+2) Install the following files in your Web server's document
+ directory:
-ice.slice=/opt/icephp/demo/Ice/hello/Hello.ice
+ * client.php
+ * Hello.php
-For a Linux RPM installation, this directive can be added to
-/etc/php.d/ice.ini.
+ The file Hello.php is generated from Hello.ice when you run make or
+ nmake in this directory. Verify that the files have appropriate
+ access rights.
-Finally, start the hello server on the Web server host and try out the
-script. You can use a hello server from any language mapping.
+3) In a command window on the Web server host, start a hello server.
+ You can use a server from any Ice language mapping.
-Note that support for secure invocations via SSL are disabled by
-default. If you have configured SSL for the Ice extension, edit
-hello.php and set the have_ssl variable to true.
+4) Start a Web browser and open the client.php page to begin using the
+ demo. Note that support for secure invocations via SSL are disabled
+ by default. If you have configured SSL for the Ice extension, edit
+ client.php and set the have_ssl variable to true.
=========================================================================
diff --git a/php/demo/Ice/hello/hello.php b/php/demo/Ice/hello/client.php
index 80d0ea77585..50dfb7976e7 100644
--- a/php/demo/Ice/hello/hello.php
+++ b/php/demo/Ice/hello/client.php
@@ -16,7 +16,10 @@
//
// **********************************************************************
-Ice_loadProfile();
+require 'Ice.php';
+require 'Hello.php';
+
+$ICE = Ice_initialize();
//
// Change this to true if SSL is configured for the PHP extension.
@@ -67,11 +70,11 @@ if(isset($_POST["submitted"]))
if($p->ice_isTwoway())
{
- $hello = $p->ice_checkedCast("::Demo::Hello");
+ $hello = Demo_HelloPrxHelper::checkedCast($p);
}
else
{
- $hello = $p->ice_uncheckedCast("::Demo::Hello");
+ $hello = Demo_HelloPrxHelper::uncheckedCast($p);
}
if(isset($_POST["sayHello"]))
diff --git a/php/demo/Ice/value/.gitignore b/php/demo/Ice/value/.gitignore
new file mode 100644
index 00000000000..5c706038d7c
--- /dev/null
+++ b/php/demo/Ice/value/.gitignore
@@ -0,0 +1 @@
+Value.php
diff --git a/php/demo/Ice/value/Client.php b/php/demo/Ice/value/Client.php
index 961de48151c..7f0699cf4da 100644
--- a/php/demo/Ice/value/Client.php
+++ b/php/demo/Ice/value/Client.php
@@ -8,7 +8,10 @@
//
// **********************************************************************
-Ice_loadProfile();
+require 'Ice.php';
+require 'Value.php';
+
+$ICE = Ice_initialize();
class PrinterI extends Demo_Printer
{
@@ -57,7 +60,7 @@ class ObjectFactory implements Ice_ObjectFactory
try
{
$base = $ICE->stringToProxy("initial:default -p 10000");
- $initial = $base->ice_checkedCast("::Demo::Initial");
+ $initial = Demo_InitialPrxHelper::checkedCast($base);
echo "\n";
echo "Let's first transfer a simple object, for a class without\n";
@@ -125,7 +128,7 @@ try
fgets(STDIN);
$derivedAsBase = $initial->getDerivedPrinter();
- echo "==> The type ID of the received object is \"",get_class($derivedAsBase),"\"\n";
+ echo "==> The class of the received object is \"",get_class($derivedAsBase),"\"\n";
assert($derivedAsBase instanceof Demo_Printer);
echo "\n";
@@ -141,7 +144,7 @@ try
assert($derivedAsBase instanceof Demo_DerivedPrinter);
$derived = $derivedAsBase;
echo "==> dynamic_cast<> to derived object succeeded\n";
- echo "==> The type ID of the received object is \"",get_class($derived),"\"\n";
+ echo "==> The class of the received object is \"",get_class($derived),"\"\n";
echo "\n";
echo "Let's print the message contained in the derived object, and\n";
diff --git a/php/demo/Ice/value/Client_ns.php b/php/demo/Ice/value/Client_ns.php
new file mode 100644
index 00000000000..d75bdea4079
--- /dev/null
+++ b/php/demo/Ice/value/Client_ns.php
@@ -0,0 +1,191 @@
+<?php
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+require 'Ice_ns.php';
+require 'Value.php';
+
+$ICE = Ice\initialize();
+
+class PrinterI extends Demo\Printer
+{
+ function printBackwards()
+ {
+ echo strrev($this->message),"\n";
+ }
+}
+
+class DerivedPrinterI extends Demo\DerivedPrinter
+{
+ function printBackwards()
+ {
+ echo strrev($this->message),"\n";
+ }
+
+ function printUpperCase()
+ {
+ echo strtoupper($this->derivedMessage),"\n";
+ }
+}
+
+class ObjectFactory implements Ice\ObjectFactory
+{
+ function create($type)
+ {
+ if($type == "::Demo::Printer")
+ {
+ return new PrinterI;
+ }
+
+ if($type == "::Demo::DerivedPrinter")
+ {
+ return new DerivedPrinterI;
+ }
+
+ assert(false);
+ return null;
+ }
+
+ function destroy()
+ {
+ }
+}
+
+try
+{
+ $base = $ICE->stringToProxy("initial:default -p 10000");
+ $initial = Demo\InitialPrxHelper::checkedCast($base);
+
+ echo "\n";
+ echo "Let's first transfer a simple object, for a class without\n";
+ echo "operations, and print its contents. No factory is required\n";
+ echo "for this.\n";
+ echo "[press enter]\n";
+ fgets(STDIN);
+
+ $simple = $initial->getSimple();
+ echo "==> ",$simple->message,"\n";
+
+ echo "\n";
+ echo "Yes, this worked. Now let's try to transfer an object for a class\n";
+ echo "with operations as type ::Printer, without installing a factory first.\n";
+ echo "This should give us a `no factory' exception.\n";
+ echo "[press enter]\n";
+ fgets(STDIN);
+
+ try
+ {
+ $initial->getPrinter($printer, $printerProxy);
+ die("Did not get the expected NoObjectFactoryException!");
+ }
+ catch(Ice\NoObjectFactoryException $ex)
+ {
+ print_r($ex);
+ }
+
+ echo "\n";
+ echo "Yep, that's what we expected. Now let's try again, but with\n";
+ echo "installing an appropriate factory first. If successful, we print\n";
+ echo "the object's content.\n";
+ echo "[press enter]\n";
+ fgets(STDIN);
+
+ $factory = new ObjectFactory;
+ $ICE->addObjectFactory($factory, "::Demo::Printer");
+
+ $initial->getPrinter($printer, $printerProxy);
+ echo "==> ",$printer->message,"\n";
+
+ echo "\n";;
+ echo "Cool, it worked! Let's try calling the printBackwards() method\n";
+ echo "on the object we just received locally.\n";
+ echo "[press enter]\n";
+ fgets(STDIN);
+
+ echo "==> ";
+ $printer->printBackwards();
+
+ echo "\n";
+ echo "Now we call the same method, but on the remote object. Watch the\n";
+ echo "server's output.\n";
+ echo "[press enter]\n";
+ fgets(STDIN);
+
+ $printerProxy->printBackwards();
+
+ echo "\n";
+ echo "Next, we transfer a derived object from the server as a base\n";
+ echo "object. Since we haven't yet installed a factory for the derived\n";
+ echo "class, the derived class (::Demo::DerivedPrinter) is sliced\n";
+ echo "to its base class (::Demo::Printer).\n";
+ echo "[press enter]\n";
+ fgets(STDIN);
+
+ $derivedAsBase = $initial->getDerivedPrinter();
+ echo "==> The class of the received object is \"",get_class($derivedAsBase),"\"\n";
+ assert($derivedAsBase instanceof Demo\Printer);
+
+ echo "\n";
+ echo "Now we install a factory for the derived class, and try again.\n";
+ echo "Because we receive the derived object as a base object, we\n";
+ echo "we need to do a dynamic_cast<> to get from the base to the derived object.\n";
+ echo "[press enter]\n";
+ fgets(STDIN);
+
+ $ICE->addObjectFactory($factory, "::Demo::DerivedPrinter");
+
+ $derivedAsBase = $initial->getDerivedPrinter();
+ assert($derivedAsBase instanceof Demo\DerivedPrinter);
+ $derived = $derivedAsBase;
+ echo "==> dynamic_cast<> to derived object succeeded\n";
+ echo "==> The class of the received object is \"",get_class($derived),"\"\n";
+
+ echo "\n";
+ echo "Let's print the message contained in the derived object, and\n";
+ echo "call the operation printUppercase() on the derived object\n";
+ echo "locally.\n";
+ echo "[press enter]\n";
+ fgets(STDIN);
+
+ echo "==> ",$derived->derivedMessage,"\n";
+ echo "==> ";
+ $derived->printUppercase();
+
+ echo "\n";
+ echo "Finally, we try the same again, but instead of returning the\n";
+ echo "derived object, we throw an exception containing the derived\n";
+ echo "object.\n";
+ echo "[press enter]\n";
+ fgets(STDIN);
+
+ try
+ {
+ $initial->throwDerivedPrinter();
+ die("Did not get the expected DerivedPrinterException!");
+ }
+ catch(Demo\DerivedPrinterException $ex)
+ {
+ $derived = $ex->derived;
+ assert($derived != null);
+ }
+
+ echo "==> ",$derived->derivedMessage,"\n";
+ echo "==> ";
+ $derived->printUppercase();
+
+ echo "\n";
+ echo "That's it for this demo. Have fun with Ice!\n";
+
+ $initial->shutdown();
+}
+catch(Ice_LocalException $ex)
+{
+ print_r($ex);
+}
+?>
diff --git a/php/demo/Ice/value/Makefile b/php/demo/Ice/value/Makefile
new file mode 100644
index 00000000000..6e89da926b1
--- /dev/null
+++ b/php/demo/Ice/value/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Value.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/demo/Ice/value/Makefile.mak b/php/demo/Ice/value/Makefile.mak
new file mode 100644
index 00000000000..6ecb5c99128
--- /dev/null
+++ b/php/demo/Ice/value/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Value.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/demo/Ice/value/php.ini b/php/demo/Ice/value/php.ini
index df79f3d08d2..ba8717cc1ab 100644
--- a/php/demo/Ice/value/php.ini
+++ b/php/demo/Ice/value/php.ini
@@ -1,25 +1,22 @@
-ice.slice=Value.ice
-
;
; Windows Configuration
; ---------------------
;
-; Enable the two lines below. Replace "C:\Ice\bin" with the
-; bin directory of your Ice installation.
+; Enable the lines below. Replace "C:\Ice" with the directory of
+; your Ice installation.
;
-;extension_dir = C:\Ice\bin
+;extension_dir = C:\Ice\php
;extension = php_ice.dll
+;include_path = C:\Ice\php
;
; Unix Configuration
; ------------------
;
; If you are using a dynamic Ice extension on Unix, enable the
-; two lines below. Replace "/opt/Ice/lib" with the directory
-; containing the extension's shared library.
-;
-; Furthermore, if you built the dynamic Ice extension from source,
-; replace "icephp.so" in the second line with "ice.so".
+; lines below. Replace "/opt/Ice" with the directory of your
+; Ice installation.
;
-;extension_dir = /opt/Ice/lib
+;extension_dir = /opt/Ice/php
;extension = IcePHP.so
+;include_path = /opt/Ice/php
diff --git a/php/demo/Makefile b/php/demo/Makefile
new file mode 100644
index 00000000000..33208ca279b
--- /dev/null
+++ b/php/demo/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = Ice Glacier2
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/php/demo/Makefile.mak b/php/demo/Makefile.mak
new file mode 100644
index 00000000000..87075f70eba
--- /dev/null
+++ b/php/demo/Makefile.mak
@@ -0,0 +1,19 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = Ice Glacier2
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/lib/.gitignore b/php/lib/.gitignore
index 39af5887579..337b0d0e758 100644
--- a/php/lib/.gitignore
+++ b/php/lib/.gitignore
@@ -1 +1,6 @@
-# Dummy file, so that git retains this otherwise empty directory.
+Glacier2
+Ice
+IceBox
+IceGrid
+IcePatch2
+IceStorm
diff --git a/php/lib/Glacier2.php b/php/lib/Glacier2.php
new file mode 100644
index 00000000000..dea4a62062e
--- /dev/null
+++ b/php/lib/Glacier2.php
@@ -0,0 +1,13 @@
+<?php
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+require 'Glacier2/Router.php';
+require 'Glacier2/PermissionsVerifier.php';
+?>
diff --git a/php/lib/Ice.php b/php/lib/Ice.php
new file mode 100644
index 00000000000..e301c9d1ffe
--- /dev/null
+++ b/php/lib/Ice.php
@@ -0,0 +1,177 @@
+<?php
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+//
+// Exceptions.
+//
+abstract class Ice_Exception extends Exception
+{
+ public function __construct($message = '')
+ {
+ parent::__construct($message);
+ }
+
+ abstract public function ice_name();
+}
+
+abstract class Ice_UserException extends Ice_Exception
+{
+ public function __construct($message = '')
+ {
+ parent::__construct($message);
+ }
+}
+
+abstract class Ice_LocalException extends Ice_Exception
+{
+ public function __construct($message = '')
+ {
+ parent::__construct($message);
+ }
+}
+
+interface Ice_Object
+{
+ public function ice_isA($id);
+ public function ice_ping();
+ public function ice_ids();
+ public function ice_id();
+
+ //
+ // No need to define these here; the marshaling code will invoke them if defined by a subclass.
+ //
+ //public function ice_preMarshal();
+ //public function ice_postUnmarshal();
+}
+
+abstract class Ice_ObjectImpl implements Ice_Object
+{
+ public function ice_isA($id)
+ {
+ return array_search($id, ice_ids());
+ }
+
+ public function ice_ping()
+ {
+ }
+
+ public function ice_ids()
+ {
+ return array(ice_id());
+ }
+
+ public function ice_id()
+ {
+ return "::Ice::Object";
+ }
+}
+
+$Ice__t_Object = IcePHP_defineClass('::Ice::Object', "Ice_Object", true, null, null, null);
+$Ice__t_ObjectSeq = IcePHP_defineSequence('::Ice::ObjectSeq', $Ice__t_Object, true, 4);
+$Ice__t_LocalObject = IcePHP_defineClass('::Ice::LocalObject', "Ice_LocalObject", true, null, null, null);
+$Ice__t_ObjectPrx = IcePHP_defineProxy($Ice__t_Object);
+$Ice__t_ObjectProxySeq = IcePHP_defineSequence('::Ice::ObjectProxySeq', $Ice__t_ObjectPrx, true, 2);
+
+interface Ice_ObjectFactory
+{
+ public function create($id);
+ public function destroy();
+}
+
+class Ice_InitializationData
+{
+ public function __construct($properties=null, $logger=null)
+ {
+ $this->properties = $properties;
+ $this->logger = $logger;
+ }
+
+ public $properties;
+ public $logger;
+}
+
+$Ice_sliceChecksums = array();
+
+//
+// Include certain generated files.
+//
+require 'Ice/BuiltinSequences.php';
+require 'Ice/EndpointTypes.php';
+require 'Ice/LocalException.php';
+require 'Ice/Locator.php';
+require 'Ice/ObjectFactory.php';
+require 'Ice/Process.php';
+require 'Ice/Router.php';
+
+IcePHP_defineOperation($Ice__t_Object, 'ice_isA', 0, 0, array($IcePHP__t_string), null, $IcePHP__t_bool, null);
+IcePHP_defineOperation($Ice__t_Object, 'ice_ping', 0, 0, null, null, null, null);
+IcePHP_defineOperation($Ice__t_Object, 'ice_id', 0, 0, null, null, $IcePHP__t_string, null);
+IcePHP_defineOperation($Ice__t_Object, 'ice_ids', 0, 0, null, null, $Ice__t_StringSeq, null);
+
+//
+// Proxy comparison functions.
+//
+function Ice_proxyIdentityCompare($lhs, $rhs)
+{
+ if(($lhs != null && !($lhs instanceof Ice_ObjectPrx)) || ($rhs != null && !($rhs instanceof Ice_ObjectPrx)))
+ {
+ throw new InvalidArgumentException('argument is not a proxy');
+ }
+ if($lhs == null && $rhs == null)
+ {
+ return 0;
+ }
+ elseif($lhs == null && $rhs != null)
+ {
+ return -1;
+ }
+ elseif($lhs != null && $rhs == null)
+ {
+ return 1;
+ }
+ else
+ {
+ $lid = $lhs->ice_getIdentity();
+ $rid = $rhs->ice_getIdentity();
+ if($lid < $rid)
+ {
+ return -1;
+ }
+ elseif($lid > $rid)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+}
+
+function Ice_proxyIdentityEqual($lhs, $rhs)
+{
+ return Ice_proxyIdentityCompare($lhs, $rhs) == 0;
+}
+
+function Ice_proxyIdentityAndFacetCompare($lhs, $rhs)
+{
+ $n = Ice_proxyIdentityCompare($lhs, $rhs);
+ if($n == 0 && $lhs != null && $rhs != null)
+ {
+ $n = strcmp($lhs->ice_getFacet(), $rhs->ice_getFacet());
+ }
+ return $n;
+}
+
+function Ice_proxyIdentityAndFacetEqual($lhs, $rhs)
+{
+ return Ice_proxyIdentityAndFacetCompare($lhs, $rhs) == 0;
+}
+?>
diff --git a/php/lib/IceBox.php b/php/lib/IceBox.php
new file mode 100644
index 00000000000..15501980f30
--- /dev/null
+++ b/php/lib/IceBox.php
@@ -0,0 +1,12 @@
+<?php
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+require 'IceBox/IceBox.php';
+?>
diff --git a/php/lib/IceGrid.php b/php/lib/IceGrid.php
new file mode 100644
index 00000000000..fc42e00c418
--- /dev/null
+++ b/php/lib/IceGrid.php
@@ -0,0 +1,19 @@
+<?php
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+require 'IceGrid/Admin.php';
+require 'IceGrid/Descriptor.php';
+require 'IceGrid/FileParser.php';
+require 'IceGrid/Locator.php';
+require 'IceGrid/Observer.php';
+require 'IceGrid/Query.php';
+require 'IceGrid/Registry.php';
+require 'IceGrid/UserAccountMapper.php';
+?>
diff --git a/php/lib/IcePatch2.php b/php/lib/IcePatch2.php
new file mode 100644
index 00000000000..93a990aa73f
--- /dev/null
+++ b/php/lib/IcePatch2.php
@@ -0,0 +1,12 @@
+<?php
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+require 'IcePatch2/FileServer.php';
+?>
diff --git a/php/lib/IceStorm.php b/php/lib/IceStorm.php
new file mode 100644
index 00000000000..8a396345124
--- /dev/null
+++ b/php/lib/IceStorm.php
@@ -0,0 +1,12 @@
+<?php
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+require 'IceStorm/IceStorm.php';
+?>
diff --git a/php/lib/Ice_ns.php b/php/lib/Ice_ns.php
new file mode 100644
index 00000000000..12c4d3159fd
--- /dev/null
+++ b/php/lib/Ice_ns.php
@@ -0,0 +1,186 @@
+<?php
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+namespace Ice
+{
+ //
+ // Exceptions.
+ //
+ abstract class Exception extends \Exception
+ {
+ public function __construct($message = '')
+ {
+ parent::__construct($message);
+ }
+
+ abstract public function ice_name();
+ }
+
+ abstract class UserException extends Exception
+ {
+ public function __construct($message = '')
+ {
+ parent::__construct($message);
+ }
+ }
+
+ abstract class LocalException extends Exception
+ {
+ public function __construct($message = '')
+ {
+ parent::__construct($message);
+ }
+ }
+
+ interface Object
+ {
+ public function ice_isA($id);
+ public function ice_ping();
+ public function ice_ids();
+ public function ice_id();
+
+ //
+ // No need to define these here; the marshaling code will invoke them if defined by a subclass.
+ //
+ //public function ice_preMarshal();
+ //public function ice_postUnmarshal();
+ }
+
+ abstract class ObjectImpl implements Object
+ {
+ public function ice_isA($id)
+ {
+ return array_search($id, ice_ids());
+ }
+
+ public function ice_ping()
+ {
+ }
+
+ public function ice_ids()
+ {
+ return array(ice_id());
+ }
+
+ public function ice_id()
+ {
+ return "::Ice::Object";
+ }
+ }
+
+ $Ice__t_Object = IcePHP_defineClass('::Ice::Object', "Ice\\Object", true, null, null, null);
+ $Ice__t_ObjectSeq = IcePHP_defineSequence('::Ice::ObjectSeq', $Ice__t_Object, true, 4);
+ $Ice__t_LocalObject = IcePHP_defineClass('::Ice::LocalObject', "Ice\\LocalObject", true, null, null, null);
+ $Ice__t_ObjectPrx = IcePHP_defineProxy($Ice__t_Object);
+ $Ice__t_ObjectProxySeq = IcePHP_defineSequence('::Ice::ObjectProxySeq', $Ice__t_ObjectPrx, true, 2);
+
+ interface ObjectFactory
+ {
+ public function create($id);
+ public function destroy();
+ }
+
+ class InitializationData
+ {
+ public function __construct($properties=null, $logger=null)
+ {
+ $this->properties = $properties;
+ $this->logger = $logger;
+ }
+
+ public $properties;
+ public $logger;
+ }
+
+ $Ice_sliceChecksums = array();
+}
+
+namespace
+{
+//
+// Include certain generated files.
+//
+require 'Ice/BuiltinSequences.php';
+require 'Ice/EndpointTypes.php';
+require 'Ice/LocalException.php';
+require 'Ice/Locator.php';
+require 'Ice/ObjectFactory.php';
+require 'Ice/Process.php';
+require 'Ice/Router.php';
+
+IcePHP_defineOperation($Ice__t_Object, 'ice_isA', 0, 0, array($IcePHP__t_string), array(), $IcePHP__t_bool, null);
+IcePHP_defineOperation($Ice__t_Object, 'ice_ping', 0, 0, null, null, null, null);
+IcePHP_defineOperation($Ice__t_Object, 'ice_id', 0, 0, null, null, $IcePHP__t_string, null);
+IcePHP_defineOperation($Ice__t_Object, 'ice_ids', 0, 0, null, null, $Ice__t_StringSeq, null);
+}
+
+namespace Ice
+{
+ //
+ // Proxy comparison functions.
+ //
+ function proxyIdentityCompare($lhs, $rhs)
+ {
+ if(($lhs != null && !($lhs instanceof ObjectPrx)) || ($rhs != null && !($rhs instanceof ObjectPrx)))
+ {
+ throw new InvalidArgumentException('argument is not a proxy');
+ }
+ if($lhs == null && $rhs == null)
+ {
+ return 0;
+ }
+ elseif($lhs == null && $rhs != null)
+ {
+ return -1;
+ }
+ elseif($lhs != null && $rhs == null)
+ {
+ return 1;
+ }
+ else
+ {
+ $lid = $lhs->ice_getIdentity();
+ $rid = $rhs->ice_getIdentity();
+ if($lid < $rid)
+ {
+ return -1;
+ }
+ elseif($lid > $rid)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+
+ function proxyIdentityEqual($lhs, $rhs)
+ {
+ return proxyIdentityCompare($lhs, $rhs) == 0;
+ }
+
+ function proxyIdentityAndFacetCompare($lhs, $rhs)
+ {
+ $n = proxyIdentityCompare($lhs, $rhs);
+ if($n == 0 && $lhs != null && $rhs != null)
+ {
+ $n = strcmp($lhs->ice_getFacet(), $rhs->ice_getFacet());
+ }
+ return $n;
+ }
+
+ function proxyIdentityAndFacetEqual($lhs, $rhs)
+ {
+ return proxyIdentityAndFacetCompare($lhs, $rhs) == 0;
+ }
+}
+?>
diff --git a/php/lib/Makefile b/php/lib/Makefile
new file mode 100644
index 00000000000..4124ea83ca2
--- /dev/null
+++ b/php/lib/Makefile
@@ -0,0 +1,142 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+include $(top_srcdir)/config/Make.rules
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check Ice.php!
+#
+ICE_SRCS = Ice/LocalException.php \
+ Ice/Communicator.php \
+ Ice/CommunicatorF.php \
+ Ice/Logger.php \
+ Ice/LoggerF.php \
+ Ice/BuiltinSequences.php \
+ Ice/ObjectAdapterF.php \
+ Ice/Properties.php \
+ Ice/PropertiesF.php \
+ Ice/ObjectFactory.php \
+ Ice/ObjectFactoryF.php \
+ Ice/Identity.php \
+ Ice/Current.php \
+ Ice/ImplicitContextF.php \
+ Ice/ImplicitContext.php \
+ Ice/Router.php \
+ Ice/RouterF.php \
+ Ice/Plugin.php \
+ Ice/PluginF.php \
+ Ice/Locator.php \
+ Ice/LocatorF.php \
+ Ice/StatsF.php \
+ Ice/Stats.php \
+ Ice/Process.php \
+ Ice/ProcessF.php \
+ Ice/FacetMap.php \
+ Ice/Connection.php \
+ Ice/ConnectionF.php \
+ Ice/SliceChecksumDict.php \
+ Ice/Endpoint.php \
+ Ice/EndpointF.php \
+ Ice/EndpointTypes.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check Glacier2.php!
+#
+GLACIER2_SRCS = Glacier2/RouterF.php \
+ Glacier2/Router.php \
+ Glacier2/Session.php \
+ Glacier2/PermissionsVerifierF.php \
+ Glacier2/PermissionsVerifier.php \
+ Glacier2/SSLInfo.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IceBox.php!
+#
+ICEBOX_SRCS = IceBox/IceBox.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IceGrid.php!
+#
+ICEGRID_SRCS = IceGrid/Admin.php \
+ IceGrid/Descriptor.php \
+ IceGrid/Exception.php \
+ IceGrid/FileParser.php \
+ IceGrid/Locator.php \
+ IceGrid/Observer.php \
+ IceGrid/Query.php \
+ IceGrid/Registry.php \
+ IceGrid/Session.php \
+ IceGrid/UserAccountMapper.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IcePatch2.php!
+#
+ICEPATCH2_SRCS = IcePatch2/FileInfo.php \
+ IcePatch2/FileServer.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IceStorm.php!
+#
+ICESTORM_SRCS = IceStorm/IceStorm.php
+
+ALL_SRCS = $(ICE_SRCS) \
+ $(GLACIER2_SRCS) \
+ $(ICEBOX_SRCS) \
+ $(ICEGRID_SRCS) \
+ $(ICEPATCH2_SRCS) \
+ $(ICESTORM_SRCS)
+
+MODULES = Glacier2 Ice IceBox IceGrid IcePatch2 IceStorm
+ifeq ("$(USE_NAMESPACES)","yes")
+MODULE_SRCS = Glacier2.php Ice_ns.php IceBox.php IceGrid.php IcePatch2.php IceStorm.php
+else
+MODULE_SRCS = Glacier2.php Ice.php IceBox.php IceGrid.php IcePatch2.php IceStorm.php
+endif
+
+all:: $(ALL_SRCS)
+
+Ice/%.php: $(slicedir)/Ice/%.ice
+ @mkdir -p $(notdir $(<D))
+ $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $<
+
+Glacier2/%.php: $(slicedir)/Glacier2/%.ice
+ @mkdir -p $(notdir $(<D))
+ $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $<
+
+IceBox/%.php: $(slicedir)/IceBox/%.ice
+ @mkdir -p $(notdir $(<D))
+ $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $<
+
+IceGrid/%.php: $(slicedir)/IceGrid/%.ice
+ @mkdir -p $(notdir $(<D))
+ $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $<
+
+IcePatch2/%.php: $(slicedir)/IcePatch2/%.ice
+ @mkdir -p $(notdir $(<D))
+ $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $<
+
+IceStorm/%.php: $(slicedir)/IceStorm/%.ice
+ @mkdir -p $(notdir $(<D))
+ $(SLICE2PHP) --output-dir $(notdir $(<D)) --ice $(SLICE2PHPFLAGS) $<
+
+install:: $(ALL_SRCS)
+ @echo "Installing generated code"
+ @for i in $(MODULES) ; \
+ do \
+ $(INSTALL_DATA) -r $$i $(install_phpdir) ; \
+ done
+ @for i in $(MODULE_SRCS) ; \
+ do \
+ $(INSTALL_DATA) $$i $(install_phpdir) ; \
+ done
+
+clean::
+ rm -rf $(MODULES)
diff --git a/php/lib/Makefile.mak b/php/lib/Makefile.mak
new file mode 100644
index 00000000000..6bdc68f9c02
--- /dev/null
+++ b/php/lib/Makefile.mak
@@ -0,0 +1,123 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check Ice.php!
+#
+ICE_SRCS = Ice\LocalException.php \
+ Ice\Communicator.php \
+ Ice\CommunicatorF.php \
+ Ice\Logger.php \
+ Ice\LoggerF.php \
+ Ice\BuiltinSequences.php \
+ Ice\ObjectAdapterF.php \
+ Ice\Properties.php \
+ Ice\PropertiesF.php \
+ Ice\ObjectFactory.php \
+ Ice\ObjectFactoryF.php \
+ Ice\Identity.php \
+ Ice\Current.php \
+ Ice\ImplicitContextF.php \
+ Ice\ImplicitContext.php \
+ Ice\Router.php \
+ Ice\RouterF.php \
+ Ice\Plugin.php \
+ Ice\PluginF.php \
+ Ice\Locator.php \
+ Ice\LocatorF.php \
+ Ice\StatsF.php \
+ Ice\Stats.php \
+ Ice\Process.php \
+ Ice\ProcessF.php \
+ Ice\FacetMap.php \
+ Ice\Connection.php \
+ Ice\ConnectionF.php \
+ Ice\SliceChecksumDict.php \
+ Ice\Endpoint.php \
+ Ice\EndpointF.php \
+ Ice\EndpointTypes.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check Glacier2.php!
+#
+GLACIER2_SRCS = Glacier2\RouterF.php \
+ Glacier2\Router.php \
+ Glacier2\Session.php \
+ Glacier2\PermissionsVerifierF.php \
+ Glacier2\PermissionsVerifier.php \
+ Glacier2\SSLInfo.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IceBox.php!
+#
+ICEBOX_SRCS = IceBox\IceBox.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IceGrid.php!
+#
+ICEGRID_SRCS = IceGrid\Admin.php \
+ IceGrid\Descriptor.php \
+ IceGrid\Exception.php \
+ IceGrid\FileParser.php \
+ IceGrid\Locator.php \
+ IceGrid\Observer.php \
+ IceGrid\Query.php \
+ IceGrid\Registry.php \
+ IceGrid\Session.php \
+ IceGrid\UserAccountMapper.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IcePatch2.php!
+#
+ICEPATCH2_SRCS = IcePatch2\FileInfo.php \
+ IcePatch2\FileServer.php
+
+#
+# IMPORTANT: If you add or remove Slice files, you also need to check IceStorm.php!
+#
+ICESTORM_SRCS = IceStorm\IceStorm.php
+
+ALL_SRCS = $(ICE_SRCS) \
+ $(GLACIER2_SRCS) \
+ $(ICEBOX_SRCS) \
+ $(ICEGRID_SRCS) \
+ $(ICEPATCH2_SRCS) \
+ $(ICESTORM_SRCS)
+
+MODULES = Glacier2 Ice IceBox IceGrid IcePatch2 IceStorm
+!if "$(USE_NAMESPACES)" == "yes"
+MODULE_SRCS = Glacier2.php Ice_ns.php IceBox.php IceGrid.php IcePatch2.php IceStorm.php
+!else
+MODULE_SRCS = Glacier2.php Ice.php IceBox.php IceGrid.php IcePatch2.php IceStorm.php
+!endif
+
+all:: $(ALL_SRCS)
+
+$(MODULES):
+ -mkdir $@
+
+$(ALL_SRCS): $(MODULES) {$(slicedir)}$*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) --output-dir $(*D) --ice $(slicedir)\$*.ice
+
+install::
+ @echo "Installing generated code"
+ @for %i in ( $(MODULES) ) do \
+ @if not exist $(install_phpdir)\%i \
+ mkdir $(install_phpdir)\%i
+ @for %i in ( $(MODULES) ) do \
+ copy %i\* $(install_phpdir)\%i
+ @for %i in ( $(MODULE_SRCS) ) do \
+ copy %i $(install_phpdir)
+
+clean::
+ -rmdir /S /Q $(MODULES)
diff --git a/php/src/IcePHP/.depend b/php/src/IcePHP/.depend
index e69de29bb2d..d82ec855f70 100644
--- a/php/src/IcePHP/.depend
+++ b/php/src/IcePHP/.depend
@@ -0,0 +1,10 @@
+Communicator$(OBJEXT): Communicator.cpp Communicator.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Logger.h Properties.h Proxy.h Types.h Operation.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Util.h $(ice_cpp_dir)/include/IceUtil/Options.h $(ice_cpp_dir)/include/IceUtil/RecMutex.h
+Connection$(OBJEXT): Connection.cpp Connection.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Util.h
+Endpoint$(OBJEXT): Endpoint.cpp Endpoint.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Util.h
+Init$(OBJEXT): Init.cpp Communicator.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Connection.h Endpoint.h Logger.h Operation.h Properties.h Proxy.h Types.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Util.h
+Logger$(OBJEXT): Logger.cpp Logger.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Util.h
+Operation$(OBJEXT): Operation.cpp Operation.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Communicator.h Proxy.h Types.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Util.h $(ice_cpp_dir)/include/Slice/PHPUtil.h $(ice_cpp_dir)/include/Slice/Parser.h
+Properties$(OBJEXT): Properties.cpp Properties.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Util.h
+Proxy$(OBJEXT): Proxy.cpp Proxy.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Communicator.h Types.h Operation.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Connection.h Endpoint.h Util.h
+Types$(OBJEXT): Types.cpp Types.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h Communicator.h Operation.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h Proxy.h Util.h $(ice_cpp_dir)/include/IceUtil/InputUtil.h $(ice_cpp_dir)/include/IceUtil/ScopedArray.h $(ice_cpp_dir)/include/Slice/PHPUtil.h $(ice_cpp_dir)/include/Slice/Parser.h
+Util$(OBJEXT): Util.cpp Util.h Config.h $(ice_cpp_dir)/include/Ice/Ice.h $(ice_cpp_dir)/include/Ice/Initialize.h $(ice_cpp_dir)/include/Ice/CommunicatorF.h $(ice_cpp_dir)/include/Ice/LocalObjectF.h $(ice_cpp_dir)/include/IceUtil/Shared.h $(ice_cpp_dir)/include/IceUtil/Config.h $(ice_cpp_dir)/include/Ice/Handle.h $(ice_cpp_dir)/include/IceUtil/Handle.h $(ice_cpp_dir)/include/IceUtil/Exception.h $(ice_cpp_dir)/include/Ice/Config.h $(ice_cpp_dir)/include/Ice/ProxyHandle.h $(ice_cpp_dir)/include/Ice/ProxyF.h $(ice_cpp_dir)/include/Ice/ObjectF.h $(ice_cpp_dir)/include/Ice/GCCountMap.h $(ice_cpp_dir)/include/Ice/GCShared.h $(ice_cpp_dir)/include/Ice/Exception.h $(ice_cpp_dir)/include/Ice/LocalObject.h $(ice_cpp_dir)/include/Ice/UndefSysMacros.h $(ice_cpp_dir)/include/Ice/PropertiesF.h $(ice_cpp_dir)/include/Ice/Proxy.h $(ice_cpp_dir)/include/IceUtil/Mutex.h $(ice_cpp_dir)/include/IceUtil/Lock.h $(ice_cpp_dir)/include/IceUtil/ThreadException.h $(ice_cpp_dir)/include/IceUtil/Time.h $(ice_cpp_dir)/include/Ice/ProxyFactoryF.h $(ice_cpp_dir)/include/Ice/ConnectionIF.h $(ice_cpp_dir)/include/Ice/RequestHandlerF.h $(ice_cpp_dir)/include/Ice/EndpointIF.h $(ice_cpp_dir)/include/Ice/EndpointF.h $(ice_cpp_dir)/include/Ice/EndpointTypes.h $(ice_cpp_dir)/include/Ice/ObjectAdapterF.h $(ice_cpp_dir)/include/Ice/ReferenceF.h $(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h $(ice_cpp_dir)/include/Ice/Current.h $(ice_cpp_dir)/include/Ice/ConnectionF.h $(ice_cpp_dir)/include/Ice/Identity.h $(ice_cpp_dir)/include/Ice/StreamF.h $(ice_cpp_dir)/include/Ice/Object.h $(ice_cpp_dir)/include/Ice/IncomingAsyncF.h $(ice_cpp_dir)/include/Ice/InstanceF.h $(ice_cpp_dir)/include/Ice/LoggerF.h $(ice_cpp_dir)/include/Ice/StatsF.h $(ice_cpp_dir)/include/Ice/StringConverter.h $(ice_cpp_dir)/include/Ice/Plugin.h $(ice_cpp_dir)/include/Ice/BuiltinSequences.h $(ice_cpp_dir)/include/IceUtil/Unicode.h $(ice_cpp_dir)/include/Ice/LocalException.h $(ice_cpp_dir)/include/Ice/Properties.h $(ice_cpp_dir)/include/Ice/Outgoing.h $(ice_cpp_dir)/include/IceUtil/Monitor.h $(ice_cpp_dir)/include/IceUtil/Cond.h $(ice_cpp_dir)/include/Ice/BasicStream.h $(ice_cpp_dir)/include/Ice/ObjectFactoryF.h $(ice_cpp_dir)/include/Ice/Buffer.h $(ice_cpp_dir)/include/Ice/Protocol.h $(ice_cpp_dir)/include/Ice/OutgoingAsync.h $(ice_cpp_dir)/include/IceUtil/Timer.h $(ice_cpp_dir)/include/IceUtil/Thread.h $(ice_cpp_dir)/include/Ice/Incoming.h $(ice_cpp_dir)/include/Ice/ServantLocatorF.h $(ice_cpp_dir)/include/Ice/ServantManagerF.h $(ice_cpp_dir)/include/Ice/Direct.h $(ice_cpp_dir)/include/Ice/Logger.h $(ice_cpp_dir)/include/Ice/LoggerUtil.h $(ice_cpp_dir)/include/Ice/Stats.h $(ice_cpp_dir)/include/Ice/Communicator.h $(ice_cpp_dir)/include/Ice/RouterF.h $(ice_cpp_dir)/include/Ice/LocatorF.h $(ice_cpp_dir)/include/Ice/PluginF.h $(ice_cpp_dir)/include/Ice/ImplicitContextF.h $(ice_cpp_dir)/include/Ice/ObjectFactory.h $(ice_cpp_dir)/include/Ice/ObjectAdapter.h $(ice_cpp_dir)/include/Ice/FacetMap.h $(ice_cpp_dir)/include/Ice/Endpoint.h $(ice_cpp_dir)/include/Ice/ServantLocator.h $(ice_cpp_dir)/include/Ice/IncomingAsync.h $(ice_cpp_dir)/include/Ice/Process.h $(ice_cpp_dir)/include/Ice/Application.h $(ice_cpp_dir)/include/Ice/Connection.h $(ice_cpp_dir)/include/Ice/Functional.h $(ice_cpp_dir)/include/IceUtil/Functional.h $(ice_cpp_dir)/include/Ice/Stream.h $(ice_cpp_dir)/include/Ice/ImplicitContext.h $(ice_cpp_dir)/include/Ice/Locator.h $(ice_cpp_dir)/include/Ice/UserExceptionFactory.h $(ice_cpp_dir)/include/Ice/FactoryTableInit.h $(ice_cpp_dir)/include/Ice/FactoryTable.h $(ice_cpp_dir)/include/IceUtil/StaticMutex.h $(ice_cpp_dir)/include/Ice/UserExceptionFactoryF.h $(ice_cpp_dir)/include/Ice/ProcessF.h $(ice_cpp_dir)/include/Ice/Router.h $(ice_cpp_dir)/include/Ice/DispatchInterceptor.h $(ice_cpp_dir)/include/Ice/IconvStringConverter.h $(ice_cpp_dir)/include/IceUtil/UUID.h $(ice_cpp_dir)/include/Slice/PHPUtil.h $(ice_cpp_dir)/include/Slice/Parser.h $(ice_cpp_dir)/include/IceUtil/OutputUtil.h
diff --git a/php/src/IcePHP/Communicator.cpp b/php/src/IcePHP/Communicator.cpp
index 40a315a3f84..ca48dc52565 100644
--- a/php/src/IcePHP/Communicator.cpp
+++ b/php/src/IcePHP/Communicator.cpp
@@ -7,11 +7,14 @@
//
// **********************************************************************
-#include <IceUtil/DisableWarnings.h>
#include <Communicator.h>
+#include <Logger.h>
+#include <Properties.h>
#include <Proxy.h>
-#include <Marshal.h>
#include <Util.h>
+#include <IceUtil/Options.h>
+#include <IceUtil/StaticMutex.h>
+#include <IceUtil/Timer.h>
using namespace std;
using namespace IcePHP;
@@ -21,704 +24,1554 @@ ZEND_EXTERN_MODULE_GLOBALS(ice)
//
// Class entries represent the PHP class implementations we have registered.
//
-static zend_class_entry* _communicatorClassEntry;
+namespace IcePHP
+{
+
+zend_class_entry* communicatorClassEntry = 0;
//
-// Ice::Communicator support.
+// An active communicator is in use by at least one request and may have
+// registered so that it remains active after a request completes. The
+// communicator is destroyed when there are no more references to this
+// object.
//
-static zend_object_handlers _handlers;
+class ActiveCommunicator : public IceUtil::Shared
+{
+public:
-extern "C"
+ ActiveCommunicator(const Ice::CommunicatorPtr& c);
+ ~ActiveCommunicator();
+
+ const Ice::CommunicatorPtr communicator;
+ vector<string> ids;
+ int expires;
+ IceUtil::Time lastAccess;
+};
+typedef IceUtil::Handle<ActiveCommunicator> ActiveCommunicatorPtr;
+
+typedef std::map<std::string, zval*> ObjectFactoryMap;
+
+class CommunicatorInfoI : public CommunicatorInfo
{
-static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC);
-static zend_object_value handleClone(zval* TSRMLS_DC);
-static void handleFreeStorage(void* TSRMLS_DC);
+public:
-static union _zend_function* handleGetMethod(zval**, char*, int TSRMLS_DC);
-}
+ CommunicatorInfoI(const ActiveCommunicatorPtr&, zval*);
+
+ virtual void getZval(zval* TSRMLS_DC);
+ virtual void addRef(TSRMLS_D);
+ virtual void decRef(TSRMLS_D);
+
+ virtual Ice::CommunicatorPtr getCommunicator() const;
-static void initCommunicator(ice_object* TSRMLS_DC);
+ bool addObjectFactory(const std::string&, zval* TSRMLS_DC);
+ bool findObjectFactory(const std::string&, zval* TSRMLS_DC);
+ void destroyObjectFactories(TSRMLS_D);
+
+ const ActiveCommunicatorPtr ac;
+ const zval zv;
+ ObjectFactoryMap objectFactories;
+};
+typedef IceUtil::Handle<CommunicatorInfoI> CommunicatorInfoIPtr;
//
-// Function entries for Ice::Communicator methods.
+// Each PHP request has its own set of object factories. More precisely, there is
+// an object factory map for each communicator that is created by a PHP request.
+// The factory class defined below delegates the create/destroy methods to PHP
+// objects supplied by the application. An instance of this class is installed
+// as the communicator's default object factory, and the class holds a reference
+// to its communicator. When create is invoked, the class resolves the appropriate
+// PHP object as follows:
//
-static function_entry _methods[] =
-{
- {"__construct", PHP_FN(Ice_Communicator___construct), 0},
- {"getProperty", PHP_FN(Ice_Communicator_getProperty), 0},
- {"setProperty", PHP_FN(Ice_Communicator_setProperty), 0},
- {"stringToProxy", PHP_FN(Ice_Communicator_stringToProxy), 0},
- {"proxyToString", PHP_FN(Ice_Communicator_proxyToString), 0},
- {"propertyToProxy", PHP_FN(Ice_Communicator_propertyToProxy), 0},
- {"stringToIdentity", PHP_FN(Ice_Communicator_stringToIdentity), 0},
- {"identityToString", PHP_FN(Ice_Communicator_identityToString), 0},
- {"addObjectFactory", PHP_FN(Ice_Communicator_addObjectFactory), 0},
- {"findObjectFactory", PHP_FN(Ice_Communicator_findObjectFactory), 0},
- {"flushBatchRequests", PHP_FN(Ice_Communicator_flushBatchRequests), 0},
- {0, 0, 0}
+// * Using its communicator reference as the key, look up the corresponding
+// CommunicatorInfoI object in the request-specific communicator map.
+//
+// * In the object factory map held by the CommunicatorInfoI object, look for a
+// PHP factory object using the same algorithm as the Ice core.
+//
+class ObjectFactoryI : public Ice::ObjectFactory
+{
+public:
+
+ ObjectFactoryI(const Ice::CommunicatorPtr&);
+
+ virtual Ice::ObjectPtr create(const std::string&);
+ virtual void destroy();
+
+private:
+
+ Ice::CommunicatorPtr _communicator;
};
-bool
-IcePHP::communicatorInit(TSRMLS_D)
+class ReaperTask : public IceUtil::TimerTask
{
- //
- // Register the Ice_Communicator class.
- //
- zend_class_entry ce;
- INIT_CLASS_ENTRY(ce, "Ice_Communicator", _methods);
- ce.create_object = handleAlloc;
- _communicatorClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
- memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
- _handlers.clone_obj = handleClone;
- _handlers.get_method = handleGetMethod;
+public:
+
+ virtual void runTimerTask();
+};
- return true;
}
-bool
-IcePHP::createCommunicator(TSRMLS_D)
+//
+// Communicator support.
+//
+static zend_object_handlers _handlers;
+
+//
+// The profile map holds Properties objects corresponding to the "default" profile
+// (defined via the ice.config & ice.options settings in php.ini) as well as named
+// profiles defined in an external file.
+//
+typedef map<string, Ice::PropertiesPtr> ProfileMap;
+static ProfileMap _profiles;
+static const string _defaultProfileName = "";
+
+//
+// This map represents communicators that have been registered so that they can be used
+// by multiple PHP requests.
+//
+typedef map<string, ActiveCommunicatorPtr> RegisteredCommunicatorMap;
+static RegisteredCommunicatorMap _registeredCommunicators;
+static IceUtil::StaticMutex _registeredCommunicatorsMutex = ICE_STATIC_MUTEX_INITIALIZER;
+
+static IceUtil::TimerPtr _timer;
+
+//
+// This map is stored in the "global" variables for each PHP request and holds
+// the communicators that have been created (or registered communicators that have
+// been used) by the request.
+//
+typedef map<Ice::CommunicatorPtr, CommunicatorInfoIPtr> CommunicatorMap;
+
+extern "C"
{
- zval* global;
- MAKE_STD_ZVAL(global);
+static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC);
+static void handleFreeStorage(void* TSRMLS_DC);
+static zend_object_value handleClone(zval* TSRMLS_DC);
+}
+
+ZEND_METHOD(Ice_Communicator, __construct)
+{
+ runtimeError("communicators cannot be instantiated directly" TSRMLS_CC);
+}
+
+ZEND_METHOD(Ice_Communicator, destroy)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
//
- // Create the global variable for the communicator, but delay creation of the communicator
- // itself until it is first used (see handleGetMethod).
+ // Remove all registrations.
//
- if(object_init_ex(global, _communicatorClassEntry) != SUCCESS)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create object for communicator");
- return false;
+ IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex);
+ for(vector<string>::iterator p = _this->ac->ids.begin(); p != _this->ac->ids.end(); ++p)
+ {
+ _registeredCommunicators.erase(*p);
+ }
+ _this->ac->ids.clear();
}
//
- // Register the global variable "ICE" to hold the communicator.
+ // We need to destroy any object factories installed by this request.
//
- ICE_G(communicator) = global;
- ZEND_SET_GLOBAL_VAR("ICE", global);
+ _this->destroyObjectFactories(TSRMLS_C);
- return true;
+ Ice::CommunicatorPtr c = _this->getCommunicator();
+ assert(c);
+ CommunicatorMap* m = reinterpret_cast<CommunicatorMap*>(ICE_G(communicatorMap));
+ assert(m);
+ assert(m->find(c) != m->end());
+ m->erase(c);
+
+ try
+ {
+ c->destroy();
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
}
-Ice::CommunicatorPtr
-IcePHP::getCommunicator(TSRMLS_D)
+ZEND_METHOD(Ice_Communicator, stringToProxy)
{
- Ice::CommunicatorPtr result;
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
- void* data;
- if(zend_hash_find(&EG(symbol_table), "ICE", sizeof("ICE"), &data) == SUCCESS)
+ char* str;
+ int strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &strLen) != SUCCESS)
{
- zval** zv = reinterpret_cast<zval**>(data);
- ice_object* obj = getObject(*zv TSRMLS_CC);
- assert(obj);
+ RETURN_NULL();
+ }
+ string s(str, strLen);
- //
- // Initialize the communicator if necessary.
- //
- if(!obj->ptr)
+ try
+ {
+ Ice::ObjectPrx prx = _this->getCommunicator()->stringToProxy(s);
+ if(!createProxy(return_value, prx, _this TSRMLS_CC))
{
- try
- {
- initCommunicator(obj TSRMLS_CC);
- }
- catch(const IceUtil::Exception& ex)
- {
- ostringstream ostr;
- ex.ice_print(ostr);
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize communicator:\n%s", ostr.str().c_str());
- return 0;
- }
+ RETURN_NULL();
}
-
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
- result = *_this;
}
-
- return result;
-}
-
-zval*
-IcePHP::getCommunicatorZval(TSRMLS_D)
-{
- void* data = 0;
- zend_hash_find(&EG(symbol_table), "ICE", sizeof("ICE"), &data);
- assert(data);
- zval **zv = reinterpret_cast<zval**>(data);
- return *zv;
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
}
-ZEND_FUNCTION(Ice_Communicator___construct)
+ZEND_METHOD(Ice_Communicator, proxyToString)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "Ice_Communicator cannot be instantiated, use the global variable $ICE");
-}
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
-ZEND_FUNCTION(Ice_Communicator_getProperty)
-{
- if(ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2)
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zv, proxyClassEntry) != SUCCESS)
{
- WRONG_PARAM_COUNT;
+ RETURN_NULL();
}
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ try
{
- return;
+ string str;
+ if(zv)
+ {
+ Ice::ObjectPrx prx;
+ ClassInfoPtr info;
+ if(!fetchProxy(zv, prx, info TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ assert(prx);
+ str = prx->ice_toString();
+ }
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
}
- assert(obj->ptr);
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
+}
- char *name;
- int nameLen;
- char *def = 0;
- int defLen = 0;
+ZEND_METHOD(Ice_Communicator, propertyToProxy)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name, &nameLen, &def, &defLen) == FAILURE)
+ char* str;
+ int strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &strLen) != SUCCESS)
{
RETURN_NULL();
}
+ string s(str, strLen);
try
{
- string val = (*_this)->getProperties()->getProperty(name);
- if(val.empty() && def)
- {
- RETURN_STRING(def, 1);
- }
- else
+ Ice::ObjectPrx prx = _this->getCommunicator()->propertyToProxy(s);
+ if(!createProxy(return_value, prx, _this TSRMLS_CC))
{
- RETURN_STRING(const_cast<char*>(val.c_str()), 1);
+ RETURN_NULL();
}
}
catch(const IceUtil::Exception& ex)
{
throwException(ex TSRMLS_CC);
- RETURN_EMPTY_STRING();
+ RETURN_NULL();
}
}
-ZEND_FUNCTION(Ice_Communicator_setProperty)
+ZEND_METHOD(Ice_Communicator, stringToIdentity)
{
- if(ZEND_NUM_ARGS() != 2)
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ char* str;
+ int strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &strLen) != SUCCESS)
{
- WRONG_PARAM_COUNT;
+ RETURN_NULL();
}
+ string s(str, strLen);
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ try
{
- return;
+ Ice::Identity id = _this->getCommunicator()->stringToIdentity(s);
+ if(!createIdentity(return_value, id TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
}
- assert(obj->ptr);
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Communicator, identityToString)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
- char *prop;
- int propLen;
- char *val;
- int valLen;
+ zend_class_entry* identityClass = idToClass("::Ice::Identity" TSRMLS_CC);
+ assert(identityClass);
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &prop, &propLen, &val, &valLen) == FAILURE)
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zv, identityClass) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ Ice::Identity id;
+ if(!extractIdentity(zv, id TSRMLS_CC))
{
RETURN_NULL();
}
try
{
- (*_this)->getProperties()->setProperty(prop, val);
+ string str = _this->getCommunicator()->identityToString(id);
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
}
catch(const IceUtil::Exception& ex)
{
throwException(ex TSRMLS_CC);
+ RETURN_NULL();
}
- RETURN_EMPTY_STRING();
}
-ZEND_FUNCTION(Ice_Communicator_stringToProxy)
+ZEND_METHOD(Ice_Communicator, addObjectFactory)
{
- if(ZEND_NUM_ARGS() != 1)
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ zend_class_entry* factoryClass = idToClass("Ice::ObjectFactory" TSRMLS_CC);
+ assert(factoryClass);
+
+ zval* factory;
+ char* id;
+ int idLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os!", &factory, factoryClass, &id, &idLen TSRMLS_CC) !=
+ SUCCESS)
{
- WRONG_PARAM_COUNT;
+ RETURN_NULL();
}
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ string type;
+ if(id)
{
- return;
+ type = string(id, idLen);
}
- assert(obj->ptr);
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
-
- char *str;
- int len;
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE)
+ if(!_this->addObjectFactory(type, factory TSRMLS_CC))
{
RETURN_NULL();
}
+}
- Ice::ObjectPrx proxy;
- try
+ZEND_METHOD(Ice_Communicator, findObjectFactory)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ char* id;
+ int idLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &id, &idLen TSRMLS_CC) != SUCCESS)
{
- proxy = (*_this)->stringToProxy(str);
+ RETURN_NULL();
}
- catch(const IceUtil::Exception& ex)
+
+ string type;
+ if(id)
{
- throwException(ex TSRMLS_CC);
- RETURN_NULL();
+ type = string(id, idLen);
}
- if(!createProxy(return_value, proxy TSRMLS_CC))
+ if(!_this->findObjectFactory(type, return_value TSRMLS_CC))
{
RETURN_NULL();
}
}
-ZEND_FUNCTION(Ice_Communicator_proxyToString)
+ZEND_METHOD(Ice_Communicator, getImplicitContext)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
+ runtimeError("not implemented" TSRMLS_CC);
+}
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ZEND_METHOD(Ice_Communicator, getProperties)
+{
+ if(ZEND_NUM_ARGS() > 0)
{
- return;
+ WRONG_PARAM_COUNT;
}
- assert(obj->ptr);
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
- zval* zprx;
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zprx, proxyClassEntry) == FAILURE)
+ try
{
- RETURN_EMPTY_STRING();
+ Ice::PropertiesPtr props = _this->getCommunicator()->getProperties();
+ if(!createProperties(return_value, props TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
}
-
- Ice::ObjectPrx proxy;
- Slice::ClassDefPtr def;
- if(!zprx || !fetchProxy(zprx, proxy, def TSRMLS_CC))
+ catch(const IceUtil::Exception& ex)
{
- RETURN_EMPTY_STRING();
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
}
+}
+
+ZEND_METHOD(Ice_Communicator, getLogger)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- string result = (*_this)->proxyToString(proxy);
- RETURN_STRING(const_cast<char*>(result.c_str()), 1);
+ Ice::LoggerPtr logger = _this->getCommunicator()->getLogger();
+ if(!createLogger(return_value, logger TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
}
catch(const IceUtil::Exception& ex)
{
throwException(ex TSRMLS_CC);
- RETURN_EMPTY_STRING();
+ RETURN_NULL();
}
}
-ZEND_FUNCTION(Ice_Communicator_propertyToProxy)
+ZEND_METHOD(Ice_Communicator, getDefaultRouter)
{
- if(ZEND_NUM_ARGS() != 1)
+ if(ZEND_NUM_ARGS() > 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
{
- return;
+ Ice::RouterPrx router = _this->getCommunicator()->getDefaultRouter();
+ if(router)
+ {
+ ClassInfoPtr info = getClassInfoById("::Ice::Router" TSRMLS_CC);
+ if(!info)
+ {
+ runtimeError("no definition for Ice::Router" TSRMLS_CC);
+ RETURN_NULL();
+ }
+ if(!createProxy(return_value, router, info, _this TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ else
+ {
+ RETURN_NULL();
+ }
}
- assert(obj->ptr);
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
- char *str;
- int len;
+ZEND_METHOD(Ice_Communicator, setDefaultRouter)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE)
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zv, proxyClassEntry TSRMLS_CC) != SUCCESS)
{
RETURN_NULL();
}
Ice::ObjectPrx proxy;
+ ClassInfoPtr info;
+ if(zv && !fetchProxy(zv, proxy, info TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+
try
{
- proxy = (*_this)->propertyToProxy(str);
+ Ice::RouterPrx router;
+ if(proxy)
+ {
+ if(!info || !info->isA("::Ice::Router"))
+ {
+ invalidArgument("setDefaultRouter requires a proxy narrowed to Ice::Router" TSRMLS_CC);
+ RETURN_NULL();
+ }
+ router = Ice::RouterPrx::uncheckedCast(proxy);
+ }
+ _this->getCommunicator()->setDefaultRouter(router);
}
catch(const IceUtil::Exception& ex)
{
throwException(ex TSRMLS_CC);
RETURN_NULL();
}
-
- if(!createProxy(return_value, proxy TSRMLS_CC))
- {
- RETURN_NULL();
- }
}
-ZEND_FUNCTION(Ice_Communicator_identityToString)
+ZEND_METHOD(Ice_Communicator, getDefaultLocator)
{
- if(ZEND_NUM_ARGS() != 1)
+ if(ZEND_NUM_ARGS() > 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ Ice::LocatorPrx locator = _this->getCommunicator()->getDefaultLocator();
+ if(locator)
+ {
+ ClassInfoPtr info = getClassInfoById("::Ice::Locator" TSRMLS_CC);
+ if(!info)
+ {
+ runtimeError("no definition for Ice::Locator" TSRMLS_CC);
+ RETURN_NULL();
+ }
+ if(!createProxy(return_value, locator, info, _this TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ else
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
{
- return;
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
}
- assert(obj->ptr);
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
+}
- zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC);
- assert(cls);
+ZEND_METHOD(Ice_Communicator, setDefaultLocator)
+{
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
- zval *zid;
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zv, proxyClassEntry TSRMLS_CC) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zid, cls) == FAILURE)
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr info;
+ if(zv && !fetchProxy(zv, proxy, info TSRMLS_CC))
{
RETURN_NULL();
}
- Ice::Identity id;
- if(extractIdentity(zid, id TSRMLS_CC))
+ try
{
- string s = (*_this)->identityToString(id);
- RETURN_STRINGL(const_cast<char*>(s.c_str()), s.length(), 1);
+ Ice::LocatorPrx locator;
+ if(proxy)
+ {
+ if(!info || !info->isA("::Ice::Locator"))
+ {
+ invalidArgument("setDefaultRouter requires a proxy narrowed to Ice::Locator" TSRMLS_CC);
+ RETURN_NULL();
+ }
+ locator = Ice::LocatorPrx::uncheckedCast(proxy);
+ }
+ _this->getCommunicator()->setDefaultLocator(locator);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
}
}
-ZEND_FUNCTION(Ice_Communicator_stringToIdentity)
+ZEND_METHOD(Ice_Communicator, flushBatchRequests)
{
- if(ZEND_NUM_ARGS() != 1)
+ CommunicatorInfoIPtr _this = Wrapper<CommunicatorInfoIPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ if(ZEND_NUM_ARGS() != 8)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ try
{
- return;
+ _this->getCommunicator()->flushBatchRequests();
}
- assert(obj->ptr);
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
-
- char* str;
- int len;
-
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE)
+ catch(const IceUtil::Exception& ex)
{
+ throwException(ex TSRMLS_CC);
RETURN_NULL();
}
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleAlloc(zend_class_entry* ce TSRMLS_DC)
+{
+ zend_object_value result;
+
+ Wrapper<CommunicatorInfoIPtr>* obj = Wrapper<CommunicatorInfoIPtr>::create(ce TSRMLS_CC);
+ assert(obj);
+
+ result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC);
+ result.handlers = &_handlers;
+ return result;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleFreeStorage(void* p TSRMLS_DC)
+{
+ Wrapper<CommunicatorInfoIPtr>* obj = static_cast<Wrapper<CommunicatorInfoIPtr>*>(p);
+ delete obj->ptr;
+ zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleClone(zval* zv TSRMLS_DC)
+{
+ php_error_docref(0 TSRMLS_CC, E_ERROR, "communicators cannot be cloned");
+ return zend_object_value();
+}
+
+static CommunicatorInfoIPtr
+createCommunicator(zval* zv, const ActiveCommunicatorPtr& ac TSRMLS_DC)
+{
try
{
- Ice::Identity id = (*_this)->stringToIdentity(str);
- createIdentity(return_value, id TSRMLS_CC);
+ if(object_init_ex(zv, communicatorClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize communicator object" TSRMLS_CC);
+ return 0;
+ }
+
+ Wrapper<CommunicatorInfoIPtr>* obj = Wrapper<CommunicatorInfoIPtr>::extract(zv TSRMLS_CC);
+ assert(!obj->ptr);
+
+ CommunicatorInfoIPtr info = new CommunicatorInfoI(ac, zv);
+ obj->ptr = new CommunicatorInfoIPtr(info);
+
+ CommunicatorMap* m;
+ if(ICE_G(communicatorMap))
+ {
+ m = reinterpret_cast<CommunicatorMap*>(ICE_G(communicatorMap));
+ }
+ else
+ {
+ m = new CommunicatorMap;
+ ICE_G(communicatorMap) = m;
+ }
+ m->insert(CommunicatorMap::value_type(ac->communicator, info));
+
+ return info;
}
catch(const IceUtil::Exception& ex)
{
throwException(ex TSRMLS_CC);
+ return 0;
}
}
-ZEND_FUNCTION(Ice_Communicator_addObjectFactory)
+static CommunicatorInfoIPtr
+initializeCommunicator(zval* zv, Ice::StringSeq& args, const Ice::InitializationData& initData TSRMLS_DC)
{
- if(ZEND_NUM_ARGS() != 2)
+ try
{
- WRONG_PARAM_COUNT;
+ Ice::CommunicatorPtr c = Ice::initialize(args, initData);
+ ActiveCommunicatorPtr ac = new ActiveCommunicator(c);
+
+ //
+ // Install a default object factory that delegates to PHP factories.
+ //
+ c->addObjectFactory(new ObjectFactoryI(c), "");
+
+ CommunicatorInfoIPtr info = createCommunicator(zv, ac TSRMLS_CC);
+ if(!info)
+ {
+ try
+ {
+ c->destroy();
+ }
+ catch(...)
+ {
+ }
+ }
+
+ return info;
}
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ return 0;
+ }
+}
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ZEND_FUNCTION(Ice_initialize)
+{
+ if(ZEND_NUM_ARGS() > 2)
{
- return;
+ runtimeError("too many arguments" TSRMLS_CC);
+ RETURN_NULL();
}
- assert(obj->ptr);
- zval* zfactory;
- char* id;
- int len;
+ zend_class_entry* initClass = idToClass("::Ice::InitializationData" TSRMLS_CC);
+ assert(initClass);
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "os", &zfactory, &id, &len) == FAILURE)
+ //
+ // Retrieve the arguments.
+ //
+ zval*** args = static_cast<zval***>(emalloc(ZEND_NUM_ARGS() * sizeof(zval**)));
+ AutoEfree autoArgs(args); // Call efree on return
+ if(zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE)
{
- return;
+ runtimeError("unable to get arguments" TSRMLS_CC);
+ RETURN_NULL();
}
+ Ice::StringSeq seq;
+ Ice::InitializationData initData;
+ zval* zvinit = 0;
+
//
- // Verify that the object implements Ice_ObjectFactory.
+ // Accept the following invocations:
//
- // TODO: When zend_check_class is changed to also check interfaces, we can remove this code and
- // pass the class entry for Ice_ObjectFactory to zend_parse_parameters instead.
+ // initialize(array, InitializationData)
+ // initialize(array)
+ // initialize(InitializationData)
+ // initialize()
//
- zend_class_entry* ce = Z_OBJCE_P(zfactory);
- zend_class_entry* base = findClass("Ice_ObjectFactory" TSRMLS_CC);
- assert(base);
- if(!checkClass(ce, base))
+ if(ZEND_NUM_ARGS())
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "object does not implement Ice_ObjectFactory");
- return;
+ if(Z_TYPE_PP(args[0]) == IS_ARRAY)
+ {
+ if(!extractStringArray(*args[0], seq TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ if(ZEND_NUM_ARGS() > 1)
+ {
+ if(Z_TYPE_PP(args[1]) != IS_OBJECT || Z_OBJCE_PP(args[1]) != initClass)
+ {
+ string s = zendTypeToString(Z_TYPE_PP(args[1]));
+ invalidArgument("expected InitializationData object but received %s" TSRMLS_CC, s.c_str());
+ RETURN_NULL();
+ }
+ zvinit = *args[1];
+ }
+ }
+ else if(Z_TYPE_PP(args[0]) == IS_OBJECT && Z_OBJCE_PP(args[0]) == initClass)
+ {
+ if(ZEND_NUM_ARGS() > 1)
+ {
+ runtimeError("too many arguments" TSRMLS_CC);
+ RETURN_NULL();
+ }
+ zvinit = *args[0];
+ }
+ else
+ {
+ string s = zendTypeToString(Z_TYPE_PP(args[0]));
+ invalidArgument("unexpected argument type %s" TSRMLS_CC, s.c_str());
+ RETURN_NULL();
+ }
}
- ObjectFactoryMap* ofm = static_cast<ObjectFactoryMap*>(ICE_G(objectFactoryMap));
- ObjectFactoryMap::iterator p = ofm->find(id);
- if(p != ofm->end())
+ if(zvinit)
{
- Ice::AlreadyRegisteredException ex(__FILE__, __LINE__);
- ex.kindOfObject = "object factory";
- ex.id = id;
- throwException(ex TSRMLS_CC);
- return;
- }
+ void* data;
+ string member;
- //
- // Create a new zval with the same object handle as the factory.
- //
- zval* zv;
- MAKE_STD_ZVAL(zv);
- Z_TYPE_P(zv) = IS_OBJECT;
- zv->value.obj = zfactory->value.obj;
+ member = "properties";
+ if(zend_hash_find(Z_OBJPROP_P(zvinit), STRCAST(member.c_str()), member.size() + 1, &data) == SUCCESS)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!fetchProperties(*val, initData.properties TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
- //
- // Increment the factory's reference count.
- //
- Z_OBJ_HT_P(zv)->add_ref(zv TSRMLS_CC);
+ member = "logger";
+ if(zend_hash_find(Z_OBJPROP_P(zvinit), STRCAST(member.c_str()), member.size() + 1, &data) == SUCCESS)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!fetchLogger(*val, initData.logger TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ }
- //
- // Update the factory map.
- //
- ofm->insert(ObjectFactoryMap::value_type(id, zv));
+ CommunicatorInfoIPtr info = initializeCommunicator(return_value, seq, initData TSRMLS_CC);
+ if(!info)
+ {
+ RETURN_NULL();
+ }
}
-ZEND_FUNCTION(Ice_Communicator_findObjectFactory)
+ZEND_FUNCTION(Ice_register)
{
- if(ZEND_NUM_ARGS() != 1)
+ zval* comm;
+ char* s;
+ int sLen;
+ long expires = 0;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &comm, communicatorClassEntry, &s, &sLen, &expires
+ TSRMLS_CC) != SUCCESS)
{
- WRONG_PARAM_COUNT;
+ RETURN_NULL();
}
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ string id(s, sLen);
+ if(id.empty())
{
+ invalidArgument("communicator id cannot be empty" TSRMLS_CC);
RETURN_NULL();
}
- assert(obj->ptr);
- char* id;
- int len;
+ CommunicatorInfoIPtr info = Wrapper<CommunicatorInfoIPtr>::value(comm TSRMLS_CC);
+ assert(info);
+
+ IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex);
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &len) == FAILURE)
+ RegisteredCommunicatorMap::iterator p = _registeredCommunicators.find(id);
+ if(p != _registeredCommunicators.end())
{
- RETURN_NULL();
+ if(p->second->communicator != info->getCommunicator())
+ {
+ //
+ // A different communicator is already registered with that ID.
+ //
+ RETURN_FALSE;
+ }
}
-
- ObjectFactoryMap* ofm = static_cast<ObjectFactoryMap*>(ICE_G(objectFactoryMap));
- ObjectFactoryMap::iterator p = ofm->find(id);
- if(p == ofm->end())
+ else
{
- RETURN_NULL();
+ info->ac->ids.push_back(id);
+ _registeredCommunicators[id] = info->ac;
}
- //
- // Set the zval with the same object handle as the factory.
- //
- Z_TYPE_P(return_value) = IS_OBJECT;
- return_value->value.obj = p->second->value.obj;
+ if(expires > 0)
+ {
+ //
+ // Update the expiration time. If a communicator is registered with multiple IDs, we
+ // always use the most recent expiration setting.
+ //
+ info->ac->expires = static_cast<int>(expires);
+ info->ac->lastAccess = IceUtil::Time::now();
- //
- // Increment the factory's reference count.
- //
- Z_OBJ_HT_P(p->second)->add_ref(p->second TSRMLS_CC);
+ //
+ // Start the timer if necessary. Reap expired communicators every five minutes.
+ //
+ if(!_timer)
+ {
+ _timer = new IceUtil::Timer;
+ _timer->scheduleRepeated(new ReaperTask, IceUtil::Time::seconds(5 * 60));
+ }
+ }
+
+ RETURN_TRUE;
}
-ZEND_FUNCTION(Ice_Communicator_flushBatchRequests)
+ZEND_FUNCTION(Ice_unregister)
{
- if(ZEND_NUM_ARGS() != 0)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = getObject(getThis() TSRMLS_CC);
- if(!obj)
+ char* s;
+ int sLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s, &sLen TSRMLS_CC) != SUCCESS)
{
RETURN_NULL();
}
- assert(obj->ptr);
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
- try
- {
- (*_this)->flushBatchRequests();;
- }
- catch(const IceUtil::Exception& ex)
+ string id(s, sLen);
+
+ IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex);
+
+ RegisteredCommunicatorMap::iterator p = _registeredCommunicators.find(id);
+ if(p == _registeredCommunicators.end())
{
- throwException(ex TSRMLS_CC);
+ //
+ // No communicator registered with that ID.
+ //
+ RETURN_FALSE;
}
+
+ //
+ // Remove the ID from the ActiveCommunicator's list of registered IDs.
+ //
+ ActiveCommunicatorPtr ac = p->second;
+ vector<string>::iterator q = find(ac->ids.begin(), ac->ids.end(), id);
+ assert(q != ac->ids.end());
+ ac->ids.erase(q);
+
+ _registeredCommunicators.erase(p);
+
+ RETURN_TRUE;
}
-ZEND_FUNCTION(Ice_stringToIdentity)
+ZEND_FUNCTION(Ice_find)
{
- if(ZEND_NUM_ARGS() != 1)
+ char* s;
+ int sLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s, &sLen TSRMLS_CC) != SUCCESS)
{
- WRONG_PARAM_COUNT;
+ RETURN_NULL();
}
- char* str;
- int len;
+ string id(s, sLen);
+
+ IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex);
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE)
+ RegisteredCommunicatorMap::iterator p = _registeredCommunicators.find(id);
+ if(p == _registeredCommunicators.end())
{
+ //
+ // No communicator registered with that ID.
+ //
RETURN_NULL();
}
- try
+ if(p->second->expires > 0)
{
- Ice::CommunicatorPtr communicator = getCommunicator(TSRMLS_C);
- Ice::Identity id = communicator->stringToIdentity(str);
- createIdentity(return_value, id TSRMLS_CC);
+ p->second->lastAccess = IceUtil::Time::now();
}
- catch(const IceUtil::Exception& ex)
+
+ //
+ // Check if this communicator has already been obtained by the current request.
+ // If so, we can return the existing PHP object that corresponds to the communicator.
+ //
+ CommunicatorMap* m = reinterpret_cast<CommunicatorMap*>(ICE_G(communicatorMap));
+ if(m)
{
- throwException(ex TSRMLS_CC);
+ CommunicatorMap::iterator q = m->find(p->second->communicator);
+ if(q != m->end())
+ {
+ q->second->getZval(return_value TSRMLS_CC);
+ return;
+ }
+ }
+
+ if(!createCommunicator(return_value, p->second TSRMLS_CC))
+ {
+ RETURN_NULL();
}
}
-ZEND_FUNCTION(Ice_identityToString)
+ZEND_FUNCTION(Ice_getProperties)
{
- if(ZEND_NUM_ARGS() != 1)
+ char* s = 0;
+ int sLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &s, &sLen TSRMLS_CC) != SUCCESS)
{
- WRONG_PARAM_COUNT;
+ RETURN_NULL();
}
- zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC);
- assert(cls);
-
- zval *zid;
+ string name;
+ if(s)
+ {
+ name = string(s, sLen);
+ }
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zid, cls) == FAILURE)
+ ProfileMap::iterator p = _profiles.find(name);
+ if(p == _profiles.end())
{
RETURN_NULL();
}
- Ice::Identity id;
- if(extractIdentity(zid, id TSRMLS_CC))
+ Ice::PropertiesPtr clone = p->second->clone();
+ if(!createProperties(return_value, clone TSRMLS_CC))
{
- Ice::CommunicatorPtr communicator = getCommunicator(TSRMLS_C);
- string s = communicator->identityToString(id);
- RETURN_STRINGL(const_cast<char*>(s.c_str()), s.length(), 1);
+ RETURN_NULL();
}
}
-#ifdef _WIN32
-extern "C"
-#endif
-static zend_object_value
-handleAlloc(zend_class_entry* ce TSRMLS_DC)
+//
+// Predefined methods for Communicator.
+//
+static function_entry _interfaceMethods[] =
{
- zend_object_value result;
-
- ice_object* obj = newObject(ce TSRMLS_CC);
- assert(obj);
+ {0, 0, 0}
+};
+static function_entry _classMethods[] =
+{
+ ZEND_ME(Ice_Communicator, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ ZEND_ME(Ice_Communicator, destroy, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, stringToProxy, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, proxyToString, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, propertyToProxy, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, stringToIdentity, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, identityToString, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, addObjectFactory, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, findObjectFactory, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, getImplicitContext, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, getProperties, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, getLogger, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, getDefaultRouter, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, setDefaultRouter, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, getDefaultLocator, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, setDefaultLocator, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Communicator, flushBatchRequests, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
- result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC);
- result.handlers = &_handlers;
+static bool
+createProfile(const string& name, const string& config, const string& options TSRMLS_DC)
+{
+ ProfileMap::iterator p = _profiles.find(name);
+ if(p != _profiles.end())
+ {
+ php_error_docref(0 TSRMLS_CC, E_WARNING, "duplicate Ice profile `%s'", name.c_str());
+ return false;
+ }
- return result;
-}
+ Ice::PropertiesPtr properties = Ice::createProperties();
-#ifdef _WIN32
-extern "C"
-#endif
-static zend_object_value
-handleClone(zval* zv TSRMLS_DC)
-{
- zend_object_value result;
- memset(&result, 0, sizeof(zend_object_value));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "__clone is not supported for Ice_Communicator");
- return result;
-}
+ if(!config.empty())
+ {
+ try
+ {
+ properties->load(config);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ ostringstream ostr;
+ ex.ice_print(ostr);
+ php_error_docref(0 TSRMLS_CC, E_WARNING, "unable to load Ice configuration file %s:\n%s", config.c_str(),
+ ostr.str().c_str());
+ return false;
+ }
+ }
-#ifdef _WIN32
-extern "C"
-#endif
-static void
-handleFreeStorage(void* p TSRMLS_DC)
-{
- ice_object* obj = static_cast<ice_object*>(p);
- if(obj->ptr)
+ if(!options.empty())
{
- Ice::CommunicatorPtr* _this = static_cast<Ice::CommunicatorPtr*>(obj->ptr);
+ vector<string> args;
try
{
- (*_this)->destroy();
+ args = IceUtilInternal::Options::split(options);
}
catch(const IceUtil::Exception& ex)
{
ostringstream ostr;
ex.ice_print(ostr);
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to destroy communicator:\n%s", ostr.str().c_str());
+ string msg = ostr.str();
+ php_error_docref(0 TSRMLS_CC, E_WARNING, "error occurred while parsing the options `%s':\n%s",
+ options.c_str(), msg.c_str());
+ return false;
}
- delete _this;
+
+ properties->parseCommandLineOptions("", args);
}
- zend_objects_free_object_storage(reinterpret_cast<zend_object*>(p) TSRMLS_CC);
+ _profiles[name] = properties;
+ return true;
}
-#ifdef _WIN32
-extern "C"
-#endif
-static union _zend_function*
-handleGetMethod(zval** zv, char* method, int len TSRMLS_DC)
+static bool
+parseProfiles(const string& file TSRMLS_DC)
{
//
- // Delegate to the standard implementation of get_method. We're simply using this hook
- // as a convenient way of implementing lazy initialization of the communicator.
+ // The Zend engine doesn't export a function for loading an INI file, so we
+ // have to do it ourselves. The format is:
+ //
+ // [profile-name]
+ // ice.config = config-file
+ // ice.options = args
//
- zend_function* result = zend_get_std_object_handlers()->get_method(zv, method, len TSRMLS_CC);
- if(result)
+ ifstream in(file.c_str());
+ if(!in)
{
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(*zv TSRMLS_CC));
- if(!obj->ptr)
+ php_error_docref(0 TSRMLS_CC, E_WARNING, "unable to open Ice profiles in %s", file.c_str());
+ return false;
+ }
+
+ string name, config, options;
+ char line[1024];
+ while(in.getline(line, 1024))
+ {
+ const string delim = " \t\r\n";
+ string s = line;
+
+ string::size_type idx = s.find(';');
+ if(idx != string::npos)
+ {
+ s.erase(idx);
+ }
+
+ idx = s.find_last_not_of(delim);
+ if(idx != string::npos && idx + 1 < s.length())
+ {
+ s.erase(idx + 1);
+ }
+
+ string::size_type beg = s.find_first_not_of(delim);
+ if(beg == string::npos)
{
- if(!ICE_G(profile))
+ continue;
+ }
+
+ if(s[beg] == '[')
+ {
+ beg++;
+ string::size_type end = s.find_first_of(" \t]", beg);
+ if(end == string::npos || s[s.length() - 1] != ']')
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "$ICE used before a profile was loaded");
- return 0;
+ php_error_docref(0 TSRMLS_CC, E_WARNING, "invalid profile section in file %s:\n%s\n", file.c_str(),
+ line);
+ return false;
}
- try
+ if(!name.empty())
{
- initCommunicator(obj TSRMLS_CC);
+ createProfile(name, config, options TSRMLS_CC);
+ config.clear();
+ options.clear();
}
- catch(const IceUtil::Exception& ex)
+
+ name = s.substr(beg, end - beg);
+ }
+ else
+ {
+ string::size_type end = s.find_first_of(delim + "=", beg);
+ assert(end != string::npos);
+
+ string key = s.substr(beg, end - beg);
+
+ end = s.find('=', end);
+ if(end == string::npos)
+ {
+ php_error_docref(0 TSRMLS_CC, E_WARNING, "invalid profile entry in file %s:\n%s\n", file.c_str(), line);
+ return false;
+ }
+ ++end;
+
+ string value;
+ beg = s.find_first_not_of(delim, end);
+ if(beg != string::npos)
+ {
+ end = s.length();
+ value = s.substr(beg, end - beg);
+ }
+
+ if(key == "config" || key == "ice.config")
+ {
+ config = value;
+ }
+ else if(key == "options" || key == "ice.options")
+ {
+ options = value;
+ }
+ else
+ {
+ php_error_docref(0 TSRMLS_CC, E_WARNING, "unknown profile entry in file %s:\n%s\n", file.c_str(), line);
+ }
+
+ if(name.empty())
{
- ostringstream ostr;
- ex.ice_print(ostr);
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize communicator:\n%s", ostr.str().c_str());
- return 0;
+ php_error_docref(0 TSRMLS_CC, E_WARNING, "no section for profile entry in file %s:\n%s\n", file.c_str(),
+ line);
+ return false;
}
}
}
- return result;
+ if(!name.empty())
+ {
+ if(!createProfile(name, config, options TSRMLS_CC))
+ {
+ return false;
+ }
+ }
+
+ return true;
}
-//
-// Initialize a communicator instance and store it in the given object. Can raise exceptions.
-//
-static void
-initCommunicator(ice_object* obj TSRMLS_DC)
+bool
+IcePHP::communicatorInit(TSRMLS_D)
{
- assert(!obj->ptr);
+ //
+ // We register an interface and a class that implements the interface. This allows
+ // applications to safely include the Slice-generated code for the type.
+ //
+
+ //
+ // Register the Communicator interface.
+ //
+ zend_class_entry ce;
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Communicator"), _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Communicator", _interfaceMethods);
+#endif
+ zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC);
- Ice::PropertiesPtr* properties = static_cast<Ice::PropertiesPtr*>(ICE_G(properties));
+ //
+ // Register the Communicator class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Communicator", _classMethods);
+ ce.create_object = handleAlloc;
+ communicatorClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _handlers.clone_obj = handleClone;
+ zend_class_implements(communicatorClassEntry TSRMLS_CC, 1, interface);
- Ice::InitializationData initData;
- initData.properties = *properties;
- Ice::CommunicatorPtr communicator = Ice::initialize(initData);
- obj->ptr = new Ice::CommunicatorPtr(communicator);
+ //
+ // Create the profiles from configuration settings.
+ //
+ const char* config = INI_STR("ice.config");
+ const char* options = INI_STR("ice.options");
+ if(!createProfile(_defaultProfileName, config, options TSRMLS_CC))
+ {
+ return false;
+ }
+
+ const char* profiles = INI_STR("ice.profiles");
+ if(strlen(profiles) > 0)
+ {
+ if(!parseProfiles(profiles TSRMLS_CC))
+ {
+ return false;
+ }
+
+ if(INI_BOOL("ice.hide_profiles"))
+ {
+ memset(const_cast<char*>(profiles), '*', strlen(profiles));
+ //
+ // For some reason the code below does not work as expected. It causes a call
+ // to ini_get_all() to segfault.
+ //
+ /*
+ if(zend_alter_ini_entry("ice.profiles", sizeof("ice.profiles"), "<hidden>", sizeof("<hidden>") - 1,
+ PHP_INI_ALL, PHP_INI_STAGE_STARTUP) == FAILURE)
+ {
+ return false;
+ }
+ */
+ }
+ }
+
+ return true;
+}
+
+bool
+IcePHP::communicatorShutdown(TSRMLS_D)
+{
+ _profiles.clear();
+
+ IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex);
+
+ if(_timer)
+ {
+ _timer->destroy();
+ _timer = 0;
+ }
+
+ //
+ // Clearing the map releases the last remaining reference counts of the ActiveCommunicator
+ // objects. The ActiveCommunicator destructor destroys its communicator.
+ //
+ _registeredCommunicators.clear();
+
+ return true;
+}
+
+bool
+IcePHP::communicatorRequestInit(TSRMLS_D)
+{
+ ICE_G(communicatorMap) = 0;
+
+ return true;
+}
+
+bool
+IcePHP::communicatorRequestShutdown(TSRMLS_D)
+{
+ if(ICE_G(communicatorMap))
+ {
+ CommunicatorMap* m = static_cast<CommunicatorMap*>(ICE_G(communicatorMap));
+ for(CommunicatorMap::iterator p = m->begin(); p != m->end(); ++p)
+ {
+ CommunicatorInfoIPtr info = p->second;
+
+ //
+ // We need to destroy any object factories installed during this request.
+ //
+ info->destroyObjectFactories(TSRMLS_C);
+ }
+
+ //
+ // Deleting the map decrements the reference count of its ActiveCommunicator
+ // values. If there are no other references to an ActiveCommunicator, its
+ // destructor destroys the communicator.
+ //
+ delete m;
+ }
+
+ return true;
+}
+
+IcePHP::ActiveCommunicator::ActiveCommunicator(const Ice::CommunicatorPtr& c) :
+ communicator(c), expires(0)
+{
+}
+IcePHP::ActiveCommunicator::~ActiveCommunicator()
+{
//
- // Register our default object factory with the communicator.
+ // There are no more references to this communicator, so we can safely destroy it now.
//
- Ice::ObjectFactoryPtr factory = new PHPObjectFactory(TSRMLS_C);
- communicator->addObjectFactory(factory, "");
+ try
+ {
+ communicator->destroy();
+ }
+ catch(...)
+ {
+ }
+}
+
+IcePHP::CommunicatorInfoI::CommunicatorInfoI(const ActiveCommunicatorPtr& c, zval* z) :
+ ac(c),
+ zv(*z) // This is legal - it simply copies the object's handle.
+{
+}
+
+void
+IcePHP::CommunicatorInfoI::getZval(zval* z TSRMLS_DC)
+{
+ Z_TYPE_P(z) = IS_OBJECT;
+ z->value.obj = zv.value.obj;
+ addRef(TSRMLS_C);
+}
+
+void
+IcePHP::CommunicatorInfoI::addRef(TSRMLS_D)
+{
+ zval* p = const_cast<zval*>(&zv);
+ Z_OBJ_HT_P(p)->add_ref(p TSRMLS_CC);
+}
+
+void
+IcePHP::CommunicatorInfoI::decRef(TSRMLS_D)
+{
+ zval* p = const_cast<zval*>(&zv);
+ Z_OBJ_HT(zv)->del_ref(p TSRMLS_CC);
+}
+
+Ice::CommunicatorPtr
+IcePHP::CommunicatorInfoI::getCommunicator() const
+{
+ return ac->communicator;
+}
+
+bool
+IcePHP::CommunicatorInfoI::addObjectFactory(const string& id, zval* factory TSRMLS_DC)
+{
+ ObjectFactoryMap::iterator p = objectFactories.find(id);
+ if(p != objectFactories.end())
+ {
+ Ice::AlreadyRegisteredException ex(__FILE__, __LINE__);
+ ex.kindOfObject = "object factory";
+ ex.id = id;
+ throwException(ex TSRMLS_CC);
+ return false;
+ }
+
+ objectFactories.insert(ObjectFactoryMap::value_type(id, factory));
+ Z_ADDREF_P(factory);
+
+ return true;
+}
+
+bool
+IcePHP::CommunicatorInfoI::findObjectFactory(const string& id, zval* zv TSRMLS_DC)
+{
+ ObjectFactoryMap::iterator p = objectFactories.find(id);
+ if(p != objectFactories.end())
+ {
+ *zv = *p->second; // This is legal - it simply copies the object's handle.
+ INIT_PZVAL(zv);
+ zval_copy_ctor(zv);
+ return true;
+ }
+
+ return false;
+}
+
+void
+IcePHP::CommunicatorInfoI::destroyObjectFactories(TSRMLS_D)
+{
+ for(ObjectFactoryMap::iterator p = objectFactories.begin(); p != objectFactories.end(); ++p)
+ {
+ //
+ // Invoke the destroy method on each registered PHP factory.
+ //
+ invokeMethod(p->second, "destroy" TSRMLS_CC);
+ zend_clear_exception(TSRMLS_C);
+ zval_ptr_dtor(&p->second);
+ }
+}
+
+IcePHP::ObjectFactoryI::ObjectFactoryI(const Ice::CommunicatorPtr& communicator) :
+ _communicator(communicator)
+{
+}
+
+Ice::ObjectPtr
+IcePHP::ObjectFactoryI::create(const string& id)
+{
+ //
+ // Get the TSRM id for the current request.
+ //
+ TSRMLS_FETCH();
+
+ CommunicatorMap* m = static_cast<CommunicatorMap*>(ICE_G(communicatorMap));
+ assert(m);
+ CommunicatorMap::iterator p = m->find(_communicator);
+ assert(p != m->end());
+
+ CommunicatorInfoIPtr info = p->second;
+
+ zval* factory = 0;
+
+ //
+ // Check if the application has registered a factory for this id.
+ //
+ ObjectFactoryMap::iterator q = info->objectFactories.find(id);
+ if(q == info->objectFactories.end())
+ {
+ q = info->objectFactories.find(""); // Look for a default factory.
+ }
+ if(q != info->objectFactories.end())
+ {
+ factory = q->second;
+ }
+
+ //
+ // Get the type information.
+ //
+ ClassInfoPtr cls = getClassInfoById(id TSRMLS_CC);
+ if(!cls)
+ {
+ return 0;
+ }
+
+ if(factory)
+ {
+ zval* arg;
+ MAKE_STD_ZVAL(arg);
+ ZVAL_STRINGL(arg, STRCAST(id.c_str()), id.length(), 1);
+
+ zval* obj = 0;
+
+ zend_try
+ {
+ zend_call_method_with_1_params(&factory, 0, 0, "create", &obj, arg);
+ }
+ zend_catch
+ {
+ obj = 0;
+ }
+ zend_end_try();
+
+ zval_ptr_dtor(&arg);
+
+ //
+ // Bail out if an exception has already been thrown.
+ //
+ if(!obj || EG(exception))
+ {
+ throw AbortMarshaling();
+ }
+
+ AutoDestroy destroy(obj);
+
+ if(Z_TYPE_P(obj) == IS_NULL)
+ {
+ return 0;
+ }
+
+ return new ObjectReader(obj, cls, info TSRMLS_CC);
+ }
+
+ //
+ // If the requested type is an abstract class, then we give up.
+ //
+ if(cls->isAbstract)
+ {
+ return 0;
+ }
+
+ //
+ // Instantiate the object.
+ //
+ zval* obj;
+ MAKE_STD_ZVAL(obj);
+ AutoDestroy destroy(obj);
+
+ if(object_init_ex(obj, cls->zce) != SUCCESS)
+ {
+ throw AbortMarshaling();
+ }
+
+ if(!invokeMethod(obj, ZEND_CONSTRUCTOR_FUNC_NAME TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+
+ return new ObjectReader(obj, cls, info TSRMLS_CC);
+}
+
+void
+IcePHP::ObjectFactoryI::destroy()
+{
+ _communicator = 0;
+}
+
+void
+IcePHP::ReaperTask::runTimerTask()
+{
+ IceUtil::StaticMutex::Lock sync(_registeredCommunicatorsMutex);
+
+ IceUtil::Time now = IceUtil::Time::now();
+ RegisteredCommunicatorMap::iterator p = _registeredCommunicators.begin();
+ while(p != _registeredCommunicators.end())
+ {
+ if(p->second->lastAccess + IceUtil::Time::seconds(p->second->expires * 60) <= now)
+ {
+ try
+ {
+ p->second->communicator->destroy();
+ }
+ catch(...)
+ {
+ }
+ _registeredCommunicators.erase(p++);
+ }
+ else
+ {
+ ++p;
+ }
+ }
}
diff --git a/php/src/IcePHP/Communicator.h b/php/src/IcePHP/Communicator.h
index 25483ffd644..c6f59c1cba5 100644
--- a/php/src/IcePHP/Communicator.h
+++ b/php/src/IcePHP/Communicator.h
@@ -7,63 +7,69 @@
//
// **********************************************************************
-#ifndef ICE_PHP_COMMUNICATOR_H
-#define ICE_PHP_COMMUNICATOR_H
+#ifndef ICEPHP_COMMUNICATOR_H
+#define ICEPHP_COMMUNICATOR_H
#include <Config.h>
+#include <Ice/CommunicatorF.h>
//
-// Ice_Communicator class methods.
+// Global functions.
//
extern "C"
{
-ZEND_FUNCTION(Ice_Communicator___construct);
-ZEND_FUNCTION(Ice_Communicator_getProperty);
-ZEND_FUNCTION(Ice_Communicator_setProperty);
-ZEND_FUNCTION(Ice_Communicator_stringToProxy);
-ZEND_FUNCTION(Ice_Communicator_proxyToString);
-ZEND_FUNCTION(Ice_Communicator_propertyToProxy);
-ZEND_FUNCTION(Ice_Communicator_stringToIdentity);
-ZEND_FUNCTION(Ice_Communicator_identityToString);
-ZEND_FUNCTION(Ice_Communicator_addObjectFactory);
-ZEND_FUNCTION(Ice_Communicator_findObjectFactory);
-ZEND_FUNCTION(Ice_Communicator_flushBatchRequests);
+ZEND_FUNCTION(Ice_initialize);
+ZEND_FUNCTION(Ice_register);
+ZEND_FUNCTION(Ice_unregister);
+ZEND_FUNCTION(Ice_find);
+ZEND_FUNCTION(Ice_getProperties);
}
-#define ICE_PHP_COMMUNICATOR_FUNCTIONS \
- ZEND_FE(Ice_Communicator___construct, NULL) \
- ZEND_FE(Ice_Communicator_getProperty, NULL) \
- ZEND_FE(Ice_Communicator_setProperty, NULL) \
- ZEND_FE(Ice_Communicator_stringToProxy, NULL) \
- ZEND_FE(Ice_Communicator_proxyToString, NULL) \
- ZEND_FE(Ice_Communicator_propertyToProxy, NULL) \
- ZEND_FE(Ice_Communicator_stringToIdentity, NULL) \
- ZEND_FE(Ice_Communicator_identityToString, NULL) \
- ZEND_FE(Ice_Communicator_addObjectFactory, NULL) \
- ZEND_FE(Ice_Communicator_findObjectFactory, NULL) \
- ZEND_FE(Ice_Communicator_flushBatchRequests, NULL)
+#define ICEPHP_COMMUNICATOR_FUNCTIONS \
+ ZEND_FE(Ice_initialize, NULL) \
+ ZEND_FE(Ice_register, NULL) \
+ ZEND_FE(Ice_unregister, NULL) \
+ ZEND_FE(Ice_find, NULL) \
+ ZEND_FE(Ice_getProperties, NULL)
-//
-// Ice_Identity global functions.
-//
-extern "C"
-{
-ZEND_FUNCTION(Ice_stringToIdentity);
-ZEND_FUNCTION(Ice_identityToString);
-}
-
-#define ICE_PHP_IDENTITY_FUNCTIONS \
- ZEND_FE(Ice_stringToIdentity, NULL) \
- ZEND_FE(Ice_identityToString, NULL)
+#ifdef ICEPHP_USE_NAMESPACES
+# define ICEPHP_COMMUNICATOR_NS_FUNCTIONS \
+ ZEND_NS_FALIAS("Ice", initialize, Ice_initialize, NULL) \
+ ZEND_NS_FALIAS("Ice", register, Ice_register, NULL) \
+ ZEND_NS_FALIAS("Ice", unregister, Ice_unregister, NULL) \
+ ZEND_NS_FALIAS("Ice", find, Ice_find, NULL) \
+ ZEND_NS_FALIAS("Ice", getProperties, Ice_getProperties, NULL)
+#else
+# define ICEPHP_COMMUNICATOR_NS_FUNCTIONS
+#endif
namespace IcePHP
{
bool communicatorInit(TSRMLS_D);
+bool communicatorShutdown(TSRMLS_D);
+bool communicatorRequestInit(TSRMLS_D);
+bool communicatorRequestShutdown(TSRMLS_D);
+
+//
+// Class entry.
+//
+extern zend_class_entry* communicatorClassEntry;
+
+//
+// The CommunicatorInfo class represents a communicator that is in use by a PHP request.
+//
+class CommunicatorInfo : public IceUtil::Shared
+{
+public:
+
+ virtual void getZval(zval* TSRMLS_DC) = 0;
+ virtual void addRef(TSRMLS_D) = 0;
+ virtual void decRef(TSRMLS_D) = 0;
-bool createCommunicator(TSRMLS_D);
-Ice::CommunicatorPtr getCommunicator(TSRMLS_D);
-zval* getCommunicatorZval(TSRMLS_D);
+ virtual Ice::CommunicatorPtr getCommunicator() const = 0;
+};
+typedef IceUtil::Handle<CommunicatorInfo> CommunicatorInfoPtr;
} // End of namespace IcePHP
diff --git a/php/src/IcePHP/Config.h b/php/src/IcePHP/Config.h
index 304d31dd625..46601ec260b 100644
--- a/php/src/IcePHP/Config.h
+++ b/php/src/IcePHP/Config.h
@@ -21,7 +21,6 @@
#endif
#include <Ice/Ice.h>
-#include <Slice/Parser.h>
#ifdef _WIN32
# undef WIN32_LEAN_AND_MEAN
@@ -60,6 +59,13 @@ extern zend_module_entry ice_module_entry;
#include "TSRM.h"
#endif
+//
+// The PHP header files define a macro named "inline".
+//
+#ifdef inline
+# undef inline
+#endif
+
ZEND_MINIT_FUNCTION(ice);
ZEND_MSHUTDOWN_FUNCTION(ice);
ZEND_RINIT_FUNCTION(ice);
@@ -67,17 +73,37 @@ ZEND_RSHUTDOWN_FUNCTION(ice);
ZEND_MINFO_FUNCTION(ice);
ZEND_BEGIN_MODULE_GLOBALS(ice)
- zval* communicator;
- void* marshalerMap;
- void* profile;
- void* properties;
- void* objectFactoryMap;
+ void* communicatorMap;
+ void* idToClassInfoMap;
+ void* nameToClassInfoMap;
+ void* proxyInfoMap;
+ void* exceptionInfoMap;
ZEND_END_MODULE_GLOBALS(ice)
#ifdef ZTS
-#define ICE_G(v) TSRMG(ice_globals_id, zend_ice_globals*, v)
+# define ICE_G(v) TSRMG(ice_globals_id, zend_ice_globals*, v)
+#else
+# define ICE_G(v) (ice_globals.v)
+#endif
+
+#ifndef Z_ADDREF_P
+# ifndef ZVAL_ADDREF
+# error "Unknown PHP version"
+# endif
+# define Z_ADDREF_P(zv) ZVAL_ADDREF(zv)
+#endif
+
+#ifndef ZEND_MN
+# define ZEND_MN(name) ZEND_FN(name)
+#endif
+
+#ifdef STRCAST
+# error "STRCAST already defined!"
+#endif
+#if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3)
+# define STRCAST(s) s
#else
-#define ICE_G(v) (ice_globals.v)
+# define STRCAST(s) const_cast<char*>(s)
#endif
#endif
diff --git a/php/src/IcePHP/Connection.cpp b/php/src/IcePHP/Connection.cpp
new file mode 100644
index 00000000000..e4bad5a0352
--- /dev/null
+++ b/php/src/IcePHP/Connection.cpp
@@ -0,0 +1,304 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Connection.h>
+#include <Util.h>
+
+using namespace std;
+using namespace IcePHP;
+
+ZEND_EXTERN_MODULE_GLOBALS(ice)
+
+//
+// Class entries represent the PHP class implementations we have registered.
+//
+namespace IcePHP
+{
+zend_class_entry* connectionClassEntry = 0;
+}
+
+//
+// Ice::Connection support.
+//
+static zend_object_handlers _handlers;
+
+extern "C"
+{
+static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC);
+static void handleFreeStorage(void* TSRMLS_DC);
+static int handleCompare(zval*, zval* TSRMLS_DC);
+}
+
+ZEND_METHOD(Ice_Connection, __construct)
+{
+ runtimeError("Connection cannot be instantiated" TSRMLS_CC);
+}
+
+ZEND_METHOD(Ice_Connection, __toString)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ string str = _this->toString();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, close)
+{
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ zend_bool b;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b TSRMLS_CC) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ _this->close(b ? true : false);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, flushBatchRequests)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ _this->flushBatchRequests();
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, type)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ string str = _this->type();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, timeout)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ Ice::Int timeout = _this->timeout();
+ ZVAL_LONG(return_value, static_cast<long>(timeout));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Connection, toString)
+{
+ ZEND_MN(Ice_Connection___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleAlloc(zend_class_entry* ce TSRMLS_DC)
+{
+ zend_object_value result;
+
+ Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::create(ce TSRMLS_CC);
+ assert(obj);
+
+ result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC);
+ result.handlers = &_handlers;
+
+ return result;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleFreeStorage(void* p TSRMLS_DC)
+{
+ Wrapper<Ice::ConnectionPtr>* obj = static_cast<Wrapper<Ice::ConnectionPtr>*>(p);
+ delete obj->ptr;
+ zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static int
+handleCompare(zval* zobj1, zval* zobj2 TSRMLS_DC)
+{
+ //
+ // PHP guarantees that the objects have the same class.
+ //
+
+ Ice::ConnectionPtr con1 = Wrapper<Ice::ConnectionPtr>::value(zobj1 TSRMLS_CC);
+ assert(con1);
+ Ice::ConnectionPtr con2 = Wrapper<Ice::ConnectionPtr>::value(zobj2 TSRMLS_CC);
+ assert(con2);
+
+ if(con1 == con2)
+ {
+ return 0;
+ }
+ else if(con1 < con2)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+//
+// Predefined methods for Connection.
+//
+static function_entry _interfaceMethods[] =
+{
+ {0, 0, 0}
+};
+static function_entry _classMethods[] =
+{
+ ZEND_ME(Ice_Connection, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ ZEND_ME(Ice_Connection, __toString, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Connection, close, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Connection, flushBatchRequests, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Connection, type, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Connection, timeout, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Connection, toString, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+
+bool
+IcePHP::connectionInit(TSRMLS_D)
+{
+ //
+ // We register an interface and a class that implements the interface. This allows
+ // applications to safely include the Slice-generated code for the type.
+ //
+
+ //
+ // Register the Connection interface.
+ //
+ zend_class_entry ce;
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Connection"), _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Connection", _interfaceMethods);
+#endif
+ zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC);
+
+ //
+ // Register the Connection class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Connection", _classMethods);
+ ce.create_object = handleAlloc;
+ connectionClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _handlers.compare_objects = handleCompare;
+ zend_class_implements(connectionClassEntry TSRMLS_CC, 1, interface);
+
+ return true;
+}
+
+bool
+IcePHP::createConnection(zval* zv, const Ice::ConnectionPtr& p TSRMLS_DC)
+{
+ if(object_init_ex(zv, connectionClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize connection" TSRMLS_CC);
+ return false;
+ }
+
+ Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::extract(zv TSRMLS_CC);
+ assert(obj);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::ConnectionPtr(p);
+
+ return true;
+}
+
+bool
+IcePHP::fetchConnection(zval* zv, Ice::ConnectionPtr& connection TSRMLS_DC)
+{
+ if(ZVAL_IS_NULL(zv))
+ {
+ connection = 0;
+ }
+ else
+ {
+ if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != connectionClassEntry)
+ {
+ invalidArgument("value is not a connection" TSRMLS_CC);
+ return false;
+ }
+ Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::extract(zv TSRMLS_CC);
+ if(!obj)
+ {
+ return false;
+ }
+ connection = *obj->ptr;
+ }
+ return true;
+}
diff --git a/php/src/IcePHP/Connection.h b/php/src/IcePHP/Connection.h
new file mode 100644
index 00000000000..03d67d71357
--- /dev/null
+++ b/php/src/IcePHP/Connection.h
@@ -0,0 +1,30 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICEPHP_CONNECTION_H
+#define ICEPHP_CONNECTION_H
+
+#include <Config.h>
+
+namespace IcePHP
+{
+
+bool connectionInit(TSRMLS_D);
+
+bool createConnection(zval*, const Ice::ConnectionPtr& TSRMLS_DC);
+bool fetchConnection(zval*, Ice::ConnectionPtr& TSRMLS_DC);
+
+//
+// Class entry.
+//
+extern zend_class_entry* connectionClassEntry;
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/IcePHP/Endpoint.cpp b/php/src/IcePHP/Endpoint.cpp
new file mode 100644
index 00000000000..b4b41f6a43a
--- /dev/null
+++ b/php/src/IcePHP/Endpoint.cpp
@@ -0,0 +1,500 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Endpoint.h>
+#include <Util.h>
+
+using namespace std;
+using namespace IcePHP;
+
+ZEND_EXTERN_MODULE_GLOBALS(ice)
+
+//
+// Class entries represent the PHP class implementations we have registered.
+//
+namespace IcePHP
+{
+zend_class_entry* endpointClassEntry = 0;
+}
+
+static zend_class_entry* tcpEndpointClassEntry = 0;
+static zend_class_entry* udpEndpointClassEntry = 0;
+static zend_class_entry* opaqueEndpointClassEntry = 0;
+
+//
+// Ice::Endpoint support.
+//
+static zend_object_handlers _handlers;
+
+extern "C"
+{
+static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC);
+static void handleFreeStorage(void* TSRMLS_DC);
+}
+
+ZEND_METHOD(Ice_Endpoint, __construct)
+{
+ runtimeError("Endpoint cannot be instantiated" TSRMLS_CC);
+}
+
+ZEND_METHOD(Ice_Endpoint, __toString)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr _this = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ string str = _this->toString();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Endpoint, toString)
+{
+ ZEND_MN(Ice_Endpoint___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+ZEND_METHOD(Ice_Endpoint, timeout)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr _this = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ long timeout = static_cast<long>(_this->timeout());
+ RETURN_LONG(timeout);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Endpoint, compress)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr _this = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ RETURN_BOOL(_this->timeout() ? 1 : 0);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_TcpEndpoint, host)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(base);
+ Ice::TcpEndpointPtr _this = Ice::TcpEndpointPtr::dynamicCast(base);
+ assert(_this);
+
+ try
+ {
+ string str = _this->host();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_TcpEndpoint, port)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(base);
+ Ice::TcpEndpointPtr _this = Ice::TcpEndpointPtr::dynamicCast(base);
+ assert(_this);
+
+ try
+ {
+ long port = static_cast<long>(_this->port());
+ RETURN_LONG(port);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_UdpEndpoint, host)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(base);
+ Ice::UdpEndpointPtr _this = Ice::UdpEndpointPtr::dynamicCast(base);
+ assert(_this);
+
+ try
+ {
+ string str = _this->host();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_UdpEndpoint, port)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(base);
+ Ice::UdpEndpointPtr _this = Ice::UdpEndpointPtr::dynamicCast(base);
+ assert(_this);
+
+ try
+ {
+ long port = static_cast<long>(_this->port());
+ RETURN_LONG(port);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_UdpEndpoint, mcastInterface)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(base);
+ Ice::UdpEndpointPtr _this = Ice::UdpEndpointPtr::dynamicCast(base);
+ assert(_this);
+
+ try
+ {
+ string str = _this->mcastInterface();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_UdpEndpoint, mcastTtl)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(base);
+ Ice::UdpEndpointPtr _this = Ice::UdpEndpointPtr::dynamicCast(base);
+ assert(_this);
+
+ try
+ {
+ long port = static_cast<long>(_this->mcastTtl());
+ RETURN_LONG(port);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_OpaqueEndpoint, rawBytes)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::EndpointPtr base = Wrapper<Ice::EndpointPtr>::value(getThis() TSRMLS_CC);
+ assert(base);
+ Ice::OpaqueEndpointPtr _this = Ice::OpaqueEndpointPtr::dynamicCast(base);
+ assert(_this);
+
+ try
+ {
+ Ice::ByteSeq seq = _this->rawBytes();
+ array_init(return_value);
+ for(Ice::ByteSeq::iterator p = seq.begin(); p != seq.end(); ++p)
+ {
+ add_next_index_long(return_value, static_cast<long>(*p));
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleAlloc(zend_class_entry* ce TSRMLS_DC)
+{
+ zend_object_value result;
+
+ Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::create(ce TSRMLS_CC);
+ assert(obj);
+
+ result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC);
+ result.handlers = &_handlers;
+
+ return result;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleFreeStorage(void* p TSRMLS_DC)
+{
+ Wrapper<Ice::EndpointPtr>* obj = static_cast<Wrapper<Ice::EndpointPtr>*>(p);
+ delete obj->ptr;
+ zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
+}
+
+//
+// Predefined methods for Endpoint.
+//
+static function_entry _interfaceMethods[] =
+{
+ {0, 0, 0}
+};
+static function_entry _endpointMethods[] =
+{
+ ZEND_ME(Ice_Endpoint, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ ZEND_ME(Ice_Endpoint, __toString, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Endpoint, toString, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Endpoint, timeout, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Endpoint, compress, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+static function_entry _tcpEndpointMethods[] =
+{
+ ZEND_ME(Ice_TcpEndpoint, host, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_TcpEndpoint, port, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+static function_entry _udpEndpointMethods[] =
+{
+ ZEND_ME(Ice_UdpEndpoint, host, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_UdpEndpoint, port, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_UdpEndpoint, mcastInterface, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_UdpEndpoint, mcastTtl, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+static function_entry _opaqueEndpointMethods[] =
+{
+ ZEND_ME(Ice_OpaqueEndpoint, rawBytes, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+
+bool
+IcePHP::endpointInit(TSRMLS_D)
+{
+ //
+ // We register an interface and a class that implements the interface. This allows
+ // applications to safely include the Slice-generated code for the type.
+ //
+
+ //
+ // Register the Endpoint interface.
+ //
+ zend_class_entry ce;
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Endpoint"), _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Endpoint", _interfaceMethods);
+#endif
+ zend_class_entry* endpointInterface = zend_register_internal_interface(&ce TSRMLS_CC);
+
+ //
+ // Register the TcpEndpoint interface.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("TcpEndpoint"), _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_TcpEndpoint", _interfaceMethods);
+#endif
+ zend_class_entry* tcpEndpointInterface = zend_register_internal_interface(&ce TSRMLS_CC);
+ zend_class_implements(tcpEndpointInterface TSRMLS_CC, 1, endpointInterface);
+
+ //
+ // Register the UdpEndpoint interface.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("UdpEndpoint"), _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_UdpEndpoint", _interfaceMethods);
+#endif
+ zend_class_entry* udpEndpointInterface = zend_register_internal_interface(&ce TSRMLS_CC);
+ zend_class_implements(udpEndpointInterface TSRMLS_CC, 1, endpointInterface);
+
+ //
+ // Register the OpaqueEndpoint interface.
+ //
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("OpaqueEndpoint"), _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_OpaqueEndpoint", _interfaceMethods);
+#endif
+ zend_class_entry* opaqueEndpointInterface = zend_register_internal_interface(&ce TSRMLS_CC);
+ zend_class_implements(opaqueEndpointInterface TSRMLS_CC, 1, endpointInterface);
+
+ //
+ // Register the Endpoint class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Endpoint", _endpointMethods);
+ ce.create_object = handleAlloc;
+ endpointClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ zend_class_implements(endpointClassEntry TSRMLS_CC, 1, endpointInterface);
+
+ //
+ // Register the TcpEndpoint class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_TcpEndpoint", _tcpEndpointMethods);
+ ce.create_object = handleAlloc;
+ tcpEndpointClassEntry = zend_register_internal_class_ex(&ce, endpointClassEntry, NULL TSRMLS_CC);
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ zend_class_implements(tcpEndpointClassEntry TSRMLS_CC, 1, tcpEndpointInterface);
+
+ //
+ // Register the UdpEndpoint class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_UdpEndpoint", _udpEndpointMethods);
+ ce.create_object = handleAlloc;
+ udpEndpointClassEntry = zend_register_internal_class_ex(&ce, endpointClassEntry, NULL TSRMLS_CC);
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ zend_class_implements(udpEndpointClassEntry TSRMLS_CC, 1, udpEndpointInterface);
+
+ //
+ // Register the OpaqueEndpoint class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_OpaqueEndpoint", _opaqueEndpointMethods);
+ ce.create_object = handleAlloc;
+ opaqueEndpointClassEntry = zend_register_internal_class_ex(&ce, endpointClassEntry, NULL TSRMLS_CC);
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ zend_class_implements(opaqueEndpointClassEntry TSRMLS_CC, 1, opaqueEndpointInterface);
+
+ return true;
+}
+
+bool
+IcePHP::createEndpoint(zval* zv, const Ice::EndpointPtr& p TSRMLS_DC)
+{
+ zend_class_entry* ce;
+ if(Ice::TcpEndpointPtr::dynamicCast(p))
+ {
+ ce = tcpEndpointClassEntry;
+ }
+ else if(Ice::UdpEndpointPtr::dynamicCast(p))
+ {
+ ce = udpEndpointClassEntry;
+ }
+ else if(Ice::OpaqueEndpointPtr::dynamicCast(p))
+ {
+ ce = opaqueEndpointClassEntry;
+ }
+ else
+ {
+ ce = endpointClassEntry;
+ }
+
+ if(object_init_ex(zv, ce) != SUCCESS)
+ {
+ runtimeError("unable to initialize endpoint" TSRMLS_CC);
+ return false;
+ }
+
+ Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::extract(zv TSRMLS_CC);
+ assert(obj);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::EndpointPtr(p);
+
+ return true;
+}
+
+bool
+IcePHP::fetchEndpoint(zval* zv, Ice::EndpointPtr& endpoint TSRMLS_DC)
+{
+ if(ZVAL_IS_NULL(zv))
+ {
+ endpoint = 0;
+ }
+ else
+ {
+ if(Z_TYPE_P(zv) != IS_OBJECT || !checkClass(Z_OBJCE_P(zv), endpointClassEntry))
+ {
+ invalidArgument("value is not an endpoint" TSRMLS_CC);
+ return false;
+ }
+ Wrapper<Ice::EndpointPtr>* obj = Wrapper<Ice::EndpointPtr>::extract(zv TSRMLS_CC);
+ if(!obj)
+ {
+ return false;
+ }
+ endpoint = *obj->ptr;
+ }
+ return true;
+}
diff --git a/php/src/IcePHP/Endpoint.h b/php/src/IcePHP/Endpoint.h
new file mode 100644
index 00000000000..dbf1556bb99
--- /dev/null
+++ b/php/src/IcePHP/Endpoint.h
@@ -0,0 +1,30 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICEPHP_ENDPOINT_H
+#define ICEPHP_ENDPOINT_H
+
+#include <Config.h>
+
+namespace IcePHP
+{
+
+bool endpointInit(TSRMLS_D);
+
+bool createEndpoint(zval*, const Ice::EndpointPtr& TSRMLS_DC);
+bool fetchEndpoint(zval*, Ice::EndpointPtr& TSRMLS_DC);
+
+//
+// Class entry.
+//
+extern zend_class_entry* endpointClassEntry;
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/IcePHP/Init.cpp b/php/src/IcePHP/Init.cpp
index 338a2276fb2..6ffa681f534 100644
--- a/php/src/IcePHP/Init.cpp
+++ b/php/src/IcePHP/Init.cpp
@@ -8,9 +8,13 @@
// **********************************************************************
#include <Communicator.h>
-#include <Marshal.h>
-#include <Profile.h>
+#include <Connection.h>
+#include <Endpoint.h>
+#include <Logger.h>
+#include <Operation.h>
+#include <Properties.h>
#include <Proxy.h>
+#include <Types.h>
#include <Util.h>
using namespace std;
@@ -19,14 +23,18 @@ using namespace IcePHP;
ZEND_DECLARE_MODULE_GLOBALS(ice)
//
-// Entries for all object methods and global functions.
+// Entries for all global functions.
//
function_entry ice_functions[] =
{
- ICE_PHP_COMMUNICATOR_FUNCTIONS
- ICE_PHP_IDENTITY_FUNCTIONS
- ICE_PHP_PROXY_FUNCTIONS
- ICE_PHP_PROFILE_FUNCTIONS
+ ICEPHP_COMMUNICATOR_FUNCTIONS
+ ICEPHP_COMMUNICATOR_NS_FUNCTIONS
+ ICEPHP_OPERATION_FUNCTIONS
+ ICEPHP_PROPERTIES_FUNCTIONS
+ ICEPHP_PROPERTIES_NS_FUNCTIONS
+ ICEPHP_TYPE_FUNCTIONS
+ ICEPHP_UTIL_FUNCTIONS
+ ICEPHP_UTIL_NS_FUNCTIONS
{0, 0, 0}
};
@@ -53,16 +61,17 @@ PHP_INI_BEGIN()
PHP_INI_ENTRY("ice.config", "", PHP_INI_SYSTEM, 0)
PHP_INI_ENTRY("ice.options", "", PHP_INI_SYSTEM, 0)
PHP_INI_ENTRY("ice.profiles", "", PHP_INI_SYSTEM, 0)
- PHP_INI_ENTRY("ice.slice", "", PHP_INI_SYSTEM, 0)
+ PHP_INI_ENTRY("ice.hide_profiles", "1", PHP_INI_SYSTEM, 0)
PHP_INI_END()
extern "C"
int initIceGlobals(zend_ice_globals* g)
{
- g->communicator = 0;
- g->marshalerMap = 0;
- g->profile = 0;
- g->properties = 0;
+ g->communicatorMap = 0;
+ g->idToClassInfoMap = 0;
+ g->nameToClassInfoMap = 0;
+ g->proxyInfoMap = 0;
+ g->exceptionInfoMap = 0;
return SUCCESS;
}
@@ -71,12 +80,12 @@ ZEND_MINIT_FUNCTION(ice)
REGISTER_INI_ENTRIES();
ZEND_INIT_MODULE_GLOBALS(ice, initIceGlobals, 0);
- if(!profileInit(TSRMLS_C))
+ if(!communicatorInit(TSRMLS_C))
{
return FAILURE;
}
- if(!communicatorInit(TSRMLS_C))
+ if(!propertiesInit(TSRMLS_C))
{
return FAILURE;
}
@@ -86,6 +95,26 @@ ZEND_MINIT_FUNCTION(ice)
return FAILURE;
}
+ if(!typesInit(TSRMLS_C))
+ {
+ return FAILURE;
+ }
+
+ if(!loggerInit(TSRMLS_C))
+ {
+ return FAILURE;
+ }
+
+ if(!endpointInit(TSRMLS_C))
+ {
+ return FAILURE;
+ }
+
+ if(!connectionInit(TSRMLS_C))
+ {
+ return FAILURE;
+ }
+
return SUCCESS;
}
@@ -95,7 +124,7 @@ ZEND_MSHUTDOWN_FUNCTION(ice)
int status = SUCCESS;
- if(!profileShutdown(TSRMLS_C))
+ if(!communicatorShutdown(TSRMLS_C))
{
status = FAILURE;
}
@@ -105,18 +134,14 @@ ZEND_MSHUTDOWN_FUNCTION(ice)
ZEND_RINIT_FUNCTION(ice)
{
- ICE_G(communicator) = 0;
- ICE_G(marshalerMap) = new MarshalerMap;
- ICE_G(profile) = 0;
- ICE_G(properties) = 0;
- ICE_G(objectFactoryMap) = new ObjectFactoryMap;
-
- //
- // Create the global variable "ICE" to hold the communicator for this request. The
- // communicator won't actually be created until the script uses this global variable
- // for the first time.
- //
- if(!createCommunicator(TSRMLS_C))
+ ICE_G(communicatorMap) = 0;
+
+ if(!communicatorRequestInit(TSRMLS_C))
+ {
+ return FAILURE;
+ }
+
+ if(!typesRequestInit(TSRMLS_C))
{
return FAILURE;
}
@@ -126,20 +151,15 @@ ZEND_RINIT_FUNCTION(ice)
ZEND_RSHUTDOWN_FUNCTION(ice)
{
- //
- // Invoke destroy() on each registered factory.
- //
- ObjectFactoryMap* ofm = static_cast<ObjectFactoryMap*>(ICE_G(objectFactoryMap));
- for(ObjectFactoryMap::iterator p = ofm->begin(); p != ofm->end(); ++p)
+ if(!communicatorRequestShutdown(TSRMLS_C))
{
- zval* factory = p->second;
- zend_call_method_with_0_params(&factory, 0, 0, "destroy", 0);
- zval_ptr_dtor(&factory);
+ return FAILURE;
}
- delete ofm;
- delete static_cast<MarshalerMap*>(ICE_G(marshalerMap));
- delete static_cast<Ice::PropertiesPtr*>(ICE_G(properties));
+ if(!typesRequestShutdown(TSRMLS_C))
+ {
+ return FAILURE;
+ }
return SUCCESS;
}
diff --git a/php/src/IcePHP/Logger.cpp b/php/src/IcePHP/Logger.cpp
new file mode 100644
index 00000000000..62bba11f75a
--- /dev/null
+++ b/php/src/IcePHP/Logger.cpp
@@ -0,0 +1,278 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Logger.h>
+#include <Util.h>
+
+using namespace std;
+using namespace IcePHP;
+
+ZEND_EXTERN_MODULE_GLOBALS(ice)
+
+//
+// Class entries represent the PHP class implementations we have registered.
+//
+namespace IcePHP
+{
+zend_class_entry* loggerClassEntry = 0;
+}
+
+//
+// Logger support.
+//
+static zend_object_handlers _loggerHandlers;
+
+extern "C"
+{
+static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC);
+static void handleFreeStorage(void* TSRMLS_DC);
+static zend_object_value handleClone(zval* TSRMLS_DC);
+}
+
+ZEND_METHOD(Ice_Logger, __construct)
+{
+ runtimeError("logger objects cannot be instantiated" TSRMLS_CC);
+}
+
+ZEND_METHOD(Ice_Logger, __toString)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_NULL();
+}
+
+ZEND_METHOD(Ice_Logger, print)
+{
+ char* m;
+ int mLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &m, &mLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string msg(m, mLen);
+ try
+ {
+ _this->print(msg);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Logger, trace)
+{
+ char* c;
+ int cLen;
+ char* m;
+ int mLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &c, &cLen, &m, &mLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string category(c, cLen);
+ string msg(m, mLen);
+ try
+ {
+ _this->trace(category, msg);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Logger, warning)
+{
+ char* m;
+ int mLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &m, &mLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string msg(m, mLen);
+ try
+ {
+ _this->warning(msg);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Logger, error)
+{
+ char* m;
+ int mLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &m, &mLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string msg(m, mLen);
+ try
+ {
+ _this->error(msg);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleAlloc(zend_class_entry* ce TSRMLS_DC)
+{
+ zend_object_value result;
+
+ Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::create(ce TSRMLS_CC);
+ assert(obj);
+
+ result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC);
+ result.handlers = &_loggerHandlers;
+
+ return result;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleFreeStorage(void* p TSRMLS_DC)
+{
+ Wrapper<Ice::LoggerPtr>* obj = static_cast<Wrapper<Ice::LoggerPtr>*>(p);
+ delete obj->ptr;
+ zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleClone(zval* zv TSRMLS_DC)
+{
+ php_error_docref(0 TSRMLS_CC, E_ERROR, "loggers cannot be cloned");
+ return zend_object_value();
+}
+
+//
+// Predefined methods for Logger.
+//
+static function_entry _interfaceMethods[] =
+{
+ {0, 0, 0}
+};
+static function_entry _classMethods[] =
+{
+ ZEND_ME(Ice_Logger, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ ZEND_ME(Ice_Logger, __toString, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Logger, print, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Logger, trace, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Logger, warning, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Logger, error, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+
+bool
+IcePHP::loggerInit(TSRMLS_D)
+{
+ //
+ // We register an interface and a class that implements the interface. This allows
+ // applications to safely include the Slice-generated code for the type.
+ //
+
+ //
+ // Register the Logger interface.
+ //
+ zend_class_entry ce;
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Logger"), _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Logger", _interfaceMethods);
+#endif
+ zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC);
+
+ //
+ // Register the Logger class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Logger", _classMethods);
+ ce.create_object = handleAlloc;
+ loggerClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
+ memcpy(&_loggerHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _loggerHandlers.clone_obj = handleClone;
+ zend_class_implements(loggerClassEntry TSRMLS_CC, 1, interface);
+
+ return true;
+}
+
+bool
+IcePHP::createLogger(zval* zv, const Ice::LoggerPtr& p TSRMLS_DC)
+{
+ if(object_init_ex(zv, loggerClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize logger object" TSRMLS_CC);
+ return false;
+ }
+
+ Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::extract(zv TSRMLS_CC);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::LoggerPtr(p);
+
+ return true;
+}
+
+bool
+IcePHP::fetchLogger(zval* zv, Ice::LoggerPtr& p TSRMLS_DC)
+{
+ if(!ZVAL_IS_NULL(zv))
+ {
+ if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != loggerClassEntry)
+ {
+ invalidArgument("value is not a logger object" TSRMLS_CC);
+ return false;
+ }
+ p = Wrapper<Ice::LoggerPtr>::value(zv TSRMLS_CC);
+ if(!p)
+ {
+ runtimeError("unable to retrieve logger object from object store" TSRMLS_CC);
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/php/src/IcePHP/Logger.h b/php/src/IcePHP/Logger.h
new file mode 100644
index 00000000000..e2eb76937bb
--- /dev/null
+++ b/php/src/IcePHP/Logger.h
@@ -0,0 +1,30 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICEPHP_LOGGER_H
+#define ICEPHP_LOGGER_H
+
+#include <Config.h>
+
+namespace IcePHP
+{
+
+bool loggerInit(TSRMLS_D);
+
+bool createLogger(zval*, const Ice::LoggerPtr& TSRMLS_DC);
+bool fetchLogger(zval*, Ice::LoggerPtr& TSRMLS_DC);
+
+//
+// Class entry.
+//
+extern zend_class_entry* loggerClassEntry;
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/IcePHP/Makefile b/php/src/IcePHP/Makefile
index 6d56a5f21cf..e375b035dd7 100644
--- a/php/src/IcePHP/Makefile
+++ b/php/src/IcePHP/Makefile
@@ -15,10 +15,14 @@ SONAME = $(LIBNAME)
TARGETS = $(libdir)/$(LIBNAME)
OBJS = Communicator.o \
+ Connection.o \
+ Endpoint.o \
Init.o \
- Marshal.o \
- Profile.o \
+ Logger.o \
+ Operation.o \
+ Properties.o \
Proxy.o \
+ Types.o \
Util.o
SRCS = $(OBJS:.o=.cpp)
@@ -36,4 +40,10 @@ $(libdir)/$(LIBNAME): $(OBJS)
install:: all
$(call installphplib,$(libdir)/$(LIBNAME),$(install_libdir))
+depend:: $(SRCS)
+ -rm -f .depend
+ if test -n "$(SRCS)" ; then \
+ $(CXX) -DMAKEDEPEND -M $(CXXFLAGS) $(CPPFLAGS) $(SRCS) | $(ice_dir)/config/makedepend.py >> .depend; \
+ fi
+
include .depend
diff --git a/php/src/IcePHP/Makefile.mak b/php/src/IcePHP/Makefile.mak
index 61de9aecb85..0600357074e 100644
--- a/php/src/IcePHP/Makefile.mak
+++ b/php/src/IcePHP/Makefile.mak
@@ -10,22 +10,29 @@
top_srcdir = ..\..
LIBNAME = php_ice$(LIBSUFFIX).lib
-DLLNAME = $(bindir)\php_ice$(LIBSUFFIX).dll
+DLLNAME = $(libdir)\php_ice$(LIBSUFFIX).dll
TARGETS = $(LIBNAME) $(DLLNAME)
OBJS = Communicator.obj \
+ Connection.obj \
+ Endpoint.obj \
Init.obj \
- Marshal.obj \
- Profile.obj \
+ Logger.obj \
+ Operation.obj \
+ Properties.obj \
Proxy.obj \
+ Types.obj \
Util.obj
SRCS = $(OBJS:.obj=.cpp)
!include $(top_srcdir)\config\Make.rules.mak
-CPPFLAGS = -I. -I.. $(CPPFLAGS) $(ICE_CPPFLAGS) $(PHP_CPPFLAGS)
+CPPFLAGS = -I. -I.. $(CPPFLAGS) $(ICE_CPPFLAGS) $(PHP_CPPFLAGS)
+!if "$(CPP_COMPILER)" == "VC90" || "$(CPP_COMPILER)" == "VC90_EXPRESS"
+CPPFLAGS = $(CPPFLAGS) -D_USE_32BIT_TIME_T
+!endif
!if "$(OPTIMIZE)" != "yes"
PDBFLAGS = /pdb:$(LIBNAME:.lib=.pdb)
!endif
@@ -40,6 +47,6 @@ $(DLLNAME): $(OBJS)
move $(DLLNAME:.dll=.lib) $(LIBNAME)
install:: all
- copy $(DLLNAME) $(install_bindir)
+ copy $(DLLNAME) $(install_libdir)
!include .depend
diff --git a/php/src/IcePHP/Marshal.cpp b/php/src/IcePHP/Marshal.cpp
deleted file mode 100644
index fe802f345d1..00000000000
--- a/php/src/IcePHP/Marshal.cpp
+++ /dev/null
@@ -1,2305 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#include <Marshal.h>
-#include <Profile.h>
-#include <Proxy.h>
-#include <Util.h>
-
-#include <IceUtil/InputUtil.h>
-#include <IceUtil/OutputUtil.h>
-#include <IceUtil/ScopedArray.h>
-
-using namespace std;
-using namespace IcePHP;
-
-ZEND_EXTERN_MODULE_GLOBALS(ice)
-
-//
-// The marshaling implementation is fairly straightforward. The factory methods in the
-// Marshaler base class examine the given Slice type and create a Marshaler subclass
-// that is responsible for marshaling that type. Some caching is done for complex types
-// such as struct and class; the cached Marshaler instance is stored as a member of the
-// ice_class_entry struct. (Cached instances are destroyed by Slice_destroyClasses.)
-//
-// The implementation of Ice object marshaling is more complex. In order to interface
-// with the Ice stream interface, we need to supply Ice::Object instances, and we must
-// be able to properly handle object graphs and cycles. The solution is to wrap each
-// PHP object with a temporary Ice::Object, and maintain a table that associates each PHP
-// object to its wrapper, so that graphs work correctly.
-//
-// The ObjectMarshaler class doesn't actually marshal object instances. Rather, it
-// represents the top-level marshaler for a particular formal type (i.e., the declared
-// type of a data member or operation parameter). During marshaling, the ObjectMarshaler
-// validates the type of the object to ensure it is compatible with the formal type,
-// and then obtains or creates an ObjectWriter instance for the object. Since each PHP
-// object is represented by an unsigned integer handle, looking up the wrapper is simple.
-//
-// Once the writer is obtained, the marshaler gives it to the stream. Eventually, the
-// stream will invoke write on the writer, at which point the data members are
-// marshaled. For efficiency, each "slice" of the object's state is marshaled by an
-// ObjectSliceMarshaler, which is cached for future reuse.
-//
-// Note that a graph of PHP objects does not result in an equivalent graph of writers.
-// Links between objects exist only in the PHP object representation. Furthermore, the
-// lifetime of the writers is bound to the operation, not to the PHP objects. Writers
-// exist only as a bridge to the C++ marshaling facility.
-//
-// Unmarshaling of Ice objects works in a similar fashion. A default object factory
-// is installed in the communicator that is capable of instantiating any concrete
-// class type for which a definition is present, including the type "::Ice::Object".
-// It returns an instance of ObjectReader, a subclass of Ice::Object that overrides
-// the read method to unmarshal object state. The setValue method is eventually
-// called on the ObjectReader in order to transfer its object handle to a different
-// zval value.
-//
-
-namespace IcePHP
-{
-
-//
-// Marshaler subclass definitions.
-//
-class PrimitiveMarshaler : public Marshaler
-{
-public:
- PrimitiveMarshaler(const Slice::BuiltinPtr&);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
- bool validate(zval* TSRMLS_DC);
-
-private:
- Slice::BuiltinPtr _type;
-};
-typedef IceUtil::Handle<PrimitiveMarshaler> PrimitiveMarshalerPtr;
-
-class SequenceMarshaler : public Marshaler
-{
-public:
- SequenceMarshaler(const Slice::SequencePtr& TSRMLS_DC);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
-private:
- Slice::SequencePtr _type;
- Slice::BuiltinPtr _builtin;
- MarshalerPtr _elementMarshaler;
-};
-
-class ProxyMarshaler : public Marshaler
-{
-public:
- ProxyMarshaler(const Slice::ProxyPtr&);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
-private:
- Slice::ProxyPtr _type;
-};
-
-class MemberMarshaler : public Marshaler
-{
-public:
- MemberMarshaler(const string&, const MarshalerPtr&);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
-private:
- string _name;
- MarshalerPtr _marshaler;
-};
-
-class StructMarshaler : public Marshaler
-{
-public:
- StructMarshaler(const Slice::StructPtr& TSRMLS_DC);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
-private:
- Slice::StructPtr _type;
- zend_class_entry* _class;
- vector<MarshalerPtr> _members;
-};
-
-class EnumMarshaler : public Marshaler
-{
-public:
- EnumMarshaler(const Slice::EnumPtr& TSRMLS_DC);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
-private:
- zend_class_entry* _class;
- long _count;
-};
-
-class NativeDictionaryMarshaler : public Marshaler
-{
-public:
- NativeDictionaryMarshaler(const Slice::TypePtr&, const Slice::TypePtr& TSRMLS_DC);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
-private:
- Slice::Builtin::Kind _keyKind;
- MarshalerPtr _keyMarshaler;
- MarshalerPtr _valueMarshaler;
-};
-
-class ExceptionMarshaler : public Marshaler
-{
-public:
- ExceptionMarshaler(const Slice::ExceptionPtr& TSRMLS_DC);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
-private:
- Slice::ExceptionPtr _ex;
- zend_class_entry* _class;
-};
-
-//
-// Special marshaler just for the Ice::Object slice.
-//
-class IceObjectSliceMarshaler : public Marshaler
-{
-public:
- IceObjectSliceMarshaler(TSRMLS_D);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-};
-
-class ObjectSliceMarshaler : public Marshaler
-{
-public:
- ObjectSliceMarshaler(const string&, const Slice::DataMemberList& TSRMLS_DC);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
-private:
- string _scoped;
- vector<MarshalerPtr> _members;
-};
-
-class ObjectWriter : public Ice::ObjectWriter
-{
-public:
- ObjectWriter(zval*, const Slice::SyntaxTreeBasePtr&, ObjectMap& TSRMLS_DC);
- ~ObjectWriter();
-
- virtual void ice_preMarshal();
-
- virtual void write(const Ice::OutputStreamPtr&) const;
-
-private:
- zval* _value;
- Slice::ClassDefPtr _type; // nil if type is ::Ice::Object
- ObjectMap& _map;
-#ifdef ZTS
- TSRMLS_D;
-#endif
-};
-
-class ReadObjectCallback : public Ice::ReadObjectCallback
-{
-public:
-
- virtual void invoke(const ::Ice::ObjectPtr&);
-
- zend_class_entry* ce; // The formal type
- string scoped;
- zval* zv; // The destination zval
-};
-typedef IceUtil::Handle<ReadObjectCallback> ReadObjectCallbackPtr;
-
-class ObjectReader : public Ice::ObjectReader
-{
-public:
- ObjectReader(zval*, const Slice::ClassDefPtr& TSRMLS_DC);
- ~ObjectReader();
-
- virtual void ice_postUnmarshal();
-
- virtual void read(const Ice::InputStreamPtr&, bool);
-
- void setValue(zend_class_entry*, const string&, zval*);
-
-private:
- zval* _value;
- Slice::ClassDefPtr _type; // nil if type is ::Ice::Object
-#ifdef ZTS
- TSRMLS_D;
-#endif
- zend_class_entry* _class;
-};
-typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr;
-
-class ObjectMarshaler : public Marshaler
-{
-public:
- ObjectMarshaler(const Slice::ClassDefPtr& TSRMLS_DC);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC);
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC);
-
- virtual void destroy();
-
-private:
- Slice::ClassDefPtr _def;
- zend_class_entry* _class; // The static class type.
- string _scoped;
-};
-
-} // End of namespace IcePHP
-
-//
-// Marshaler implementation.
-//
-IcePHP::Marshaler::Marshaler()
-{
-}
-
-IcePHP::Marshaler::~Marshaler()
-{
-}
-
-MarshalerPtr
-IcePHP::Marshaler::createMarshaler(const Slice::TypePtr& type TSRMLS_DC)
-{
- Slice::BuiltinPtr builtin = Slice::BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- switch(builtin->kind())
- {
- case Slice::Builtin::KindByte:
- case Slice::Builtin::KindBool:
- case Slice::Builtin::KindShort:
- case Slice::Builtin::KindInt:
- case Slice::Builtin::KindLong:
- case Slice::Builtin::KindFloat:
- case Slice::Builtin::KindDouble:
- case Slice::Builtin::KindString:
- return new PrimitiveMarshaler(builtin);
-
- case Slice::Builtin::KindObject:
- return new ObjectMarshaler(0 TSRMLS_CC);
-
- case Slice::Builtin::KindObjectProxy:
- return new ProxyMarshaler(0);
-
- case Slice::Builtin::KindLocalObject:
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unexpected local type");
- return 0;
- }
- }
-
- Slice::SequencePtr seq = Slice::SequencePtr::dynamicCast(type);
- if(seq)
- {
- return new SequenceMarshaler(seq TSRMLS_CC);
- }
-
- Slice::ProxyPtr proxy = Slice::ProxyPtr::dynamicCast(type);
- if(proxy)
- {
- return new ProxyMarshaler(proxy);
- }
-
- Slice::StructPtr st = Slice::StructPtr::dynamicCast(type);
- if(st)
- {
- //
- // Check to see if a marshaler for this type has already been created. If not, create
- // one and cache it in the marshaler map for future use.
- //
- string scoped = st->scoped();
- MarshalerMap* marshalerMap = static_cast<MarshalerMap*>(ICE_G(marshalerMap));
- MarshalerMap::iterator p = marshalerMap->find(scoped);
- if(p != marshalerMap->end())
- {
- return p->second;
- }
- else
- {
- MarshalerPtr result = new StructMarshaler(st TSRMLS_CC);
- marshalerMap->insert(pair<string, MarshalerPtr>(scoped, result));
- return result;
- }
- }
-
- Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(type);
- if(en)
- {
- return new EnumMarshaler(en TSRMLS_CC);
- }
-
- Slice::DictionaryPtr dict = Slice::DictionaryPtr::dynamicCast(type);
- if(dict)
- {
- if(isNativeKey(dict->keyType()))
- {
- return new NativeDictionaryMarshaler(dict->keyType(), dict->valueType() TSRMLS_CC);
- }
- }
-
- Slice::ClassDeclPtr cl = Slice::ClassDeclPtr::dynamicCast(type);
- if(cl)
- {
- //
- // Don't cache ObjectMarshaler - we cache ObjectSliceMarshaler instead.
- //
- Slice::ClassDefPtr def = cl->definition();
- if(!def)
- {
- string scoped = cl->scoped();
- php_error_docref(0 TSRMLS_CC, E_ERROR, "cannot use Slice %s %s because it has not been defined",
- cl->isInterface() ? "interface" : "class", scoped.c_str());
- return 0;
- }
- return new ObjectMarshaler(def TSRMLS_CC);
- }
-
- return 0;
-}
-
-MarshalerPtr
-IcePHP::Marshaler::createMemberMarshaler(const string& name, const Slice::TypePtr& type TSRMLS_DC)
-{
- MarshalerPtr result;
- MarshalerPtr m = createMarshaler(type TSRMLS_CC);
- if(m)
- {
- result = new MemberMarshaler(name, m);
- }
- return result;
-}
-
-MarshalerPtr
-IcePHP::Marshaler::createExceptionMarshaler(const Slice::ExceptionPtr& ex TSRMLS_DC)
-{
- return new ExceptionMarshaler(ex TSRMLS_CC);
-}
-
-//
-// PrimitiveMarshaler implementation.
-//
-IcePHP::PrimitiveMarshaler::PrimitiveMarshaler(const Slice::BuiltinPtr& type) :
- _type(type)
-{
-}
-
-bool
-IcePHP::PrimitiveMarshaler::validate(zval* zv TSRMLS_DC)
-{
- switch(_type->kind())
- {
- case Slice::Builtin::KindBool:
- {
- if(Z_TYPE_P(zv) != IS_BOOL)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected boolean value but received %s", s.c_str());
- return false;
- }
- break;
- }
- case Slice::Builtin::KindByte:
- {
- if(Z_TYPE_P(zv) != IS_LONG)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected byte value but received %s", s.c_str());
- return false;
- }
- long val = Z_LVAL_P(zv);
- if(val < 0 || val > 255)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "value %ld is out of range for a byte", val);
- return false;
- }
- break;
- }
- case Slice::Builtin::KindShort:
- {
- if(Z_TYPE_P(zv) != IS_LONG)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected short value but received %s", s.c_str());
- return false;
- }
- long val = Z_LVAL_P(zv);
- if(val < SHRT_MIN || val > SHRT_MAX)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "value %ld is out of range for a short", val);
- return false;
- }
- break;
- }
- case Slice::Builtin::KindInt:
- {
- if(Z_TYPE_P(zv) != IS_LONG)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected int value but received %s", s.c_str());
- return false;
- }
- long val = Z_LVAL_P(zv);
- if(val < INT_MIN || val > INT_MAX)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "value %ld is out of range for an int", val);
- return false;
- }
- break;
- }
- case Slice::Builtin::KindLong:
- {
- //
- // The platform's 'long' type may not be 64 bits, so we also accept
- // a string argument for this type.
- //
- if(Z_TYPE_P(zv) != IS_LONG && Z_TYPE_P(zv) != IS_STRING)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected long value but received %s", s.c_str());
- return false;
- }
- Ice::Long val;
- if(Z_TYPE_P(zv) == IS_LONG)
- {
- val = Z_LVAL_P(zv);
- }
- else
- {
- string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
- if(!IceUtilInternal::stringToInt64(sval, val))
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "invalid long value `%s'", Z_STRVAL_P(zv));
- return false;
- }
- }
- break;
- }
- case Slice::Builtin::KindFloat:
- {
- if(Z_TYPE_P(zv) != IS_DOUBLE)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected float value but received %s", s.c_str());
- return false;
- }
- break;
- }
- case Slice::Builtin::KindDouble:
- {
- if(Z_TYPE_P(zv) != IS_DOUBLE)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected double value but received %s", s.c_str());
- return false;
- }
- break;
- }
- case Slice::Builtin::KindString:
- {
- if(Z_TYPE_P(zv) != IS_STRING && Z_TYPE_P(zv) != IS_NULL)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected string value but received %s", s.c_str());
- return false;
- }
- break;
- }
-
- case Slice::Builtin::KindObject:
- case Slice::Builtin::KindObjectProxy:
- case Slice::Builtin::KindLocalObject:
- assert(false);
- }
- return true;
-}
-
-bool
-IcePHP::PrimitiveMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& TSRMLS_DC)
-{
- if(!validate(zv TSRMLS_CC))
- {
- return false;
- }
-
- switch(_type->kind())
- {
- case Slice::Builtin::KindBool:
- {
- assert(Z_TYPE_P(zv) == IS_BOOL);
- os->writeBool(Z_BVAL_P(zv) ? true : false);
- break;
- }
- case Slice::Builtin::KindByte:
- {
- assert(Z_TYPE_P(zv) == IS_LONG);
- long val = Z_LVAL_P(zv);
- assert(val >= 0 && val <= 255);
- os->writeByte(static_cast<Ice::Byte>(val));
- break;
- }
- case Slice::Builtin::KindShort:
- {
- assert(Z_TYPE_P(zv) == IS_LONG);
- long val = Z_LVAL_P(zv);
- assert(val >= SHRT_MIN && val <= SHRT_MAX);
- os->writeShort(static_cast<Ice::Short>(val));
- break;
- }
- case Slice::Builtin::KindInt:
- {
- assert(Z_TYPE_P(zv) == IS_LONG);
- long val = Z_LVAL_P(zv);
- assert(val >= INT_MIN && val <= INT_MAX);
- os->writeInt(static_cast<Ice::Int>(val));
- break;
- }
- case Slice::Builtin::KindLong:
- {
- //
- // The platform's 'long' type may not be 64 bits, so we also accept
- // a string argument for this type.
- //
- assert(Z_TYPE_P(zv) == IS_LONG || Z_TYPE_P(zv) == IS_STRING);
- Ice::Long val;
- if(Z_TYPE_P(zv) == IS_LONG)
- {
- val = Z_LVAL_P(zv);
- }
- else
- {
- string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
- IceUtilInternal::stringToInt64(sval, val);
- }
- os->writeLong(val);
- break;
- }
- case Slice::Builtin::KindFloat:
- {
- assert(Z_TYPE_P(zv) == IS_DOUBLE);
- double val = Z_DVAL_P(zv);
- os->writeFloat(static_cast<Ice::Float>(val));
- break;
- }
- case Slice::Builtin::KindDouble:
- {
- assert(Z_TYPE_P(zv) == IS_DOUBLE);
- double val = Z_DVAL_P(zv);
- os->writeDouble(val);
- break;
- }
- case Slice::Builtin::KindString:
- {
- assert(Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_NULL);
- if(Z_TYPE_P(zv) == IS_STRING)
- {
- string val(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
- os->writeString(val);
- }
- else
- {
- os->writeString(string());
- }
- break;
- }
-
- case Slice::Builtin::KindObject:
- case Slice::Builtin::KindObjectProxy:
- case Slice::Builtin::KindLocalObject:
- assert(false);
- }
- return true;
-}
-
-bool
-IcePHP::PrimitiveMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- switch(_type->kind())
- {
- case Slice::Builtin::KindBool:
- {
- bool val = is->readBool();
- ZVAL_BOOL(zv, val ? 1 : 0);
- break;
- }
- case Slice::Builtin::KindByte:
- {
- Ice::Byte val = is->readByte();
- ZVAL_LONG(zv, val & 0xff);
- break;
- }
- case Slice::Builtin::KindShort:
- {
- Ice::Short val = is->readShort();
- ZVAL_LONG(zv, val);
- break;
- }
- case Slice::Builtin::KindInt:
- {
- Ice::Int val = is->readInt();
- ZVAL_LONG(zv, val);
- break;
- }
- case Slice::Builtin::KindLong:
- {
- Ice::Long val = is->readLong();
-
- //
- // The platform's 'long' type may not be 64 bits, so we store 64-bit
- // values as a string.
- //
- if(sizeof(Ice::Long) > sizeof(long) && (val < LONG_MIN || val > LONG_MAX))
- {
- string str = IceUtilInternal::int64ToString(val);
- ZVAL_STRINGL(zv, const_cast<char*>(str.c_str()), str.length(), 1);
- }
- else
- {
- ZVAL_LONG(zv, static_cast<long>(val));
- }
- break;
- }
- case Slice::Builtin::KindFloat:
- {
- Ice::Float val = is->readFloat();
- ZVAL_DOUBLE(zv, val);
- break;
- }
- case Slice::Builtin::KindDouble:
- {
- Ice::Double val = is->readDouble();
- ZVAL_DOUBLE(zv, val);
- break;
- }
- case Slice::Builtin::KindString:
- {
- string val = is->readString();
- ZVAL_STRINGL(zv, const_cast<char*>(val.c_str()), val.length(), 1);
- break;
- }
-
- case Slice::Builtin::KindObject:
- case Slice::Builtin::KindObjectProxy:
- case Slice::Builtin::KindLocalObject:
- assert(false);
- }
-
- return true;
-}
-
-void
-IcePHP::PrimitiveMarshaler::destroy()
-{
-}
-
-//
-// SequenceMarshaler implementation.
-//
-IcePHP::SequenceMarshaler::SequenceMarshaler(const Slice::SequencePtr& type TSRMLS_DC) :
- _type(type)
-{
- Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type);
- if(b && b->kind() != Slice::Builtin::KindObject && b->kind() != Slice::Builtin::KindObjectProxy)
- {
- _builtin = b;
- }
- _elementMarshaler = createMarshaler(type->type() TSRMLS_CC);
-}
-
-bool
-IcePHP::SequenceMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC)
-{
- if(Z_TYPE_P(zv) != IS_ARRAY && Z_TYPE_P(zv) != IS_NULL)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected array or null for sequence but received %s", s.c_str());
- return false;
- }
-
- if(Z_TYPE_P(zv) == IS_NULL)
- {
- os->writeSize(0);
- return true;
- }
-
- HashTable* arr = Z_ARRVAL_P(zv);
-
- HashPosition pos;
- zend_hash_internal_pointer_reset_ex(arr, &pos);
- Ice::Int sz = static_cast<Ice::Int>(zend_hash_num_elements(arr));
-
- if(_builtin)
- {
- PrimitiveMarshalerPtr pm = PrimitiveMarshalerPtr::dynamicCast(_elementMarshaler);
- assert(pm);
- switch(_builtin->kind())
- {
- case Slice::Builtin::KindBool:
- {
- Ice::BoolSeq seq(sz);
- Ice::Int i = 0;
- void* data;
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(!pm->validate(*val TSRMLS_CC))
- {
- return false;
- }
- seq[i++] = Z_BVAL_P(*val) ? true : false;
- zend_hash_move_forward_ex(arr, &pos);
- }
- os->writeBoolSeq(seq);
- break;
- }
- case Slice::Builtin::KindByte:
- {
- Ice::ByteSeq seq(sz);
- Ice::Int i = 0;
- void* data;
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(!pm->validate(*val TSRMLS_CC))
- {
- return false;
- }
- long l = Z_LVAL_P(*val);
- assert(l >= 0 && l <= 255);
- seq[i++] = static_cast<Ice::Byte>(l);
- zend_hash_move_forward_ex(arr, &pos);
- }
- os->writeByteSeq(seq);
- break;
- }
- case Slice::Builtin::KindShort:
- {
- Ice::ShortSeq seq(sz);
- Ice::Int i = 0;
- void* data;
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(!pm->validate(*val TSRMLS_CC))
- {
- return false;
- }
- long l = Z_LVAL_P(*val);
- assert(l >= SHRT_MIN && l <= SHRT_MAX);
- seq[i++] = static_cast<Ice::Short>(l);
- zend_hash_move_forward_ex(arr, &pos);
- }
- os->writeShortSeq(seq);
- break;
- }
- case Slice::Builtin::KindInt:
- {
- Ice::IntSeq seq(sz);
- Ice::Int i = 0;
- void* data;
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(!pm->validate(*val TSRMLS_CC))
- {
- return false;
- }
- long l = Z_LVAL_P(*val);
- assert(l >= INT_MIN && l <= INT_MAX);
- seq[i++] = static_cast<Ice::Int>(l);
- zend_hash_move_forward_ex(arr, &pos);
- }
- os->writeIntSeq(seq);
- break;
- }
- case Slice::Builtin::KindLong:
- {
- Ice::LongSeq seq(sz);
- Ice::Int i = 0;
- void* data;
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(!pm->validate(*val TSRMLS_CC))
- {
- return false;
- }
- //
- // The platform's 'long' type may not be 64 bits, so we also accept
- // a string argument for this type.
- //
- assert(Z_TYPE_P(*val) == IS_LONG || Z_TYPE_P(*val) == IS_STRING);
- Ice::Long l;
- if(Z_TYPE_P(*val) == IS_LONG)
- {
- l = Z_LVAL_P(*val);
- }
- else
- {
- string sval(Z_STRVAL_P(*val), Z_STRLEN_P(*val));
- IceUtilInternal::stringToInt64(sval, l);
- }
- seq[i++] = l;
- zend_hash_move_forward_ex(arr, &pos);
- }
- os->writeLongSeq(seq);
- break;
- }
- case Slice::Builtin::KindFloat:
- {
- Ice::FloatSeq seq(sz);
- Ice::Int i = 0;
- void* data;
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(!pm->validate(*val TSRMLS_CC))
- {
- return false;
- }
- double d = Z_DVAL_P(*val);
- seq[i++] = static_cast<Ice::Float>(d);
- zend_hash_move_forward_ex(arr, &pos);
- }
- os->writeFloatSeq(seq);
- break;
- }
- case Slice::Builtin::KindDouble:
- {
- Ice::DoubleSeq seq(sz);
- Ice::Int i = 0;
- void* data;
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(!pm->validate(*val TSRMLS_CC))
- {
- return false;
- }
- double d = Z_DVAL_P(*val);
- seq[i++] = d;
- zend_hash_move_forward_ex(arr, &pos);
- }
- os->writeDoubleSeq(seq);
- break;
- }
- case Slice::Builtin::KindString:
- {
- Ice::StringSeq seq(sz);
- Ice::Int i = 0;
- void* data;
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(!pm->validate(*val TSRMLS_CC))
- {
- return false;
- }
- string s;
- if(Z_TYPE_P(*val) == IS_STRING)
- {
- s = string(Z_STRVAL_P(*val), Z_STRLEN_P(*val));
- }
- else
- {
- assert(Z_TYPE_P(*val) == IS_NULL);
- }
- seq[i++] = s;
- zend_hash_move_forward_ex(arr, &pos);
- }
- os->writeStringSeq(seq);
- break;
- }
-
- case Slice::Builtin::KindObject:
- case Slice::Builtin::KindObjectProxy:
- case Slice::Builtin::KindLocalObject:
- assert(false);
- }
- }
- else
- {
- os->writeSize(sz);
-
- void* data;
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(!_elementMarshaler->marshal(*val, os, m TSRMLS_CC))
- {
- return false;
- }
- zend_hash_move_forward_ex(arr, &pos);
- }
- }
-
- return true;
-}
-
-bool
-IcePHP::SequenceMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- array_init(zv);
-
- if(_builtin)
- {
- switch(_builtin->kind())
- {
- case Slice::Builtin::KindBool:
- {
- pair<const bool*, const bool*> pr;
- IceUtilInternal::ScopedArray<bool> arr(is->readBoolSeq(pr));
- Ice::Int i = 0;
- for(const bool* p = pr.first; p != pr.second; ++p, ++i)
- {
- zval* val;
- MAKE_STD_ZVAL(val);
- ZVAL_BOOL(val, *p ? 1 : 0);
- add_index_zval(zv, i, val);
- }
- break;
- }
- case Slice::Builtin::KindByte:
- {
- pair<const Ice::Byte*, const Ice::Byte*> pr;
- is->readByteSeq(pr);
- Ice::Int i = 0;
- for(const Ice::Byte* p = pr.first; p != pr.second; ++p, ++i)
- {
- zval* val;
- MAKE_STD_ZVAL(val);
- ZVAL_LONG(val, *p & 0xff);
- add_index_zval(zv, i, val);
- }
- break;
- }
- case Slice::Builtin::KindShort:
- {
- pair<const Ice::Short*, const Ice::Short*> pr;
- IceUtilInternal::ScopedArray<Ice::Short> arr(is->readShortSeq(pr));
- Ice::Int i = 0;
- for(const Ice::Short* p = pr.first; p != pr.second; ++p, ++i)
- {
- zval* val;
- MAKE_STD_ZVAL(val);
- ZVAL_LONG(val, *p);
- add_index_zval(zv, i, val);
- }
- break;
- }
- case Slice::Builtin::KindInt:
- {
- pair<const Ice::Int*, const Ice::Int*> pr;
- IceUtilInternal::ScopedArray<Ice::Int> arr(is->readIntSeq(pr));
- Ice::Int i = 0;
- for(const Ice::Int* p = pr.first; p != pr.second; ++p, ++i)
- {
- zval* val;
- MAKE_STD_ZVAL(val);
- ZVAL_LONG(val, *p);
- add_index_zval(zv, i, val);
- }
- break;
- }
- case Slice::Builtin::KindLong:
- {
- pair<const Ice::Long*, const Ice::Long*> pr;
- IceUtilInternal::ScopedArray<Ice::Long> arr(is->readLongSeq(pr));
- Ice::Int i = 0;
- for(const Ice::Long* p = pr.first; p != pr.second; ++p, ++i)
- {
- zval* val;
- MAKE_STD_ZVAL(val);
- //
- // The platform's 'long' type may not be 64 bits, so we store 64-bit
- // values as a string.
- //
- if(sizeof(Ice::Long) > sizeof(long) && (*p < LONG_MIN || *p > LONG_MAX))
- {
- string str = IceUtilInternal::int64ToString(*p);
- ZVAL_STRINGL(val, const_cast<char*>(str.c_str()), str.length(), 1);
- }
- else
- {
- ZVAL_LONG(val, static_cast<long>(*p));
- }
- add_index_zval(zv, i, val);
- }
- break;
- }
- case Slice::Builtin::KindFloat:
- {
- pair<const Ice::Float*, const Ice::Float*> pr;
- IceUtilInternal::ScopedArray<Ice::Float> arr(is->readFloatSeq(pr));
- Ice::Int i = 0;
- for(const Ice::Float* p = pr.first; p != pr.second; ++p, ++i)
- {
- zval* val;
- MAKE_STD_ZVAL(val);
- ZVAL_DOUBLE(zv, *p);
- add_index_zval(zv, i, val);
- }
- break;
- }
- case Slice::Builtin::KindDouble:
- {
- pair<const Ice::Double*, const Ice::Double*> pr;
- IceUtilInternal::ScopedArray<Ice::Double> arr(is->readDoubleSeq(pr));
- Ice::Int i = 0;
- for(const Ice::Double* p = pr.first; p != pr.second; ++p, ++i)
- {
- zval* val;
- MAKE_STD_ZVAL(val);
- ZVAL_DOUBLE(zv, *p);
- add_index_zval(zv, i, val);
- }
- break;
- }
- case Slice::Builtin::KindString:
- {
- Ice::StringSeq seq = is->readStringSeq();
- Ice::Int i = 0;
- for(Ice::StringSeq::iterator p = seq.begin(); p != seq.end(); ++p, ++i)
- {
- zval* val;
- MAKE_STD_ZVAL(val);
- ZVAL_STRINGL(val, const_cast<char*>(p->c_str()), p->length(), 1);
- add_index_zval(zv, i, val);
- }
- break;
- }
-
- case Slice::Builtin::KindObject:
- case Slice::Builtin::KindObjectProxy:
- case Slice::Builtin::KindLocalObject:
- assert(false);
- }
- }
- else
- {
- Ice::Int sz = is->readSize();
- for(Ice::Int i = 0; i < sz; ++i)
- {
- zval* val;
- MAKE_STD_ZVAL(val);
- if(!_elementMarshaler->unmarshal(val, is TSRMLS_CC))
- {
- return false;
- }
- add_index_zval(zv, i, val);
- }
- }
-
- return true;
-}
-
-void
-IcePHP::SequenceMarshaler::destroy()
-{
- _elementMarshaler->destroy();
- _elementMarshaler = 0;
-}
-
-//
-// ProxyMarshaler implementation.
-//
-IcePHP::ProxyMarshaler::ProxyMarshaler(const Slice::ProxyPtr& type) :
- _type(type)
-{
-}
-
-bool
-IcePHP::ProxyMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& TSRMLS_DC)
-{
- if(Z_TYPE_P(zv) != IS_OBJECT && Z_TYPE_P(zv) != IS_NULL)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected proxy value but received %s", s.c_str());
- return false;
- }
-
- Ice::ObjectPrx proxy;
- Slice::ClassDefPtr def;
- if(!ZVAL_IS_NULL(zv))
- {
- if(!fetchProxy(zv, proxy, def TSRMLS_CC))
- {
- return false;
- }
-
- if(_type)
- {
- string scoped = _type->_class()->scoped();
- if(def)
- {
- if(!def->isA(scoped))
- {
- string s = def->scoped();
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected a proxy of type %s but received %s",
- scoped.c_str(), s.c_str());
- return false;
- }
- }
- else
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected a proxy of type %s", scoped.c_str());
- return false;
- }
- }
- }
- os->writeProxy(proxy);
-
- return true;
-}
-
-bool
-IcePHP::ProxyMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- Ice::ObjectPrx proxy = is->readProxy();
-
- if(!proxy)
- {
- ZVAL_NULL(zv);
- return true;
- }
-
- //
- // If _type is not a primitive proxy (i.e., Builtin::KindObjectProxy), then we
- // want to associate our class with the proxy so that it is considered to be
- // "narrowed".
- //
- Slice::ClassDefPtr def;
- if(_type)
- {
- def = _type->_class()->definition();
- }
-
- if(!createProxy(zv, proxy, def TSRMLS_CC))
- {
- return false;
- }
-
- return true;
-}
-
-void
-IcePHP::ProxyMarshaler::destroy()
-{
-}
-
-//
-// MemberMarshaler implementation.
-//
-IcePHP::MemberMarshaler::MemberMarshaler(const string& name, const MarshalerPtr& marshaler) :
- _name(name), _marshaler(marshaler)
-{
-}
-
-bool
-IcePHP::MemberMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC)
-{
- void* data;
- if(zend_hash_find(Z_OBJPROP_P(zv), const_cast<char*>(_name.c_str()), _name.length() + 1, &data) == FAILURE)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "member `%s' is not defined", _name.c_str());
- return false;
- }
-
- zval** val = reinterpret_cast<zval**>(data);
- return _marshaler->marshal(*val, os, m TSRMLS_CC);;
-}
-
-bool
-IcePHP::MemberMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- zval* val;
- MAKE_STD_ZVAL(val);
-
- if(!_marshaler->unmarshal(val, is TSRMLS_CC))
- {
- return false;
- }
-
- //
- // The add_property_zval function fails if the data member has protected visibility.
- // As a workaround, before calling the function we change the current scope to be that
- // of the object.
- //
- zend_class_entry *oldScope = EG(scope);
- EG(scope) = Z_OBJCE_P(zv);
-
- int status = add_property_zval(zv, const_cast<char*>(_name.c_str()), val);
-
- EG(scope) = oldScope; // Restore the previous scope.
-
- if(status == FAILURE)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to set member `%s'", _name.c_str());
- return false;
- }
-
- zval_ptr_dtor(&val); // add_property_zval increments the refcount.
-
- return true;
-}
-
-void
-IcePHP::MemberMarshaler::destroy()
-{
- _marshaler->destroy();
- _marshaler = 0;
-}
-
-//
-// StructMarshaler implementation.
-//
-IcePHP::StructMarshaler::StructMarshaler(const Slice::StructPtr& type TSRMLS_DC) :
- _type(type)
-{
- _class = findClassScoped(type->scoped() TSRMLS_CC);
- assert(_class);
-
- Slice::DataMemberList members = type->dataMembers();
- for(Slice::DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
- {
- MarshalerPtr marshaler = createMemberMarshaler((*q)->name(), (*q)->type() TSRMLS_CC);
- assert(marshaler);
- _members.push_back(marshaler);
- }
-}
-
-bool
-IcePHP::StructMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC)
-{
- if(Z_TYPE_P(zv) != IS_OBJECT)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected struct value of type %s but received %s", _class->name,
- s.c_str());
- return false;
- }
-
- //
- // Compare class entries.
- //
- zend_class_entry* ce = Z_OBJCE_P(zv);
- if(ce != _class)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected struct value of type %s but received %s", _class->name,
- ce->name);
- return false;
- }
-
- for(vector<MarshalerPtr>::iterator p = _members.begin(); p != _members.end(); ++p)
- {
- if(!(*p)->marshal(zv, os, m TSRMLS_CC))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool
-IcePHP::StructMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- if(object_init_ex(zv, _class) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize object of type %s", _class->name);
- return false;
- }
-
- for(vector<MarshalerPtr>::iterator p = _members.begin(); p != _members.end(); ++p)
- {
- if(!(*p)->unmarshal(zv, is TSRMLS_CC))
- {
- return false;
- }
- }
-
- return true;
-}
-
-void
-IcePHP::StructMarshaler::destroy()
-{
- vector<MarshalerPtr> members = _members;
- _members.clear();
- for(vector<MarshalerPtr>::iterator p = members.begin(); p != members.end(); ++p)
- {
- (*p)->destroy();
- }
-}
-
-//
-// EnumMarshaler implementation.
-//
-IcePHP::EnumMarshaler::EnumMarshaler(const Slice::EnumPtr& type TSRMLS_DC)
-{
- _class = findClassScoped(type->scoped() TSRMLS_CC);
- assert(_class);
- _count = static_cast<long>(type->getEnumerators().size());
-}
-
-bool
-IcePHP::EnumMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& TSRMLS_DC)
-{
- if(Z_TYPE_P(zv) != IS_LONG)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected long value for enum %s but received %s", _class->name,
- s.c_str());
- return false;
- }
-
- //
- // Validate value.
- //
- long val = Z_LVAL_P(zv);
- if(val < 0 || val >= _count)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "value %ld is out of range for enum %s", val, _class->name);
- return false;
- }
-
- if(_count <= 127)
- {
- os->writeByte(static_cast<Ice::Byte>(val));
- }
- else if(_count <= 32767)
- {
- os->writeShort(static_cast<Ice::Short>(val));
- }
- else
- {
- os->writeInt(static_cast<Ice::Int>(val));
- }
-
- return true;
-}
-
-bool
-IcePHP::EnumMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- if(_count <= 127)
- {
- Ice::Byte val = is->readByte();
- ZVAL_LONG(zv, val);
- }
- else if(_count <= 32767)
- {
- Ice::Short val = is->readShort();
- ZVAL_LONG(zv, val);
- }
- else
- {
- Ice::Int val = is->readInt();
- ZVAL_LONG(zv, val);
- }
-
- return true;
-}
-
-void
-IcePHP::EnumMarshaler::destroy()
-{
-}
-
-//
-// NativeDictionaryMarshaler implementation.
-//
-IcePHP::NativeDictionaryMarshaler::NativeDictionaryMarshaler(const Slice::TypePtr& keyType,
- const Slice::TypePtr& valueType TSRMLS_DC)
-{
- Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(keyType);
- assert(b);
- _keyKind = b->kind();
- _keyMarshaler = createMarshaler(keyType TSRMLS_CC);
- _valueMarshaler = createMarshaler(valueType TSRMLS_CC);
-}
-
-bool
-IcePHP::NativeDictionaryMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC)
-{
- if(Z_TYPE_P(zv) != IS_ARRAY && Z_TYPE_P(zv) != IS_NULL)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected array or null for dictionary but received %s", s.c_str());
- return false;
- }
-
- if(Z_TYPE_P(zv) == IS_NULL)
- {
- os->writeSize(0);
- return true;
- }
-
- HashTable* arr = Z_ARRVAL_P(zv);
- HashPosition pos;
- void* data;
-
- os->writeSize(zend_hash_num_elements(arr));
-
- zend_hash_internal_pointer_reset_ex(arr, &pos);
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
-
- //
- // Get the key (which can be a long or a string).
- //
- char* keyStr;
- uint keyLen;
- ulong keyNum;
- int keyType = zend_hash_get_current_key_ex(arr, &keyStr, &keyLen, &keyNum, 0, &pos);
-
- //
- // Store the key in a zval, so that we can reuse the PrimitiveMarshaler logic.
- //
- zval zkey;
- if(keyType == HASH_KEY_IS_LONG)
- {
- ZVAL_LONG(&zkey, keyNum);
- }
- else
- {
- ZVAL_STRINGL(&zkey, keyStr, keyLen - 1, 1);
- }
-
- //
- // Convert the zval to the key type required by Slice, if necessary.
- //
- switch(_keyKind)
- {
- case Slice::Builtin::KindBool:
- {
- convert_to_boolean(&zkey);
- break;
- }
-
- case Slice::Builtin::KindByte:
- case Slice::Builtin::KindShort:
- case Slice::Builtin::KindInt:
- case Slice::Builtin::KindLong:
- {
- if(keyType == HASH_KEY_IS_STRING)
- {
- convert_to_long(&zkey);
- }
- break;
- }
-
- case Slice::Builtin::KindString:
- {
- if(keyType == HASH_KEY_IS_LONG)
- {
- convert_to_string(&zkey);
- }
- break;
- }
-
- case Slice::Builtin::KindFloat:
- case Slice::Builtin::KindDouble:
- case Slice::Builtin::KindObject:
- case Slice::Builtin::KindObjectProxy:
- case Slice::Builtin::KindLocalObject:
- assert(false);
- }
-
- //
- // Marshal the key.
- //
- if(!_keyMarshaler->marshal(&zkey, os, m TSRMLS_CC))
- {
- zval_dtor(&zkey);
- return false;
- }
-
- zval_dtor(&zkey);
-
- //
- // Marshal the value.
- //
- if(!_valueMarshaler->marshal(*val, os, m TSRMLS_CC))
- {
- return false;
- }
-
- zend_hash_move_forward_ex(arr, &pos);
- }
-
- return true;
-}
-
-bool
-IcePHP::NativeDictionaryMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- array_init(zv);
-
- Ice::Int sz = is->readSize();
-
- for(Ice::Int i = 0; i < sz; ++i)
- {
- zval key;
- zval* val;
- INIT_ZVAL(key);
- MAKE_STD_ZVAL(val);
-
- if(!_keyMarshaler->unmarshal(&key, is TSRMLS_CC))
- {
- return false;
- }
- if(!_valueMarshaler->unmarshal(val, is TSRMLS_CC))
- {
- return false;
- }
-
- switch(Z_TYPE(key))
- {
- case IS_LONG:
- add_index_zval(zv, Z_LVAL(key), val);
- break;
- case IS_BOOL:
- add_index_zval(zv, Z_BVAL(key) ? 1 : 0, val);
- break;
- case IS_STRING:
- add_assoc_zval_ex(zv, Z_STRVAL(key), Z_STRLEN(key) + 1, val);
- break;
- default:
- assert(false);
- return false;
- }
- zval_dtor(&key);
- }
-
- return true;
-}
-
-void
-IcePHP::NativeDictionaryMarshaler::destroy()
-{
- _keyMarshaler->destroy();
- _keyMarshaler = 0;
- _valueMarshaler->destroy();
- _valueMarshaler = 0;
-}
-
-//
-// ExceptionMarshaler implementation.
-//
-IcePHP::ExceptionMarshaler::ExceptionMarshaler(const Slice::ExceptionPtr& ex TSRMLS_DC) :
- _ex(ex)
-{
- _class = findClassScoped(ex->scoped() TSRMLS_CC);
- assert(_class);
-}
-
-bool
-IcePHP::ExceptionMarshaler::marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC)
-{
- //
- // We never need to marshal an exception.
- //
- php_error_docref(0 TSRMLS_CC, E_ERROR, "exception marshaling is not supported");
- return false;
-}
-
-bool
-IcePHP::ExceptionMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- if(object_init_ex(zv, _class) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize exception %s", _class->name);
- return false;
- }
-
- //
- // NOTE: The type id for the first slice has already been read.
- //
-
- Slice::ExceptionPtr ex = _ex;
- while(ex)
- {
- Slice::DataMemberList members = ex->dataMembers();
- is->startSlice();
- for(Slice::DataMemberList::iterator p = members.begin(); p != members.end(); ++p)
- {
- MarshalerPtr member = createMemberMarshaler((*p)->name(), (*p)->type() TSRMLS_CC);
- if(!member->unmarshal(zv, is TSRMLS_CC))
- {
- return false;
- }
- }
- is->endSlice();
- ex = ex->base();
- if(ex)
- {
- is->readString(); // Skip id.
- }
- }
-
- return true;
-}
-
-void
-IcePHP::ExceptionMarshaler::destroy()
-{
-}
-
-//
-// IceObjectSliceMarshaler implementation.
-//
-IcePHP::IceObjectSliceMarshaler::IceObjectSliceMarshaler(TSRMLS_D)
-{
-}
-
-bool
-IcePHP::IceObjectSliceMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& TSRMLS_DC)
-{
- assert(Z_TYPE_P(zv) == IS_OBJECT);
-
- os->writeTypeId(Ice::Object::ice_staticId());
- os->startSlice();
- os->writeSize(0); // For compatibility with the old AFM.
- os->endSlice();
-
- return true;
-}
-
-bool
-IcePHP::IceObjectSliceMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- assert(Z_TYPE_P(zv) == IS_OBJECT);
-
- //
- // Do not read type id here - see ObjectReader::__read().
- //
- //is->readTypeId()
-
- is->startSlice();
-
- // For compatibility with the old AFM.
- Ice::Int sz = is->readSize();
- if(sz != 0)
- {
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
-
- is->endSlice();
-
- return true;
-}
-
-void
-IcePHP::IceObjectSliceMarshaler::destroy()
-{
-}
-
-//
-// ObjectSliceMarshaler implementation.
-//
-IcePHP::ObjectSliceMarshaler::ObjectSliceMarshaler(const string& scoped,
- const Slice::DataMemberList& members TSRMLS_DC) :
- _scoped(scoped)
-{
- for(Slice::DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
- {
- MarshalerPtr marshaler = createMemberMarshaler((*p)->name(), (*p)->type() TSRMLS_CC);
- assert(marshaler);
- _members.push_back(marshaler);
- }
-}
-
-bool
-IcePHP::ObjectSliceMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC)
-{
- assert(Z_TYPE_P(zv) == IS_OBJECT);
-
- os->writeTypeId(_scoped);
- os->startSlice();
- for(vector<MarshalerPtr>::iterator p = _members.begin(); p != _members.end(); ++p)
- {
- if(!(*p)->marshal(zv, os, m TSRMLS_CC))
- {
- return false;
- }
- }
- os->endSlice();
-
- return true;
-}
-
-bool
-IcePHP::ObjectSliceMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- assert(Z_TYPE_P(zv) == IS_OBJECT);
-
- //
- // Do not read type id here - see ObjectReader::__read().
- //
- //is->readTypeId()
-
- is->startSlice();
- for(vector<MarshalerPtr>::iterator p = _members.begin(); p != _members.end(); ++p)
- {
- if(!(*p)->unmarshal(zv, is TSRMLS_CC))
- {
- return false;
- }
- }
- is->endSlice();
-
- return true;
-}
-
-void
-IcePHP::ObjectSliceMarshaler::destroy()
-{
- vector<MarshalerPtr> members = _members;
- _members.clear();
- for(vector<MarshalerPtr>::iterator p = members.begin(); p != members.end(); ++p)
- {
- (*p)->destroy();
- }
-}
-
-//
-// ObjectWriter implementation.
-//
-IcePHP::ObjectWriter::ObjectWriter(zval* value, const Slice::SyntaxTreeBasePtr& type, ObjectMap& m TSRMLS_DC) :
- _value(value), _map(m)
-{
-#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
-// Strange Sun C++ 5.3 bug.
- const IceUtil::HandleBase<Slice::SyntaxTreeBase>& hb = type;
- _type = Slice::ClassDefPtr::dynamicCast(hb);
-#else
- _type = Slice::ClassDefPtr::dynamicCast(type);
-#endif
-
-#ifdef ZTS
- this->TSRMLS_C = TSRMLS_C;
-#endif
-
- Z_OBJ_HT_P(_value)->add_ref(_value TSRMLS_CC);
-}
-
-IcePHP::ObjectWriter::~ObjectWriter()
-{
- Z_OBJ_HT_P(_value)->del_ref(_value TSRMLS_CC);
-}
-
-void
-IcePHP::ObjectWriter::ice_preMarshal()
-{
- zend_call_method_with_0_params(&_value, 0, 0, "ice_preMarshal", 0);
-}
-
-void
-IcePHP::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
-{
- MarshalerMap* marshalerMap = static_cast<MarshalerMap*>(ICE_G(marshalerMap));
- ObjectMap& objectMap = const_cast<ObjectMap&>(_map);
- zval* value = const_cast<zval*>(_value);
-
- Slice::ClassDefPtr def = _type;
- while(true)
- {
- string scoped = def->scoped();
- MarshalerPtr slice;
- MarshalerMap::iterator p = marshalerMap->find(scoped);
- if(p != marshalerMap->end())
- {
- slice = p->second;
- }
- else
- {
- slice = new ObjectSliceMarshaler(scoped, def->dataMembers() TSRMLS_CC);
- marshalerMap->insert(pair<string, MarshalerPtr>(scoped, slice));
- }
-
- if(!slice->marshal(value, os, objectMap TSRMLS_CC))
- {
- Ice::MarshalException ex(__FILE__, __LINE__);
- ex.reason = "unable to marshal object slice of type " + scoped;
- throw ex;
- }
-
- Slice::ClassList bases = def->bases();
- if(!bases.empty() && !bases.front()->isInterface())
- {
- def = bases.front();
- }
- else
- {
- break;
- }
- }
-
- //
- // Marshal the Ice::Object slice.
- //
- MarshalerPtr slice;
- MarshalerMap::iterator p = marshalerMap->find(Ice::Object::ice_staticId());
- if(p != marshalerMap->end())
- {
- slice = p->second;
- }
- else
- {
- slice = new IceObjectSliceMarshaler(TSRMLS_C);
- marshalerMap->insert(pair<string, MarshalerPtr>(Ice::Object::ice_staticId(), slice));
- }
-
- if(!slice->marshal(value, os, objectMap TSRMLS_CC))
- {
- Ice::MarshalException ex(__FILE__, __LINE__);
- ex.reason = "unable to marshal object slice of type Ice::Object";
- throw ex;
- }
-}
-
-//
-// ReadObjectCallback implementation.
-//
-void
-IcePHP::ReadObjectCallback::invoke(const Ice::ObjectPtr& v)
-{
- ObjectReaderPtr p = ObjectReaderPtr::dynamicCast(v);
- if(p)
- {
- p->setValue(ce, scoped, zv);
- }
- else
- {
- ZVAL_NULL(zv);
- }
-}
-
-//
-// ObjectReader implementation.
-//
-IcePHP::ObjectReader::ObjectReader(zval* val, const Slice::ClassDefPtr& type TSRMLS_DC) :
- _value(val), _type(type)
-{
-#ifdef ZTS
- this->TSRMLS_C = TSRMLS_C;
-#endif
-
- ZVAL_ADDREF(_value);
-
- _class = Z_OBJCE_P(_value);
-}
-
-IcePHP::ObjectReader::~ObjectReader()
-{
- zval_ptr_dtor(&_value);
-}
-
-void
-IcePHP::ObjectReader::ice_postUnmarshal()
-{
- zend_call_method_with_0_params(&_value, 0, 0, "ice_postUnmarshal", 0);
-}
-
-void
-IcePHP::ObjectReader::read(const Ice::InputStreamPtr& is, bool rid)
-{
- MarshalerMap* marshalerMap = static_cast<MarshalerMap*>(ICE_G(marshalerMap));
-
- //
- // Unmarshal the slices of a user-defined class.
- //
- if(_type)
- {
- Slice::ClassDefPtr def = _type;
- while(true)
- {
- string scoped;
- if(rid)
- {
- scoped = is->readTypeId();
- }
- else
- {
- scoped = def->scoped();
- }
-
- MarshalerPtr slice;
- MarshalerMap::iterator p = marshalerMap->find(scoped);
- if(p != marshalerMap->end())
- {
- slice = p->second;
- }
- else
- {
- slice = new ObjectSliceMarshaler(scoped, def->dataMembers() TSRMLS_CC);
- marshalerMap->insert(pair<string, MarshalerPtr>(scoped, slice));
- }
-
- if(!slice->unmarshal(_value, is TSRMLS_CC))
- {
- Ice::MarshalException ex(__FILE__, __LINE__);
- ex.reason = "unable to unmarshal object slice of type " + scoped;
- throw ex;
- }
-
- rid = true;
-
- Slice::ClassList bases = def->bases();
- if(!bases.empty() && !bases.front()->isInterface())
- {
- def = bases.front();
- }
- else
- {
- break;
- }
- }
- }
-
- //
- // Unmarshal the Ice::Object slice.
- //
- if(rid)
- {
- is->readTypeId();
- }
-
- MarshalerPtr slice;
- MarshalerMap::iterator p = marshalerMap->find(Ice::Object::ice_staticId());
- if(p != marshalerMap->end())
- {
- slice = p->second;
- }
- else
- {
- slice = new IceObjectSliceMarshaler(TSRMLS_C);
- marshalerMap->insert(pair<string, MarshalerPtr>(Ice::Object::ice_staticId(), slice));
- }
-
- if(!slice->unmarshal(_value, is TSRMLS_CC))
- {
- Ice::MarshalException ex(__FILE__, __LINE__);
- ex.reason = "unable to unmarshal object slice of type Ice::Object";
- throw ex;
- }
-}
-
-void
-IcePHP::ObjectReader::setValue(zend_class_entry* ce, const string& scoped, zval* zv)
-{
- //
- // Compare the class entries. The argument "ce" represents the formal type.
- //
- if(!checkClass(_class, ce))
- {
- Ice::UnexpectedObjectException ex(__FILE__, __LINE__);
- ex.type = _type ? _type->scoped() : "::Ice::Object";
- ex.expectedType = scoped;
- throw ex;
- }
-
- //
- // Now both zvals have the same object handle (they point at the same object). We need to
- // increment the object's reference count accordingly.
- //
- Z_TYPE_P(zv) = IS_OBJECT;
- zv->value.obj = _value->value.obj;
- Z_OBJ_HT_P(_value)->add_ref(_value TSRMLS_CC);
-}
-
-//
-// ObjectMarshaler implementation.
-//
-IcePHP::ObjectMarshaler::ObjectMarshaler(const Slice::ClassDefPtr& def TSRMLS_DC) :
- _def(def)
-{
- //
- // Find the class entry for this type.
- //
- if(def)
- {
- _scoped = def->scoped();
- _class = findClassScoped(_scoped TSRMLS_CC);
- }
- else
- {
- _scoped = "::Ice::Object";
- _class = findClass("Ice_Object" TSRMLS_CC);
- }
-
- assert(_class);
-}
-
-bool
-IcePHP::ObjectMarshaler::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap& m TSRMLS_DC)
-{
- if(Z_TYPE_P(zv) == IS_NULL)
- {
- os->writeObject(0);
- return true;
- }
-
- if(Z_TYPE_P(zv) != IS_OBJECT)
- {
- string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected object value of type %s but received %s", _class->name,
- s.c_str());
- return false;
- }
-
- //
- // Verify that the given object is compatible with the formal type.
- //
- zend_class_entry* ce = Z_OBJCE_P(zv);
- if(!checkClass(ce, _class))
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected object value of type %s but received %s", _class->name,
- ce->name);
- return false;
- }
-
- //
- // ObjectWriter is a subclass of Ice::Object that wraps a PHP object for marshaling. It is
- // possible that this PHP object has already been marshaled, therefore we first must check
- // the object map to see if this object is present. If so, we use the existing ObjectWriter,
- // otherwise we create a new one. The key of the map is the object's handle.
- //
- Ice::ObjectPtr writer;
-
- ObjectMap::iterator q = m.find(Z_OBJ_HANDLE_P(zv));
- if(q == m.end())
- {
- //
- // Determine the most-derived Slice type implemented by this object by scanning its
- // inheritance hierarchy until we find a class or interface that we recognize.
- //
- Profile* profile = static_cast<Profile*>(ICE_G(profile));
- assert(profile);
- zend_class_entry* cls = ce;
- const Profile::ClassMap& classes = profile->classes();
- Profile::ClassMap::const_iterator p = classes.find(cls->name);
- while(p == classes.end())
- {
- if(cls->parent)
- {
- p = classes.find(cls->parent->name);
- }
- for(zend_uint i = 0; i < cls->num_interfaces && p == classes.end(); ++i)
- {
- p = classes.find(cls->interfaces[i]->name);
- }
- cls = cls->parent;
- }
- assert(p != classes.end());
-
- writer = new ObjectWriter(zv, p->second, m TSRMLS_CC);
- m.insert(pair<unsigned int, Ice::ObjectPtr>(Z_OBJ_HANDLE_P(zv), writer));
- }
- else
- {
- writer = q->second;
- }
-
- //
- // Give the writer to the stream. The stream will eventually call write() on it.
- //
- os->writeObject(writer);
-
- return true;
-}
-
-bool
-IcePHP::ObjectMarshaler::unmarshal(zval* zv, const Ice::InputStreamPtr& is TSRMLS_DC)
-{
- ReadObjectCallbackPtr cb = new ReadObjectCallback;
- cb->ce = _class;
- cb->scoped = _scoped;
- cb->zv = zv;
-
- //
- // Invoke readObject(), passing our callback object. When the object is eventually unmarshaled,
- // our callback will be invoked and we will assign a value to zv.
- //
- is->readObject(cb);
-
- return true;
-}
-
-void
-IcePHP::ObjectMarshaler::destroy()
-{
-}
-
-//
-// PHPObjectFactory implementation.
-//
-IcePHP::PHPObjectFactory::PHPObjectFactory(TSRMLS_D)
-{
-#ifdef ZTS
- this->TSRMLS_C = TSRMLS_C;
-#endif
-}
-
-Ice::ObjectPtr
-IcePHP::PHPObjectFactory::create(const string& scoped)
-{
- Profile* profile = static_cast<Profile*>(ICE_G(profile));
- assert(profile);
-
- ObjectFactoryMap* ofm = static_cast<ObjectFactoryMap*>(ICE_G(objectFactoryMap));
- assert(ofm);
-
- //
- // We can only unmarshal an object if we have the definition of its Slice type.
- //
- const Profile::ClassMap& classes = profile->classes();
- Profile::ClassMap::const_iterator p = classes.find(flatten(scoped));
- Slice::ClassDefPtr def;
- if(p != classes.end())
- {
- def = p->second;
- }
- else
- {
- return 0;
- }
-
- //
- // First check our map for a factory registered for this type.
- //
- ObjectFactoryMap::iterator q = ofm->find(scoped);
- if(q == ofm->end())
- {
- //
- // Next, check for a default factory.
- //
- q = ofm->find("");
- }
-
- //
- // If we found a factory, invoke create() on the object.
- //
- if(q != ofm->end())
- {
- zval* id;
- MAKE_STD_ZVAL(id);
- ZVAL_STRINGL(id, const_cast<char*>(scoped.c_str()), scoped.length(), 1);
-
- zval* zresult = 0;
-
- zend_call_method_with_1_params(&q->second, 0, 0, "create", &zresult, id);
-
- zval_ptr_dtor(&id);
-
- AutoDestroy destroyResult(zresult);
-
- //
- // Bail out if an exception has already been thrown.
- //
- if(EG(exception))
- {
- throw AbortMarshaling();
- }
-
- if(zresult)
- {
- //
- // If the factory returned a non-null value, verify that it is an object, and that it
- // implements Ice_Object.
- //
- if(!ZVAL_IS_NULL(zresult))
- {
- if(Z_TYPE_P(zresult) != IS_OBJECT)
- {
- Ice::MarshalException ex(__FILE__, __LINE__);
- ex.reason = "object factory did not return an object for type " + scoped;
- throw ex;
- }
-
- zend_class_entry* ce = Z_OBJCE_P(zresult);
- zend_class_entry* base = findClass("Ice_Object" TSRMLS_CC);
- if(!checkClass(ce, base))
- {
- Ice::MarshalException ex(__FILE__, __LINE__);
- ex.reason = "object returned by factory does not implement Ice_Object";
- throw ex;
- }
-
- return new ObjectReader(zresult, def TSRMLS_CC);
- }
- }
- }
-
- //
- // Attempt to find a class entry for the given type id. If no class entry is
- // found, or the class is abstract, then we return nil and the stream will skip
- // the slice and try again.
- //
- zend_class_entry* cls = findClassScoped(scoped TSRMLS_CC);
-
- //
- // Instantiate the class if it's not abstract.
- //
- Ice::ObjectPtr result;
- const int abstractFlags = ZEND_ACC_INTERFACE | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
- if(cls && (cls->ce_flags & abstractFlags) == 0)
- {
- zval* obj;
- MAKE_STD_ZVAL(obj);
- object_init_ex(obj, cls);
- result = new ObjectReader(obj, def TSRMLS_CC);
- zval_ptr_dtor(&obj);
- }
-
- return result;
-}
-
-void
-IcePHP::PHPObjectFactory::destroy()
-{
-}
diff --git a/php/src/IcePHP/Marshal.h b/php/src/IcePHP/Marshal.h
deleted file mode 100644
index 620c33c7ddf..00000000000
--- a/php/src/IcePHP/Marshal.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#ifndef ICE_PHP_MARSHAL_H
-#define ICE_PHP_MARSHAL_H
-
-#include <Config.h>
-
-namespace IcePHP
-{
-
-//
-// The object map associates a Zend object handle to an Ice object.
-//
-typedef std::map<unsigned int, Ice::ObjectPtr> ObjectMap;
-
-class Marshaler;
-typedef IceUtil::Handle<Marshaler> MarshalerPtr;
-
-class Marshaler : public IceUtil::SimpleShared
-{
-public:
- virtual ~Marshaler();
-
- static MarshalerPtr createMarshaler(const Slice::TypePtr& TSRMLS_DC);
- static MarshalerPtr createMemberMarshaler(const std::string&, const Slice::TypePtr& TSRMLS_DC);
- static MarshalerPtr createExceptionMarshaler(const Slice::ExceptionPtr& TSRMLS_DC);
-
- virtual bool marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap& TSRMLS_DC) = 0;
- virtual bool unmarshal(zval*, const Ice::InputStreamPtr& TSRMLS_DC) = 0;
-
- virtual void destroy() = 0;
-
-protected:
- Marshaler();
-};
-
-//
-// Associates a scoped type id to its marshaler.
-//
-typedef std::map<std::string, MarshalerPtr> MarshalerMap;
-
-//
-// Associates a scoped type id to its factory.
-//
-typedef std::map<std::string, zval*> ObjectFactoryMap;
-
-//
-// This class is raised as an exception when object marshaling needs to be aborted.
-//
-class AbortMarshaling
-{
-};
-
-//
-// PHPObjectFactory is an implementation of Ice::ObjectFactory that creates PHP objects.
-// It is also the registry for user-defined PHP factory implementations. A single instance
-// can be used for all types.
-//
-class PHPObjectFactory : public Ice::ObjectFactory
-{
-public:
- PHPObjectFactory(TSRMLS_D);
-
- virtual Ice::ObjectPtr create(const std::string&);
- virtual void destroy();
-
-#ifdef ZTS
-private:
- TSRMLS_D;
-#endif
-};
-typedef IceUtil::Handle<PHPObjectFactory> PHPObjectFactoryPtr;
-
-} // End of namespace IcePHP
-
-#endif
diff --git a/php/src/IcePHP/Operation.cpp b/php/src/IcePHP/Operation.cpp
new file mode 100644
index 00000000000..64ff018487b
--- /dev/null
+++ b/php/src/IcePHP/Operation.cpp
@@ -0,0 +1,711 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Operation.h>
+#include <Communicator.h>
+#include <Proxy.h>
+#include <Types.h>
+#include <Util.h>
+#include <Slice/PHPUtil.h>
+
+using namespace std;
+using namespace IcePHP;
+using namespace Slice::PHP;
+
+extern "C"
+{
+ZEND_FUNCTION(IcePHP_Operation_call);
+}
+
+namespace IcePHP
+{
+
+//
+// Receives an out parameter or return value.
+//
+class ResultCallback : public UnmarshalCallback
+{
+public:
+
+ ResultCallback();
+ ~ResultCallback();
+
+ virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC);
+
+ zval* zv;
+};
+typedef IceUtil::Handle<ResultCallback> ResultCallbackPtr;
+typedef vector<ResultCallbackPtr> ResultCallbackList;
+
+//
+// Encapsulates attributes of an operation.
+//
+class OperationI : public Operation
+{
+public:
+
+ OperationI(const char*, Ice::OperationMode, Ice::OperationMode, zval*, zval*, zval*, zval* TSRMLS_DC);
+ ~OperationI();
+
+ virtual zend_function* function();
+
+ string name; // On-the-wire name.
+ Ice::OperationMode mode;
+ Ice::OperationMode sendMode;
+ TypeInfoList inParams;
+ TypeInfoList outParams;
+ TypeInfoPtr returnType;
+ ExceptionInfoList exceptions;
+ bool sendsClasses;
+ bool returnsClasses;
+ int numParams;
+
+private:
+
+ zend_internal_function* _zendFunction;
+
+ static void convertParams(zval*, TypeInfoList&, bool& TSRMLS_DC);
+ static void getArgInfo(zend_arg_info&, const TypeInfoPtr&, bool);
+};
+typedef IceUtil::Handle<OperationI> OperationIPtr;
+
+//
+// The base class for client-side invocations.
+//
+class Invocation : virtual public IceUtil::Shared
+{
+public:
+
+ Invocation(const Ice::ObjectPrx&, const CommunicatorInfoPtr& TSRMLS_DC);
+
+ virtual void invoke(INTERNAL_FUNCTION_PARAMETERS) = 0;
+
+protected:
+
+ Ice::ObjectPrx _prx;
+ CommunicatorInfoPtr _communicator;
+#ifdef ZTS
+ TSRMLS_D;
+#endif
+};
+typedef IceUtil::Handle<Invocation> InvocationPtr;
+
+//
+// TypedInvocation uses the information in the given operation to validate, marshal, and unmarshal
+// parameters and exceptions.
+//
+class TypedInvocation : virtual public Invocation
+{
+public:
+
+ TypedInvocation(const Ice::ObjectPrx&, const CommunicatorInfoPtr&, const OperationIPtr& TSRMLS_DC);
+
+protected:
+
+ OperationIPtr _op;
+
+ bool prepareRequest(int, zval**, Ice::ByteSeq& TSRMLS_DC);
+ void unmarshalResults(int, zval**, zval*, const pair<const Ice::Byte*, const Ice::Byte*>& TSRMLS_DC);
+ zval* unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& TSRMLS_DC);
+ bool validateException(const ExceptionInfoPtr& TSRMLS_DC) const;
+ void checkTwowayOnly(const Ice::ObjectPrx&) const;
+};
+
+//
+// A synchronous typed invocation.
+//
+class SyncTypedInvocation : virtual public TypedInvocation
+{
+public:
+
+ SyncTypedInvocation(const Ice::ObjectPrx&, const CommunicatorInfoPtr&, const OperationIPtr& TSRMLS_DC);
+
+ virtual void invoke(INTERNAL_FUNCTION_PARAMETERS);
+};
+
+}
+
+//
+// ResultCallback implementation.
+//
+IcePHP::ResultCallback::ResultCallback() :
+ zv(0)
+{
+}
+
+IcePHP::ResultCallback::~ResultCallback()
+{
+ if(zv)
+ {
+ zval_ptr_dtor(&zv);
+ }
+}
+
+void
+IcePHP::ResultCallback::unmarshaled(zval* val, zval*, void* TSRMLS_DC)
+{
+ //
+ // Keep a reference to the unmarshaled value.
+ //
+ zv = val;
+ Z_ADDREF_P(zv);
+}
+
+//
+// OperationI implementation.
+//
+IcePHP::OperationI::OperationI(const char* n, Ice::OperationMode m, Ice::OperationMode sm, zval* in, zval* out,
+ zval* ret, zval* ex TSRMLS_DC) :
+ name(n), mode(m), sendMode(sm), sendsClasses(false), returnsClasses(false), _zendFunction(0)
+{
+ //
+ // inParams
+ //
+ if(in)
+ {
+ convertParams(in, inParams, sendsClasses TSRMLS_CC);
+ }
+
+ //
+ // outParams
+ //
+ if(out)
+ {
+ convertParams(out, outParams, returnsClasses TSRMLS_CC);
+ }
+
+ numParams = static_cast<int>(inParams.size() + outParams.size());
+
+ //
+ // returnType
+ //
+ if(ret)
+ {
+ returnType = Wrapper<TypeInfoPtr>::value(ret TSRMLS_CC);
+ if(!returnsClasses)
+ {
+ returnsClasses = returnType->usesClasses();
+ }
+ }
+
+ //
+ // exceptions
+ //
+ if(ex)
+ {
+ HashTable* arr = Z_ARRVAL_P(ex);
+ HashPosition pos;
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ ExceptionInfoPtr i = Wrapper<ExceptionInfoPtr>::value(*val TSRMLS_CC);
+ exceptions.push_back(i);
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+ }
+}
+
+IcePHP::OperationI::~OperationI()
+{
+ if(_zendFunction)
+ {
+ delete []_zendFunction->arg_info;
+ efree(_zendFunction->function_name);
+ efree(_zendFunction);
+ }
+}
+
+zend_function*
+IcePHP::OperationI::function()
+{
+ if(!_zendFunction)
+ {
+ //
+ // Create an array that indicates how arguments are passed to the operation.
+ //
+ zend_arg_info* argInfo = new zend_arg_info[numParams];
+
+ int i = 0;
+ TypeInfoList::const_iterator p;
+ for(p = inParams.begin(); p != inParams.end(); ++p, ++i)
+ {
+ getArgInfo(argInfo[i], *p, false);
+ argInfo[i].required_num_args = static_cast<zend_uint>(numParams);
+ }
+ for(p = outParams.begin(); p != outParams.end(); ++p, ++i)
+ {
+ getArgInfo(argInfo[i], *p, true);
+ argInfo[i].required_num_args = static_cast<zend_uint>(numParams);
+ }
+
+ string fixed = fixIdent(name);
+ _zendFunction = static_cast<zend_internal_function*>(emalloc(sizeof(zend_internal_function)));
+ _zendFunction->type = ZEND_INTERNAL_FUNCTION;
+ _zendFunction->function_name = estrndup(STRCAST(fixed.c_str()), fixed.length());
+ _zendFunction->scope = proxyClassEntry;
+ _zendFunction->fn_flags = ZEND_ACC_PUBLIC;
+ _zendFunction->prototype = 0;
+ _zendFunction->num_args = static_cast<zend_uint>(numParams);
+ _zendFunction->arg_info = argInfo;
+ _zendFunction->pass_rest_by_reference = 0;
+ _zendFunction->required_num_args = _zendFunction->num_args;
+ _zendFunction->return_reference = 0;
+ _zendFunction->handler = ZEND_FN(IcePHP_Operation_call);
+ }
+
+ return reinterpret_cast<zend_function*>(_zendFunction);
+}
+
+void
+IcePHP::OperationI::convertParams(zval* p, TypeInfoList& params, bool& usesClasses TSRMLS_DC)
+{
+ usesClasses = false;
+
+ assert(Z_TYPE_P(p) == IS_ARRAY);
+ HashTable* arr = Z_ARRVAL_P(p);
+ HashPosition pos;
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(*val TSRMLS_CC);
+ params.push_back(type);
+ if(!usesClasses)
+ {
+ usesClasses = type->usesClasses();
+ }
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+}
+
+void
+IcePHP::OperationI::getArgInfo(zend_arg_info& arg, const TypeInfoPtr& info, bool out)
+{
+ arg.name = 0;
+ arg.class_name = 0;
+ arg.allow_null = 1;
+ if(SequenceInfoPtr::dynamicCast(info) || DictionaryInfoPtr::dynamicCast(info))
+ {
+ arg.array_type_hint = 1;
+ }
+ else
+ {
+ arg.array_type_hint = 0;
+ }
+ arg.return_reference = 0;
+ arg.pass_by_reference = out ? 1 : 0;
+}
+
+//
+// Invocation
+//
+IcePHP::Invocation::Invocation(const Ice::ObjectPrx& prx, const CommunicatorInfoPtr& communicator TSRMLS_DC) :
+ _prx(prx), _communicator(communicator)
+{
+#ifdef ZTS
+ this->TSRMLS_C = TSRMLS_C;
+#endif
+}
+
+//
+// TypedInvocation
+//
+IcePHP::TypedInvocation::TypedInvocation(const Ice::ObjectPrx& prx, const CommunicatorInfoPtr& communicator,
+ const OperationIPtr& op TSRMLS_DC) :
+ Invocation(prx, communicator TSRMLS_CC), _op(op)
+{
+}
+
+bool
+IcePHP::TypedInvocation::prepareRequest(int argc, zval** args, Ice::ByteSeq& bytes TSRMLS_DC)
+{
+ //
+ // Verify that the expected number of arguments are supplied. The context argument is optional.
+ //
+ if(argc != _op->numParams && argc != _op->numParams + 1)
+ {
+ runtimeError("incorrect number of parameters (%d)" TSRMLS_CC, argc);
+ return false;
+ }
+
+ //
+ // The operation's configuration (zend_function) forces out parameters
+ // to be passed by reference.
+ //
+ for(int i = static_cast<int>(_op->inParams.size()); i < _op->numParams; ++i)
+ {
+ assert(PZVAL_IS_REF(args[i]));
+ }
+
+ if(!_op->inParams.empty())
+ {
+ try
+ {
+ //
+ // Marshal the in parameters.
+ //
+ Ice::OutputStreamPtr os = Ice::createOutputStream(_communicator->getCommunicator());
+
+ ObjectMap objectMap;
+ int i = 0;
+ for(TypeInfoList::iterator p = _op->inParams.begin(); p != _op->inParams.end(); ++p, ++i)
+ {
+ zval* arg = args[i];
+ if(!(*p)->validate(arg TSRMLS_CC))
+ {
+ invalidArgument("invalid value for argument %d in operation `%s'" TSRMLS_CC, i, _op->name.c_str());
+ return false;
+ }
+ (*p)->marshal(arg, os, &objectMap TSRMLS_CC);
+ }
+
+ if(_op->sendsClasses)
+ {
+ os->writePendingObjects();
+ }
+
+ os->finished(bytes);
+ }
+ catch(const AbortMarshaling&)
+ {
+ return false;
+ }
+ catch(const Ice::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void
+IcePHP::TypedInvocation::unmarshalResults(int argc, zval** args, zval* ret,
+ const pair<const Ice::Byte*, const Ice::Byte*>& bytes TSRMLS_DC)
+{
+ Ice::InputStreamPtr is = Ice::createInputStream(_communicator->getCommunicator(), bytes);
+
+ //
+ // These callbacks collect references to the unmarshaled values. We copy them into
+ // the argument list *after* any pending objects have been unmarshaled.
+ //
+ ResultCallbackList outParamCallbacks;
+ ResultCallbackPtr retCallback;
+
+ //
+ // Unmarshal the out parameters.
+ //
+ for(TypeInfoList::iterator p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
+ {
+ ResultCallbackPtr cb = new ResultCallback;
+ outParamCallbacks.push_back(cb);
+ (*p)->unmarshal(is, cb, _communicator, 0, 0 TSRMLS_CC);
+ }
+
+ //
+ // Unmarshal the return value.
+ //
+ if(_op->returnType)
+ {
+ retCallback = new ResultCallback;
+ _op->returnType->unmarshal(is, retCallback, _communicator, 0, 0 TSRMLS_CC);
+ }
+
+ if(_op->returnsClasses)
+ {
+ is->readPendingObjects();
+ }
+
+ int i = static_cast<int>(_op->inParams.size());
+ for(ResultCallbackList::iterator q = outParamCallbacks.begin(); q != outParamCallbacks.end(); ++q, ++i)
+ {
+ //
+ // We must explicitly destroy the existing contents of all zvals passed
+ // as out parameters, otherwise leaks occur.
+ //
+ zval* val = (*q)->zv;
+ zval_dtor(args[i]);
+ args[i]->value = val->value;
+ Z_TYPE_P(args[i]) = Z_TYPE_P(val);
+ zval_copy_ctor(args[i]);
+ }
+
+ if(_op->returnType)
+ {
+ ret->value = retCallback->zv->value;
+ Z_TYPE_P(ret) = Z_TYPE_P(retCallback->zv);
+ zval_copy_ctor(ret);
+ }
+}
+
+zval*
+IcePHP::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& bytes TSRMLS_DC)
+{
+ int traceSlicing = -1;
+
+ Ice::InputStreamPtr is = Ice::createInputStream(_communicator->getCommunicator(), bytes);
+
+ is->readBool(); // usesClasses
+
+ string id = is->readString();
+ const string origId = id;
+
+ while(!id.empty())
+ {
+ ExceptionInfoPtr info = getExceptionInfo(id TSRMLS_CC);
+ if(info)
+ {
+ zval* ex = info->unmarshal(is, _communicator TSRMLS_CC);
+ if(ex)
+ {
+ if(info->usesClasses)
+ {
+ is->readPendingObjects();
+ }
+
+ if(validateException(info TSRMLS_CC))
+ {
+ return ex;
+ }
+ else
+ {
+ zval_ptr_dtor(&ex);
+ Ice::UnknownUserException uue(__FILE__, __LINE__,
+ "operation raised undeclared exception `" + id + "'");
+ return convertException(uue TSRMLS_CC);
+ }
+ }
+ }
+ else
+ {
+ if(traceSlicing == -1)
+ {
+ traceSlicing =
+ _communicator->getCommunicator()->getProperties()->getPropertyAsInt("Ice.Trace.Slicing") > 0;
+ }
+
+ if(traceSlicing > 0)
+ {
+ _communicator->getCommunicator()->getLogger()->trace("Slicing", "unknown exception type `" + id + "'");
+ }
+
+ is->skipSlice(); // Slice off what we don't understand.
+
+ try
+ {
+ id = is->readString(); // Read type id for next slice.
+ }
+ catch(Ice::UnmarshalOutOfBoundsException& ex)
+ {
+ //
+ // When readString raises this exception it means we've seen the last slice,
+ // so we set the reason member to a more helpful message.
+ //
+ ex.reason = "unknown exception type `" + origId + "'";
+ return convertException(ex TSRMLS_CC);
+ }
+ }
+ }
+
+ //
+ // Getting here should be impossible: we can get here only if the
+ // sender has marshaled a sequence of type IDs, none of which we
+ // have a factory for. This means that sender and receiver disagree
+ // about the Slice definitions they use.
+ //
+ Ice::UnknownUserException uue(__FILE__, __LINE__, "unknown exception type `" + origId + "'");
+ return convertException(uue TSRMLS_CC);
+}
+
+bool
+IcePHP::TypedInvocation::validateException(const ExceptionInfoPtr& info TSRMLS_DC) const
+{
+ for(ExceptionInfoList::const_iterator p = _op->exceptions.begin(); p != _op->exceptions.end(); ++p)
+ {
+ if(info->isA((*p)->id))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+IcePHP::TypedInvocation::checkTwowayOnly(const Ice::ObjectPrx& proxy) const
+{
+ if((_op->returnType || !_op->outParams.empty()) && !proxy->ice_isTwoway())
+ {
+ Ice::TwowayOnlyException ex(__FILE__, __LINE__);
+ ex.operation = _op->name;
+ throw ex;
+ }
+}
+
+//
+// SyncTypedInvocation
+//
+IcePHP::SyncTypedInvocation::SyncTypedInvocation(const Ice::ObjectPrx& prx, const CommunicatorInfoPtr& communicator,
+ const OperationIPtr& op TSRMLS_DC) :
+ Invocation(prx, communicator TSRMLS_CC), TypedInvocation(prx, communicator, op TSRMLS_CC)
+{
+}
+
+void
+IcePHP::SyncTypedInvocation::invoke(INTERNAL_FUNCTION_PARAMETERS)
+{
+ //
+ // Retrieve the arguments.
+ //
+ zval*** args = static_cast<zval***>(emalloc(ZEND_NUM_ARGS() * sizeof(zval**)));
+ AutoEfree autoArgs(args); // Call efree on return
+ if(zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE)
+ {
+ runtimeError("unable to get arguments" TSRMLS_CC);
+ return;
+ }
+
+ Ice::ByteSeq params;
+ if(!prepareRequest(ZEND_NUM_ARGS(), *args, params TSRMLS_CC))
+ {
+ return;
+ }
+
+ bool hasCtx = false;
+ Ice::Context ctx;
+ if(ZEND_NUM_ARGS() == _op->numParams + 1)
+ {
+ if(!extractStringMap(*args[ZEND_NUM_ARGS() - 1], ctx TSRMLS_CC))
+ {
+ return;
+ }
+ hasCtx = true;
+ }
+
+ try
+ {
+ checkTwowayOnly(_prx);
+
+ //
+ // Invoke the operation.
+ //
+ vector<Ice::Byte> result;
+ bool status;
+ {
+ if(hasCtx)
+ {
+ status = _prx->ice_invoke(_op->name, _op->sendMode, params, result, ctx);
+ }
+ else
+ {
+ status = _prx->ice_invoke(_op->name, _op->sendMode, params, result);
+ }
+ }
+
+ //
+ // Process the reply.
+ //
+ if(_prx->ice_isTwoway())
+ {
+ if(!status)
+ {
+ //
+ // Unmarshal a user exception.
+ //
+ pair<const Ice::Byte*, const Ice::Byte*> rb(0, 0);
+ if(!result.empty())
+ {
+ rb.first = &result[0];
+ rb.second = &result[0] + result.size();
+ }
+
+ zval* ex = unmarshalException(rb TSRMLS_CC);
+ if(ex)
+ {
+ zend_throw_exception_object(ex TSRMLS_CC);
+ }
+ }
+ else if(!_op->outParams.empty() || _op->returnType)
+ {
+ //
+ // Unmarshal the results.
+ //
+ pair<const Ice::Byte*, const Ice::Byte*> rb(0, 0);
+ if(!result.empty())
+ {
+ rb.first = &result[0];
+ rb.second = &result[0] + result.size();
+ }
+ unmarshalResults(ZEND_NUM_ARGS(), *args, return_value, rb TSRMLS_CC);
+ }
+ }
+ }
+ catch(const AbortMarshaling&)
+ {
+ }
+ catch(const Ice::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineOperation)
+{
+ zval* cls;
+ char* name;
+ int nameLen;
+ long mode;
+ long sendMode;
+ zval* inParams;
+ zval* outParams;
+ zval* returnType;
+ zval* exceptions;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oslla!a!o!a!", &cls, &name, &nameLen, &mode, &sendMode,
+ &inParams, &outParams, &returnType, &exceptions) == FAILURE)
+ {
+ return;
+ }
+
+ TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(cls TSRMLS_CC);
+ ClassInfoPtr c = ClassInfoPtr::dynamicCast(type);
+ assert(c);
+
+ OperationIPtr op = new OperationI(name, static_cast<Ice::OperationMode>(mode),
+ static_cast<Ice::OperationMode>(sendMode), inParams, outParams, returnType,
+ exceptions TSRMLS_CC);
+
+ c->addOperation(name, op);
+}
+
+ZEND_FUNCTION(IcePHP_Operation_call)
+{
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr cls;
+ CommunicatorInfoPtr comm;
+#ifndef NDEBUG
+ bool b =
+#endif
+ fetchProxy(getThis(), proxy, cls, comm TSRMLS_CC);
+ assert(b);
+ assert(proxy);
+ assert(cls);
+
+ OperationPtr op = cls->getOperation(get_active_function_name(TSRMLS_C));
+ assert(op); // handleGetMethod should have already verified the operation's existence.
+ OperationIPtr opi = OperationIPtr::dynamicCast(op);
+ assert(opi);
+
+ InvocationPtr inv = new SyncTypedInvocation(proxy, comm, opi TSRMLS_CC);
+ inv->invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
diff --git a/php/src/IcePHP/Operation.h b/php/src/IcePHP/Operation.h
new file mode 100644
index 00000000000..aaa39b8c873
--- /dev/null
+++ b/php/src/IcePHP/Operation.h
@@ -0,0 +1,40 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICEPHP_OPERATION_H
+#define ICEPHP_OPERATION_H
+
+#include <Config.h>
+
+//
+// Global functions.
+//
+extern "C"
+{
+ZEND_FUNCTION(IcePHP_defineOperation);
+}
+
+#define ICEPHP_OPERATION_FUNCTIONS \
+ ZEND_FE(IcePHP_defineOperation, NULL)
+
+namespace IcePHP
+{
+
+class Operation : public IceUtil::Shared
+{
+public:
+
+ virtual zend_function* function() = 0;
+
+};
+typedef IceUtil::Handle<Operation> OperationPtr;
+
+}
+
+#endif
diff --git a/php/src/IcePHP/Profile.cpp b/php/src/IcePHP/Profile.cpp
deleted file mode 100644
index 3e79ae26d8f..00000000000
--- a/php/src/IcePHP/Profile.cpp
+++ /dev/null
@@ -1,1617 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#include <Profile.h>
-#include <Util.h>
-
-#include <Slice/Preprocessor.h>
-#include <IceUtil/Options.h>
-#include <IceUtil/InputUtil.h>
-#include <fstream>
-
-using namespace std;
-using namespace IcePHP;
-
-ZEND_EXTERN_MODULE_GLOBALS(ice)
-
-//
-// The name we give to the default profile.
-//
-static const char* _defaultProfileName = "__default__";
-
-//
-// The table of profiles.
-//
-static map<string, Profile*> _profiles;
-
-namespace IcePHP
-{
-
-//
-// CodeVisitor descends the Slice parse tree and generates PHP code for certain Slice types.
-//
-class CodeVisitor : public Slice::ParserVisitor
-{
-public:
- CodeVisitor(ostream&, Profile::ClassMap&, bool TSRMLS_DC);
-
- virtual void visitClassDecl(const Slice::ClassDeclPtr&);
- virtual bool visitClassDefStart(const Slice::ClassDefPtr&);
- virtual void visitClassDefEnd(const Slice::ClassDefPtr&);
- virtual bool visitExceptionStart(const Slice::ExceptionPtr&);
- virtual void visitExceptionEnd(const Slice::ExceptionPtr&);
- virtual bool visitStructStart(const Slice::StructPtr&);
- virtual void visitStructEnd(const Slice::StructPtr&);
- virtual void visitOperation(const Slice::OperationPtr&);
- virtual void visitDataMember(const Slice::DataMemberPtr&);
- virtual void visitDictionary(const Slice::DictionaryPtr&);
- virtual void visitEnum(const Slice::EnumPtr&);
- virtual void visitConst(const Slice::ConstPtr&);
-
-private:
-
- string getTypeHint(const Slice::TypePtr&);
- string getDefaultValue(const Slice::TypePtr&);
- void writeConstructorParameter(const Slice::DataMemberPtr&);
- void writeConstructorAssignment(const Slice::DataMemberPtr&);
-
- ostream& _out;
- Profile::ClassMap& _classes;
- bool _suppressWarnings;
-#ifdef ZTS
- TSRMLS_D;
-#endif
-};
-
-} // End of namespace IcePHP
-
-//
-// This PHP code defines the core types we need. We supply a few of the common
-// local exception subclasses; all other local exceptions are mapped to
-// UnknownLocalException. We don't define Ice::Identity here because it's
-// possible the user will have included its definition (see createProfile).
-//
-// NOTE: If a local exception is added or removed here, then changes are also
-// necessary to IcePHP::throwException.
-//
-static const char* _coreTypes =
- "abstract class Ice_Exception extends Exception\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Exception::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "abstract class Ice_LocalException extends Ice_Exception\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_Exception::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "class Ice_TwowayOnlyException extends Ice_LocalException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_LocalException::__construct($message);\n"
- " }\n"
- "\n"
- " function __toString()\n"
- " {\n"
- " return get_class($this) . \"\\n\" .\n"
- " \" operation: \" . $this->operation;\n"
- " }\n"
- "\n"
- " public $operation;\n"
- "}\n"
- "\n"
- "class Ice_UnknownException extends Ice_LocalException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_LocalException::__construct($message);\n"
- " }\n"
- "\n"
- " function __toString()\n"
- " {\n"
- " return get_class($this) . \"\\n\" .\n"
- " $this->unknown;\n"
- " }\n"
- "\n"
- " public $unknown;\n"
- "}\n"
- "\n"
- "class Ice_UnknownLocalException extends Ice_UnknownException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_UnknownException::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "class Ice_UnknownUserException extends Ice_UnknownException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_UnknownException::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "class Ice_RequestFailedException extends Ice_LocalException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_LocalException::__construct($message);\n"
- " }\n"
- "\n"
- " function __toString()\n"
- " {\n"
- " return get_class($this) . \"\\n\" .\n"
- " \" identity: \" . Ice_identityToString($this->id) . \"\\n\" .\n"
- " \" facet: \" . $this->facet . \"\\n\" .\n"
- " \" operation: \" . $this->operation;\n"
- " }\n"
- "\n"
- " public $id;\n"
- " public $facet;\n"
- " public $operation;\n"
- "}\n"
- "\n"
- "class Ice_ObjectNotExistException extends Ice_RequestFailedException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_RequestFailedException::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "class Ice_FacetNotExistException extends Ice_RequestFailedException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_RequestFailedException::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "class Ice_OperationNotExistException extends Ice_RequestFailedException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_RequestFailedException::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "class Ice_ProtocolException extends Ice_LocalException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_LocalException::__construct($message);\n"
- " }\n"
- "\n"
- " function __toString()\n"
- " {\n"
- " return get_class($this) . \"\\n\" .\n"
- " \" reason: \" . $this->reason;\n"
- " }\n"
- "\n"
- " public $reason;\n"
- "}\n"
- "\n"
- "class Ice_MarshalException extends Ice_ProtocolException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_ProtocolException::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "class Ice_NoObjectFactoryException extends Ice_MarshalException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_MarshalException::__construct($message);\n"
- " }\n"
- "\n"
- " function __toString()\n"
- " {\n"
- " return get_class($this) . \"\\n\" .\n"
- " \" reason: \" . $this->reason . \"\\n\" .\n"
- " \" type: \" . $this->type;\n"
- " }\n"
- "\n"
- " public $type;\n"
- "}\n"
- "\n"
- "class Ice_UnexpectedObjectException extends Ice_MarshalException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_MarshalException::__construct($message);\n"
- " }\n"
- "\n"
- " function __toString()\n"
- " {\n"
- " return get_class($this) . \"\\n\" .\n"
- " \" reason: \" . $this->reason . \"\\n\" .\n"
- " \" type: \" . $this->type . \"\\n\" .\n"
- " \" expectedType: \" . $this->expectedType;\n"
- " }\n"
- "\n"
- " public $type;\n"
- "}\n"
- "\n"
- "class Ice_ProfileAlreadyLoadedException extends Ice_LocalException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_LocalException::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "class Ice_ProfileNotFoundException extends Ice_LocalException\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_LocalException::__construct($message);\n"
- " }\n"
- "\n"
- " function __toString()\n"
- " {\n"
- " return get_class($this) . \"\\n\" .\n"
- " \" name: \" . $this->name;\n"
- " }\n"
- "\n"
- " public $name;\n"
- "}\n"
- "\n"
- "abstract class Ice_UserException extends Ice_Exception\n"
- "{\n"
- " function __construct($message = '')\n"
- " {\n"
- " Ice_Exception::__construct($message);\n"
- " }\n"
- "}\n"
- "\n"
- "interface Ice_LocalObject\n"
- "{\n"
- "}\n"
- "\n"
- "class Ice_LocalObjectImpl implements Ice_LocalObject\n"
- "{\n"
- "}\n"
- "\n"
- "interface Ice_Object\n"
- "{\n"
- " function ice_preMarshal();\n"
- " function ice_postUnmarshal();\n"
- "}\n"
- "\n"
- "abstract class Ice_ObjectImpl implements Ice_Object\n"
- "{\n"
- " function ice_preMarshal()\n"
- " {\n"
- " }\n"
- "\n"
- " function ice_postUnmarshal()\n"
- " {\n"
- " }\n"
- "}\n"
- "\n"
- "interface Ice_ObjectFactory\n"
- "{\n"
- " function create($id);\n"
- " function destroy();\n"
- "}\n"
-;
-
-//
-// Parse the Slice files that define the types and operations available to a PHP script.
-//
-static bool
-parseSlice(const string& argStr, vector<Slice::UnitPtr>& units, bool& suppressWarnings TSRMLS_DC)
-{
- vector<string> args;
- try
- {
- args = IceUtilInternal::Options::split(argStr);
- }
- catch(const IceUtil::Exception& ex)
- {
- ostringstream ostr;
- ex.ice_print(ostr);
- string msg = ostr.str();
- php_error_docref(0 TSRMLS_CC, E_ERROR, "error occurred while parsing Slice options in `%s':\n%s",
- argStr.c_str(), msg.c_str());
- return false;
- }
-
- IceUtilInternal::Options opts;
- opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
- opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
- opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
- opts.addOpt("d", "debug");
- opts.addOpt("", "ice");
- opts.addOpt("w");
-
- vector<string> files;
- try
- {
- args.insert(args.begin(), ""); // dummy argv[0]
- files = opts.parse(args);
- if(files.empty() && !argStr.empty())
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "no Slice files specified in `%s'", argStr.c_str());
- return false;
- }
- }
- catch(const IceUtil::Exception& ex)
- {
- ostringstream ostr;
- ex.ice_print(ostr);
- string msg = ostr.str();
- php_error_docref(0 TSRMLS_CC, E_ERROR, "error occurred while parsing Slice options in `%s':\n%s",
- argStr.c_str(), msg.c_str());
- return false;
- }
-
- vector<string> cppArgs;
- bool debug = false;
- bool ice = true; // This must be true so that we can create Ice::Identity when necessary.
- if(opts.isSet("D"))
- {
- vector<string> optargs = opts.argVec("D");
- for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
- {
- cppArgs.push_back("-D" + *i);
- }
- }
- if(opts.isSet("U"))
- {
- vector<string> optargs = opts.argVec("U");
- for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
- {
- cppArgs.push_back("-U" + *i);
- }
- }
- if(opts.isSet("I"))
- {
- vector<string> optargs = opts.argVec("I");
- for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
- {
- cppArgs.push_back("-I" + *i);
- }
- }
- debug = opts.isSet("d") || opts.isSet("debug");
- suppressWarnings = opts.isSet("w");
-
- bool ignoreRedefs = false;
- bool all = true;
-
- for(vector<string>::iterator p = files.begin(); p != files.end(); ++p)
- {
- Slice::UnitPtr unit = Slice::Unit::createUnit(ignoreRedefs, all, ice);
- Slice::Preprocessor icecpp("icecpp", *p, cppArgs);
- FILE* cppHandle = icecpp.preprocess(false);
-
- if(cppHandle == 0)
- {
- return false;
- }
-
- int parseStatus = unit->parse(*p, cppHandle, debug);
-
- if(!icecpp.close())
- {
- return false;
- }
-
- if(parseStatus == EXIT_FAILURE)
- {
- return false;
- }
-
- units.push_back(unit);
- }
-
- return true;
-}
-
-static bool
-createProfile(const string& name, const string& config, const string& options, const string& slice TSRMLS_DC)
-{
- map<string, Profile*>::iterator p = _profiles.find(name);
- if(p != _profiles.end())
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "profile `%s' already exists", name.c_str());
- return false;
- }
-
- Ice::PropertiesPtr properties = Ice::createProperties();
-
- if(!config.empty())
- {
- try
- {
- properties->load(config);
- }
- catch(const IceUtil::Exception& ex)
- {
- ostringstream ostr;
- ex.ice_print(ostr);
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to load Ice configuration file %s:\n%s", config.c_str(),
- ostr.str().c_str());
- return false;
- }
- }
-
- if(!options.empty())
- {
- vector<string> args;
- try
- {
- args = IceUtilInternal::Options::split(options);
- }
- catch(const IceUtil::Exception& ex)
- {
- ostringstream ostr;
- ex.ice_print(ostr);
- string msg = ostr.str();
- php_error_docref(0 TSRMLS_CC, E_ERROR, "error occurred while parsing the options `%s':\n%s",
- options.c_str(), msg.c_str());
- return false;
- }
- properties->parseCommandLineOptions("", args);
- }
-
- //
- // We create a Unit for each Slice file.
- //
- vector<Slice::UnitPtr> units;
-
- //
- // Even if the profile specifies no Slice files, we still need to obtain builtin
- // types as well as create types such as Ice::Identity.
- //
- {
- Slice::UnitPtr unit = Slice::Unit::createUnit(false, false, true);
-
- //
- // Create the Slice definition for Ice::Identity if it doesn't exist. The PHP class will
- // be created automatically by CodeVisitor.
- //
- string scoped = "::Ice::Identity";
- Slice::TypeList l = unit->lookupTypeNoBuiltin(scoped, false);
- if(l.empty())
- {
- Slice::ContainedList c = unit->lookupContained("Ice", false);
- Slice::ModulePtr module;
- if(c.empty())
- {
- module = unit->createModule("Ice");
- }
- else
- {
- module = Slice::ModulePtr::dynamicCast(c.front());
- if(!module)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR,
- "the symbol `::Ice' is defined in Slice but is not a module");
- return false;
- }
- }
- Slice::StructPtr identity = module->createStruct("Identity", false);
- Slice::TypePtr str = unit->builtin(Slice::Builtin::KindString);
- identity->createDataMember("category", str);
- identity->createDataMember("name", str);
- }
-
- //
- // Create the Slice definition for Ice::EndpointSelectionType if it doesn't exist. The PHP class will
- // be created automatically by CodeVisitor.
- //
- scoped = "::Ice::EndpointSelectionType";
- l = unit->lookupTypeNoBuiltin(scoped, false);
- if(l.empty())
- {
- Slice::ContainedList c = unit->lookupContained("Ice", false);
- Slice::ModulePtr module;
- if(c.empty())
- {
- module = unit->createModule("Ice");
- }
- else
- {
- module = Slice::ModulePtr::dynamicCast(c.front());
- if(!module)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR,
- "the symbol `::Ice' is defined in Slice but is not a module");
- return false;
- }
- }
- Slice::EnumPtr en = module->createEnum("EndpointSelectionType", false);
- Slice::EnumeratorList el;
- el.push_back(module->createEnumerator("Random"));
- el.push_back(module->createEnumerator("Ordered"));
- en->setEnumerators(el);
- }
-
- units.push_back(unit);
- }
-
- bool suppressWarnings = false;
- if(!slice.empty() && !parseSlice(slice, units, suppressWarnings TSRMLS_CC))
- {
- return false;
- }
-
- //
- // Descend the parse trees to generate PHP code.
- //
- ostringstream out;
- Profile::ClassMap classes;
- for(vector<Slice::UnitPtr>::const_iterator q = units.begin(); q != units.end(); ++ q)
- {
- CodeVisitor visitor(out, classes, suppressWarnings TSRMLS_CC);
- (*q)->visit(&visitor, false);
- }
-
- _profiles[name] = new Profile(name, units, out.str(), classes, properties);
-
- return true;
-}
-
-bool
-IcePHP::profileInit(TSRMLS_D)
-{
- //
- // The default profile is configured using ice.config, ice.options and ice.slice. Named profiles
- // are contained in a separate INI file, whose name is defined by ice.profiles.
- //
- const char* config = INI_STR("ice.config");
- const char* options = INI_STR("ice.options");
- const char* profiles = INI_STR("ice.profiles");
- const char* slice = INI_STR("ice.slice");
-
- if(!createProfile(_defaultProfileName, config, options, slice TSRMLS_CC))
- {
- return false;
- }
-
- if(strlen(profiles) > 0)
- {
- //
- // The Zend engine doesn't export a function for loading an INI file, so we
- // have to do it ourselves. The format is:
- //
- // [profile-name]
- // ice.config = config-file
- // ice.options = args
- // ice.slice = slice-args
- //
- ifstream in(profiles);
- if(!in)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to open Ice profiles in %s", profiles);
- return false;
- }
-
- string currentName, currentConfig, currentOptions, currentSlice;
- char line[1024];
- while(in.getline(line, 1024))
- {
- const string delim = " \t\r\n";
- string s = line;
-
- string::size_type idx = s.find(';');
- if(idx != string::npos)
- {
- s.erase(idx);
- }
-
- idx = s.find_last_not_of(delim);
- if(idx != string::npos && idx + 1 < s.length())
- {
- s.erase(idx + 1);
- }
-
- string::size_type beg = s.find_first_not_of(delim);
- if(beg == string::npos)
- {
- continue;
- }
-
- if(s[beg] == '[')
- {
- beg++;
- string::size_type end = s.find_first_of(" \t]", beg);
- if(end == string::npos || s[s.length() - 1] != ']')
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "invalid profile section in file %s:\n%s\n", profiles,
- line);
- return false;
- }
-
- if(!currentName.empty())
- {
- if(!createProfile(currentName, currentConfig, currentOptions, currentSlice TSRMLS_CC))
- {
- return false;
- }
- currentConfig.clear();
- currentOptions.clear();
- currentSlice.clear();
- }
-
- currentName = s.substr(beg, end - beg);
- }
- else
- {
- string::size_type end = s.find_first_of(delim + "=", beg);
- assert(end != string::npos);
-
- string key = s.substr(beg, end - beg);
-
- end = s.find('=', end);
- if(end == string::npos)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "invalid profile entry in file %s:\n%s\n", profiles,
- line);
- return false;
- }
- ++end;
-
- string value;
- beg = s.find_first_not_of(delim, end);
- if(beg != string::npos)
- {
- end = s.length();
- value = s.substr(beg, end - beg);
- }
-
- if(key == "config" || key == "ice.config")
- {
- currentConfig = value;
- }
- else if(key == "options" || key == "ice.options")
- {
- currentOptions = value;
- }
- else if(key == "slice" || key == "ice.slice")
- {
- currentSlice = value;
- }
- else
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unknown profile entry in file %s:\n%s\n", profiles,
- line);
- return false;
- }
-
- if(currentName.empty())
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "no section for profile entry in file %s:\n%s\n",
- profiles, line);
- return false;
- }
- }
- }
-
- if(!currentName.empty() && !createProfile(currentName, currentConfig, currentOptions, currentSlice TSRMLS_CC))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool
-IcePHP::profileShutdown(TSRMLS_D)
-{
- for(map<string, Profile*>::iterator p = _profiles.begin(); p != _profiles.end(); ++p)
- {
- p->second->destroy(TSRMLS_C);
- delete p->second;
- }
-
- _profiles.clear();
-
- return true;
-}
-
-IcePHP::Profile::Profile(const string& name, const vector<Slice::UnitPtr>& units, const string& code,
- const ClassMap& classes, const Ice::PropertiesPtr& properties) :
- _name(name), _units(units), _code(code), _classes(classes), _properties(properties)
-{
-}
-
-string
-IcePHP::Profile::name() const
-{
- return _name;
-}
-
-string
-IcePHP::Profile::code() const
-{
- return _code;
-}
-
-const IcePHP::Profile::ClassMap&
-IcePHP::Profile::classes() const
-{
- return _classes;
-}
-
-Ice::PropertiesPtr
-IcePHP::Profile::properties() const
-{
- return _properties;
-}
-
-Slice::TypePtr
-IcePHP::Profile::lookupType(const string& id) const
-{
- for(vector<Slice::UnitPtr>::const_iterator p = _units.begin(); p != _units.end(); ++p)
- {
- Slice::TypeList l = (*p)->lookupType(id, false);
- if(!l.empty())
- {
- return l.front();
- }
- }
-
- return 0;
-}
-
-Slice::ExceptionPtr
-IcePHP::Profile::lookupException(const string& id) const
-{
- for(vector<Slice::UnitPtr>::const_iterator p = _units.begin(); p != _units.end(); ++p)
- {
- Slice::ExceptionPtr ex = (*p)->lookupException(id, false);
- if(ex)
- {
- return ex;
- }
- }
-
- return 0;
-}
-
-void
-IcePHP::Profile::destroy(TSRMLS_D)
-{
- for(vector<Slice::UnitPtr>::iterator p = _units.begin(); p != _units.end(); ++p)
- {
- try
- {
- (*p)->destroy();
- }
- catch(const IceUtil::Exception& ex)
- {
- ostringstream ostr;
- ex.ice_print(ostr);
- php_error_docref(0 TSRMLS_CC, E_ERROR, "error while destroying Slice parse tree:\n%s\n",
- ostr.str().c_str());
- }
- }
-}
-
-static bool
-do_load(const string& name, const Ice::StringSeq& args TSRMLS_DC)
-{
- Profile* profile = static_cast<Profile*>(ICE_G(profile));
-
- if(profile)
- {
- //
- // A profile has already been loaded; raise Ice_ProfileAlreadyLoadedException.
- //
- zend_class_entry* cls = findClass("Ice_ProfileAlreadyLoadedException" TSRMLS_CC);
- assert(cls);
-
- zval* zex;
- MAKE_STD_ZVAL(zex);
- if(object_init_ex(zex, cls) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return false;
- }
-
- zend_throw_exception_object(zex TSRMLS_CC);
- return false;
- }
-
- string profileName = name;
- if(profileName.empty())
- {
- profileName = _defaultProfileName;
- }
-
- //
- // Compile the core types if necessary. We do this now so that the exceptions
- // are available.
- //
- if(!findClass("Ice_Exception" TSRMLS_CC))
- {
- if(zend_eval_string(const_cast<char*>(_coreTypes), 0, "__core" TSRMLS_CC) == FAILURE)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create core types:\n%s\n", _coreTypes);
- return false;
- }
- }
-
- map<string, Profile*>::iterator p = _profiles.find(profileName);
- if(p == _profiles.end())
- {
- zend_class_entry* cls = findClass("Ice_ProfileNotFoundException" TSRMLS_CC);
- assert(cls);
-
- zval* zex;
- MAKE_STD_ZVAL(zex);
- if(object_init_ex(zex, cls) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return false;
- }
-
- //
- // Set the name member.
- //
- zend_update_property_string(cls, zex, "name", sizeof("name") - 1,
- const_cast<char*>(profileName.c_str()) TSRMLS_CC);
-
- zend_throw_exception_object(zex TSRMLS_CC);
- return false;
- }
- profile = p->second;
-
- //
- // Compile the user-defined types.
- //
- if(zend_eval_string(const_cast<char*>(profile->code().c_str()), 0, "__slice" TSRMLS_CC) == FAILURE)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create Slice types:\n%s\n", profile->code().c_str());
- return false;
- }
-
- //
- // Make a copy of the profile's properties, and include any command-line arguments.
- //
- Ice::PropertiesPtr properties = Ice::createProperties();
- properties->parseCommandLineOptions("", profile->properties()->getCommandLineOptions());
- properties->parseCommandLineOptions("", args);
- ICE_G(properties) = new Ice::PropertiesPtr(properties);
-
- ICE_G(profile) = profile;
- return true;
-}
-
-ZEND_FUNCTION(Ice_stringVersion)
-{
- if(ZEND_NUM_ARGS() != 0)
- {
- WRONG_PARAM_COUNT;
- }
-
- string s = ICE_STRING_VERSION;
- RETURN_STRINGL(const_cast<char*>(s.c_str()), s.length(), 1);
-}
-
-ZEND_FUNCTION(Ice_intVersion)
-{
- if(ZEND_NUM_ARGS() != 0)
- {
- WRONG_PARAM_COUNT;
- }
-
- RETURN_LONG(ICE_INT_VERSION);
-}
-
-ZEND_FUNCTION(Ice_loadProfile)
-{
- if(ZEND_NUM_ARGS() > 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- char* name = "";
- int len;
-
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &len) == FAILURE)
- {
- return;
- }
-
- Ice::StringSeq args;
- do_load(name, args TSRMLS_CC);
-}
-
-ZEND_FUNCTION(Ice_loadProfileWithArgs)
-{
- if(ZEND_NUM_ARGS() > 2)
- {
- WRONG_PARAM_COUNT;
- }
-
- zval* zv;
- char* name = "";
- int len;
-
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|s", &zv, &name, &len) == FAILURE)
- {
- return;
- }
-
- //
- // Extract the command-line arguments from the array.
- //
- Ice::StringSeq args;
- HashTable* arr = Z_ARRVAL_P(zv);
- void* data;
- HashPosition pos;
- zend_hash_internal_pointer_reset_ex(arr, &pos);
- while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
- {
- zval** val = reinterpret_cast<zval**>(data);
- if(Z_TYPE_PP(val) != IS_STRING)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "argument array must contain strings");
- return;
- }
- args.push_back(Z_STRVAL_PP(val));
- zend_hash_move_forward_ex(arr, &pos);
- }
-
- do_load(name, args TSRMLS_CC);
-}
-
-ZEND_FUNCTION(Ice_dumpProfile)
-{
- Profile* profile = static_cast<Profile*>(ICE_G(profile));
- Ice::PropertiesPtr* properties = static_cast<Ice::PropertiesPtr*>(ICE_G(properties));
-
- if(!profile)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "no profile has been loaded");
- return;
- }
-
- ostringstream out;
- out << "Ice profile: " << profile->name() << endl;
-
- Ice::PropertyDict props = (*properties)->getPropertiesForPrefix("");
- if(!props.empty())
- {
- out << endl << "Ice configuration properties:" << endl << endl;
- for(Ice::PropertyDict::iterator p = props.begin(); p != props.end(); ++p)
- {
- out << p->first << "=" << p->second << endl;
- }
- }
- else
- {
- out << endl << "Ice configuration properties: <none>" << endl;
- }
-
- string code = profile->code();
- if(!code.empty())
- {
- out << endl << "PHP code for Slice types:" << endl << endl;
- out << code;
- }
- else
- {
- out << endl << "PHP code for Slice types: <none>" << endl;
- }
-
- string s = out.str();
- PUTS(s.c_str());
-}
-
-IcePHP::CodeVisitor::CodeVisitor(ostream& out, map<string, Slice::ClassDefPtr>& classes, bool suppressWarnings
- TSRMLS_DC) :
- _out(out), _classes(classes), _suppressWarnings(suppressWarnings)
-{
-#ifdef ZTS
- this->TSRMLS_C = TSRMLS_C;
-#endif
-}
-
-void
-IcePHP::CodeVisitor::visitClassDecl(const Slice::ClassDeclPtr& p)
-{
- Slice::ClassDefPtr def = p->definition();
- if(!def && !_suppressWarnings)
- {
- string scoped = p->scoped();
- php_error_docref(0 TSRMLS_CC, E_WARNING, "%s %s declared but not defined",
- p->isInterface() ? "interface" : "class", scoped.c_str());
- }
-}
-
-bool
-IcePHP::CodeVisitor::visitClassDefStart(const Slice::ClassDefPtr& p)
-{
- string flat = flatten(p->scoped());
-
- _classes[flat] = p;
-
- Slice::ClassList bases = p->bases();
- Slice::ClassDefPtr base;
-
- if(p->isInterface())
- {
- _out << "if(!interface_exists(\"" << flat << "\"))" << endl;
- _out << "{" << endl;
- _out << "interface " << flat;
- if(!bases.empty())
- {
- _out << " extends ";
- for(Slice::ClassList::iterator q = bases.begin(); q != bases.end(); ++q)
- {
- if(q != bases.begin())
- {
- _out << ",";
- }
- _out << flatten((*q)->scoped());
- }
- }
- else if(!p->isLocal())
- {
- _out << " extends Ice_Object";
- }
- }
- else
- {
- _out << "if(!class_exists(\"" << flat << "\"))" << endl;
- _out << "{" << endl;
- if(p->isAbstract())
- {
- _out << "abstract ";
- }
- _out << "class " << flat;
- if(!bases.empty() && !bases.front()->isInterface())
- {
- _out << " extends " << flatten(bases.front()->scoped());
- base = bases.front();
- bases.pop_front();
- }
- else if(!p->isLocal())
- {
- _out << " extends Ice_ObjectImpl";
- }
- if(!bases.empty())
- {
- _out << " implements ";
- for(Slice::ClassList::iterator q = bases.begin(); q != bases.end(); ++q)
- {
- if(q != bases.begin())
- {
- _out << ",";
- }
- _out << flatten((*q)->scoped());
- }
- }
- }
-
- _out << endl << '{' << endl;
-
- if(!p->isInterface())
- {
- Slice::DataMemberList baseMembers;
- if(base)
- {
- baseMembers = base->allDataMembers();
- }
-
- Slice::DataMemberList members = p->dataMembers();
- Slice::DataMemberList::const_iterator q;
-
- //
- // Generate a constructor.
- //
- _out << "function __construct(";
- for(q = baseMembers.begin(); q != baseMembers.end(); ++q)
- {
- if(q != baseMembers.begin())
- {
- _out << ", ";
- }
- writeConstructorParameter(*q);
- }
- for(q = members.begin(); q != members.end(); ++q)
- {
- if(!baseMembers.empty() || q != members.begin())
- {
- _out << ", ";
- }
- writeConstructorParameter(*q);
- }
- _out << ')' << endl;
- _out << '{' << endl;
- if(base)
- {
- _out << " parent::__construct(";
- for(q = baseMembers.begin(); q != baseMembers.end(); ++q)
- {
- if(q != baseMembers.begin())
- {
- _out << ", ";
- }
- _out << '$' << fixIdent((*q)->name());
- }
- _out << ");" << endl;
- }
- for(q = members.begin(); q != members.end(); ++q)
- {
- writeConstructorAssignment(*q);
- }
- _out << "}" << endl;
- }
-
- return true;
-}
-
-void
-IcePHP::CodeVisitor::visitClassDefEnd(const Slice::ClassDefPtr& p)
-{
- _out << '}' << endl;
- _out << '}' << endl; // interface_exists/class_exists
-}
-
-bool
-IcePHP::CodeVisitor::visitExceptionStart(const Slice::ExceptionPtr& p)
-{
- string flat = flatten(p->scoped());
- Slice::ExceptionPtr base = p->base();
-
- _out << "if(!class_exists(\"" << flat << "\"))" << endl;
- _out << "{" << endl;
- _out << "class " << flat << " extends ";
- string baseName;
- if(!base)
- {
- if(p->isLocal())
- {
- baseName = "Ice_LocalException";
- }
- else
- {
- baseName = "Ice_UserException";
- }
- }
- else
- {
- baseName = flatten(base->scoped());
- }
-
- _out << baseName << endl << '{' << endl;
-
- Slice::DataMemberList baseMembers;
- if(base)
- {
- baseMembers = base->allDataMembers();
- }
-
- Slice::DataMemberList members = p->dataMembers();
- Slice::DataMemberList::const_iterator q;
-
- //
- // Generate a constructor.
- //
- _out << "function __construct($_message=''";
- for(q = baseMembers.begin(); q != baseMembers.end(); ++q)
- {
- _out << ", ";
- writeConstructorParameter(*q);
- }
- for(q = members.begin(); q != members.end(); ++q)
- {
- _out << ", ";
- writeConstructorParameter(*q);
- }
- _out << ')' << endl;
- _out << '{' << endl;
- _out << " " << baseName << "::__construct($_message";
- for(q = baseMembers.begin(); q != baseMembers.end(); ++q)
- {
- _out << ", $" << fixIdent((*q)->name());
- }
- _out << ");" << endl;
- for(q = members.begin(); q != members.end(); ++q)
- {
- writeConstructorAssignment(*q);
- }
- _out << "}" << endl;
-
- return true;
-}
-
-void
-IcePHP::CodeVisitor::visitExceptionEnd(const Slice::ExceptionPtr& p)
-{
- _out << '}' << endl;
- _out << '}' << endl; // class_exists
-}
-
-bool
-IcePHP::CodeVisitor::visitStructStart(const Slice::StructPtr& p)
-{
- string flat = flatten(p->scoped());
-
- _out << "if(!class_exists(\"" << flat << "\"))" << endl;
- _out << "{" << endl;
- _out << "class " << flatten(p->scoped()) << endl;
- _out << '{' << endl;
-
- //
- // Generate a constructor.
- //
- Slice::DataMemberList members = p->dataMembers();
- Slice::DataMemberList::const_iterator q;
- _out << "function __construct(";
- for(q = members.begin(); q != members.end(); ++q)
- {
- if(q != members.begin())
- {
- _out << ", ";
- }
- writeConstructorParameter(*q);
- }
- _out << ')' << endl;
- _out << '{' << endl;
- for(q = members.begin(); q != members.end(); ++q)
- {
- writeConstructorAssignment(*q);
- }
- _out << '}' << endl;
-
- return true;
-}
-
-void
-IcePHP::CodeVisitor::visitStructEnd(const Slice::StructPtr& p)
-{
- _out << '}' << endl;
- _out << '}' << endl; // class_exists
-}
-
-void
-IcePHP::CodeVisitor::visitOperation(const Slice::OperationPtr& p)
-{
- string name = fixIdent(p->name());
-
- Slice::ParamDeclList params = p->parameters();
-
- Slice::ClassDefPtr cl = Slice::ClassDefPtr::dynamicCast(p->container());
- assert(cl);
-
- if(!cl->isInterface())
- {
- _out << "abstract ";
- }
- _out << "function " << name << '(';
- for(Slice::ParamDeclList::const_iterator q = params.begin(); q != params.end(); ++q)
- {
- Slice::ParamDeclPtr param = *q;
- if(q != params.begin())
- {
- _out << ", ";
- }
- if(param->isOutParam())
- {
- _out << '&';
- }
- else
- {
- string hint = getTypeHint(param->type());
- if(!hint.empty())
- {
- _out << hint << ' ';
- }
- }
- _out << '$' << fixIdent(param->name());
- }
- _out << ");" << endl;
-}
-
-void
-IcePHP::CodeVisitor::visitDataMember(const Slice::DataMemberPtr& p)
-{
- Slice::ContainedPtr cont = Slice::ContainedPtr::dynamicCast(p->container());
- assert(cont);
- if(Slice::ClassDefPtr::dynamicCast(cont) && (cont->hasMetaData("protected") || p->hasMetaData("protected")))
- {
- _out << "protected $" << fixIdent(p->name()) << ';' << endl;
- }
- else
- {
- _out << "public $" << fixIdent(p->name()) << ';' << endl;
- }
-}
-
-void
-IcePHP::CodeVisitor::visitDictionary(const Slice::DictionaryPtr& p)
-{
- Slice::TypePtr keyType = p->keyType();
- if(!isNativeKey(keyType) && !_suppressWarnings)
- {
- //
- // TODO: Generate class.
- //
- string scoped = p->scoped();
- php_error_docref(0 TSRMLS_CC, E_WARNING, "skipping dictionary %s - unsupported key type", scoped.c_str());
- }
-}
-
-void
-IcePHP::CodeVisitor::visitEnum(const Slice::EnumPtr& p)
-{
- string flat = flatten(p->scoped());
-
- _out << "if(!class_exists(\"" << flat << "\"))" << endl;
- _out << "{" << endl;
- _out << "class " << flat << endl;
- _out << '{' << endl;
-
- //
- // Create a class constant for each enumerator.
- //
- Slice::EnumeratorList l = p->getEnumerators();
- Slice::EnumeratorList::const_iterator q;
- long i;
- for(q = l.begin(), i = 0; q != l.end(); ++q, ++i)
- {
- string name = fixIdent((*q)->name());
- _out << " const " << fixIdent((*q)->name()) << " = " << i << ';' << endl;
- }
-
- _out << '}' << endl;
- _out << '}' << endl; // class_exists
-}
-
-void
-IcePHP::CodeVisitor::visitConst(const Slice::ConstPtr& p)
-{
- string flat = flatten(p->scoped());
- Slice::TypePtr type = p->type();
- string value = p->value();
-
- _out << "if(!defined(\"" << flat << "\"))" << endl;
- _out << "{" << endl;
- _out << "define(\"" << flat << "\", ";
-
- Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type);
- Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(type);
- if(b)
- {
- switch(b->kind())
- {
- case Slice::Builtin::KindBool:
- case Slice::Builtin::KindByte:
- case Slice::Builtin::KindShort:
- case Slice::Builtin::KindInt:
- case Slice::Builtin::KindFloat:
- case Slice::Builtin::KindDouble:
- _out << value;
- break;
-
- case Slice::Builtin::KindLong:
- {
- IceUtil::Int64 l;
- IceUtilInternal::stringToInt64(value, l);
- //
- // The platform's 'long' type may not be 64 bits, so we store 64-bit
- // values as a string.
- //
- if(sizeof(IceUtil::Int64) > sizeof(long) && (l < LONG_MIN || l > LONG_MAX))
- {
- _out << "\"" << value << "\";";
- }
- else
- {
- _out << value;
- }
- break;
- }
-
- case Slice::Builtin::KindString:
- {
- //
- // Expand strings into the basic source character set. We can't use isalpha() and the like
- // here because they are sensitive to the current locale.
- //
- static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789"
- "_{}[]#()<>%:;,?*+=/^&|~!=,\\' \t";
- static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end());
-
- _out << "\""; // Opening "
-
- ios_base::fmtflags originalFlags = _out.flags(); // Save stream state
- streamsize originalWidth = _out.width();
- ostream::char_type originalFill = _out.fill();
-
- for(string::const_iterator c = value.begin(); c != value.end(); ++c)
- {
- if(*c == '$')
- {
- _out << "\\$";
- }
- else if(*c == '"')
- {
- _out << "\\\"";
- }
- else if(charSet.find(*c) == charSet.end())
- {
- unsigned char uc = *c; // char may be signed, so make it positive
- _out << "\\"; // Print as octal if not in basic source character set
- _out.flags(ios_base::oct);
- _out.width(3);
- _out.fill('0');
- _out << static_cast<unsigned>(uc);
- }
- else
- {
- _out << *c; // Print normally if in basic source character set
- }
- }
-
- _out.fill(originalFill); // Restore stream state
- _out.width(originalWidth);
- _out.flags(originalFlags);
-
- _out << "\""; // Closing "
-
- break;
- }
-
- case Slice::Builtin::KindObject:
- case Slice::Builtin::KindObjectProxy:
- case Slice::Builtin::KindLocalObject:
- assert(false);
- }
- }
- else if(en)
- {
- string::size_type colon = value.rfind(':');
- if(colon != string::npos)
- {
- value = value.substr(colon + 1);
- }
- Slice::EnumeratorList l = en->getEnumerators();
- Slice::EnumeratorList::iterator q;
- for(q = l.begin(); q != l.end(); ++q)
- {
- if((*q)->name() == value)
- {
- _out << flatten(en->scoped()) << "::" << fixIdent(value);
- break;
- }
- }
- }
-
- _out << ");" << endl;
- _out << "}" << endl; // defined
-}
-
-string
-IcePHP::CodeVisitor::getTypeHint(const Slice::TypePtr& type)
-{
- //
- // Currently, the Zend engine does not allow an argument with a type hint to have
- // a value of null, therefore we can only use type hints for structs.
- //
- Slice::StructPtr st = Slice::StructPtr::dynamicCast(type);
- if(st)
- {
- return flatten(st->scoped());
- }
-
- return string();
-}
-
-string
-IcePHP::CodeVisitor::getDefaultValue(const Slice::TypePtr& type)
-{
- Slice::BuiltinPtr builtin = Slice::BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- switch(builtin->kind())
- {
- case Slice::Builtin::KindByte:
- case Slice::Builtin::KindShort:
- case Slice::Builtin::KindInt:
- case Slice::Builtin::KindLong:
- return "0";
-
- case Slice::Builtin::KindBool:
- return "false";
-
- case Slice::Builtin::KindFloat:
- case Slice::Builtin::KindDouble:
- return "0.0";
-
- case Slice::Builtin::KindString:
- return "''";
-
- case Slice::Builtin::KindObject:
- case Slice::Builtin::KindObjectProxy:
- case Slice::Builtin::KindLocalObject:
- return "null";
- }
- }
-
- Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(type);
- if(en)
- {
- //
- // Use the first enumerator.
- //
- string flat = flatten(en->scoped());
- Slice::EnumeratorList l = en->getEnumerators();
- string name = fixIdent(l.front()->name());
- return flat + "::" + name;
- }
-
- Slice::StructPtr str = Slice::StructPtr::dynamicCast(type);
- if(str)
- {
- return "new " + flatten(str->scoped()) + "()";
- }
-
- return "null";
-}
-
-void
-IcePHP::CodeVisitor::writeConstructorParameter(const Slice::DataMemberPtr& member)
-{
- _out << '$' << fixIdent(member->name()) << '=';
- //
- // Structure types must be handled specially.
- //
- if(Slice::StructPtr::dynamicCast(member->type()))
- {
- //
- // If a data member is a structure, we want to initialize it to a new instance of the
- // structure type. However, PHP does not allow a call to "new" in the default value of
- // a function argument, so we assign a marker value now and create the instance in the
- // constructor body.
- //
- _out << "-1";
- }
- else
- {
- _out << getDefaultValue(member->type());
- }
-}
-
-void
-IcePHP::CodeVisitor::writeConstructorAssignment(const Slice::DataMemberPtr& member)
-{
- //
- // Structure types are instantiated in the constructor body.
- //
- string name = fixIdent(member->name());
- if(Slice::StructPtr::dynamicCast(member->type()))
- {
- _out << " $this->" << name << " = $" << name << " == -1 ? " << getDefaultValue(member->type())
- << " : $" << name << ';' << endl;
- }
- else
- {
- _out << " $this->" << name << " = $" << name << ';' << endl;
- }
-}
diff --git a/php/src/IcePHP/Profile.h b/php/src/IcePHP/Profile.h
deleted file mode 100644
index 32ff4b241ab..00000000000
--- a/php/src/IcePHP/Profile.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#ifndef ICE_PHP_PROFILE_H
-#define ICE_PHP_PROFILE_H
-
-#include <Config.h>
-
-//
-// Global functions.
-//
-extern "C"
-{
-ZEND_FUNCTION(Ice_stringVersion);
-ZEND_FUNCTION(Ice_intVersion);
-ZEND_FUNCTION(Ice_loadProfile);
-ZEND_FUNCTION(Ice_loadProfileWithArgs);
-ZEND_FUNCTION(Ice_dumpProfile);
-}
-
-#define ICE_PHP_PROFILE_FUNCTIONS \
- ZEND_FE(Ice_stringVersion, NULL) \
- ZEND_FE(Ice_intVersion, NULL) \
- ZEND_FE(Ice_loadProfile, NULL) \
- ZEND_FE(Ice_loadProfileWithArgs, NULL) \
- ZEND_FE(Ice_dumpProfile, NULL)
-
-namespace IcePHP
-{
-
-bool profileInit(TSRMLS_D);
-bool profileShutdown(TSRMLS_D);
-
-//
-// Profile contains information about an Ice configuration. A pointer to a Profile instance
-// is stored in the PHP globals (see php_ice.h) when a script invokes Ice_loadProfile().
-//
-class Profile
-{
-public:
-
- typedef std::map<std::string, Slice::ClassDefPtr> ClassMap;
-
- Profile(const std::string&, const std::vector<Slice::UnitPtr>&, const std::string&, const ClassMap&,
- const Ice::PropertiesPtr&);
-
- std::string name() const;
- std::string code() const;
- const ClassMap& classes() const;
- Ice::PropertiesPtr properties() const;
-
- Slice::TypePtr lookupType(const std::string&) const;
- Slice::ExceptionPtr lookupException(const std::string&) const;
-
- void destroy(TSRMLS_D);
-
-private:
-
- std::string _name; // The profile name
- std::vector<Slice::UnitPtr> _units; // The parsed Slice files
- std::string _code; // PHP code generated from Slice types
- ClassMap _classes; // Associates flattened type ids to their ClassDefs
- Ice::PropertiesPtr _properties; // Configuration properties
-};
-
-} // End of namespace IcePHP
-
-#endif
diff --git a/php/src/IcePHP/Properties.cpp b/php/src/IcePHP/Properties.cpp
new file mode 100644
index 00000000000..24bba29c2c1
--- /dev/null
+++ b/php/src/IcePHP/Properties.cpp
@@ -0,0 +1,671 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Properties.h>
+#include <Util.h>
+
+using namespace std;
+using namespace IcePHP;
+
+ZEND_EXTERN_MODULE_GLOBALS(ice)
+
+//
+// Class entries represent the PHP class implementations we have registered.
+//
+namespace IcePHP
+{
+zend_class_entry* propertiesClassEntry = 0;
+}
+
+//
+// Properties support.
+//
+static zend_object_handlers _handlers;
+
+extern "C"
+{
+static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC);
+static void handleFreeStorage(void* TSRMLS_DC);
+static zend_object_value handleClone(zval* TSRMLS_DC);
+}
+
+ZEND_METHOD(Ice_Properties, __construct)
+{
+ runtimeError("properties objects cannot be instantiated, use createProperties()" TSRMLS_CC);
+}
+
+ZEND_METHOD(Ice_Properties, __toString)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ Ice::PropertyDict val = _this->getPropertiesForPrefix("");
+ string str;
+ for(Ice::PropertyDict::const_iterator p = val.begin(); p != val.end(); ++p)
+ {
+ if(p != val.begin())
+ {
+ str.append("\n");
+ }
+ str.append(p->first + "=" + p->second);
+ }
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getProperty)
+{
+ char* name;
+ int nameLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &nameLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string propName(name, nameLen);
+ try
+ {
+ string val = _this->getProperty(propName);
+ RETURN_STRINGL(STRCAST(val.c_str()), val.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyWithDefault)
+{
+ char* name;
+ int nameLen;
+ char* def;
+ int defLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss!", &name, &nameLen, &def, &defLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string propName(name, nameLen);
+ string defaultValue;
+ if(def)
+ {
+ defaultValue = string(def, defLen);
+ }
+
+ try
+ {
+ string val = _this->getPropertyWithDefault(propName, defaultValue);
+ RETURN_STRINGL(STRCAST(val.c_str()), val.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyAsInt)
+{
+ char* name;
+ int nameLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &nameLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string propName(name, nameLen);
+ try
+ {
+ Ice::Int val = _this->getPropertyAsInt(propName);
+ RETURN_LONG(static_cast<long>(val));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyAsIntWithDefault)
+{
+ char* name;
+ int nameLen;
+ long def;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name, &nameLen, &def) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string propName(name, nameLen);
+ try
+ {
+ Ice::Int val = _this->getPropertyAsIntWithDefault(propName, def);
+ RETURN_LONG(static_cast<long>(val));
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyAsList)
+{
+ char* name;
+ int nameLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &nameLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string propName(name, nameLen);
+ try
+ {
+ Ice::StringSeq val = _this->getPropertyAsList(propName);
+ if(!createStringArray(return_value, val TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertyAsListWithDefault)
+{
+ char* name;
+ int nameLen;
+ zval* def;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa!", &name, &nameLen, &def) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string propName(name, nameLen);
+ Ice::StringSeq defaultValue;
+ if(def && !extractStringArray(def, defaultValue TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::StringSeq val = _this->getPropertyAsListWithDefault(propName, defaultValue);
+ if(!createStringArray(return_value, val TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getPropertiesForPrefix)
+{
+ char* p;
+ int pLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &p, &pLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string prefix;
+ if(p)
+ {
+ prefix = string(p, pLen);
+ }
+
+ try
+ {
+ Ice::PropertyDict val = _this->getPropertiesForPrefix(prefix);
+ if(!createStringMap(return_value, val TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, setProperty)
+{
+ char* name;
+ int nameLen;
+ char* val;
+ int valLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss!", &name, &nameLen, &val, &valLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string propName(name, nameLen);
+ string propValue;
+ if(val)
+ {
+ propValue = string(val, valLen);
+ }
+
+ try
+ {
+ _this->setProperty(propName, propValue);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, getCommandLineOptions)
+{
+ if(ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ Ice::StringSeq val = _this->getCommandLineOptions();
+ if(!createStringArray(return_value, val TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, parseCommandLineOptions)
+{
+ char* p;
+ int pLen;
+ zval* opts;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!a!", &p, &pLen, &opts) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string prefix;
+ if(p)
+ {
+ prefix = string(p, pLen);
+ }
+ Ice::StringSeq options;
+ if(opts && !extractStringArray(opts, options TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::StringSeq val = _this->parseCommandLineOptions(prefix, options);
+ if(!createStringArray(return_value, val TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, parseIceCommandLineOptions)
+{
+ zval* opts;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!", &opts) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ Ice::StringSeq options;
+ if(opts && !extractStringArray(opts, options TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::StringSeq val = _this->parseIceCommandLineOptions(options);
+ if(!createStringArray(return_value, val TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, load)
+{
+ char* f;
+ int fLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &f, &fLen) == FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ string file(f, fLen);
+
+ try
+ {
+ _this->load(file);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+ZEND_METHOD(Ice_Properties, clone)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ Ice::PropertiesPtr _this = Wrapper<Ice::PropertiesPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
+
+ try
+ {
+ Ice::PropertiesPtr pclone = _this->clone();
+
+ if(!createProperties(return_value, pclone TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleAlloc(zend_class_entry* ce TSRMLS_DC)
+{
+ zend_object_value result;
+
+ Wrapper<Ice::PropertiesPtr>* obj = Wrapper<Ice::PropertiesPtr>::create(ce TSRMLS_CC);
+ assert(obj);
+
+ result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage, 0 TSRMLS_CC);
+ result.handlers = &_handlers;
+
+ return result;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleFreeStorage(void* p TSRMLS_DC)
+{
+ Wrapper<Ice::PropertiesPtr>* obj = static_cast<Wrapper<Ice::PropertiesPtr>*>(p);
+ delete obj->ptr;
+ zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleClone(zval* zv TSRMLS_DC)
+{
+ zend_object_value result;
+ memset(&result, 0, sizeof(zend_object_value));
+
+ Ice::PropertiesPtr p = Wrapper<Ice::PropertiesPtr>::value(zv TSRMLS_CC);
+ assert(p);
+
+ Ice::PropertiesPtr pclone = p->clone();
+
+ zval* clone;
+ MAKE_STD_ZVAL(clone);
+ if(!createProperties(clone, pclone TSRMLS_CC))
+ {
+ return result;
+ }
+
+ //
+ // We only need to return the new object's handle, so we must destroy the zval containing
+ // a reference to the new object. We increment the object's reference count to ensure it
+ // does not get destroyed.
+ //
+ result = clone->value.obj;
+ Z_OBJ_HT_P(clone)->add_ref(clone TSRMLS_CC);
+ zval_dtor(clone);
+ efree(clone);
+
+ return result;
+}
+
+ZEND_FUNCTION(Ice_createProperties)
+{
+ zval* arglist = 0;
+ zval* defaultsObj = 0;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!O!", &arglist, &defaultsObj, propertiesClassEntry) ==
+ FAILURE)
+ {
+ RETURN_NULL();
+ }
+
+ Ice::StringSeq seq;
+ if(arglist && !extractStringArray(arglist, seq TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+
+ Ice::PropertiesPtr defaults;
+ if(defaultsObj && !fetchProperties(defaultsObj, defaults TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+
+ try
+ {
+ Ice::PropertiesPtr props = Ice::createProperties(seq, defaults);
+ if(!createProperties(return_value, props TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+
+ if(arglist && PZVAL_IS_REF(arglist))
+ {
+ zval_dtor(arglist);
+ if(!createStringArray(arglist, seq TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+ }
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ RETURN_NULL();
+ }
+}
+
+//
+// Predefined methods for Properties.
+//
+static function_entry _interfaceMethods[] =
+{
+ {0, 0, 0}
+};
+static function_entry _classMethods[] =
+{
+ ZEND_ME(Ice_Properties, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ ZEND_ME(Ice_Properties, __toString, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, getProperty, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, getPropertyWithDefault, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, getPropertyAsInt, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, getPropertyAsIntWithDefault, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, getPropertyAsList, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, getPropertyAsListWithDefault, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, getPropertiesForPrefix, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, setProperty, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, getCommandLineOptions, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, parseCommandLineOptions, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, parseIceCommandLineOptions, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, load, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_Properties, clone, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
+
+bool
+IcePHP::propertiesInit(TSRMLS_D)
+{
+ //
+ // We register an interface and a class that implements the interface. This allows
+ // applications to safely include the Slice-generated code for the type.
+ //
+
+ //
+ // Register the Properties interface.
+ //
+ zend_class_entry ce;
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("Properties"), _interfaceMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_Properties", _interfaceMethods);
+#endif
+ zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC);
+
+ //
+ // Register the Properties class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_Properties", _classMethods);
+ ce.create_object = handleAlloc;
+ propertiesClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _handlers.clone_obj = handleClone;
+ zend_class_implements(propertiesClassEntry TSRMLS_CC, 1, interface);
+
+ return true;
+}
+
+bool
+IcePHP::createProperties(zval* zv, const Ice::PropertiesPtr& p TSRMLS_DC)
+{
+ if(object_init_ex(zv, propertiesClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize properties object" TSRMLS_CC);
+ return false;
+ }
+
+ Wrapper<Ice::PropertiesPtr>* obj = Wrapper<Ice::PropertiesPtr>::extract(zv TSRMLS_CC);
+ assert(!obj->ptr);
+ obj->ptr = new Ice::PropertiesPtr(p);
+
+ return true;
+}
+
+bool
+IcePHP::fetchProperties(zval* zv, Ice::PropertiesPtr& p TSRMLS_DC)
+{
+ if(!ZVAL_IS_NULL(zv))
+ {
+ if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != propertiesClassEntry)
+ {
+ invalidArgument("value is not a properties object" TSRMLS_CC);
+ return false;
+ }
+ p = Wrapper<Ice::PropertiesPtr>::value(zv TSRMLS_CC);
+ if(!p)
+ {
+ runtimeError("unable to retrieve properties object from object store" TSRMLS_CC);
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/php/src/IcePHP/Properties.h b/php/src/IcePHP/Properties.h
new file mode 100644
index 00000000000..4124ff3659e
--- /dev/null
+++ b/php/src/IcePHP/Properties.h
@@ -0,0 +1,48 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICEPHP_PROPERTIES_H
+#define ICEPHP_PROPERTIES_H
+
+#include <Config.h>
+
+//
+// Global functions.
+//
+extern "C"
+{
+ZEND_FUNCTION(Ice_createProperties);
+}
+
+#define ICEPHP_PROPERTIES_FUNCTIONS \
+ ZEND_FE(Ice_createProperties, NULL)
+
+#ifdef ICEPHP_USE_NAMESPACES
+# define ICEPHP_PROPERTIES_NS_FUNCTIONS \
+ ZEND_NS_FALIAS("Ice", createProperties, Ice_createProperties, NULL)
+#else
+# define ICEPHP_PROPERTIES_NS_FUNCTIONS
+#endif
+
+namespace IcePHP
+{
+
+bool propertiesInit(TSRMLS_D);
+
+bool createProperties(zval*, const Ice::PropertiesPtr& TSRMLS_DC);
+bool fetchProperties(zval*, Ice::PropertiesPtr& TSRMLS_DC);
+
+//
+// Class entry.
+//
+extern zend_class_entry* propertiesClassEntry;
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/IcePHP/Proxy.cpp b/php/src/IcePHP/Proxy.cpp
index 9b22aca798e..65bb3cd9e6d 100644
--- a/php/src/IcePHP/Proxy.cpp
+++ b/php/src/IcePHP/Proxy.cpp
@@ -7,11 +7,9 @@
//
// **********************************************************************
-#include <IceUtil/DisableWarnings.h>
#include <Proxy.h>
-#include <Communicator.h>
-#include <Marshal.h>
-#include <Profile.h>
+#include <Connection.h>
+#include <Endpoint.h>
#include <Util.h>
using namespace std;
@@ -22,28 +20,25 @@ ZEND_EXTERN_MODULE_GLOBALS(ice)
//
// Here's a brief description of how proxies are handled by this extension.
//
-// A single PHP class, Ice_ObjectPrx, is registered. This is an "internal" class,
+// A single PHP class, ObjectPrx, is registered. This is an "internal" class,
// i.e., implemented by this extension, and it is used to represent all proxies
// regardless of interface type.
//
// Like in C++, a proxy is only capable of invoking the Ice::ObjectPrx operations
// until it is narrowed with a checked or unchecked cast. Unlike C++, no PHP classes
-// are created for proxies, because all marshaling activity is driven by the Slice
+// are created for proxies, because all marshaling activity is driven by the type
// definitions, not by statically-generated code.
//
-// In order to perform a checked or unchecked cast, the user invokes ice_checkedCast
-// or ice_uncheckedCast on the proxy to be narrowed, supplying a scoped name for the
-// desired type. Internally, the proxy validates the scoped name and returns a new
-// proxy containing the Slice class or interface definition. This proxy is considered
+// In order to perform a checked or unchecked cast, the generated code invokes
+// ice_checkedCast or ice_uncheckedCast on the proxy to be narrowed, supplying a scoped
+// name for the desired type. Internally, the proxy validates the scoped name and returns
+// a new proxy containing the class or interface definition. This proxy is considered
// to be narrowed to that interface and therefore supports user-defined operations.
//
-// Naturally, there are many predefined proxy methods (e.g., ice_isA, etc.), but
+// Naturally, there are many predefined proxy methods (e.g., ice_getIdentity, etc.), but
// the proxy also needs to support user-defined operations (if it has type information).
// We use a Zend API hook that allows us to intercept the invocation of unknown methods
-// on the proxy object. At this point, the proxy checks the interface definition for
-// an operation with the given name, and then creates an Operation object (see below)
-// that is responsible for invoking the operation. The proxy caches the Operation objects
-// for future reuse.
+// on the proxy object.
//
//
@@ -52,346 +47,73 @@ ZEND_EXTERN_MODULE_GLOBALS(ice)
namespace IcePHP
{
zend_class_entry* proxyClassEntry = 0;
-zend_class_entry* endpointClassEntry = 0;
-zend_class_entry* connectionClassEntry = 0;
}
//
-// Ice::ObjectPrx and Ice::Endpoint support.
+// Ice::ObjectPrx support.
//
-static zend_object_handlers _proxyHandlers;
-static zend_object_handlers _endpointHandlers;
-static zend_object_handlers _connectionHandlers;
+static zend_object_handlers _handlers;
extern "C"
{
-static zend_object_value handleProxyAlloc(zend_class_entry* TSRMLS_DC);
-static void handleProxyFreeStorage(void* TSRMLS_DC);
-static zend_object_value handleProxyClone(zval* TSRMLS_DC);
-static union _zend_function* handleProxyGetMethod(zval**, char*, int TSRMLS_DC);
-static int handleProxyCompare(zval*, zval* TSRMLS_DC);
-ZEND_FUNCTION(Ice_ObjectPrx_call);
-
-static zend_object_value handleEndpointAlloc(zend_class_entry* TSRMLS_DC);
-static void handleEndpointFreeStorage(void* TSRMLS_DC);
-
-static zend_object_value handleConnectionAlloc(zend_class_entry* TSRMLS_DC);
-static void handleConnectionFreeStorage(void* TSRMLS_DC);
-static int handleConnectionCompare(zval*, zval* TSRMLS_DC);
+static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC);
+static void handleFreeStorage(void* TSRMLS_DC);
+static zend_object_value handleClone(zval* TSRMLS_DC);
+static union _zend_function* handleGetMethod(zval**, char*, int TSRMLS_DC);
+static int handleCompare(zval*, zval* TSRMLS_DC);
}
-static bool lookupClass(const string&, Slice::ClassDefPtr& TSRMLS_DC);
+static ClassInfoPtr lookupClass(const string& TSRMLS_DC);
namespace IcePHP
{
//
-// Encapsulates an operation description.
-//
-class Operation : public IceUtil::SimpleShared
-{
-public:
- Operation(const Ice::ObjectPrx&, const string&, const Slice::OperationPtr&, const Ice::CommunicatorPtr&
- TSRMLS_DC);
- virtual ~Operation();
-
- zend_function* getZendFunction() const;
- void invoke(INTERNAL_FUNCTION_PARAMETERS);
-
-private:
- void throwUserException(Ice::InputStreamPtr& TSRMLS_DC);
-
- Ice::ObjectPrx _proxy;
- string _name; // Local name, not the on-the-wire name
- Slice::OperationPtr _op;
- Ice::CommunicatorPtr _communicator;
-#ifdef ZTS
- TSRMLS_D;
-#endif
- vector<string> _paramNames;
- MarshalerPtr _result;
- vector<MarshalerPtr> _inParams;
- vector<MarshalerPtr> _outParams;
- zend_internal_function* _zendFunction;
-};
-typedef IceUtil::Handle<Operation> OperationPtr;
-
-//
// Encapsulates proxy and type information.
//
-class Proxy
+class Proxy : public IceUtil::Shared
{
public:
- Proxy(const Ice::ObjectPrx&, const Slice::ClassDefPtr& TSRMLS_DC);
- ~Proxy();
- const Ice::ObjectPrx& getProxy() const;
- const Slice::ClassDefPtr& getClass() const;
-
- OperationPtr getOperation(const string&);
+ Proxy(const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
+ ~Proxy();
- string toString() const;
+ bool clone(zval*, const Ice::ObjectPrx& TSRMLS_DC);
+ bool cloneUntyped(zval*, const Ice::ObjectPrx& TSRMLS_DC);
+ static bool create(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
-private:
- Ice::ObjectPrx _proxy;
- Slice::ClassDefPtr _class;
-#ifdef ZTS
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr info;
+ CommunicatorInfoPtr communicator;
+ zval* connection;
+ zval* cachedConnection;
+#if ZTS
TSRMLS_D;
#endif
- zval _communicatorZval;
- Ice::CommunicatorPtr _communicator;
- Slice::OperationList _classOps;
- map<string, OperationPtr> _ops;
};
+typedef IceUtil::Handle<Proxy> ProxyPtr;
} // End of namespace IcePHP
-//
-// Predefined methods for Ice_ObjectPrx.
-//
-static function_entry _proxyMethods[] =
-{
- {"__construct", PHP_FN(Ice_ObjectPrx___construct), 0},
- {"__tostring", PHP_FN(Ice_ObjectPrx___tostring), 0},
- {"ice_getCommunicator", PHP_FN(Ice_ObjectPrx_ice_getCommunicator), 0},
- {"ice_toString", PHP_FN(Ice_ObjectPrx_ice_toString), 0},
- {"ice_isA", PHP_FN(Ice_ObjectPrx_ice_isA), 0},
- {"ice_ping", PHP_FN(Ice_ObjectPrx_ice_ping), 0},
- {"ice_id", PHP_FN(Ice_ObjectPrx_ice_id), 0},
- {"ice_ids", PHP_FN(Ice_ObjectPrx_ice_ids), 0},
- {"ice_getIdentity", PHP_FN(Ice_ObjectPrx_ice_getIdentity), 0},
- {"ice_newIdentity", PHP_FN(Ice_ObjectPrx_ice_identity), 0},
- {"ice_identity", PHP_FN(Ice_ObjectPrx_ice_identity), 0},
- {"ice_getContext", PHP_FN(Ice_ObjectPrx_ice_getContext), 0},
- {"ice_newContext", PHP_FN(Ice_ObjectPrx_ice_context), 0},
- {"ice_context", PHP_FN(Ice_ObjectPrx_ice_context), 0},
- {"ice_getFacet", PHP_FN(Ice_ObjectPrx_ice_getFacet), 0},
- {"ice_newFacet", PHP_FN(Ice_ObjectPrx_ice_facet), 0},
- {"ice_facet", PHP_FN(Ice_ObjectPrx_ice_facet), 0},
- {"ice_getAdapterId", PHP_FN(Ice_ObjectPrx_ice_getAdapterId), 0},
- {"ice_newAdapterId", PHP_FN(Ice_ObjectPrx_ice_adapterId), 0},
- {"ice_adapterId", PHP_FN(Ice_ObjectPrx_ice_adapterId), 0},
- {"ice_getEndpoints", PHP_FN(Ice_ObjectPrx_ice_getEndpoints), 0},
- {"ice_newEndpoints", PHP_FN(Ice_ObjectPrx_ice_endpoints), 0},
- {"ice_endpoints", PHP_FN(Ice_ObjectPrx_ice_endpoints), 0},
- {"ice_getLocatorCacheTimeout", PHP_FN(Ice_ObjectPrx_ice_getLocatorCacheTimeout), 0},
- {"ice_locatorCacheTimeout", PHP_FN(Ice_ObjectPrx_ice_locatorCacheTimeout), 0},
- {"ice_isConnectionCached", PHP_FN(Ice_ObjectPrx_ice_isConnectionCached), 0},
- {"ice_connectionCached", PHP_FN(Ice_ObjectPrx_ice_connectionCached), 0},
- {"ice_getEndpointSelection", PHP_FN(Ice_ObjectPrx_ice_getEndpointSelection), 0},
- {"ice_endpointSelection", PHP_FN(Ice_ObjectPrx_ice_endpointSelection), 0},
- {"ice_isSecure", PHP_FN(Ice_ObjectPrx_ice_isSecure), 0},
- {"ice_secure", PHP_FN(Ice_ObjectPrx_ice_secure), 0},
- {"ice_isPreferSecure", PHP_FN(Ice_ObjectPrx_ice_isPreferSecure), 0},
- {"ice_preferSecure", PHP_FN(Ice_ObjectPrx_ice_preferSecure), 0},
- {"ice_getRouter", PHP_FN(Ice_ObjectPrx_ice_getRouter), 0},
- {"ice_router", PHP_FN(Ice_ObjectPrx_ice_router), 0},
- {"ice_getLocator", PHP_FN(Ice_ObjectPrx_ice_getLocator), 0},
- {"ice_locator", PHP_FN(Ice_ObjectPrx_ice_locator), 0},
- {"ice_twoway", PHP_FN(Ice_ObjectPrx_ice_twoway), 0},
- {"ice_isTwoway", PHP_FN(Ice_ObjectPrx_ice_isTwoway), 0},
- {"ice_oneway", PHP_FN(Ice_ObjectPrx_ice_oneway), 0},
- {"ice_isOneway", PHP_FN(Ice_ObjectPrx_ice_isOneway), 0},
- {"ice_batchOneway", PHP_FN(Ice_ObjectPrx_ice_batchOneway), 0},
- {"ice_isBatchOneway", PHP_FN(Ice_ObjectPrx_ice_isBatchOneway), 0},
- {"ice_datagram", PHP_FN(Ice_ObjectPrx_ice_datagram), 0},
- {"ice_isDatagram", PHP_FN(Ice_ObjectPrx_ice_isDatagram), 0},
- {"ice_batchDatagram", PHP_FN(Ice_ObjectPrx_ice_batchDatagram), 0},
- {"ice_isBatchDatagram", PHP_FN(Ice_ObjectPrx_ice_isBatchDatagram), 0},
- {"ice_compress", PHP_FN(Ice_ObjectPrx_ice_compress), 0},
- {"ice_timeout", PHP_FN(Ice_ObjectPrx_ice_timeout), 0},
- {"ice_connectionId", PHP_FN(Ice_ObjectPrx_ice_connectionId), 0},
- {"ice_getConnection", PHP_FN(Ice_ObjectPrx_ice_getConnection), 0},
- {"ice_getCachedConnection", PHP_FN(Ice_ObjectPrx_ice_getCachedConnection), 0},
- {"ice_uncheckedCast", PHP_FN(Ice_ObjectPrx_ice_uncheckedCast), 0},
- {"ice_checkedCast", PHP_FN(Ice_ObjectPrx_ice_checkedCast), 0},
- {0, 0, 0}
-};
-
-//
-// Predefined methods for Ice_Endpoint.
-//
-static function_entry _endpointMethods[] =
-{
- {"__construct", PHP_FN(Ice_Endpoint___construct), 0},
- {"__tostring", PHP_FN(Ice_Endpoint___tostring), 0},
- {"toString", PHP_FN(Ice_Endpoint_toString), 0},
- {0, 0, 0}
-};
-
-//
-// Predefined methods for Ice_Connection.
-//
-static function_entry _connectionMethods[] =
-{
- {"__construct", PHP_FN(Ice_Connection___construct), 0},
- {"__tostring", PHP_FN(Ice_Connection___tostring), 0},
- {"close", PHP_FN(Ice_Connection_close), 0},
- {"flushBatchRequests", PHP_FN(Ice_Connection_flushBatchRequests), 0},
- {"type", PHP_FN(Ice_Connection_type), 0},
- {"timeout", PHP_FN(Ice_Connection_timeout), 0},
- {"toString", PHP_FN(Ice_Connection_toString), 0},
- {0, 0, 0}
-};
-
-bool
-IcePHP::proxyInit(TSRMLS_D)
-{
- //
- // Register the Ice_ObjectPrx class.
- //
- zend_class_entry ce;
- INIT_CLASS_ENTRY(ce, "Ice_ObjectPrx", _proxyMethods);
- ce.create_object = handleProxyAlloc;
- proxyClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
- memcpy(&_proxyHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
- _proxyHandlers.clone_obj = handleProxyClone;
- _proxyHandlers.get_method = handleProxyGetMethod;
- _proxyHandlers.compare_objects = handleProxyCompare;
-
- //
- // Register the Ice_Endpoint class.
- //
- INIT_CLASS_ENTRY(ce, "Ice_Endpoint", _endpointMethods);
- ce.create_object = handleEndpointAlloc;
- endpointClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
- memcpy(&_endpointHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
-
- //
- // Register the Ice_Connection class.
- //
- INIT_CLASS_ENTRY(ce, "Ice_Connection", _connectionMethods);
- ce.create_object = handleConnectionAlloc;
- connectionClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
- memcpy(&_connectionHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
- _connectionHandlers.compare_objects = handleConnectionCompare;
-
- return true;
-}
-
-bool
-IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC)
-{
- return createProxy(zv, p, 0 TSRMLS_CC);
-}
-
-bool
-IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const Slice::ClassDefPtr& def TSRMLS_DC)
-{
- if(object_init_ex(zv, proxyClassEntry) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize proxy");
- return false;
- }
-
- ice_object* zprx = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC));
- assert(!zprx->ptr);
- zprx->ptr = new Proxy(p, def TSRMLS_CC);
-
- return true;
-}
-
-bool
-IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, Slice::ClassDefPtr& def TSRMLS_DC)
-{
- if(!ZVAL_IS_NULL(zv))
- {
- void* p = zend_object_store_get_object(zv TSRMLS_CC);
- if(!p)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to retrieve proxy object from object store");
- return false;
- }
- if(Z_OBJCE_P(zv) != proxyClassEntry)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "value is not a proxy");
- return false;
- }
- ice_object* obj = static_cast<ice_object*>(p);
- assert(obj->ptr);
- Proxy* proxy = static_cast<Proxy*>(obj->ptr);
- prx = proxy->getProxy();
- def = proxy->getClass();
- }
- return true;
-}
-
-static bool
-createEndpoint(zval* zv, const Ice::EndpointPtr& p TSRMLS_DC)
-{
- if(object_init_ex(zv, endpointClassEntry) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize endpoint");
- return false;
- }
-
- ice_object* ze = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC));
- assert(!ze->ptr);
- ze->ptr = new Ice::EndpointPtr(p);
-
- return true;
-}
-
-static bool
-fetchEndpoint(zval* zv, Ice::EndpointPtr& endpoint TSRMLS_DC)
-{
- if(!ZVAL_IS_NULL(zv))
- {
- void* p = zend_object_store_get_object(zv TSRMLS_CC);
- if(!p)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to retrieve endpoint object from object store");
- return false;
- }
- if(Z_OBJCE_P(zv) != endpointClassEntry)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "value is not an endpoint");
- return false;
- }
- ice_object* obj = static_cast<ice_object*>(p);
- assert(obj->ptr);
- Ice::EndpointPtr* pe = static_cast<Ice::EndpointPtr*>(obj->ptr);
- endpoint = *pe;
- }
- return true;
-}
-
-static bool
-createConnection(zval* zv, const Ice::ConnectionPtr& p TSRMLS_DC)
-{
- if(object_init_ex(zv, connectionClassEntry) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize connection");
- return false;
- }
-
- ice_object* ze = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC));
- assert(!ze->ptr);
- ze->ptr = new Ice::ConnectionPtr(p);
-
- return true;
-}
-
-ZEND_FUNCTION(Ice_ObjectPrx___construct)
+ZEND_METHOD(Ice_ObjectPrx, __construct)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "Ice_ObjectPrx cannot be instantiated, use $ICE->stringToProxy()");
+ runtimeError("proxies cannot be instantiated, use stringToProxy()" TSRMLS_CC);
}
-ZEND_FUNCTION(Ice_ObjectPrx___tostring)
+ZEND_METHOD(Ice_ObjectPrx, __toString)
{
if(ZEND_NUM_ARGS() > 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- string str = _this->toString();
- RETURN_STRINGL(const_cast<char*>(str.c_str()), str.length(), 1);
+ string str = _this->proxy->ice_toString();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
}
catch(const IceUtil::Exception& ex)
{
@@ -400,242 +122,43 @@ ZEND_FUNCTION(Ice_ObjectPrx___tostring)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getCommunicator)
-{
- zval* zc = getCommunicatorZval(TSRMLS_C);
-
- Z_TYPE_P(return_value) = IS_OBJECT;
- return_value->value.obj = zc->value.obj;
- Z_OBJ_HT_P(return_value)->add_ref(return_value TSRMLS_CC);
-}
-
-ZEND_FUNCTION(Ice_ObjectPrx_ice_toString)
-{
- ZEND_FN(Ice_ObjectPrx___tostring)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
-
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isA)
-{
- if(ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2)
- {
- WRONG_PARAM_COUNT;
- }
-
- char* id;
- int len;
- zval* arr = 0;
-
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &id, &len, &arr) == FAILURE)
- {
- RETURN_FALSE;
- }
-
- //
- // Populate the context (if necessary).
- //
- Ice::Context ctx;
- if(arr && !extractContext(arr, ctx TSRMLS_CC))
- {
- RETURN_FALSE;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
-
- try
- {
- bool b;
- if(arr)
- {
- b = _this->getProxy()->ice_isA(id, ctx);
- }
- else
- {
- b = _this->getProxy()->ice_isA(id);
- }
-
- RETURN_BOOL(b ? 1 : 0);
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- RETVAL_FALSE;
- }
-}
-
-ZEND_FUNCTION(Ice_ObjectPrx_ice_ping)
+ZEND_METHOD(Ice_ObjectPrx, ice_getCommunicator)
{
- if(ZEND_NUM_ARGS() > 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- zval* arr = 0;
-
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &arr) == FAILURE)
- {
- RETURN_NULL();
- }
-
- //
- // Populate the context (if necessary).
- //
- Ice::Context ctx;
- if(arr && !extractContext(arr, ctx TSRMLS_CC))
- {
- RETURN_NULL();
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
-
- try
- {
- if(arr)
- {
- _this->getProxy()->ice_ping(ctx);
- }
- else
- {
- _this->getProxy()->ice_ping();
- }
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- }
-
- RETURN_NULL();
-}
-
-ZEND_FUNCTION(Ice_ObjectPrx_ice_id)
-{
- if(ZEND_NUM_ARGS() > 1)
+ if(ZEND_NUM_ARGS() > 0)
{
WRONG_PARAM_COUNT;
}
- zval* arr = 0;
-
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &arr) == FAILURE)
- {
- RETURN_NULL();
- }
-
- //
- // Populate the context (if necessary).
- //
- Ice::Context ctx;
- if(arr && !extractContext(arr, ctx TSRMLS_CC))
- {
- RETURN_NULL();
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
- try
- {
- string id;
- if(arr)
- {
- id = _this->getProxy()->ice_id(ctx);
- }
- else
- {
- id = _this->getProxy()->ice_id();
- }
- RETURN_STRINGL(const_cast<char*>(id.c_str()), id.length(), 1);
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- RETURN_NULL();
- }
+ _this->communicator->getZval(return_value TSRMLS_CC);
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_ids)
+ZEND_METHOD(Ice_ObjectPrx, ice_toString)
{
- if(ZEND_NUM_ARGS() > 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- zval* arr = 0;
-
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &arr) == FAILURE)
- {
- RETURN_NULL();
- }
-
- //
- // Populate the context (if necessary).
- //
- Ice::Context ctx;
- if(arr && !extractContext(arr, ctx TSRMLS_CC))
- {
- RETURN_NULL();
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
-
- try
- {
- vector<string> ids;
- if(arr)
- {
- ids = _this->getProxy()->ice_ids(ctx);
- }
- else
- {
- ids = _this->getProxy()->ice_ids();
- }
-
- array_init(return_value);
- uint idx = 0;
- for(vector<string>::const_iterator p = ids.begin(); p != ids.end(); ++p, ++idx)
- {
- add_index_stringl(return_value, idx, const_cast<char*>((*p).c_str()), (*p).length(), 1);
- }
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- RETURN_NULL();
- }
+ ZEND_MN(Ice_ObjectPrx___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getIdentity)
+ZEND_METHOD(Ice_ObjectPrx, ice_getIdentity)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
- createIdentity(return_value, _this->getProxy()->ice_getIdentity() TSRMLS_CC);
+ createIdentity(return_value, _this->proxy->ice_getIdentity() TSRMLS_CC);
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_identity)
+ZEND_METHOD(Ice_ObjectPrx, ice_identity)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
- zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC);
+ zend_class_entry* cls = idToClass("::Ice::Identity" TSRMLS_CC);
assert(cls);
zval *zid;
@@ -650,8 +173,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_identity)
{
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_identity(id);
- if(!createProxy(return_value, prx TSRMLS_CC))
+ if(!_this->cloneUntyped(return_value, _this->proxy->ice_identity(id) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -664,27 +186,24 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_identity)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getContext)
+ZEND_METHOD(Ice_ObjectPrx, ice_getContext)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
-
- createContext(return_value, _this->getProxy()->ice_getContext() TSRMLS_CC);
-}
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_context)
-{
- if(ZEND_NUM_ARGS() != 1)
+ if(!createStringMap(return_value, _this->proxy->ice_getContext() TSRMLS_CC))
{
- WRONG_PARAM_COUNT;
+ RETURN_NULL();
}
+}
+ZEND_METHOD(Ice_ObjectPrx, ice_context)
+{
zval* arr = 0;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE)
@@ -696,19 +215,17 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_context)
// Populate the context.
//
Ice::Context ctx;
- if(arr && !extractContext(arr, ctx TSRMLS_CC))
+ if(arr && !extractStringMap(arr, ctx TSRMLS_CC))
{
RETURN_NULL();
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_context(ctx);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_context(ctx) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -720,21 +237,20 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_context)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getFacet)
+ZEND_METHOD(Ice_ObjectPrx, ice_getFacet)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- string facet = _this->getProxy()->ice_getFacet();
- ZVAL_STRINGL(return_value, const_cast<char*>(facet.c_str()), facet.length(), 1);
+ string facet = _this->proxy->ice_getFacet();
+ ZVAL_STRINGL(return_value, STRCAST(facet.c_str()), facet.length(), 1);
}
catch(const IceUtil::Exception& ex)
{
@@ -743,13 +259,8 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getFacet)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_facet)
+ZEND_METHOD(Ice_ObjectPrx, ice_facet)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
char* name;
int len;
@@ -758,14 +269,12 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_facet)
RETURN_NULL();
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_facet(name);
- if(!createProxy(return_value, prx TSRMLS_CC))
+ if(!_this->cloneUntyped(return_value, _this->proxy->ice_facet(name) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -777,21 +286,20 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_facet)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getAdapterId)
+ZEND_METHOD(Ice_ObjectPrx, ice_getAdapterId)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- string id = _this->getProxy()->ice_getAdapterId();
- ZVAL_STRINGL(return_value, const_cast<char*>(id.c_str()), id.length(), 1);
+ string id = _this->proxy->ice_getAdapterId();
+ ZVAL_STRINGL(return_value, STRCAST(id.c_str()), id.length(), 1);
}
catch(const IceUtil::Exception& ex)
{
@@ -800,16 +308,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getAdapterId)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_adapterId)
+ZEND_METHOD(Ice_ObjectPrx, ice_adapterId)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
char* id;
int len;
@@ -821,8 +323,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_adapterId)
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_adapterId(id);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_adapterId(id) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -834,20 +335,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_adapterId)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpoints)
+ZEND_METHOD(Ice_ObjectPrx, ice_getEndpoints)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::EndpointSeq endpoints = _this->getProxy()->ice_getEndpoints();
+ Ice::EndpointSeq endpoints = _this->proxy->ice_getEndpoints();
array_init(return_value);
uint idx = 0;
@@ -870,16 +370,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpoints)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints)
+ZEND_METHOD(Ice_ObjectPrx, ice_endpoints)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
zval* zv;
@@ -901,7 +395,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints)
if(Z_TYPE_PP(val) != IS_OBJECT)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected an element of type Ice_Endpoint");
+ runtimeError("expected an element of type Ice::Endpoint" TSRMLS_CC);
RETURN_NULL();
}
@@ -918,8 +412,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints)
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_endpoints(seq);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_endpoints(seq) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -931,20 +424,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocatorCacheTimeout)
+ZEND_METHOD(Ice_ObjectPrx, ice_getLocatorCacheTimeout)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::Int timeout = _this->getProxy()->ice_getLocatorCacheTimeout();
+ Ice::Int timeout = _this->proxy->ice_getLocatorCacheTimeout();
ZVAL_LONG(return_value, static_cast<long>(timeout));
}
catch(const IceUtil::Exception& ex)
@@ -954,16 +446,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocatorCacheTimeout)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_locatorCacheTimeout)
+ZEND_METHOD(Ice_ObjectPrx, ice_locatorCacheTimeout)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
long l;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &l) != SUCCESS)
@@ -973,8 +459,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locatorCacheTimeout)
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_locatorCacheTimeout(l);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_locatorCacheTimeout(l) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -986,20 +471,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locatorCacheTimeout)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isConnectionCached)
+ZEND_METHOD(Ice_ObjectPrx, ice_isConnectionCached)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- bool b = _this->getProxy()->ice_isConnectionCached();
+ bool b = _this->proxy->ice_isConnectionCached();
ZVAL_BOOL(return_value, b ? 1 : 0);
}
catch(const IceUtil::Exception& ex)
@@ -1009,16 +493,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isConnectionCached)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionCached)
+ZEND_METHOD(Ice_ObjectPrx, ice_connectionCached)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
zend_bool b;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b) != SUCCESS)
@@ -1028,8 +506,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionCached)
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_connectionCached(b ? true : false);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_connectionCached(b ? true : false) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1041,20 +518,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionCached)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpointSelection)
+ZEND_METHOD(Ice_ObjectPrx, ice_getEndpointSelection)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::EndpointSelectionType type = _this->getProxy()->ice_getEndpointSelection();
+ Ice::EndpointSelectionType type = _this->proxy->ice_getEndpointSelection();
ZVAL_LONG(return_value, type == Ice::Random ? 0 : 1);
}
catch(const IceUtil::Exception& ex)
@@ -1064,16 +540,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpointSelection)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_endpointSelection)
+ZEND_METHOD(Ice_ObjectPrx, ice_endpointSelection)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
long l;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &l) != SUCCESS)
@@ -1083,14 +553,14 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpointSelection)
if(l < 0 || l > 1)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expecting Random or Ordered");
+ runtimeError("expecting Random or Ordered" TSRMLS_CC);
RETURN_NULL();
}
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_endpointSelection(l == 0 ? Ice::Random : Ice::Ordered);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ Ice::EndpointSelectionType type = l == 0 ? Ice::Random : Ice::Ordered;
+ if(!_this->clone(return_value, _this->proxy->ice_endpointSelection(type) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1102,20 +572,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_endpointSelection)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isSecure)
+ZEND_METHOD(Ice_ObjectPrx, ice_isSecure)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- bool b = _this->getProxy()->ice_isSecure();
+ bool b = _this->proxy->ice_isSecure();
RETURN_BOOL(b ? 1 : 0);
}
catch(const IceUtil::Exception& ex)
@@ -1125,16 +594,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isSecure)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_secure)
+ZEND_METHOD(Ice_ObjectPrx, ice_secure)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
zend_bool b;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b TSRMLS_CC) != SUCCESS)
@@ -1144,8 +607,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_secure)
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_secure(b ? true : false);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_secure(b ? true : false) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1157,20 +619,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_secure)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isPreferSecure)
+ZEND_METHOD(Ice_ObjectPrx, ice_isPreferSecure)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- bool b = _this->getProxy()->ice_isPreferSecure();
+ bool b = _this->proxy->ice_isPreferSecure();
RETURN_BOOL(b ? 1 : 0);
}
catch(const IceUtil::Exception& ex)
@@ -1180,16 +641,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isPreferSecure)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_preferSecure)
+ZEND_METHOD(Ice_ObjectPrx, ice_preferSecure)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
zend_bool b;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b TSRMLS_CC) != SUCCESS)
@@ -1199,8 +654,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_preferSecure)
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_preferSecure(b ? true : false);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_preferSecure(b ? true : false) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1212,31 +666,30 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_preferSecure)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getRouter)
+ZEND_METHOD(Ice_ObjectPrx, ice_getRouter)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::RouterPrx router = _this->getProxy()->ice_getRouter();
+ Ice::RouterPrx router = _this->proxy->ice_getRouter();
if(router)
{
- Slice::ClassDefPtr def;
- if(!lookupClass("Ice::Router", def TSRMLS_CC))
+ ClassInfoPtr info = lookupClass("::Ice::Router" TSRMLS_CC);
+ if(!info)
{
RETURN_NULL();
}
- assert(def);
+ assert(info);
- if(!createProxy(return_value, router, def TSRMLS_CC))
+ if(!createProxy(return_value, router, info, _this->communicator TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1253,16 +706,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getRouter)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_router)
+ZEND_METHOD(Ice_ObjectPrx, ice_router)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
zval* zprx;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zprx, proxyClassEntry TSRMLS_CC) != SUCCESS)
@@ -1271,7 +718,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_router)
}
Ice::ObjectPrx proxy;
- Slice::ClassDefPtr def;
+ ClassInfoPtr def;
if(zprx && !fetchProxy(zprx, proxy, def TSRMLS_CC))
{
RETURN_NULL();
@@ -1282,7 +729,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_router)
{
if(!def || !def->isA("::Ice::Router"))
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "ice_router requires a proxy narrowed to Ice::Router");
+ runtimeError("ice_router requires a proxy narrowed to Ice::Router" TSRMLS_CC);
RETURN_NULL();
}
router = Ice::RouterPrx::uncheckedCast(proxy);
@@ -1290,8 +737,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_router)
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_router(router);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_router(router) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1303,31 +749,28 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_router)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocator)
+ZEND_METHOD(Ice_ObjectPrx, ice_getLocator)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::LocatorPrx locator = _this->getProxy()->ice_getLocator();
+ Ice::LocatorPrx locator = _this->proxy->ice_getLocator();
if(locator)
{
- Slice::ClassDefPtr def;
- if(!lookupClass("Ice::Locator", def TSRMLS_CC))
+ ClassInfoPtr info = lookupClass("::Ice::Locator" TSRMLS_CC);
+ if(!info)
{
RETURN_NULL();
}
- assert(def);
-
- if(!createProxy(return_value, locator, def TSRMLS_CC))
+ if(!createProxy(return_value, locator, info, _this->communicator TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1344,16 +787,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocator)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_locator)
+ZEND_METHOD(Ice_ObjectPrx, ice_locator)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
zval* zprx;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zprx, proxyClassEntry TSRMLS_CC) != SUCCESS)
@@ -1362,7 +799,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locator)
}
Ice::ObjectPrx proxy;
- Slice::ClassDefPtr def;
+ ClassInfoPtr def;
if(zprx && !fetchProxy(zprx, proxy, def TSRMLS_CC))
{
RETURN_NULL();
@@ -1373,7 +810,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locator)
{
if(!def || !def->isA("::Ice::Locator"))
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "ice_locator requires a proxy narrowed to Ice::Locator");
+ runtimeError("ice_locator requires a proxy narrowed to Ice::Locator" TSRMLS_CC);
RETURN_NULL();
}
locator = Ice::LocatorPrx::uncheckedCast(proxy);
@@ -1381,8 +818,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locator)
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_locator(locator);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_locator(locator) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1394,21 +830,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_locator)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_twoway)
+ZEND_METHOD(Ice_ObjectPrx, ice_twoway)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_twoway();
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_twoway() TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1420,20 +854,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_twoway)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isTwoway)
+ZEND_METHOD(Ice_ObjectPrx, ice_isTwoway)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- bool b = _this->getProxy()->ice_isTwoway();
+ bool b = _this->proxy->ice_isTwoway();
RETURN_BOOL(b ? 1 : 0);
}
catch(const IceUtil::Exception& ex)
@@ -1443,21 +876,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isTwoway)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_oneway)
+ZEND_METHOD(Ice_ObjectPrx, ice_oneway)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_oneway();
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_oneway() TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1469,20 +900,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_oneway)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isOneway)
+ZEND_METHOD(Ice_ObjectPrx, ice_isOneway)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- bool b = _this->getProxy()->ice_isOneway();
+ bool b = _this->proxy->ice_isOneway();
RETURN_BOOL(b ? 1 : 0);
}
catch(const IceUtil::Exception& ex)
@@ -1492,21 +922,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isOneway)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_batchOneway)
+ZEND_METHOD(Ice_ObjectPrx, ice_batchOneway)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_batchOneway();
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_batchOneway() TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1518,20 +946,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_batchOneway)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchOneway)
+ZEND_METHOD(Ice_ObjectPrx, ice_isBatchOneway)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- bool b = _this->getProxy()->ice_isBatchOneway();
+ bool b = _this->proxy->ice_isBatchOneway();
RETURN_BOOL(b ? 1 : 0);
}
catch(const IceUtil::Exception& ex)
@@ -1541,21 +968,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchOneway)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_datagram)
+ZEND_METHOD(Ice_ObjectPrx, ice_datagram)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_datagram();
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_datagram() TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1567,20 +992,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_datagram)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isDatagram)
+ZEND_METHOD(Ice_ObjectPrx, ice_isDatagram)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- bool b = _this->getProxy()->ice_isDatagram();
+ bool b = _this->proxy->ice_isDatagram();
RETURN_BOOL(b ? 1 : 0);
}
catch(const IceUtil::Exception& ex)
@@ -1590,21 +1014,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isDatagram)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_batchDatagram)
+ZEND_METHOD(Ice_ObjectPrx, ice_batchDatagram)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_batchDatagram();
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_batchDatagram() TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1616,20 +1038,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_batchDatagram)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchDatagram)
+ZEND_METHOD(Ice_ObjectPrx, ice_isBatchDatagram)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- bool b = _this->getProxy()->ice_isBatchDatagram();
+ bool b = _this->proxy->ice_isBatchDatagram();
RETURN_BOOL(b ? 1 : 0);
}
catch(const IceUtil::Exception& ex)
@@ -1639,16 +1060,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchDatagram)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_compress)
+ZEND_METHOD(Ice_ObjectPrx, ice_compress)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
zend_bool b;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b) != SUCCESS)
@@ -1658,8 +1073,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_compress)
try
{
- Ice::ObjectPrx prx = _this->getProxy()->ice_compress(b ? true : false);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_compress(b ? true : false) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1671,16 +1085,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_compress)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout)
+ZEND_METHOD(Ice_ObjectPrx, ice_timeout)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
@@ -1690,8 +1098,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout)
RETURN_NULL();
}
// TODO: range check?
- Ice::ObjectPrx prx = _this->getProxy()->ice_timeout(l);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_timeout(l) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1703,16 +1110,10 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionId)
+ZEND_METHOD(Ice_ObjectPrx, ice_connectionId)
{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
@@ -1722,8 +1123,7 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionId)
{
RETURN_NULL();
}
- Ice::ObjectPrx prx = _this->getProxy()->ice_connectionId(id);
- if(!createProxy(return_value, prx, _this->getClass() TSRMLS_CC))
+ if(!_this->clone(return_value, _this->proxy->ice_connectionId(id) TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1735,20 +1135,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionId)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getConnection)
+ZEND_METHOD(Ice_ObjectPrx, ice_getConnection)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::ConnectionPtr con = _this->getProxy()->ice_getConnection();
+ Ice::ConnectionPtr con = _this->proxy->ice_getConnection();
if(!createConnection(return_value, con TSRMLS_CC))
{
RETURN_NULL();
@@ -1761,20 +1160,19 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getConnection)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getCachedConnection)
+ZEND_METHOD(Ice_ObjectPrx, ice_getCachedConnection)
{
if(ZEND_NUM_ARGS() != 0)
{
WRONG_PARAM_COUNT;
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
try
{
- Ice::ConnectionPtr con = _this->getProxy()->ice_getCachedConnection();
+ Ice::ConnectionPtr con = _this->proxy->ice_getCachedConnection();
if(!con || !createConnection(return_value, con TSRMLS_CC))
{
RETURN_NULL();
@@ -1787,88 +1185,28 @@ ZEND_FUNCTION(Ice_ObjectPrx_ice_getCachedConnection)
}
}
-static bool
-lookupClass(const string& id, Slice::ClassDefPtr& def TSRMLS_DC)
+static ClassInfoPtr
+lookupClass(const string& id TSRMLS_DC)
{
- def = 0;
-
- try
+ ClassInfoPtr info = getClassInfoById(id TSRMLS_CC);
+ if(!info)
{
- Slice::TypePtr type;
- Profile* profile = static_cast<Profile*>(ICE_G(profile));
- if(profile)
- {
- type = profile->lookupType(id);
- }
-
- if(!type)
+ if(!id.empty() && id[id.size() - 1] == '*')
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "no Slice definition found for type %s", id.c_str());
- return false;
+ info = getClassInfoById(id.substr(0, id.size() - 1) TSRMLS_CC);
}
+ }
- Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type);
- if(b && b->kind() != Slice::Builtin::KindObject && b->kind() != Slice::Builtin::KindObjectProxy)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "type %s is not a class or interface", id.c_str());
- return false;
- }
-
- if(!b)
- {
- //
- // Allow the use of "::Type" (ClassDecl) or "::Type*" (Proxy).
- //
- Slice::ClassDeclPtr decl;
- Slice::ProxyPtr proxy = Slice::ProxyPtr::dynamicCast(type);
- if(proxy)
- {
- decl = proxy->_class();
- }
- else
- {
- decl = Slice::ClassDeclPtr::dynamicCast(type);
- }
-
- if(!decl)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "type %s is not a class or interface", id.c_str());
- return false;
- }
-
- if(decl->isLocal())
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "%s is a local type", id.c_str());
- return false;
- }
-
- def = decl->definition();
- if(!def)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "%s is declared but not defined", id.c_str());
- return false;
- }
-
- string scoped = decl->scoped();
-
- //
- // Verify that the script has compiled the Slice definition for this type.
- //
- if(findClassScoped(scoped TSRMLS_CC) == 0)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "the Slice definition for type %s has not been compiled",
- scoped.c_str());
- return false;
- }
- }
+ if(info && !info->defined)
+ {
+ runtimeError("%s is declared but not defined" TSRMLS_CC, id.c_str());
}
- catch(const IceUtil::Exception& ex)
+ else if(!info)
{
- throwException(ex TSRMLS_CC);
- return false;
+ runtimeError("no definition found for class or interface %s" TSRMLS_CC, id.c_str());
}
- return true;
+ return info;
}
static void
@@ -1889,11 +1227,11 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
int facetLen;
zval* arr = 0;
- if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|sa", &id, &idLen, &facet,
+ if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|s!a!", &id, &idLen, &facet,
&facetLen, &arr) == FAILURE)
{
facet = 0;
- if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &id, &idLen, &arr) ==
+ if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|a!", &id, &idLen, &arr) ==
FAILURE)
{
php_error(E_ERROR, "%s() requires a type id followed by an optional facet and/or context",
@@ -1902,28 +1240,27 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
}
}
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
+ assert(_this);
//
// Populate the context.
//
Ice::Context ctx;
- if(arr && !extractContext(arr, ctx TSRMLS_CC))
+ if(arr && !extractStringMap(arr, ctx TSRMLS_CC))
{
RETURN_NULL();
}
try
{
- Slice::ClassDefPtr def;
- if(!lookupClass(id, def TSRMLS_CC))
+ ClassInfoPtr info = lookupClass(id TSRMLS_CC);
+ if(!info)
{
RETURN_NULL();
}
- Ice::ObjectPrx prx = _this->getProxy();
+ Ice::ObjectPrx prx = _this->proxy;
if(facet)
{
prx = prx->ice_facet(facet);
@@ -1936,19 +1273,16 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
if(check)
{
- string scoped = def ? def->declaration()->scoped() : "::Ice::Object";
-
//
- // Verify that the object supports the requested type. We don't use id here,
- // because it might contain a proxy type (e.g., "::MyClass*").
+ // Verify that the object supports the requested type.
//
- if(!prx->ice_isA(scoped))
+ if(!prx->ice_isA(info->id))
{
RETURN_NULL();
}
}
- if(!createProxy(return_value, prx, def TSRMLS_CC))
+ if(!createProxy(return_value, prx, info, _this->communicator TSRMLS_CC))
{
RETURN_NULL();
}
@@ -1960,601 +1294,94 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_uncheckedCast)
+ZEND_METHOD(Ice_ObjectPrx, ice_uncheckedCast)
{
do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
}
-ZEND_FUNCTION(Ice_ObjectPrx_ice_checkedCast)
+ZEND_METHOD(Ice_ObjectPrx, ice_checkedCast)
{
do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
}
-ZEND_FUNCTION(Ice_Endpoint___construct)
-{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "Ice_Endpoint cannot be instantiated");
-}
-
-ZEND_FUNCTION(Ice_Endpoint___tostring)
-{
- if(ZEND_NUM_ARGS() > 0)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Ice::EndpointPtr* _this = static_cast<Ice::EndpointPtr*>(obj->ptr);
-
- try
- {
- string str = (*_this)->toString();
- RETURN_STRINGL(const_cast<char*>(str.c_str()), str.length(), 1);
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- RETURN_NULL();
- }
-}
-
-ZEND_FUNCTION(Ice_Endpoint_toString)
-{
- ZEND_FN(Ice_Endpoint___tostring)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
-
-ZEND_FUNCTION(Ice_Connection___construct)
-{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "Ice_Connection cannot be instantiated");
-}
-
-ZEND_FUNCTION(Ice_Connection___tostring)
-{
- if(ZEND_NUM_ARGS() > 0)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr);
-
- try
- {
- string str = (*_this)->toString();
- RETURN_STRINGL(const_cast<char*>(str.c_str()), str.length(), 1);
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- RETURN_NULL();
- }
-}
-
-ZEND_FUNCTION(Ice_Connection_close)
-{
- if(ZEND_NUM_ARGS() != 1)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr);
-
- zend_bool b;
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &b TSRMLS_CC) != SUCCESS)
- {
- RETURN_NULL();
- }
-
- try
- {
- (*_this)->close(b ? true : false);
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- RETURN_NULL();
- }
-}
-
-ZEND_FUNCTION(Ice_Connection_flushBatchRequests)
-{
- if(ZEND_NUM_ARGS() > 0)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr);
-
- try
- {
- (*_this)->flushBatchRequests();
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- RETURN_NULL();
- }
-}
-
-ZEND_FUNCTION(Ice_Connection_type)
-{
- if(ZEND_NUM_ARGS() > 0)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr);
-
- try
- {
- string str = (*_this)->type();
- RETURN_STRINGL(const_cast<char*>(str.c_str()), str.length(), 1);
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- RETURN_NULL();
- }
-}
-
-ZEND_FUNCTION(Ice_Connection_timeout)
-{
- if(ZEND_NUM_ARGS() != 0)
- {
- WRONG_PARAM_COUNT;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr);
-
- try
- {
- Ice::Int timeout = (*_this)->timeout();
- ZVAL_LONG(return_value, static_cast<long>(timeout));
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- RETURN_NULL();
- }
-}
-
-ZEND_FUNCTION(Ice_Connection_toString)
-{
- ZEND_FN(Ice_Connection___tostring)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
-
-IcePHP::Operation::Operation(const Ice::ObjectPrx& proxy, const string& name, const Slice::OperationPtr& op,
- const Ice::CommunicatorPtr& communicator TSRMLS_DC) :
- _proxy(proxy), _name(name), _op(op), _communicator(communicator), _zendFunction(0)
+IcePHP::Proxy::Proxy(const Ice::ObjectPrx& p, const ClassInfoPtr& i, const CommunicatorInfoPtr& comm TSRMLS_DC) :
+ proxy(p), info(i), communicator(comm), connection(0), cachedConnection(0)
{
#ifdef ZTS
this->TSRMLS_C = TSRMLS_C;
#endif
- //
- // Create Marshaler objects for return type and parameters.
- //
- Slice::TypePtr ret = op->returnType();
- if(ret)
- {
- _result = Marshaler::createMarshaler(ret TSRMLS_CC);
- if(!_result)
- {
- return;
- }
- }
- Slice::ParamDeclList params = op->parameters();
-
- //
- // Create an array that indicates how arguments are passed to the operation.
//
- zend_arg_info* argInfo = new zend_arg_info[params.size()];
-
- int i;
- Slice::ParamDeclList::const_iterator p;
- for(p = params.begin(), i = 0; p != params.end(); ++p, ++i)
- {
- Slice::TypePtr paramType = (*p)->type();
- MarshalerPtr m = Marshaler::createMarshaler(paramType TSRMLS_CC);
- if(!m)
- {
- break;
- }
- _paramNames.push_back((*p)->name());
- argInfo[i].name = 0;
- argInfo[i].class_name = 0;
- argInfo[i].allow_null = 1;
- Slice::ContainedPtr cont = Slice::ContainedPtr::dynamicCast(paramType);
- if(cont)
- {
- argInfo[i].array_type_hint = ((cont->containedType() == Slice::Contained::ContainedTypeSequence ||
- cont->containedType() == Slice::Contained::ContainedTypeDictionary) ? 1 : 0);
- }
- else
- {
- argInfo[i].array_type_hint = 0;
- }
- argInfo[i].return_reference = 0;
- argInfo[i].required_num_args = static_cast<zend_uint>(params.size());
- if((*p)->isOutParam())
- {
- argInfo[i].pass_by_reference = 1;
- _outParams.push_back(m);
- }
- else
- {
- argInfo[i].pass_by_reference = 0;
- _inParams.push_back(m);
- }
- }
-
- _zendFunction = static_cast<zend_internal_function*>(emalloc(sizeof(zend_internal_function)));
- _zendFunction->type = ZEND_INTERNAL_FUNCTION;
- _zendFunction->function_name = estrndup(const_cast<char*>(name.c_str()), name.length());
- _zendFunction->scope = proxyClassEntry;
- _zendFunction->fn_flags = ZEND_ACC_PUBLIC;
- _zendFunction->prototype = 0;
- _zendFunction->num_args = static_cast<zend_uint>(params.size());
- _zendFunction->arg_info = argInfo;
- _zendFunction->pass_rest_by_reference = 0;
- _zendFunction->required_num_args = _zendFunction->num_args;
- _zendFunction->return_reference = 0;
- _zendFunction->handler = ZEND_FN(Ice_ObjectPrx_call);
-}
-
-IcePHP::Operation::~Operation()
-{
- if(_zendFunction)
- {
- delete []_zendFunction->arg_info;
- efree(_zendFunction->function_name);
- efree(_zendFunction);
- }
-}
-
-zend_function*
-IcePHP::Operation::getZendFunction() const
-{
- return reinterpret_cast<zend_function*>(_zendFunction);
-}
-
-void
-IcePHP::Operation::invoke(INTERNAL_FUNCTION_PARAMETERS)
-{
- Ice::OperationMode mode = (Ice::OperationMode)_op->sendMode();
- int i;
-
- //
- // Verify that the expected number of arguments are supplied. The context argument is optional.
- //
- int numParams = static_cast<int>(_inParams.size() + _outParams.size());
- if(ZEND_NUM_ARGS() != numParams && ZEND_NUM_ARGS() != numParams + 1)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "incorrect number of parameters (%d)", numParams);
- return;
- }
-
- //
- // Retrieve the arguments.
- //
- zval*** args = static_cast<zval***>(emalloc(ZEND_NUM_ARGS() * sizeof(zval**)));
- AutoEfree autoArgs(args); // Call efree on return
- if(zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to get arguments");
- return;
- }
-
- //
- // Verify that the zvals for out parameters are passed by reference.
+ // We want to ensure that the PHP object corresponding to the communicator is
+ // not destroyed until after this proxy is destroyed.
//
- for(i = static_cast<int>(_inParams.size()); i < numParams; ++i)
- {
- if(!PZVAL_IS_REF(*args[i]))
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "argument for out parameter %s must be passed by reference",
- _paramNames[i].c_str());
- return;
- }
- }
-
- try
- {
- //
- // Marshal the arguments.
- //
- Ice::OutputStreamPtr os = Ice::createOutputStream(_communicator);
- ObjectMap objectMap;
- vector<MarshalerPtr>::iterator p;
- for(i = 0, p = _inParams.begin(); p != _inParams.end(); ++i, ++p)
- {
- if(!(*p)->marshal(*args[i], os, objectMap TSRMLS_CC))
- {
- return;
- }
- }
-
- if(_op->sendsClasses())
- {
- os->writePendingObjects();
- }
-
- Ice::ByteSeq params;
- os->finished(params);
-
- //
- // Populate the context (if necessary).
- //
- Ice::Context ctx;
- bool haveContext = false;
- if(ZEND_NUM_ARGS() == numParams + 1)
- {
- if(extractContext(*args[numParams], ctx TSRMLS_CC))
- {
- haveContext = true;
- }
- else
- {
- return;
- }
- }
-
- //
- // Invoke the operation. Don't use _name here.
- //
- Ice::ByteSeq result;
- bool status;
- if(haveContext)
- {
- status = _proxy->ice_invoke(_op->name(), mode, params, result, ctx);
- }
- else
- {
- status = _proxy->ice_invoke(_op->name(), mode, params, result);
- }
-
- //
- // Process the reply.
- //
- if(_proxy->ice_isTwoway())
- {
- Ice::InputStreamPtr is = Ice::createInputStream(_communicator, result);
-
- if(status)
- {
- //
- // Unmarshal the results.
- //
- // TODO: Check for oneway/datagram errors
- //
- for(i = _inParams.size(), p = _outParams.begin(); p != _outParams.end(); ++i, ++p)
- {
- //
- // We must explicitly destroy the existing contents of all zvals passed
- // as out parameters, otherwise leaks occur.
- //
- zval_dtor(*args[i]);
- if(!(*p)->unmarshal(*args[i], is TSRMLS_CC))
- {
- return;
- }
- }
- if(_result)
- {
- if(!_result->unmarshal(return_value, is TSRMLS_CC))
- {
- return;
- }
- }
- if(_op->returnsClasses())
- {
- is->readPendingObjects();
- }
- }
- else
- {
- //
- // Unmarshal and "throw" a user exception.
- //
- throwUserException(is TSRMLS_CC);
- }
- }
- }
- catch(const AbortMarshaling&)
- {
- //
- // We use AbortMarshaling to escape from any nesting depth if
- // a PHP exception has already been set.
- //
- assert(EG(exception));
- }
- catch(const IceUtil::Exception& ex)
- {
- throwException(ex TSRMLS_CC);
- }
+ communicator->addRef(TSRMLS_C);
}
-void
-IcePHP::Operation::throwUserException(Ice::InputStreamPtr& is TSRMLS_DC)
+IcePHP::Proxy::~Proxy()
{
- Slice::UnitPtr unit = _op->unit();
-
- is->readBool(); // usesClasses
-
- string id = is->readString();
- const string origId = id;
-
- while(!id.empty())
+ communicator->decRef(TSRMLS_C);
+ if(connection)
{
- //
- // Look for a definition of this type.
- //
- Slice::ExceptionPtr ex = unit->lookupException(id, false);
- if(ex)
- {
- if(ex->isLocal())
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "cannot unmarshal local exception %s", id.c_str());
- return;
- }
-
- MarshalerPtr m = Marshaler::createExceptionMarshaler(ex TSRMLS_CC);
- assert(m);
-
- zval* zex;
- MAKE_STD_ZVAL(zex);
- if(m->unmarshal(zex, is TSRMLS_CC))
- {
- if(ex->usesClasses())
- {
- is->readPendingObjects();
- }
- zend_throw_exception_object(zex TSRMLS_CC);
- }
- else
- {
- zval_dtor(zex);
- }
-
- return;
- }
- else
- {
- is->skipSlice();
-
- try
- {
- id = is->readString();
- }
- catch(Ice::UnmarshalOutOfBoundsException& ex)
- {
- //
- // When readString raises this exception it means we've reached the last slice,
- // so we set the reason member to a more helpful value.
- //
- ex.reason = "unknown exception type `" + origId + "'";
- throw;
- }
- }
+ zval_ptr_dtor(&connection);
}
- //
- // Getting here should be impossible: we can get here only if the
- // sender has marshaled a sequence of type IDs, none of which we
- // have a factory for. This means that sender and receiver disagree
- // about the Slice definitions they use.
- //
- throw Ice::UnknownUserException(__FILE__, __LINE__);
-}
-
-IcePHP::Proxy::Proxy(const Ice::ObjectPrx& proxy, const Slice::ClassDefPtr& cls TSRMLS_DC) :
- _proxy(proxy), _class(cls)
-{
-#ifdef ZTS
- this->TSRMLS_C = TSRMLS_C;
-#endif
-
- //
- // We want to ensure that the PHP object corresponding to the communicator is
- // not destroyed until after this proxy is destroyed. We keep a copy of the
- // communicator's zval because the symbol table holding the communicator's zval
- // may be destroyed before this proxy, therefore our destructor cannot rely on
- // symbol table lookup when it needs to decrement the reference count.
- //
- zval* zc = getCommunicatorZval(TSRMLS_C);
- _communicatorZval = *zc; // This is legal - it simply copies the object's handle
- Z_OBJ_HT(_communicatorZval)->add_ref(&_communicatorZval TSRMLS_CC);
-
- _communicator = getCommunicator(TSRMLS_C);
-
- if(cls)
+ if(cachedConnection)
{
- _classOps = _class->allOperations();
+ zval_ptr_dtor(&cachedConnection);
}
}
-IcePHP::Proxy::~Proxy()
-{
- //
- // In order to avoid the communicator's "leak warning", we have to ensure that we
- // remove any references to the communicator or its supporting objects. This must
- // be done prior to invoking del_ref(), because the C++ communicator object may
- // be destroyed during this call.
- //
- _communicator = 0;
- _ops.clear();
- _proxy = 0;
- Z_OBJ_HT(_communicatorZval)->del_ref(&_communicatorZval TSRMLS_CC);
-}
-
-const Ice::ObjectPrx&
-IcePHP::Proxy::getProxy() const
+bool
+IcePHP::Proxy::clone(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC)
{
- return _proxy;
+ return create(zv, p, info, communicator TSRMLS_CC);
}
-const Slice::ClassDefPtr&
-IcePHP::Proxy::getClass() const
+bool
+IcePHP::Proxy::cloneUntyped(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC)
{
- return _class;
+ return create(zv, p, 0, communicator TSRMLS_CC);
}
-OperationPtr
-IcePHP::Proxy::getOperation(const string& name)
+bool
+IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm
+ TSRMLS_DC)
{
- OperationPtr result;
-
- string n = lowerCase(name);
- map<string, OperationPtr>::const_iterator p = _ops.find(n);
- if(p == _ops.end())
+ ClassInfoPtr cls = info;
+ if(!cls)
{
- for(Slice::OperationList::const_iterator q = _classOps.begin(); q != _classOps.end(); ++q)
- {
- string opName = lowerCase(fixIdent((*q)->name()));
- if(n == opName)
- {
- result = new Operation(_proxy, opName, *q, _communicator TSRMLS_CC);
- _ops[opName] = result;
- break;
- }
- }
+ cls = getClassInfoById("::Ice::Object" TSRMLS_CC);
+ assert(cls);
}
- else
+
+ if(object_init_ex(zv, proxyClassEntry) != SUCCESS)
{
- result = p->second;
+ runtimeError("unable to initialize proxy" TSRMLS_CC);
+ return false;
}
- return result;
-}
+ Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv TSRMLS_CC);
+ ProxyPtr proxy = new Proxy(p, cls, comm TSRMLS_CC);
+ assert(!obj->ptr);
+ obj->ptr = new ProxyPtr(proxy);
-string
-IcePHP::Proxy::toString() const
-{
- return _communicator->proxyToString(_proxy);
+ return true;
}
#ifdef _WIN32
extern "C"
#endif
static zend_object_value
-handleProxyAlloc(zend_class_entry* ce TSRMLS_DC)
+handleAlloc(zend_class_entry* ce TSRMLS_DC)
{
zend_object_value result;
- ice_object* obj = newObject(ce TSRMLS_CC);
+ Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::create(ce TSRMLS_CC);
assert(obj);
- result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleProxyFreeStorage,
+ result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage,
0 TSRMLS_CC);
- result.handlers = &_proxyHandlers;
+ result.handlers = &_handlers;
return result;
}
@@ -2563,13 +1390,10 @@ handleProxyAlloc(zend_class_entry* ce TSRMLS_DC)
extern "C"
#endif
static void
-handleProxyFreeStorage(void* p TSRMLS_DC)
+handleFreeStorage(void* p TSRMLS_DC)
{
- ice_object* obj = static_cast<ice_object*>(p);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
-
- delete _this;
-
+ Wrapper<ProxyPtr>* obj = static_cast<Wrapper<ProxyPtr>*>(p);
+ delete obj->ptr;
zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
}
@@ -2577,7 +1401,7 @@ handleProxyFreeStorage(void* p TSRMLS_DC)
extern "C"
#endif
static zend_object_value
-handleProxyClone(zval* zv TSRMLS_DC)
+handleClone(zval* zv TSRMLS_DC)
{
//
// Create a new object that shares a C++ proxy instance with this object.
@@ -2586,22 +1410,16 @@ handleProxyClone(zval* zv TSRMLS_DC)
zend_object_value result;
memset(&result, 0, sizeof(zend_object_value));
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr obj = Wrapper<ProxyPtr>::value(zv TSRMLS_CC);
+ assert(obj);
zval* clone;
MAKE_STD_ZVAL(clone);
- if(object_init_ex(clone, IcePHP::proxyClassEntry) != SUCCESS)
+ if(!obj->clone(clone, obj->proxy TSRMLS_CC))
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize proxy");
return result;
}
- ice_object* cobj = static_cast<ice_object*>(zend_object_store_get_object(clone TSRMLS_CC));
- assert(!cobj->ptr);
- cobj->ptr = new Proxy(_this->getProxy(), _this->getClass() TSRMLS_CC);
-
//
// We only need to return the new object's handle, so we must destroy the zval containing
// a reference to the new object. We increment the object's reference count to ensure it
@@ -2619,7 +1437,7 @@ handleProxyClone(zval* zv TSRMLS_DC)
extern "C"
#endif
static union _zend_function*
-handleProxyGetMethod(zval** zv, char* method, int len TSRMLS_DC)
+handleGetMethod(zval** zv, char* method, int len TSRMLS_DC)
{
zend_function* result;
@@ -2631,27 +1449,23 @@ handleProxyGetMethod(zval** zv, char* method, int len TSRMLS_DC)
result = zend_get_std_object_handlers()->get_method(zv, method, len TSRMLS_CC);
if(!result)
{
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(*zv TSRMLS_CC));
+ Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(*zv TSRMLS_CC);
assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
+ ProxyPtr _this = *obj->ptr;
- Slice::ClassDefPtr def = _this->getClass();
- if(!def)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unknown method %s invoked on untyped proxy", method);
- return 0;
- }
+ ClassInfoPtr info = _this->info;
+ assert(info);
- OperationPtr op = _this->getOperation(method);
+ OperationPtr op = info->getOperation(method);
if(!op)
{
- string scoped = def->scoped();
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unknown operation %s invoked on proxy of type %s", method,
- scoped.c_str());
+ //
+ // Returning 0 causes PHP to report an "undefined method" error.
+ //
return 0;
}
- result = op->getZendFunction();
+ result = op->function();
}
return result;
@@ -2661,21 +1475,21 @@ handleProxyGetMethod(zval** zv, char* method, int len TSRMLS_DC)
extern "C"
#endif
static int
-handleProxyCompare(zval* zobj1, zval* zobj2 TSRMLS_DC)
+handleCompare(zval* zobj1, zval* zobj2 TSRMLS_DC)
{
//
// PHP guarantees that the objects have the same class.
//
- ice_object* obj1 = static_cast<ice_object*>(zend_object_store_get_object(zobj1 TSRMLS_CC));
+ Wrapper<ProxyPtr>* obj1 = Wrapper<ProxyPtr>::extract(zobj1 TSRMLS_CC);
assert(obj1->ptr);
- Proxy* _this1 = static_cast<Proxy*>(obj1->ptr);
- Ice::ObjectPrx prx1 = _this1->getProxy();
+ ProxyPtr _this1 = *obj1->ptr;
+ Ice::ObjectPrx prx1 = _this1->proxy;
- ice_object* obj2 = static_cast<ice_object*>(zend_object_store_get_object(zobj2 TSRMLS_CC));
+ Wrapper<ProxyPtr>* obj2 = Wrapper<ProxyPtr>::extract(zobj2 TSRMLS_CC);
assert(obj2->ptr);
- Proxy* _this2 = static_cast<Proxy*>(obj2->ptr);
- Ice::ObjectPrx prx2 = _this2->getProxy();
+ ProxyPtr _this2 = *obj2->ptr;
+ Ice::ObjectPrx prx2 = _this2->proxy;
if(prx1 == prx2)
{
@@ -2691,112 +1505,122 @@ handleProxyCompare(zval* zobj1, zval* zobj2 TSRMLS_DC)
}
}
-ZEND_FUNCTION(Ice_ObjectPrx_call)
+//
+// Predefined methods for ObjectPrx.
+//
+static function_entry _proxyMethods[] =
{
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(getThis() TSRMLS_CC));
- assert(obj->ptr);
- Proxy* _this = static_cast<Proxy*>(obj->ptr);
-
- OperationPtr op = _this->getOperation(get_active_function_name(TSRMLS_C));
- assert(op); // handleGetethod should have already verified the operation's existence.
-
- op->invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
+ ZEND_ME(Ice_ObjectPrx, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ ZEND_ME(Ice_ObjectPrx, __toString, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getCommunicator, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_toString, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getIdentity, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_identity, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getContext, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_context, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getFacet, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_facet, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getAdapterId, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_adapterId, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getEndpoints, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_endpoints, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getLocatorCacheTimeout, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_locatorCacheTimeout, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_isConnectionCached, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_connectionCached, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getEndpointSelection, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_endpointSelection, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_isSecure, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_secure, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_isPreferSecure, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_preferSecure, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getRouter, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_router, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getLocator, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_locator, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_twoway, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_isTwoway, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_oneway, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_isOneway, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_batchOneway, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_isBatchOneway, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_datagram, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_isDatagram, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_batchDatagram, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_isBatchDatagram, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_compress, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_timeout, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_connectionId, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getConnection, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_getCachedConnection, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_uncheckedCast, NULL, ZEND_ACC_PUBLIC)
+ ZEND_ME(Ice_ObjectPrx, ice_checkedCast, NULL, ZEND_ACC_PUBLIC)
+ {0, 0, 0}
+};
-#ifdef _WIN32
-extern "C"
-#endif
-static zend_object_value
-handleEndpointAlloc(zend_class_entry* ce TSRMLS_DC)
+bool
+IcePHP::proxyInit(TSRMLS_D)
{
- zend_object_value result;
-
- ice_object* obj = newObject(ce TSRMLS_CC);
- assert(obj);
-
- result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleEndpointFreeStorage,
- 0 TSRMLS_CC);
- result.handlers = &_endpointHandlers;
+ //
+ // Register the ObjectPrx class.
+ //
+ zend_class_entry ce;
+#ifdef ICEPHP_USE_NAMESPACES
+ INIT_NS_CLASS_ENTRY(ce, STRCAST("Ice"), STRCAST("ObjectPrx"), _proxyMethods);
+#else
+ INIT_CLASS_ENTRY(ce, "Ice_ObjectPrx", _proxyMethods);
+#endif
+ ce.create_object = handleAlloc;
+ proxyClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
+ //proxyClassEntry->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
+ memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ _handlers.clone_obj = handleClone;
+ _handlers.get_method = handleGetMethod;
+ _handlers.compare_objects = handleCompare;
- return result;
+ return true;
}
-#ifdef _WIN32
-extern "C"
-#endif
-static void
-handleEndpointFreeStorage(void* p TSRMLS_DC)
+bool
+IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const CommunicatorInfoPtr& comm TSRMLS_DC)
{
- ice_object* obj = static_cast<ice_object*>(p);
- Ice::EndpointPtr* _this = static_cast<Ice::EndpointPtr*>(obj->ptr);
-
- delete _this;
-
- zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
+ return Proxy::create(zv, p, 0, comm TSRMLS_CC);
}
-#ifdef _WIN32
-extern "C"
-#endif
-static zend_object_value
-handleConnectionAlloc(zend_class_entry* ce TSRMLS_DC)
+bool
+IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm
+ TSRMLS_DC)
{
- zend_object_value result;
-
- ice_object* obj = newObject(ce TSRMLS_CC);
- assert(obj);
-
- result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleConnectionFreeStorage,
- 0 TSRMLS_CC);
- result.handlers = &_connectionHandlers;
-
- return result;
+ return Proxy::create(zv, p, info, comm TSRMLS_CC);
}
-#ifdef _WIN32
-extern "C"
-#endif
-static void
-handleConnectionFreeStorage(void* p TSRMLS_DC)
+bool
+IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls TSRMLS_DC)
{
- ice_object* obj = static_cast<ice_object*>(p);
- Ice::ConnectionPtr* _this = static_cast<Ice::ConnectionPtr*>(obj->ptr);
-
- delete _this;
-
- zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
+ CommunicatorInfoPtr comm;
+ return fetchProxy(zv, prx, cls, comm TSRMLS_CC);
}
-#ifdef _WIN32
-extern "C"
-#endif
-static int
-handleConnectionCompare(zval* zobj1, zval* zobj2 TSRMLS_DC)
+bool
+IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls, CommunicatorInfoPtr& comm TSRMLS_DC)
{
- //
- // PHP guarantees that the objects have the same class.
- //
-
- ice_object* obj1 = static_cast<ice_object*>(zend_object_store_get_object(zobj1 TSRMLS_CC));
- assert(obj1->ptr);
- Ice::ConnectionPtr* _this1 = static_cast<Ice::ConnectionPtr*>(obj1->ptr);
- Ice::ConnectionPtr con1 = *_this1;
-
- ice_object* obj2 = static_cast<ice_object*>(zend_object_store_get_object(zobj2 TSRMLS_CC));
- assert(obj2->ptr);
- Ice::ConnectionPtr* _this2 = static_cast<Ice::ConnectionPtr*>(obj2->ptr);
- Ice::ConnectionPtr con2 = *_this2;
-
- if(con1 == con2)
- {
- return 0;
- }
- else if(con1 < con2)
- {
- return -1;
- }
- else
+ if(!ZVAL_IS_NULL(zv))
{
- return 1;
+ if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != proxyClassEntry)
+ {
+ invalidArgument("value is not a proxy" TSRMLS_CC);
+ return false;
+ }
+ Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv TSRMLS_CC);
+ if(!obj)
+ {
+ runtimeError("unable to retrieve proxy object from object store" TSRMLS_CC);
+ return false;
+ }
+ assert(obj->ptr);
+ prx = (*obj->ptr)->proxy;
+ cls = (*obj->ptr)->info;
+ comm = (*obj->ptr)->communicator;
}
+ return true;
}
diff --git a/php/src/IcePHP/Proxy.h b/php/src/IcePHP/Proxy.h
index e99a19a0b95..99197dd6649 100644
--- a/php/src/IcePHP/Proxy.h
+++ b/php/src/IcePHP/Proxy.h
@@ -7,152 +7,22 @@
//
// **********************************************************************
-#ifndef ICE_PHP_PROXY_H
-#define ICE_PHP_PROXY_H
+#ifndef ICEPHP_PROXY_H
+#define ICEPHP_PROXY_H
#include <Config.h>
-
-//
-// Ice_ObjectPrx class methods.
-//
-extern "C"
-{
-ZEND_FUNCTION(Ice_ObjectPrx___construct);
-ZEND_FUNCTION(Ice_ObjectPrx___tostring);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getCommunicator);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_toString);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isA);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_ping);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_id);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_ids);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getIdentity);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_identity);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getContext);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_context);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getFacet);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_facet);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getAdapterId);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_adapterId);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpoints);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_endpoints);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocatorCacheTimeout);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_locatorCacheTimeout);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isConnectionCached);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionCached);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getEndpointSelection);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_endpointSelection);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isSecure);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_secure);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isPreferSecure);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_preferSecure);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getRouter);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_router);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getLocator);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_locator);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_twoway);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isTwoway);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_oneway);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isOneway);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_batchOneway);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchOneway);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_datagram);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isDatagram);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_batchDatagram);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_isBatchDatagram);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_compress);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_timeout);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_connectionId);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getConnection);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_getCachedConnection);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_uncheckedCast);
-ZEND_FUNCTION(Ice_ObjectPrx_ice_checkedCast);
-
-ZEND_FUNCTION(Ice_Endpoint___construct);
-ZEND_FUNCTION(Ice_Endpoint___tostring);
-ZEND_FUNCTION(Ice_Endpoint_toString);
-
-ZEND_FUNCTION(Ice_Connection___construct);
-ZEND_FUNCTION(Ice_Connection___tostring);
-ZEND_FUNCTION(Ice_Connection_close);
-ZEND_FUNCTION(Ice_Connection_flushBatchRequests);
-ZEND_FUNCTION(Ice_Connection_type);
-ZEND_FUNCTION(Ice_Connection_timeout);
-ZEND_FUNCTION(Ice_Connection_toString);
-}
-
-#define ICE_PHP_PROXY_FUNCTIONS \
- ZEND_FE(Ice_ObjectPrx___construct, NULL) \
- ZEND_FE(Ice_ObjectPrx___tostring, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getCommunicator, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_toString, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_isA, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_ping, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_id, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_ids, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getIdentity, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_identity, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getContext, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_context, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getFacet, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_facet, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getAdapterId, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_adapterId, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getEndpoints, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_endpoints, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getLocatorCacheTimeout, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_locatorCacheTimeout, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_isConnectionCached, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_connectionCached, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getEndpointSelection, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_endpointSelection, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_isSecure, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_secure, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_isPreferSecure, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_preferSecure, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getRouter, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_router, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getLocator, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_locator, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_twoway, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_isTwoway, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_oneway, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_isOneway, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_batchOneway, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_isBatchOneway, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_datagram, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_isDatagram, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_batchDatagram, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_isBatchDatagram, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_compress, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_timeout, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_connectionId, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getConnection, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_getCachedConnection, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_uncheckedCast, NULL) \
- ZEND_FE(Ice_ObjectPrx_ice_checkedCast, NULL)
-
-#define ICE_PHP_ENDPOINT_FUNCTIONS \
- ZEND_FE(Ice_Endpoint___construct, NULL) \
- ZEND_FE(Ice_Endpoint___tostring, NULL) \
- ZEND_FE(Ice_Endpoint_toString, NULL)
-
-#define ICE_PHP_CONNECTION_FUNCTIONS \
- ZEND_FE(Ice_Connection___construct, NULL) \
- ZEND_FE(Ice_Connection___tostring, NULL) \
- ZEND_FE(Ice_Connection_close, NULL) \
- ZEND_FE(Ice_Connection_flushBatchRequests, NULL) \
- ZEND_FE(Ice_Connection_type, NULL) \
- ZEND_FE(Ice_Connection_timeout, NULL) \
- ZEND_FE(Ice_Connection_toString, NULL)
+#include <Communicator.h>
+#include <Types.h>
namespace IcePHP
{
bool proxyInit(TSRMLS_D);
-bool createProxy(zval*, const Ice::ObjectPrx& TSRMLS_DC);
-bool createProxy(zval*, const Ice::ObjectPrx&, const Slice::ClassDefPtr& TSRMLS_DC);
-bool fetchProxy(zval*, Ice::ObjectPrx&, Slice::ClassDefPtr& TSRMLS_DC);
+bool createProxy(zval*, const Ice::ObjectPrx&, const CommunicatorInfoPtr& TSRMLS_DC);
+bool createProxy(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
+bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr& TSRMLS_DC);
+bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr&, CommunicatorInfoPtr& TSRMLS_DC);
//
// Class entry.
diff --git a/php/src/IcePHP/Types.cpp b/php/src/IcePHP/Types.cpp
new file mode 100644
index 00000000000..151e4acb120
--- /dev/null
+++ b/php/src/IcePHP/Types.cpp
@@ -0,0 +1,2877 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Types.h>
+#include <Proxy.h>
+#include <Util.h>
+#include <IceUtil/InputUtil.h>
+#include <IceUtil/OutputUtil.h>
+#include <IceUtil/ScopedArray.h>
+#include <Slice/PHPUtil.h>
+
+using namespace std;
+using namespace IcePHP;
+using namespace IceUtil;
+using namespace IceUtilInternal;
+
+ZEND_EXTERN_MODULE_GLOBALS(ice)
+
+//
+// Class entries represent the PHP class implementations we have registered.
+//
+namespace IcePHP
+{
+zend_class_entry* typeInfoClassEntry = 0;
+zend_class_entry* exceptionInfoClassEntry = 0;
+}
+
+static zend_object_handlers _typeInfoHandlers;
+static zend_object_handlers _exceptionInfoHandlers;
+
+extern "C"
+{
+static zend_object_value handleTypeInfoAlloc(zend_class_entry* TSRMLS_DC);
+static void handleTypeInfoFreeStorage(void* TSRMLS_DC);
+
+static zend_object_value handleExceptionInfoAlloc(zend_class_entry* TSRMLS_DC);
+static void handleExceptionInfoFreeStorage(void* TSRMLS_DC);
+}
+
+typedef map<string, ProxyInfoPtr> ProxyInfoMap;
+typedef map<string, ClassInfoPtr> ClassInfoMap;
+typedef map<string, ExceptionInfoPtr> ExceptionInfoMap;
+
+//
+// getProxyInfo()
+//
+static IcePHP::ProxyInfoPtr
+getProxyInfo(const string& id TSRMLS_DC)
+{
+ if(ICE_G(proxyInfoMap))
+ {
+ ProxyInfoMap* m = reinterpret_cast<ProxyInfoMap*>(ICE_G(proxyInfoMap));
+ ProxyInfoMap::iterator p = m->find(id);
+ if(p != m->end())
+ {
+ return p->second;
+ }
+ }
+ return 0;
+}
+
+//
+// addClassInfoById()
+//
+static void
+addClassInfoById(const ClassInfoPtr& p TSRMLS_DC)
+{
+ assert(!getClassInfoById(p->id TSRMLS_CC));
+
+ ClassInfoMap* m = reinterpret_cast<ClassInfoMap*>(ICE_G(idToClassInfoMap));
+ if(!m)
+ {
+ m = new ClassInfoMap;
+ ICE_G(idToClassInfoMap) = m;
+ }
+ m->insert(ClassInfoMap::value_type(p->id, p));
+}
+
+//
+// addClassInfoByName()
+//
+static void
+addClassInfoByName(const ClassInfoPtr& p TSRMLS_DC)
+{
+ assert(!getClassInfoByName(p->name TSRMLS_CC));
+
+ ClassInfoMap* m = reinterpret_cast<ClassInfoMap*>(ICE_G(nameToClassInfoMap));
+ if(!m)
+ {
+ m = new ClassInfoMap;
+ ICE_G(nameToClassInfoMap) = m;
+ }
+ m->insert(ClassInfoMap::value_type(p->name, p));
+}
+
+static ClassInfoPtr
+getMostDerived(zend_class_entry* formal, zend_class_entry* cls, const ClassInfoPtr& c TSRMLS_DC)
+{
+ assert(checkClass(cls, formal));
+ ClassInfoPtr curr = c;
+
+ ClassInfoPtr info = getClassInfoByName(cls->name TSRMLS_CC);
+ if(info)
+ {
+ if(!curr || info->isA(curr->id))
+ {
+ curr = info;
+ }
+ }
+
+ if(cls->parent && checkClass(cls->parent, formal))
+ {
+ curr = getMostDerived(formal, cls->parent, curr TSRMLS_CC);
+ }
+
+ //
+ // Only check the interfaces if we don't have a base class.
+ //
+ if(!curr)
+ {
+ for(zend_uint i = 0; i < cls->num_interfaces && !info; ++i)
+ {
+ if(checkClass(cls->interfaces[i], formal))
+ {
+ curr = getMostDerived(formal, cls->interfaces[i], curr TSRMLS_CC);
+ }
+ }
+ }
+
+ return curr;
+}
+
+//
+// getClassInfoById()
+//
+IcePHP::ClassInfoPtr
+IcePHP::getClassInfoById(const string& id TSRMLS_DC)
+{
+ if(ICE_G(idToClassInfoMap))
+ {
+ ClassInfoMap* m = reinterpret_cast<ClassInfoMap*>(ICE_G(idToClassInfoMap));
+ ClassInfoMap::iterator p = m->find(id);
+ if(p != m->end())
+ {
+ return p->second;
+ }
+ }
+ return 0;
+}
+
+//
+// getClassInfoByName()
+//
+IcePHP::ClassInfoPtr
+IcePHP::getClassInfoByName(const string& name TSRMLS_DC)
+{
+ if(ICE_G(nameToClassInfoMap))
+ {
+ ClassInfoMap* m = reinterpret_cast<ClassInfoMap*>(ICE_G(nameToClassInfoMap));
+ ClassInfoMap::iterator p = m->find(name);
+ if(p != m->end())
+ {
+ return p->second;
+ }
+ }
+ return 0;
+}
+
+//
+// getExceptionInfo()
+//
+IcePHP::ExceptionInfoPtr
+IcePHP::getExceptionInfo(const string& id TSRMLS_DC)
+{
+ if(ICE_G(exceptionInfoMap))
+ {
+ ExceptionInfoMap* m = reinterpret_cast<ExceptionInfoMap*>(ICE_G(exceptionInfoMap));
+ ExceptionInfoMap::iterator p = m->find(id);
+ if(p != m->end())
+ {
+ return p->second;
+ }
+ }
+ return 0;
+}
+
+namespace IcePHP
+{
+
+class ReadObjectCallback : public Ice::ReadObjectCallback
+{
+public:
+
+ ReadObjectCallback(const ClassInfoPtr&, const UnmarshalCallbackPtr&, zval*, void* TSRMLS_DC);
+ ~ReadObjectCallback();
+
+ virtual void invoke(const ::Ice::ObjectPtr&);
+
+private:
+
+ ClassInfoPtr _info;
+ UnmarshalCallbackPtr _cb;
+ zval* _target;
+ void* _closure;
+#if ZTS
+ TSRMLS_D;
+#endif
+zend_object_handle _h;
+};
+
+}
+
+//
+// UnmarshalCallback implementation.
+//
+IcePHP::UnmarshalCallback::~UnmarshalCallback()
+{
+}
+
+//
+// TypeInfo implementation.
+//
+IcePHP::TypeInfo::TypeInfo()
+{
+}
+
+bool
+IcePHP::TypeInfo::usesClasses()
+{
+ return false;
+}
+
+void
+IcePHP::TypeInfo::unmarshaled(zval*, zval*, void* TSRMLS_DC)
+{
+ assert(false);
+}
+
+void
+IcePHP::TypeInfo::destroy()
+{
+}
+
+//
+// PrimitiveInfo implementation.
+//
+string
+IcePHP::PrimitiveInfo::getId() const
+{
+ switch(kind)
+ {
+ case KindBool:
+ return "bool";
+ case KindByte:
+ return "byte";
+ case KindShort:
+ return "short";
+ case KindInt:
+ return "int";
+ case KindLong:
+ return "long";
+ case KindFloat:
+ return "float";
+ case KindDouble:
+ return "double";
+ case KindString:
+ return "string";
+ }
+ assert(false);
+ return string();
+}
+
+bool
+IcePHP::PrimitiveInfo::validate(zval* zv TSRMLS_DC)
+{
+ switch(kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ if(Z_TYPE_P(zv) != IS_BOOL)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected boolean value but received %s" TSRMLS_CC, s.c_str());
+ return false;
+ }
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ if(Z_TYPE_P(zv) != IS_LONG)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected byte value but received %s" TSRMLS_CC, s.c_str());
+ return false;
+ }
+ long val = Z_LVAL_P(zv);
+ if(val < 0 || val > 255)
+ {
+ invalidArgument("value %ld is out of range for a byte" TSRMLS_CC, val);
+ return false;
+ }
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ if(Z_TYPE_P(zv) != IS_LONG)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected short value but received %s" TSRMLS_CC, s.c_str());
+ return false;
+ }
+ long val = Z_LVAL_P(zv);
+ if(val < SHRT_MIN || val > SHRT_MAX)
+ {
+ invalidArgument("value %ld is out of range for a short" TSRMLS_CC, val);
+ return false;
+ }
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ if(Z_TYPE_P(zv) != IS_LONG)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected int value but received %s" TSRMLS_CC, s.c_str());
+ return false;
+ }
+ long val = Z_LVAL_P(zv);
+ if(val < INT_MIN || val > INT_MAX)
+ {
+ invalidArgument("value %ld is out of range for an int" TSRMLS_CC, val);
+ return false;
+ }
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ //
+ // The platform's 'long' type may not be 64 bits, so we also accept
+ // a string argument for this type.
+ //
+ if(Z_TYPE_P(zv) != IS_LONG && Z_TYPE_P(zv) != IS_STRING)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected long value but received %s" TSRMLS_CC, s.c_str());
+ return false;
+ }
+ Ice::Long val;
+ if(Z_TYPE_P(zv) == IS_LONG)
+ {
+ val = Z_LVAL_P(zv);
+ }
+ else
+ {
+ string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
+ if(!IceUtilInternal::stringToInt64(sval, val))
+ {
+ invalidArgument("invalid long value `%s'" TSRMLS_CC, Z_STRVAL_P(zv));
+ return false;
+ }
+ }
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ if(Z_TYPE_P(zv) != IS_DOUBLE)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected float value but received %s" TSRMLS_CC, s.c_str());
+ return false;
+ }
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ if(Z_TYPE_P(zv) != IS_DOUBLE)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected double value but received %s" TSRMLS_CC, s.c_str());
+ return false;
+ }
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ if(Z_TYPE_P(zv) != IS_STRING && Z_TYPE_P(zv) != IS_NULL)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected string value but received %s" TSRMLS_CC, s.c_str());
+ return false;
+ }
+ break;
+ }
+ }
+
+ return true;
+}
+
+void
+IcePHP::PrimitiveInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* TSRMLS_DC)
+{
+ switch(kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ assert(Z_TYPE_P(zv) == IS_BOOL);
+ os->writeBool(Z_BVAL_P(zv) ? true : false);
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ assert(Z_TYPE_P(zv) == IS_LONG);
+ long val = Z_LVAL_P(zv);
+ assert(val >= 0 && val <= 255); // validate() should have caught this.
+ os->writeByte(static_cast<Ice::Byte>(val));
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ assert(Z_TYPE_P(zv) == IS_LONG);
+ long val = Z_LVAL_P(zv);
+ assert(val >= SHRT_MIN && val <= SHRT_MAX); // validate() should have caught this.
+ os->writeShort(static_cast<Ice::Short>(val));
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ assert(Z_TYPE_P(zv) == IS_LONG);
+ long val = Z_LVAL_P(zv);
+ assert(val >= INT_MIN && val <= INT_MAX); // validate() should have caught this.
+ os->writeInt(static_cast<Ice::Int>(val));
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ //
+ // The platform's 'long' type may not be 64 bits, so we also accept
+ // a string argument for this type.
+ //
+ assert(Z_TYPE_P(zv) == IS_LONG || Z_TYPE_P(zv) == IS_STRING); // validate() should have caught this.
+ Ice::Long val;
+ if(Z_TYPE_P(zv) == IS_LONG)
+ {
+ val = Z_LVAL_P(zv);
+ }
+ else
+ {
+ string sval(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
+ IceUtilInternal::stringToInt64(sval, val);
+ }
+ os->writeLong(val);
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ assert(Z_TYPE_P(zv) == IS_DOUBLE); // validate() should have caught this.
+ double val = Z_DVAL_P(zv);
+ os->writeFloat(static_cast<Ice::Float>(val));
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ assert(Z_TYPE_P(zv) == IS_DOUBLE); // validate() should have caught this.
+ double val = Z_DVAL_P(zv);
+ os->writeDouble(val);
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ assert(Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_NULL); // validate() should have caught this.
+ if(Z_TYPE_P(zv) == IS_STRING)
+ {
+ string val(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
+ os->writeString(val);
+ }
+ else
+ {
+ os->writeString(string());
+ }
+ break;
+ }
+ }
+}
+
+void
+IcePHP::PrimitiveInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr&, zval* target, void* closure TSRMLS_DC)
+{
+ zval* zv;
+ MAKE_STD_ZVAL(zv);
+ AutoDestroy destroy(zv);
+
+ switch(kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ bool val = is->readBool();
+ ZVAL_BOOL(zv, val ? 1 : 0);
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ Ice::Byte val = is->readByte();
+ ZVAL_LONG(zv, val & 0xff);
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ Ice::Short val = is->readShort();
+ ZVAL_LONG(zv, val);
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ Ice::Int val = is->readInt();
+ ZVAL_LONG(zv, val);
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ Ice::Long val = is->readLong();
+
+ //
+ // The platform's 'long' type may not be 64 bits, so we store 64-bit
+ // values as a string.
+ //
+ if(sizeof(Ice::Long) > sizeof(long) && (val < LONG_MIN || val > LONG_MAX))
+ {
+ string str = IceUtilInternal::int64ToString(val);
+ ZVAL_STRINGL(zv, STRCAST(str.c_str()), str.length(), 1);
+ }
+ else
+ {
+ ZVAL_LONG(zv, static_cast<long>(val));
+ }
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ Ice::Float val = is->readFloat();
+ ZVAL_DOUBLE(zv, val);
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ Ice::Double val = is->readDouble();
+ ZVAL_DOUBLE(zv, val);
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ string val = is->readString();
+ ZVAL_STRINGL(zv, STRCAST(val.c_str()), val.length(), 1);
+ break;
+ }
+ }
+
+ cb->unmarshaled(zv, target, closure TSRMLS_CC);
+}
+
+void
+IcePHP::PrimitiveInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* TSRMLS_DC)
+{
+ if(!validate(zv TSRMLS_CC))
+ {
+ out << "<invalid value - expected " << getId() << ">";
+ return;
+ }
+ zval tmp = *zv;
+ zval_copy_ctor(&tmp);
+ INIT_PZVAL(&tmp);
+ convert_to_string(&tmp);
+ out << Z_STRVAL(tmp);
+ zval_dtor(&tmp);
+}
+
+//
+// EnumInfo implementation.
+//
+string
+IcePHP::EnumInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::EnumInfo::validate(zval* zv TSRMLS_DC)
+{
+ if(Z_TYPE_P(zv) == IS_LONG)
+ {
+ Ice::StringSeq::size_type sz = static_cast<Ice::StringSeq::size_type>(Z_LVAL_P(zv));
+ return sz >= 0 && sz < enumerators.size();
+ }
+ return false;
+}
+
+void
+IcePHP::EnumInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* TSRMLS_DC)
+{
+ assert(Z_TYPE_P(zv) == IS_LONG); // validate() should have caught this.
+ int val = static_cast<int>(Z_LVAL_P(zv));
+ int count = static_cast<int>(enumerators.size());
+ assert(val >= 0 && val < count); // validate() should have caught this.
+
+ if(count <= 127)
+ {
+ os->writeByte(static_cast<Ice::Byte>(val));
+ }
+ else if(count <= 32767)
+ {
+ os->writeShort(static_cast<Ice::Short>(val));
+ }
+ else
+ {
+ os->writeInt(val);
+ }
+}
+
+void
+IcePHP::EnumInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr&, zval* target, void* closure TSRMLS_DC)
+{
+ zval* zv;
+ ALLOC_INIT_ZVAL(zv);
+ AutoDestroy destroy(zv);
+
+ int val;
+ int count = static_cast<int>(enumerators.size());
+ if(count <= 127)
+ {
+ val = is->readByte();
+ }
+ else if(count <= 32767)
+ {
+ val = is->readShort();
+ }
+ else
+ {
+ val = is->readInt();
+ }
+
+ if(val < 0 || val >= count)
+ {
+ invalidArgument("enumerator %d is out of range for enum %s" TSRMLS_CC, val, id.c_str());
+ throw AbortMarshaling();
+ }
+
+ ZVAL_LONG(zv, val);
+ cb->unmarshaled(zv, target, closure TSRMLS_CC);
+}
+
+void
+IcePHP::EnumInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* TSRMLS_DC)
+{
+ if(!validate(zv TSRMLS_CC))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+ int val = static_cast<int>(Z_LVAL_P(zv));
+ out << enumerators[val];
+}
+
+//
+// DataMember implementation.
+//
+void
+IcePHP::DataMember::unmarshaled(zval* zv, zval* target, void* TSRMLS_DC)
+{
+ assert(Z_TYPE_P(target) == IS_OBJECT);
+
+ //
+ // The add_property_zval function fails if the data member has protected visibility.
+ // As a workaround, before calling the function we change the current scope to be that
+ // of the object.
+ //
+ zend_class_entry *oldScope = EG(scope);
+ EG(scope) = Z_OBJCE_P(target);
+
+ //
+ // add_property_zval increments the refcount of zv.
+ //
+ int status = add_property_zval(target, STRCAST(name.c_str()), zv);
+
+ EG(scope) = oldScope; // Restore the previous scope.
+
+ if(status == FAILURE)
+ {
+ runtimeError("unable to set member `%s'" TSRMLS_CC, name.c_str());
+ throw AbortMarshaling();
+ }
+}
+
+//
+// StructInfo implementation.
+//
+string
+IcePHP::StructInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::StructInfo::validate(zval* zv TSRMLS_DC)
+{
+ if(Z_TYPE_P(zv) != IS_OBJECT)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected struct value of type %s but received %s" TSRMLS_CC, zce->name, s.c_str());
+ return false;
+ }
+
+ //
+ // Compare class entries.
+ //
+ zend_class_entry* ce = Z_OBJCE_P(zv);
+ if(ce != zce)
+ {
+ invalidArgument("expected struct value of type %s but received %s" TSRMLS_CC, zce->name, ce->name);
+ return false;
+ }
+
+ return true;
+}
+
+bool
+IcePHP::StructInfo::usesClasses()
+{
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ if((*q)->type->usesClasses())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+IcePHP::StructInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap TSRMLS_DC)
+{
+ assert(Z_TYPE_P(zv) == IS_OBJECT); // validate() should have caught this.
+ assert(Z_OBJCE_P(zv) == zce); // validate() should have caught this.
+
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ void* data;
+ if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size() + 1, &data) == FAILURE)
+ {
+ runtimeError("member `%s' of %s is not defined" TSRMLS_CC, member->name.c_str(), id.c_str());
+ throw AbortMarshaling();
+ }
+
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!member->type->validate(*val TSRMLS_CC))
+ {
+ invalidArgument("invalid value for %s member `%s'" TSRMLS_CC, id.c_str(), member->name.c_str());
+ throw AbortMarshaling();
+ }
+ member->type->marshal(*val, os, objectMap TSRMLS_CC);
+ }
+}
+
+void
+IcePHP::StructInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC)
+{
+ zval* zv;
+ MAKE_STD_ZVAL(zv);
+ AutoDestroy destroy(zv);
+
+ if(object_init_ex(zv, zce) != SUCCESS)
+ {
+ runtimeError("unable to initialize object of type %s" TSRMLS_CC, zce->name);
+ throw AbortMarshaling();
+ }
+
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ member->type->unmarshal(is, member, comm, zv, 0 TSRMLS_CC);
+ }
+
+ cb->unmarshaled(zv, target, closure TSRMLS_CC);
+}
+
+void
+IcePHP::StructInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC)
+{
+ if(!validate(zv TSRMLS_CC))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+ out.sb();
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ out << nl << member->name << " = ";
+ void* data;
+ if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size() + 1, &data) == SUCCESS)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ member->type->print(*val, out, history TSRMLS_CC);
+ }
+ else
+ {
+ out << "<not defined>";
+ }
+ }
+ out.eb();
+}
+
+void
+IcePHP::StructInfo::destroy()
+{
+ for(DataMemberList::iterator p = members.begin(); p != members.end(); ++p)
+ {
+ (*p)->type->destroy();
+ }
+ members.clear();
+}
+
+//
+// SequenceInfo implementation.
+//
+string
+IcePHP::SequenceInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::SequenceInfo::validate(zval* zv TSRMLS_DC)
+{
+ return Z_TYPE_P(zv) == IS_NULL || Z_TYPE_P(zv) == IS_ARRAY;
+}
+
+bool
+IcePHP::SequenceInfo::usesClasses()
+{
+ return elementType->usesClasses();
+}
+
+void
+IcePHP::SequenceInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap TSRMLS_DC)
+{
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ os->writeSize(0);
+ return;
+ }
+
+ assert(Z_TYPE_P(zv) == IS_ARRAY); // validate() should have caught this.
+
+ HashTable* arr = Z_ARRVAL_P(zv);
+
+ Ice::Int sz = static_cast<Ice::Int>(zend_hash_num_elements(arr));
+
+ if(sz == 0)
+ {
+ os->writeSize(0);
+ return;
+ }
+
+ PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
+ if(pi)
+ {
+ marshalPrimitiveSequence(pi, zv, os TSRMLS_CC);
+ return;
+ }
+
+ HashPosition pos;
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+
+ os->writeSize(sz);
+
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!elementType->validate(*val TSRMLS_CC))
+ {
+ invalidArgument("invalid value for sequence element `%s'" TSRMLS_CC, id.c_str());
+ throw AbortMarshaling();
+ }
+ elementType->marshal(*val, os, objectMap TSRMLS_CC);
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+}
+
+void
+IcePHP::SequenceInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC)
+{
+ PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
+ if(pi)
+ {
+ unmarshalPrimitiveSequence(pi, is, cb, target, closure TSRMLS_CC);
+ return;
+ }
+
+ zval* zv;
+ MAKE_STD_ZVAL(zv);
+ array_init(zv);
+ AutoDestroy destroy(zv);
+
+ Ice::Int sz = is->readSize();
+ if(variableLength)
+ {
+ is->startSeq(sz, minWireSize);
+ }
+ else
+ {
+ is->checkFixedSeq(sz, minWireSize);
+ }
+ for(Ice::Int i = 0; i < sz; ++i)
+ {
+ void* cl = reinterpret_cast<void*>(i);
+ elementType->unmarshal(is, this, comm, zv, cl TSRMLS_CC);
+ if(variableLength)
+ {
+ is->checkSeq();
+ is->endElement();
+ }
+ }
+ if(variableLength)
+ {
+ is->endSeq(sz);
+ }
+
+ cb->unmarshaled(zv, target, closure TSRMLS_CC);
+}
+
+void
+IcePHP::SequenceInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC)
+{
+ if(!validate(zv TSRMLS_CC))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ out << "{}";
+ }
+ else
+ {
+ assert(Z_TYPE_P(zv) == IS_ARRAY);
+
+ HashTable* arr = Z_ARRVAL_P(zv);
+
+ HashPosition pos;
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+
+ out.sb();
+
+ int i = 0;
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ out << nl << '[' << i << "] = ";
+ elementType->print(*val, out, history TSRMLS_CC);
+ zend_hash_move_forward_ex(arr, &pos);
+ ++i;
+ }
+
+ out.eb();
+ }
+}
+
+void
+IcePHP::SequenceInfo::unmarshaled(zval* zv, zval* target, void* closure TSRMLS_DC)
+{
+ assert(Z_TYPE_P(target) == IS_ARRAY);
+ long i = reinterpret_cast<long>(closure);
+ add_index_zval(target, i, zv);
+ Z_ADDREF_P(zv);
+}
+
+void
+IcePHP::SequenceInfo::destroy()
+{
+ if(elementType)
+ {
+ elementType->destroy();
+ elementType = 0;
+ }
+}
+
+void
+IcePHP::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, zval* zv, const Ice::OutputStreamPtr& os
+ TSRMLS_DC)
+{
+ HashTable* arr = Z_ARRVAL_P(zv);
+
+ HashPosition pos;
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+
+ Ice::Int sz = static_cast<Ice::Int>(zend_hash_num_elements(arr));
+ assert(sz > 0);
+
+ switch(pi->kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ Ice::BoolSeq seq(sz);
+ Ice::Int i = 0;
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!pi->validate(*val TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ seq[i++] = Z_BVAL_P(*val) ? true : false;
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+ os->writeBoolSeq(seq);
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ Ice::ByteSeq seq(sz);
+ Ice::Int i = 0;
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!pi->validate(*val TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ long l = Z_LVAL_P(*val);
+ assert(l >= 0 && l <= 255);
+ seq[i++] = static_cast<Ice::Byte>(l);
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+ os->writeByteSeq(seq);
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ Ice::ShortSeq seq(sz);
+ Ice::Int i = 0;
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!pi->validate(*val TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ long l = Z_LVAL_P(*val);
+ assert(l >= SHRT_MIN && l <= SHRT_MAX);
+ seq[i++] = static_cast<Ice::Short>(l);
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+ os->writeShortSeq(seq);
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ Ice::IntSeq seq(sz);
+ Ice::Int i = 0;
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!pi->validate(*val TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ long l = Z_LVAL_P(*val);
+ assert(l >= INT_MIN && l <= INT_MAX);
+ seq[i++] = static_cast<Ice::Int>(l);
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+ os->writeIntSeq(seq);
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ Ice::LongSeq seq(sz);
+ Ice::Int i = 0;
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!pi->validate(*val TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ //
+ // The platform's 'long' type may not be 64 bits, so we also accept
+ // a string argument for this type.
+ //
+ assert(Z_TYPE_P(*val) == IS_LONG || Z_TYPE_P(*val) == IS_STRING);
+ Ice::Long l;
+ if(Z_TYPE_P(*val) == IS_LONG)
+ {
+ l = Z_LVAL_P(*val);
+ }
+ else
+ {
+ string sval(Z_STRVAL_P(*val), Z_STRLEN_P(*val));
+ IceUtilInternal::stringToInt64(sval, l);
+ }
+ seq[i++] = l;
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+ os->writeLongSeq(seq);
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ Ice::FloatSeq seq(sz);
+ Ice::Int i = 0;
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!pi->validate(*val TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ double d = Z_DVAL_P(*val);
+ seq[i++] = static_cast<Ice::Float>(d);
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+ os->writeFloatSeq(seq);
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ Ice::DoubleSeq seq(sz);
+ Ice::Int i = 0;
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!pi->validate(*val TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ double d = Z_DVAL_P(*val);
+ seq[i++] = d;
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+ os->writeDoubleSeq(seq);
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ Ice::StringSeq seq(sz);
+ Ice::Int i = 0;
+ void* data;
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!pi->validate(*val TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ string s;
+ if(Z_TYPE_P(*val) == IS_STRING)
+ {
+ s = string(Z_STRVAL_P(*val), Z_STRLEN_P(*val));
+ }
+ else
+ {
+ assert(Z_TYPE_P(*val) == IS_NULL);
+ }
+ seq[i++] = s;
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+ os->writeStringSeq(seq);
+ break;
+ }
+ }
+}
+
+void
+IcePHP::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, const Ice::InputStreamPtr& is,
+ const UnmarshalCallbackPtr& cb, zval* target, void* closure TSRMLS_DC)
+{
+ zval* zv;
+ MAKE_STD_ZVAL(zv);
+ array_init(zv);
+ AutoDestroy destroy(zv);
+
+ switch(pi->kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ pair<const bool*, const bool*> pr;
+ IceUtilInternal::ScopedArray<bool> arr(is->readBoolSeq(pr));
+ for(const bool* p = pr.first; p != pr.second; ++p)
+ {
+ add_next_index_bool(zv, *p ? 1 : 0);
+ }
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ pair<const Ice::Byte*, const Ice::Byte*> pr;
+ is->readByteSeq(pr);
+ for(const Ice::Byte* p = pr.first; p != pr.second; ++p)
+ {
+ add_next_index_long(zv, *p & 0xff);
+ }
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ pair<const Ice::Short*, const Ice::Short*> pr;
+ IceUtilInternal::ScopedArray<Ice::Short> arr(is->readShortSeq(pr));
+ for(const Ice::Short* p = pr.first; p != pr.second; ++p)
+ {
+ add_next_index_long(zv, *p);
+ }
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ pair<const Ice::Int*, const Ice::Int*> pr;
+ IceUtilInternal::ScopedArray<Ice::Int> arr(is->readIntSeq(pr));
+ for(const Ice::Int* p = pr.first; p != pr.second; ++p)
+ {
+ add_next_index_long(zv, *p);
+ }
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ pair<const Ice::Long*, const Ice::Long*> pr;
+ IceUtilInternal::ScopedArray<Ice::Long> arr(is->readLongSeq(pr));
+ Ice::Int i = 0;
+ for(const Ice::Long* p = pr.first; p != pr.second; ++p, ++i)
+ {
+ zval* val;
+ MAKE_STD_ZVAL(val);
+ //
+ // The platform's 'long' type may not be 64 bits, so we store 64-bit
+ // values as a string.
+ //
+ if(sizeof(Ice::Long) > sizeof(long) && (*p < LONG_MIN || *p > LONG_MAX))
+ {
+ string str = IceUtilInternal::int64ToString(*p);
+ ZVAL_STRINGL(val, STRCAST(str.c_str()), str.length(), 1);
+ }
+ else
+ {
+ ZVAL_LONG(val, static_cast<long>(*p));
+ }
+ add_index_zval(zv, i, val);
+ }
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ pair<const Ice::Float*, const Ice::Float*> pr;
+ IceUtilInternal::ScopedArray<Ice::Float> arr(is->readFloatSeq(pr));
+ Ice::Int i = 0;
+ for(const Ice::Float* p = pr.first; p != pr.second; ++p, ++i)
+ {
+ zval* val;
+ MAKE_STD_ZVAL(val);
+ ZVAL_DOUBLE(val, *p);
+ add_index_zval(zv, i, val);
+ }
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ pair<const Ice::Double*, const Ice::Double*> pr;
+ IceUtilInternal::ScopedArray<Ice::Double> arr(is->readDoubleSeq(pr));
+ Ice::Int i = 0;
+ for(const Ice::Double* p = pr.first; p != pr.second; ++p, ++i)
+ {
+ zval* val;
+ MAKE_STD_ZVAL(val);
+ ZVAL_DOUBLE(val, *p);
+ add_index_zval(zv, i, val);
+ }
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ Ice::StringSeq seq = is->readStringSeq();
+ Ice::Int i = 0;
+ for(Ice::StringSeq::iterator p = seq.begin(); p != seq.end(); ++p, ++i)
+ {
+ zval* val;
+ MAKE_STD_ZVAL(val);
+ ZVAL_STRINGL(val, STRCAST(p->c_str()), p->length(), 1);
+ add_index_zval(zv, i, val);
+ }
+ break;
+ }
+ }
+
+ cb->unmarshaled(zv, target, closure TSRMLS_CC);
+}
+
+//
+// DictionaryInfo implementation.
+//
+string
+IcePHP::DictionaryInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::DictionaryInfo::validate(zval* zv TSRMLS_DC)
+{
+ return Z_TYPE_P(zv) == IS_NULL || Z_TYPE_P(zv) == IS_ARRAY;
+}
+
+bool
+IcePHP::DictionaryInfo::usesClasses()
+{
+ return valueType->usesClasses();
+}
+
+void
+IcePHP::DictionaryInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap TSRMLS_DC)
+{
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ os->writeSize(0);
+ return;
+ }
+
+ assert(Z_TYPE_P(zv) == IS_ARRAY); // validate() should have caught this.
+
+ PrimitiveInfoPtr piKey = PrimitiveInfoPtr::dynamicCast(keyType);
+ if(!piKey || piKey->kind == PrimitiveInfo::KindFloat || piKey->kind == PrimitiveInfo::KindDouble)
+ {
+ invalidArgument("dictionary type `%s' cannot be marshaled" TSRMLS_CC, id.c_str());
+ throw AbortMarshaling();
+ }
+
+ HashTable* arr = Z_ARRVAL_P(zv);
+
+ Ice::Int sz = static_cast<Ice::Int>(zend_hash_num_elements(arr));
+ os->writeSize(sz);
+
+ if(sz == 0)
+ {
+ return;
+ }
+
+ HashPosition pos;
+ void* data;
+
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+
+ //
+ // Get the key (which can be a long or a string).
+ //
+ char* keyStr;
+ uint keyLen;
+ ulong keyNum;
+ int hashKeyType = zend_hash_get_current_key_ex(arr, &keyStr, &keyLen, &keyNum, 0, &pos);
+
+ //
+ // Store the key in a zval, so that we can reuse the PrimitiveInfo logic.
+ //
+ zval* zkey;
+ MAKE_STD_ZVAL(zkey);
+ AutoDestroy destroy(zkey);
+
+ if(hashKeyType == HASH_KEY_IS_LONG)
+ {
+ ZVAL_LONG(zkey, keyNum);
+ }
+ else
+ {
+ ZVAL_STRINGL(zkey, keyStr, keyLen - 1, 1);
+ }
+
+ //
+ // Convert the zval to the required type, if necessary.
+ //
+ switch(piKey->kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ convert_to_boolean(zkey);
+ break;
+ }
+
+ case PrimitiveInfo::KindByte:
+ case PrimitiveInfo::KindShort:
+ case PrimitiveInfo::KindInt:
+ case PrimitiveInfo::KindLong:
+ {
+ if(hashKeyType == HASH_KEY_IS_STRING)
+ {
+ convert_to_long(zkey);
+ }
+ break;
+ }
+
+ case PrimitiveInfo::KindString:
+ {
+ if(hashKeyType == HASH_KEY_IS_LONG)
+ {
+ convert_to_string(zkey);
+ }
+ break;
+ }
+
+ case PrimitiveInfo::KindFloat:
+ case PrimitiveInfo::KindDouble:
+ assert(false);
+ }
+
+ //
+ // Marshal the key.
+ //
+ if(!keyType->validate(zkey TSRMLS_CC))
+ {
+ invalidArgument("invalid key in `%s' element" TSRMLS_CC, id.c_str());
+ throw AbortMarshaling();
+ }
+ keyType->marshal(zkey, os, objectMap TSRMLS_CC);
+
+ //
+ // Marshal the value.
+ //
+ if(!valueType->validate(*val TSRMLS_CC))
+ {
+ invalidArgument("invalid value in `%s' element" TSRMLS_CC, id.c_str());
+ throw AbortMarshaling();
+ }
+ valueType->marshal(*val, os, objectMap TSRMLS_CC);
+
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+}
+
+void
+IcePHP::DictionaryInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC)
+{
+ PrimitiveInfoPtr piKey = PrimitiveInfoPtr::dynamicCast(keyType);
+ if(!piKey || piKey->kind == PrimitiveInfo::KindFloat || piKey->kind == PrimitiveInfo::KindDouble)
+ {
+ invalidArgument("dictionary type `%s' cannot be unmarshaled" TSRMLS_CC, id.c_str());
+ throw AbortMarshaling();
+ }
+
+ zval* zv;
+ MAKE_STD_ZVAL(zv);
+ array_init(zv);
+ AutoDestroy destroy(zv);
+
+ KeyCallbackPtr keyCB = new KeyCallback;
+
+ Ice::Int sz = is->readSize();
+ for(Ice::Int i = 0; i < sz; ++i)
+ {
+ //
+ // A dictionary key cannot be a class (or contain one), so the key must be
+ // available immediately.
+ //
+ keyType->unmarshal(is, keyCB, comm, 0, 0 TSRMLS_CC);
+ assert(keyCB->key);
+
+ //
+ // Allocate a callback that holds a reference to the key.
+ //
+ ValueCallbackPtr valueCB = new ValueCallback(keyCB->key TSRMLS_CC);
+
+ //
+ // Pass the key to the callback.
+ //
+ valueType->unmarshal(is, valueCB, comm, zv, 0 TSRMLS_CC);
+ }
+
+ cb->unmarshaled(zv, target, closure TSRMLS_CC);
+}
+
+void
+IcePHP::DictionaryInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC)
+{
+ if(!validate(zv TSRMLS_CC))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ out << "{}";
+ }
+ else
+ {
+ HashTable* arr = Z_ARRVAL_P(zv);
+ HashPosition pos;
+ void* data;
+ bool first = true;
+
+ out.sb();
+
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+
+ //
+ // Get the key (which can be a long or a string).
+ //
+ char* keyStr;
+ uint keyLen;
+ ulong keyNum;
+ int hashKeyType = zend_hash_get_current_key_ex(arr, &keyStr, &keyLen, &keyNum, 0, &pos);
+
+ if(first)
+ {
+ first = false;
+ }
+ else
+ {
+ out << nl;
+ }
+ out << nl << "key = ";
+ if(hashKeyType == HASH_KEY_IS_LONG)
+ {
+ out << keyNum;
+ }
+ else
+ {
+ out << keyStr;
+ }
+ out << nl << "value = ";
+ valueType->print(*val, out, history TSRMLS_CC);
+
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+
+ out.eb();
+ }
+}
+
+IcePHP::DictionaryInfo::KeyCallback::KeyCallback() :
+ key(0)
+{
+}
+
+IcePHP::DictionaryInfo::KeyCallback::~KeyCallback()
+{
+ if(key)
+ {
+ zval_ptr_dtor(&key);
+ }
+}
+
+void
+IcePHP::DictionaryInfo::KeyCallback::unmarshaled(zval* zv, zval*, void* TSRMLS_DC)
+{
+ if(key)
+ {
+ zval_ptr_dtor(&key);
+ }
+
+ key = zv;
+ Z_ADDREF_P(key);
+}
+
+IcePHP::DictionaryInfo::ValueCallback::ValueCallback(zval* k TSRMLS_DC) :
+ key(k)
+{
+ Z_ADDREF_P(key);
+}
+
+IcePHP::DictionaryInfo::ValueCallback::~ValueCallback()
+{
+ zval_ptr_dtor(&key);
+}
+
+void
+IcePHP::DictionaryInfo::ValueCallback::unmarshaled(zval* zv, zval* target, void* TSRMLS_DC)
+{
+ assert(Z_TYPE_P(target) == IS_ARRAY);
+
+ switch(Z_TYPE_P(key))
+ {
+ case IS_LONG:
+ add_index_zval(target, Z_LVAL_P(key), zv);
+ break;
+ case IS_BOOL:
+ add_index_zval(target, Z_BVAL_P(key) ? 1 : 0, zv);
+ break;
+ case IS_STRING:
+ add_assoc_zval_ex(target, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, zv);
+ break;
+ default:
+ assert(false);
+ return;
+ }
+ Z_ADDREF_P(zv);
+}
+
+void
+IcePHP::DictionaryInfo::destroy()
+{
+ if(keyType)
+ {
+ keyType->destroy();
+ keyType = 0;
+ }
+ if(valueType)
+ {
+ valueType->destroy();
+ valueType = 0;
+ }
+}
+
+//
+// ClassInfo implementation.
+//
+string
+IcePHP::ClassInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::ClassInfo::validate(zval* val TSRMLS_DC)
+{
+ if(Z_TYPE_P(val) == IS_OBJECT)
+ {
+ return checkClass(Z_OBJCE_P(val), zce);
+ }
+ return Z_TYPE_P(val) == IS_NULL;
+}
+
+bool
+IcePHP::ClassInfo::usesClasses()
+{
+ return true;
+}
+
+void
+IcePHP::ClassInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap TSRMLS_DC)
+{
+ if(!defined)
+ {
+ runtimeError("class or interface %s is declared but not defined" TSRMLS_CC, id.c_str());
+ throw AbortMarshaling();
+ }
+
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ os->writeObject(0);
+ return;
+ }
+
+ assert(Z_TYPE_P(zv) == IS_OBJECT); // validate() should have caught this.
+ assert(checkClass(Z_OBJCE_P(zv), zce)); // validate() should have caught this.
+
+ //
+ // Ice::ObjectWriter is a subclass of Ice::Object that wraps a PHP object for marshaling.
+ // It is possible that this PHP object has already been marshaled, therefore we first must
+ // check the object map to see if this object is present. If so, we use the existing ObjectWriter,
+ // otherwise we create a new one. The key of the map is the object's handle.
+ //
+ Ice::ObjectPtr writer;
+ assert(objectMap);
+ ObjectMap::iterator q = objectMap->find(Z_OBJ_HANDLE_P(zv));
+ if(q == objectMap->end())
+ {
+ //
+ // Determine the most-derived Slice type implemented by this object by scanning its
+ // inheritance hierarchy until we find a class or interface that we recognize.
+ //
+ ClassInfoPtr info = getMostDerived(zce, Z_OBJCE_P(zv), 0 TSRMLS_CC);
+ assert(info);
+ writer = new ObjectWriter(info, zv, objectMap TSRMLS_CC);
+ objectMap->insert(ObjectMap::value_type(Z_OBJ_HANDLE_P(zv), writer));
+ }
+ else
+ {
+ writer = q->second;
+ }
+
+ //
+ // Give the writer to the stream. The stream will eventually call write() on it.
+ //
+ os->writeObject(writer);
+}
+
+void
+IcePHP::ClassInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC)
+{
+ if(!defined)
+ {
+ runtimeError("class or interface %s is declared but not defined" TSRMLS_CC, id.c_str());
+ throw AbortMarshaling();
+ }
+
+ is->readObject(new ReadObjectCallback(this, cb, target, closure TSRMLS_CC));
+}
+
+void
+IcePHP::ClassInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC)
+{
+ if(!validate(zv TSRMLS_CC))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ out << "<nil>";
+ }
+ else
+ {
+ map<unsigned int, int>::iterator q = history->objects.find(Z_OBJ_HANDLE_P(zv));
+ if(q != history->objects.end())
+ {
+ out << "<object #" << q->second << ">";
+ }
+ else
+ {
+ out << "object #" << history->index << " (" << id << ')';
+ history->objects.insert(map<unsigned int, int>::value_type(Z_OBJ_HANDLE_P(zv), history->index));
+ ++history->index;
+ out.sb();
+ printMembers(zv, out, history TSRMLS_CC);
+ out.eb();
+ }
+ }
+}
+
+void
+IcePHP::ClassInfo::destroy()
+{
+ base = 0;
+ interfaces.clear();
+ if(!members.empty())
+ {
+ DataMemberList ml = members;
+ members.clear();
+ for(DataMemberList::iterator p = ml.begin(); p != ml.end(); ++p)
+ {
+ (*p)->type->destroy();
+ }
+ }
+}
+
+void
+IcePHP::ClassInfo::printMembers(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC)
+{
+ if(base)
+ {
+ base->printMembers(zv, out, history TSRMLS_CC);
+ }
+
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ out << nl << member->name << " = ";
+ void* data;
+ if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size() + 1, &data) == SUCCESS)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ member->type->print(*val, out, history TSRMLS_CC);
+ }
+ else
+ {
+ out << "<not defined>";
+ }
+ }
+}
+
+bool
+IcePHP::ClassInfo::isA(const string& typeId) const
+{
+ if(id == typeId)
+ {
+ return true;
+ }
+
+ if(base && base->isA(typeId))
+ {
+ return true;
+ }
+
+ for(ClassInfoList::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
+ {
+ if((*p)->isA(typeId))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+IcePHP::ClassInfo::addOperation(const string& name, const OperationPtr& op)
+{
+ operations.insert(OperationMap::value_type(Slice::PHP::fixIdent(name), op));
+}
+
+IcePHP::OperationPtr
+IcePHP::ClassInfo::getOperation(const string& name) const
+{
+ OperationPtr op;
+ OperationMap::const_iterator p = operations.find(name);
+ if(p != operations.end())
+ {
+ op = p->second;
+ }
+ if(!op && base)
+ {
+ op = base->getOperation(name);
+ }
+ if(!op && !interfaces.empty())
+ {
+ for(ClassInfoList::const_iterator q = interfaces.begin(); q != interfaces.end() && !op; ++q)
+ {
+ op = (*q)->getOperation(name);
+ }
+ }
+ return op;
+}
+
+//
+// ProxyInfo implementation.
+//
+string
+IcePHP::ProxyInfo::getId() const
+{
+ return id;
+}
+
+bool
+IcePHP::ProxyInfo::validate(zval* zv TSRMLS_DC)
+{
+ if(Z_TYPE_P(zv) != IS_NULL)
+ {
+ if(Z_TYPE_P(zv) != IS_OBJECT || (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) != proxyClassEntry))
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected proxy value or null but received %s" TSRMLS_CC, s.c_str());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void
+IcePHP::ProxyInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* TSRMLS_DC)
+{
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ os->writeProxy(0);
+ }
+ else
+ {
+ assert(Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == proxyClassEntry); // validate() should have caught this.
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr info;
+ if(!fetchProxy(zv, proxy, info TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ if(!info->isA(id))
+ {
+ invalidArgument("proxy is not narrowed to %s" TSRMLS_CC, id.c_str());
+ throw AbortMarshaling();
+ }
+ os->writeProxy(proxy);
+ }
+}
+
+void
+IcePHP::ProxyInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb,
+ const CommunicatorInfoPtr& comm, zval* target, void* closure TSRMLS_DC)
+{
+ zval* zv;
+ MAKE_STD_ZVAL(zv);
+ AutoDestroy destroy(zv);
+
+ Ice::ObjectPrx proxy = is->readProxy();
+
+ if(!proxy)
+ {
+ ZVAL_NULL(zv);
+ cb->unmarshaled(zv, target, closure TSRMLS_CC);
+ return;
+ }
+
+ if(!cls->defined)
+ {
+ runtimeError("class or interface %s is declared but not defined" TSRMLS_CC, id.c_str());
+ throw AbortMarshaling();
+ }
+
+ if(!createProxy(zv, proxy, cls, comm TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ cb->unmarshaled(zv, target, closure TSRMLS_CC);
+}
+
+void
+IcePHP::ProxyInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* TSRMLS_DC)
+{
+ if(!validate(zv TSRMLS_CC))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(Z_TYPE_P(zv) == IS_NULL)
+ {
+ out << "<nil>";
+ }
+ else
+ {
+ Ice::ObjectPrx proxy;
+ ClassInfoPtr cls;
+ if(!fetchProxy(zv, proxy, cls TSRMLS_CC))
+ {
+ return;
+ }
+ out << proxy->ice_toString();
+ }
+}
+
+void
+IcePHP::ProxyInfo::destroy()
+{
+ cls = 0;
+}
+
+//
+// ObjectWriter implementation.
+//
+IcePHP::ObjectWriter::ObjectWriter(const ClassInfoPtr& info, zval* object, ObjectMap* objectMap TSRMLS_DC) :
+ _info(info), _object(object), _map(objectMap)
+{
+#ifdef ZTS
+ this->TSRMLS_C = TSRMLS_C;
+#endif
+
+ Z_OBJ_HT_P(_object)->add_ref(_object TSRMLS_CC);
+}
+
+IcePHP::ObjectWriter::~ObjectWriter()
+{
+ Z_OBJ_HT_P(_object)->del_ref(_object TSRMLS_CC);
+}
+
+void
+IcePHP::ObjectWriter::ice_preMarshal()
+{
+ string name = "ice_premarshal"; // Must be lowercase.
+ if(zend_hash_exists(&Z_OBJCE_P(_object)->function_table, STRCAST(name.c_str()), name.size() + 1))
+ {
+ if(!invokeMethod(_object, name TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ }
+}
+
+void
+IcePHP::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
+{
+ ClassInfoPtr info = _info;
+ while(info && info->id != Ice::Object::ice_staticId())
+ {
+ os->writeTypeId(info->id);
+
+ os->startSlice();
+ for(DataMemberList::iterator q = info->members.begin(); q != info->members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ void* data;
+ if(zend_hash_find(Z_OBJPROP_P(_object), STRCAST(member->name.c_str()), member->name.size() + 1, &data) ==
+ FAILURE)
+ {
+ runtimeError("member `%s' of %s is not defined" TSRMLS_CC, member->name.c_str(), _info->id.c_str());
+ throw AbortMarshaling();
+ }
+
+ zval** val = reinterpret_cast<zval**>(data);
+ if(!member->type->validate(*val TSRMLS_CC))
+ {
+ invalidArgument("invalid value for %s member `%s'" TSRMLS_CC, _info->id.c_str(), member->name.c_str());
+ throw AbortMarshaling();
+ }
+ member->type->marshal(*val, os, _map TSRMLS_CC);
+ }
+ os->endSlice();
+
+ info = info->base;
+ }
+
+ //
+ // Marshal the Ice::Object slice.
+ //
+ os->writeTypeId(Ice::Object::ice_staticId());
+ os->startSlice();
+ os->writeSize(0); // For compatibility with the old AFM.
+ os->endSlice();
+}
+
+//
+// ObjectReader implementation.
+//
+IcePHP::ObjectReader::ObjectReader(zval* object, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm TSRMLS_DC) :
+ _object(object), _info(info), _communicator(comm)
+{
+#ifdef ZTS
+ this->TSRMLS_C = TSRMLS_C;
+#endif
+
+ Z_ADDREF_P(_object);
+}
+
+IcePHP::ObjectReader::~ObjectReader()
+{
+ zval_ptr_dtor(&_object);
+}
+
+void
+IcePHP::ObjectReader::ice_postUnmarshal()
+{
+ string name = "ice_postunmarshal"; // Must be lowercase.
+ if(zend_hash_exists(&Z_OBJCE_P(_object)->function_table, STRCAST(name.c_str()), name.size() + 1))
+ {
+ if(!invokeMethod(_object, name TSRMLS_CC))
+ {
+ throw AbortMarshaling();
+ }
+ }
+}
+
+void
+IcePHP::ObjectReader::read(const Ice::InputStreamPtr& is, bool rid)
+{
+ //
+ // Unmarshal the slices of a user-defined class.
+ //
+ ClassInfoPtr info = _info;
+ while(info && info->id != Ice::Object::ice_staticId())
+ {
+ if(rid)
+ {
+ is->readTypeId();
+ }
+
+ is->startSlice();
+ for(DataMemberList::iterator p = info->members.begin(); p != info->members.end(); ++p)
+ {
+ DataMemberPtr member = *p;
+ member->type->unmarshal(is, member, _communicator, _object, 0 TSRMLS_CC);
+ }
+ is->endSlice();
+
+ rid = true;
+
+ info = info->base;
+ }
+
+ //
+ // Unmarshal the Ice::Object slice.
+ //
+ if(rid)
+ {
+ is->readTypeId();
+ }
+
+ is->startSlice();
+ // For compatibility with the old AFM.
+ Ice::Int sz = is->readSize();
+ if(sz != 0)
+ {
+ throw Ice::MarshalException(__FILE__, __LINE__);
+ }
+ is->endSlice();
+}
+
+ClassInfoPtr
+IcePHP::ObjectReader::getInfo() const
+{
+ return _info;
+}
+
+zval*
+IcePHP::ObjectReader::getObject() const
+{
+ return _object;
+}
+
+//
+// ReadObjectCallback implementation.
+//
+IcePHP::ReadObjectCallback::ReadObjectCallback(const ClassInfoPtr& info, const UnmarshalCallbackPtr& cb,
+ zval* target, void* closure TSRMLS_DC) :
+ _info(info), _cb(cb), _target(target), _closure(closure)
+{
+#ifdef ZTS
+ this->TSRMLS_C = TSRMLS_C;
+#endif
+
+ //
+ // Keep a reference to the target to prevent it from being deallocated until the
+ // Ice object is actually read.
+ //
+ if(_target)
+ {
+ Z_ADDREF_P(_target);
+ }
+}
+
+IcePHP::ReadObjectCallback::~ReadObjectCallback()
+{
+ if(_target)
+ {
+ zval_ptr_dtor(&_target);
+ }
+}
+
+void
+IcePHP::ReadObjectCallback::invoke(const Ice::ObjectPtr& p)
+{
+ if(p)
+ {
+ ObjectReaderPtr reader = ObjectReaderPtr::dynamicCast(p);
+ assert(reader);
+
+ //
+ // Verify that the unmarshaled object is compatible with the formal type.
+ //
+ zval* obj = reader->getObject();
+ if(!reader->getInfo()->isA(_info->id))
+ {
+ Ice::UnexpectedObjectException ex(__FILE__, __LINE__);
+ ex.reason = "unmarshaled object is not an instance of " + _info->id;
+ ex.type = reader->getInfo()->id;
+ ex.expectedType = _info->id;
+ throw ex;
+ }
+
+ _cb->unmarshaled(obj, _target, _closure TSRMLS_CC);
+ }
+ else
+ {
+ zval* zv;
+ MAKE_STD_ZVAL(zv);
+ AutoDestroy destroy(zv);
+ ZVAL_NULL(zv);
+ _cb->unmarshaled(zv, _target, _closure TSRMLS_CC);
+ }
+}
+
+//
+// ExceptionInfo implementation.
+//
+zval*
+IcePHP::ExceptionInfo::unmarshal(const Ice::InputStreamPtr& is, const CommunicatorInfoPtr& comm TSRMLS_DC)
+{
+ zval* zv;
+ MAKE_STD_ZVAL(zv);
+ AutoDestroy destroy(zv);
+
+ if(object_init_ex(zv, zce) != SUCCESS)
+ {
+ runtimeError("unable to initialize object of type %s" TSRMLS_CC, zce->name);
+ throw AbortMarshaling();
+ }
+
+ //
+ // NOTE: The type id for the first slice has already been read.
+ //
+ ExceptionInfoPtr info = this;
+ while(info)
+ {
+ is->startSlice();
+ for(DataMemberList::iterator q = info->members.begin(); q != info->members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ member->type->unmarshal(is, member, comm, zv, 0 TSRMLS_CC);
+ }
+ is->endSlice();
+
+ info = info->base;
+ if(info)
+ {
+ is->readString(); // Read the ID of the next slice.
+ }
+ }
+
+ return destroy.release();
+}
+
+void
+IcePHP::ExceptionInfo::print(zval* zv, IceUtilInternal::Output& out TSRMLS_DC)
+{
+ if(Z_TYPE_P(zv) != IS_OBJECT)
+ {
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected exception value of type %s but received %s" TSRMLS_CC, zce->name, s.c_str());
+ return;
+ }
+
+ //
+ // Compare class entries.
+ //
+ zend_class_entry* ce = Z_OBJCE_P(zv);
+ if(ce != zce)
+ {
+ invalidArgument("expected exception value of type %s but received %s" TSRMLS_CC, zce->name, ce->name);
+ return;
+ }
+
+ PrintObjectHistory history;
+ history.index = 0;
+
+ out << "exception " << id;
+ out.sb();
+ printMembers(zv, out, &history TSRMLS_CC);
+ out.eb();
+}
+
+void
+IcePHP::ExceptionInfo::printMembers(zval* zv, IceUtilInternal::Output& out, PrintObjectHistory* history TSRMLS_DC)
+{
+ if(base)
+ {
+ base->printMembers(zv, out, history TSRMLS_CC);
+ }
+
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ out << nl << member->name << " = ";
+ void* data;
+ if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST(member->name.c_str()), member->name.size() + 1, &data) == SUCCESS)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ member->type->print(*val, out, history TSRMLS_CC);
+ }
+ else
+ {
+ out << "<not defined>";
+ }
+ }
+}
+
+bool
+IcePHP::ExceptionInfo::isA(const string& typeId) const
+{
+ if(id == typeId)
+ {
+ return true;
+ }
+
+ if(base && base->isA(typeId))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleTypeInfoAlloc(zend_class_entry* ce TSRMLS_DC)
+{
+ zend_object_value result;
+
+ Wrapper<TypeInfoPtr>* obj = Wrapper<TypeInfoPtr>::create(ce TSRMLS_CC);
+ assert(obj);
+
+ result.handle =
+ zend_objects_store_put(obj, 0, reinterpret_cast<zend_objects_free_object_storage_t>(handleTypeInfoFreeStorage),
+ 0 TSRMLS_CC);
+ result.handlers = &_typeInfoHandlers;
+
+ return result;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleTypeInfoFreeStorage(void* p TSRMLS_DC)
+{
+ Wrapper<TypeInfoPtr>* obj = static_cast<Wrapper<TypeInfoPtr>*>(p);
+ delete obj->ptr;
+ zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
+}
+
+static bool
+createTypeInfo(zval* zv, const TypeInfoPtr& p TSRMLS_DC)
+{
+ if(object_init_ex(zv, typeInfoClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize type" TSRMLS_CC);
+ return false;
+ }
+
+ Wrapper<TypeInfoPtr>* ze = static_cast<Wrapper<TypeInfoPtr>*>(zend_object_store_get_object(zv TSRMLS_CC));
+ assert(!ze->ptr);
+ ze->ptr = new TypeInfoPtr(p);
+
+ return true;
+}
+
+ZEND_FUNCTION(IcePHP_defineEnum)
+{
+ char* id;
+ int idLen;
+ zval* enumerators;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &id, &idLen, &enumerators) == FAILURE)
+ {
+ return;
+ }
+
+ EnumInfoPtr type = new EnumInfo();
+ type->id = id;
+ HashTable* arr = Z_ARRVAL_P(enumerators);
+ void* data;
+ HashPosition pos;
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+ assert(Z_TYPE_PP(val) == IS_STRING);
+ type->enumerators.push_back(Z_STRVAL_PP(val));
+ zend_hash_move_forward_ex(arr, &pos);
+ }
+
+ if(!createTypeInfo(return_value, type TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+static void
+convertDataMembers(zval* zv, DataMemberList& l TSRMLS_DC)
+{
+ assert(Z_TYPE_P(zv) == IS_ARRAY);
+ HashTable* membersArray = Z_ARRVAL_P(zv);
+ void* data;
+ HashPosition pos;
+ zend_hash_internal_pointer_reset_ex(membersArray, &pos);
+ while(zend_hash_get_current_data_ex(membersArray, &data, &pos) != FAILURE)
+ {
+ zval** arr = reinterpret_cast<zval**>(data);
+
+ DataMemberPtr m = new DataMember();
+ zval** elem;
+
+ assert(Z_TYPE_PP(arr) == IS_ARRAY);
+ HashTable* member = Z_ARRVAL_PP(arr);
+ assert(zend_hash_num_elements(member) == 2);
+ zend_hash_index_find(member, 0, reinterpret_cast<void**>(&elem));
+ assert(Z_TYPE_PP(elem) == IS_STRING);
+ m->name = Z_STRVAL_PP(elem);
+ zend_hash_index_find(member, 1, reinterpret_cast<void**>(&elem));
+ assert(Z_TYPE_PP(elem) == IS_OBJECT);
+ m->type = Wrapper<TypeInfoPtr>::value(*elem TSRMLS_CC);
+ l.push_back(m);
+
+ zend_hash_move_forward_ex(membersArray, &pos);
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineStruct)
+{
+ char* id;
+ int idLen;
+ char* name;
+ int nameLen;
+ zval* members;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssa", &id, &idLen, &name, &nameLen, &members) == FAILURE)
+ {
+ return;
+ }
+
+ StructInfoPtr type = new StructInfo();
+ type->id = id;
+ type->name = name;
+ convertDataMembers(members, type->members TSRMLS_CC);
+ type->zce = nameToClass(type->name TSRMLS_CC);
+ assert(type->zce);
+
+ if(!createTypeInfo(return_value, type TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineSequence)
+{
+ char* id;
+ int idLen;
+ zval* element;
+ zend_bool variableLength;
+ long minWireSize;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sobl", &id, &idLen, &element, &variableLength,
+ &minWireSize) == FAILURE)
+ {
+ return;
+ }
+
+ SequenceInfoPtr type = new SequenceInfo();
+ type->id = id;
+ type->elementType = Wrapper<TypeInfoPtr>::value(element TSRMLS_CC);
+ type->variableLength = variableLength ? true : false;
+ type->minWireSize = static_cast<int>(minWireSize);
+
+ if(!createTypeInfo(return_value, type TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineDictionary)
+{
+ char* id;
+ int idLen;
+ zval* key;
+ zval* value;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "soo", &id, &idLen, &key, &value) == FAILURE)
+ {
+ return;
+ }
+
+ DictionaryInfoPtr type = new DictionaryInfo();
+ type->id = id;
+ type->keyType = Wrapper<TypeInfoPtr>::value(key TSRMLS_CC);
+ type->valueType = Wrapper<TypeInfoPtr>::value(value TSRMLS_CC);
+
+ if(!createTypeInfo(return_value, type TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineProxy)
+{
+ zval* cls;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &cls) == FAILURE)
+ {
+ return;
+ }
+
+ TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(cls TSRMLS_CC);
+ ClassInfoPtr c = ClassInfoPtr::dynamicCast(p);
+ assert(c);
+
+ ProxyInfoPtr type = getProxyInfo(c->id TSRMLS_CC);
+ if(!type)
+ {
+ type = new ProxyInfo();
+ type->id = c->id;
+
+ ProxyInfoMap* m;
+ if(ICE_G(proxyInfoMap))
+ {
+ m = reinterpret_cast<ProxyInfoMap*>(ICE_G(proxyInfoMap));
+ }
+ else
+ {
+ m = new ProxyInfoMap;
+ ICE_G(proxyInfoMap) = m;
+ }
+ m->insert(ProxyInfoMap::value_type(type->id, type));
+ }
+
+ type->cls = c;
+
+ if(!createTypeInfo(return_value, type TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_declareClass)
+{
+ if(ZEND_NUM_ARGS() != 1)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ char* id;
+ int idLen;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &idLen) == FAILURE)
+ {
+ return;
+ }
+
+ ClassInfoPtr type = new ClassInfo();
+ type->id = id;
+ type->defined = false;
+
+ addClassInfoById(type TSRMLS_CC);
+
+ if(!createTypeInfo(return_value, type TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_defineClass)
+{
+ char* id;
+ int idLen;
+ char* name;
+ int nameLen;
+ zend_bool isAbstract;
+ zval* base;
+ zval* interfaces;
+ zval* members;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssbo!a!a!", &id, &idLen, &name, &nameLen, &isAbstract, &base,
+ &interfaces, &members) == FAILURE)
+ {
+ return;
+ }
+
+ ClassInfoPtr type = getClassInfoById(id TSRMLS_CC);
+ if(!type)
+ {
+ type = new ClassInfo();
+ type->id = id;
+ addClassInfoById(type TSRMLS_CC);
+ }
+
+ type->name = name;
+ addClassInfoByName(type TSRMLS_CC);
+
+ type->isAbstract = isAbstract ? true : false;
+ if(base)
+ {
+ TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(base TSRMLS_CC);
+ type->base = ClassInfoPtr::dynamicCast(p);
+ assert(type->base);
+ }
+
+ if(interfaces)
+ {
+ HashTable* interfacesArray = Z_ARRVAL_P(interfaces);
+ void* data;
+ HashPosition pos;
+ zend_hash_internal_pointer_reset_ex(interfacesArray, &pos);
+ while(zend_hash_get_current_data_ex(interfacesArray, &data, &pos) != FAILURE)
+ {
+ zval** interfaceType = reinterpret_cast<zval**>(data);
+ TypeInfoPtr t = Wrapper<TypeInfoPtr>::value(*interfaceType TSRMLS_CC);
+ ClassInfoPtr c = ClassInfoPtr::dynamicCast(t);
+ assert(c);
+ type->interfaces.push_back(c);
+ zend_hash_move_forward_ex(interfacesArray, &pos);
+ }
+ }
+
+ if(members)
+ {
+ convertDataMembers(members, type->members TSRMLS_CC);
+ }
+
+ type->defined = true;
+ type->zce = nameToClass(type->name TSRMLS_CC);
+ assert(type->zce || type->id == "::Ice::LocalObject"); // LocalObject does not have a native PHP equivalent.
+
+ if(!createTypeInfo(return_value, type TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static zend_object_value
+handleExceptionInfoAlloc(zend_class_entry* ce TSRMLS_DC)
+{
+ zend_object_value result;
+
+ Wrapper<ExceptionInfoPtr>* obj = Wrapper<ExceptionInfoPtr>::create(ce TSRMLS_CC);
+ assert(obj);
+
+ result.handle =
+ zend_objects_store_put(obj, 0,
+ reinterpret_cast<zend_objects_free_object_storage_t>(handleExceptionInfoFreeStorage), 0 TSRMLS_CC);
+ result.handlers = &_exceptionInfoHandlers;
+
+ return result;
+}
+
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+handleExceptionInfoFreeStorage(void* p TSRMLS_DC)
+{
+ Wrapper<ExceptionInfoPtr>* obj = static_cast<Wrapper<ExceptionInfoPtr>*>(p);
+ delete obj->ptr;
+ zend_objects_free_object_storage(static_cast<zend_object*>(p) TSRMLS_CC);
+}
+
+
+static bool
+createExceptionInfo(zval* zv, const ExceptionInfoPtr& p TSRMLS_DC)
+{
+ if(object_init_ex(zv, exceptionInfoClassEntry) != SUCCESS)
+ {
+ runtimeError("unable to initialize exception info" TSRMLS_CC);
+ return false;
+ }
+
+ Wrapper<ExceptionInfoPtr>* ze = static_cast<Wrapper<ExceptionInfoPtr>*>(zend_object_store_get_object(zv TSRMLS_CC));
+ assert(!ze->ptr);
+ ze->ptr = new ExceptionInfoPtr(p);
+
+ return true;
+}
+
+ZEND_FUNCTION(IcePHP_defineException)
+{
+ char* id;
+ int idLen;
+ char* name;
+ int nameLen;
+ zval* base;
+ zval* members;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sso!a!", &id, &idLen, &name, &nameLen, &base, &members) ==
+ FAILURE)
+ {
+ return;
+ }
+
+ ExceptionInfoPtr ex = new ExceptionInfo();
+ ex->id = id;
+ ex->name = name;
+ if(base)
+ {
+ ex->base = Wrapper<ExceptionInfoPtr>::value(base TSRMLS_CC);
+ }
+ if(members)
+ {
+ convertDataMembers(members, ex->members TSRMLS_CC);
+ }
+
+ ex->usesClasses = false;
+ for(DataMemberList::iterator p = ex->members.begin(); p != ex->members.end(); ++p)
+ {
+ if(!ex->usesClasses)
+ {
+ ex->usesClasses = (*p)->type->usesClasses();
+ }
+ }
+
+ ex->zce = nameToClass(ex->name TSRMLS_CC);
+
+ assert(!getExceptionInfo(ex->id TSRMLS_CC));
+
+ ExceptionInfoMap* m;
+ if(ICE_G(exceptionInfoMap))
+ {
+ m = reinterpret_cast<ExceptionInfoMap*>(ICE_G(exceptionInfoMap));
+ }
+ else
+ {
+ m = new ExceptionInfoMap;
+ ICE_G(exceptionInfoMap) = m;
+ }
+ m->insert(ExceptionInfoMap::value_type(ex->id, ex));
+
+ if(!createExceptionInfo(return_value, ex TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(IcePHP_stringify)
+{
+ if(ZEND_NUM_ARGS() != 2)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ zval* v;
+ zval* t;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &v, &t) == FAILURE)
+ {
+ return;
+ }
+
+ TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(t TSRMLS_CC);
+ assert(type);
+
+ ostringstream ostr;
+ IceUtilInternal::Output out(ostr);
+ PrintObjectHistory history;
+ history.index = 0;
+ type->print(v, out, &history TSRMLS_CC);
+
+ string str = ostr.str();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+}
+
+ZEND_FUNCTION(IcePHP_stringifyException)
+{
+ if(ZEND_NUM_ARGS() != 2)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ zval* v;
+ zval* t;
+
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo", &v, &t) == FAILURE)
+ {
+ return;
+ }
+
+ ExceptionInfoPtr ex = Wrapper<ExceptionInfoPtr>::value(t TSRMLS_CC);
+ assert(ex);
+
+ ostringstream ostr;
+ IceUtilInternal::Output out(ostr);
+ ex->print(v, out TSRMLS_CC);
+
+ string str = ostr.str();
+ RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
+}
+
+//
+// Predefined methods for IcePHP_TypeInfo.
+//
+static function_entry _typeInfoMethods[] =
+{
+ {0, 0, 0}
+};
+
+//
+// Predefined methods for IcePHP_ExceptionInfo.
+//
+static function_entry _exceptionInfoMethods[] =
+{
+ {0, 0, 0}
+};
+
+bool
+IcePHP::typesInit(TSRMLS_D)
+{
+ zend_class_entry ce;
+
+ //
+ // Register the IcePHP_TypeInfo class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_TypeInfo", _typeInfoMethods);
+ ce.create_object = handleTypeInfoAlloc;
+ typeInfoClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
+ memcpy(&_typeInfoHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+
+ //
+ // Register the IcePHP_ExceptionInfo class.
+ //
+ INIT_CLASS_ENTRY(ce, "IcePHP_ExceptionInfo", _exceptionInfoMethods);
+ ce.create_object = handleExceptionInfoAlloc;
+ exceptionInfoClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
+ memcpy(&_exceptionInfoHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+
+ return true;
+}
+
+bool
+IcePHP::typesRequestInit(TSRMLS_D)
+{
+ //
+ // Create the global variables for the primitive types.
+ //
+ for(int i = static_cast<int>(PrimitiveInfo::KindBool); i <= static_cast<int>(PrimitiveInfo::KindString); ++i)
+ {
+ PrimitiveInfoPtr type = new PrimitiveInfo();
+ type->kind = static_cast<PrimitiveInfo::Kind>(i);
+
+ zval* zv;
+ MAKE_STD_ZVAL(zv);
+ if(!createTypeInfo(zv, type TSRMLS_CC))
+ {
+ zval_ptr_dtor(&zv);
+ return false;
+ }
+ string name = "IcePHP__t_" + type->getId();
+ ZEND_SET_SYMBOL(&EG(symbol_table), const_cast<char*>(name.c_str()), zv);
+ }
+
+ ICE_G(idToClassInfoMap) = 0;
+ ICE_G(nameToClassInfoMap) = 0;
+ ICE_G(proxyInfoMap) = 0;
+ ICE_G(exceptionInfoMap) = 0;
+
+ return true;
+}
+
+bool
+IcePHP::typesRequestShutdown(TSRMLS_D)
+{
+ if(ICE_G(proxyInfoMap))
+ {
+ ProxyInfoMap* m = static_cast<ProxyInfoMap*>(ICE_G(proxyInfoMap));
+ for(ProxyInfoMap::iterator p = m->begin(); p != m->end(); ++p)
+ {
+ p->second->destroy();
+ }
+ delete m;
+ }
+
+ if(ICE_G(idToClassInfoMap))
+ {
+ ClassInfoMap* m = static_cast<ClassInfoMap*>(ICE_G(idToClassInfoMap));
+ for(ClassInfoMap::iterator p = m->begin(); p != m->end(); ++p)
+ {
+ p->second->destroy();
+ }
+ delete m;
+ }
+
+ if(ICE_G(nameToClassInfoMap))
+ {
+ ClassInfoMap* m = static_cast<ClassInfoMap*>(ICE_G(nameToClassInfoMap));
+ delete m;
+ }
+
+ delete static_cast<ExceptionInfoMap*>(ICE_G(exceptionInfoMap));
+
+ return true;
+}
diff --git a/php/src/IcePHP/Types.h b/php/src/IcePHP/Types.h
new file mode 100644
index 00000000000..c994201717d
--- /dev/null
+++ b/php/src/IcePHP/Types.h
@@ -0,0 +1,465 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICEPHP_TYPES_H
+#define ICEPHP_TYPES_H
+
+#include <Config.h>
+#include <Communicator.h>
+#include <Operation.h>
+#include <Ice/Stream.h>
+#include <IceUtil/OutputUtil.h>
+
+//
+// Global functions.
+//
+extern "C"
+{
+ZEND_FUNCTION(IcePHP_defineEnum);
+ZEND_FUNCTION(IcePHP_defineStruct);
+ZEND_FUNCTION(IcePHP_defineSequence);
+ZEND_FUNCTION(IcePHP_defineDictionary);
+ZEND_FUNCTION(IcePHP_defineProxy);
+ZEND_FUNCTION(IcePHP_declareClass);
+ZEND_FUNCTION(IcePHP_defineClass);
+ZEND_FUNCTION(IcePHP_defineException);
+ZEND_FUNCTION(IcePHP_stringify);
+ZEND_FUNCTION(IcePHP_stringifyException);
+}
+
+#define ICEPHP_TYPE_FUNCTIONS \
+ ZEND_FE(IcePHP_defineEnum, NULL) \
+ ZEND_FE(IcePHP_defineStruct, NULL) \
+ ZEND_FE(IcePHP_defineSequence, NULL) \
+ ZEND_FE(IcePHP_defineDictionary, NULL) \
+ ZEND_FE(IcePHP_defineProxy, NULL) \
+ ZEND_FE(IcePHP_declareClass, NULL) \
+ ZEND_FE(IcePHP_defineClass, NULL) \
+ ZEND_FE(IcePHP_defineException, NULL) \
+ ZEND_FE(IcePHP_stringify, NULL) \
+ ZEND_FE(IcePHP_stringifyException, NULL)
+
+namespace IcePHP
+{
+
+//
+// This class is raised as an exception when object marshaling needs to be aborted.
+//
+class AbortMarshaling
+{
+};
+
+typedef std::map<unsigned int, Ice::ObjectPtr> ObjectMap;
+
+struct PrintObjectHistory
+{
+ int index;
+ std::map<unsigned int, int> objects;
+};
+
+//
+// The delayed nature of class unmarshaling in the Ice protocol requires us to
+// handle unmarshaling using a callback strategy. An instance of UnmarshalCallback
+// is supplied to each type's unmarshal() member function. For all types except
+// classes, the callback is invoked with the unmarshaled value before unmarshal()
+// returns. For class instances, however, the callback may not be invoked until
+// the stream's finished() function is called.
+//
+class UnmarshalCallback : public IceUtil::Shared
+{
+public:
+
+ virtual ~UnmarshalCallback();
+
+ //
+ // The unmarshaled() member function receives the unmarshaled value. The
+ // last two arguments are the values passed to unmarshal() for use by
+ // UnmarshalCallback implementations.
+ //
+ virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC) = 0;
+};
+typedef IceUtil::Handle<UnmarshalCallback> UnmarshalCallbackPtr;
+
+//
+// Base class for type information.
+//
+class TypeInfo : public UnmarshalCallback
+{
+public:
+
+ virtual std::string getId() const = 0;
+
+ virtual bool validate(zval* TSRMLS_DC) = 0;
+
+ virtual bool usesClasses(); // Default implementation returns false.
+
+ virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC); // Default implementation is assert(false).
+
+ virtual void destroy();
+
+protected:
+
+ TypeInfo();
+
+public:
+
+ //
+ // The marshal and unmarshal functions can raise Ice exceptions, and may raise
+ // AbortMarshaling if an error occurs.
+ //
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC) = 0;
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void* TSRMLS_DC) = 0;
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC) = 0;
+};
+typedef IceUtil::Handle<TypeInfo> TypeInfoPtr;
+
+//
+// Primitive type information.
+//
+class PrimitiveInfo : public TypeInfo
+{
+public:
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval* TSRMLS_DC);
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void* TSRMLS_DC);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC);
+
+ enum Kind
+ {
+ KindBool,
+ KindByte,
+ KindShort,
+ KindInt,
+ KindLong,
+ KindFloat,
+ KindDouble,
+ KindString
+ };
+
+ Kind kind;
+};
+typedef IceUtil::Handle<PrimitiveInfo> PrimitiveInfoPtr;
+
+//
+// Enum information.
+//
+class EnumInfo : public TypeInfo
+{
+public:
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval* TSRMLS_DC);
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void* TSRMLS_DC);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC);
+
+ std::string id;
+ Ice::StringSeq enumerators;
+};
+typedef IceUtil::Handle<EnumInfo> EnumInfoPtr;
+
+class DataMember : public UnmarshalCallback
+{
+public:
+
+ virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC);
+
+ std::string name;
+ TypeInfoPtr type;
+};
+typedef IceUtil::Handle<DataMember> DataMemberPtr;
+typedef std::vector<DataMemberPtr> DataMemberList;
+
+//
+// Struct information.
+//
+class StructInfo : public TypeInfo
+{
+public:
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval* TSRMLS_DC);
+
+ virtual bool usesClasses();
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void* TSRMLS_DC);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC);
+
+ virtual void destroy();
+
+ std::string id;
+ std::string name; // PHP class name
+ DataMemberList members;
+ zend_class_entry* zce;
+};
+typedef IceUtil::Handle<StructInfo> StructInfoPtr;
+
+//
+// Sequence information.
+//
+class SequenceInfo : public TypeInfo
+{
+public:
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval* TSRMLS_DC);
+
+ virtual bool usesClasses();
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void* TSRMLS_DC);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC);
+
+ virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC);
+
+ virtual void destroy();
+
+ std::string id;
+ TypeInfoPtr elementType;
+ bool variableLength;
+ int minWireSize;
+
+private:
+
+ void marshalPrimitiveSequence(const PrimitiveInfoPtr&, zval*, const Ice::OutputStreamPtr& TSRMLS_DC);
+ void unmarshalPrimitiveSequence(const PrimitiveInfoPtr&, const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&,
+ zval*, void* TSRMLS_DC);
+};
+typedef IceUtil::Handle<SequenceInfo> SequenceInfoPtr;
+
+//
+// Dictionary information.
+//
+class DictionaryInfo : public TypeInfo
+{
+public:
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval* TSRMLS_DC);
+
+ virtual bool usesClasses();
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void* TSRMLS_DC);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC);
+
+ virtual void destroy();
+
+ class KeyCallback : public UnmarshalCallback
+ {
+ public:
+
+ KeyCallback();
+ ~KeyCallback();
+
+ virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC);
+
+ zval* key;
+ };
+ typedef IceUtil::Handle<KeyCallback> KeyCallbackPtr;
+
+ class ValueCallback : public UnmarshalCallback
+ {
+ public:
+
+ ValueCallback(zval* TSRMLS_DC);
+ ~ValueCallback();
+
+ virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC);
+
+ zval* key;
+ };
+ typedef IceUtil::Handle<ValueCallback> ValueCallbackPtr;
+
+ std::string id;
+ TypeInfoPtr keyType;
+ TypeInfoPtr valueType;
+};
+typedef IceUtil::Handle<DictionaryInfo> DictionaryInfoPtr;
+
+class ExceptionInfo;
+typedef IceUtil::Handle<ExceptionInfo> ExceptionInfoPtr;
+typedef std::vector<ExceptionInfoPtr> ExceptionInfoList;
+
+class ClassInfo;
+typedef IceUtil::Handle<ClassInfo> ClassInfoPtr;
+typedef std::vector<ClassInfoPtr> ClassInfoList;
+
+typedef std::vector<TypeInfoPtr> TypeInfoList;
+
+class ClassInfo : public TypeInfo
+{
+public:
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval* TSRMLS_DC);
+
+ virtual bool usesClasses();
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void* TSRMLS_DC);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC);
+
+ virtual void destroy();
+
+ void printMembers(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC);
+
+ bool isA(const std::string&) const;
+
+ void addOperation(const std::string&, const OperationPtr&);
+ OperationPtr getOperation(const std::string&) const;
+
+ std::string id;
+ std::string name; // PHP class name
+ bool isAbstract;
+ ClassInfoPtr base;
+ ClassInfoList interfaces;
+ DataMemberList members;
+ bool defined;
+ zend_class_entry* zce;
+
+ typedef std::map<std::string, OperationPtr> OperationMap;
+ OperationMap operations;
+};
+
+//
+// Proxy information.
+//
+class ProxyInfo : public TypeInfo
+{
+public:
+
+ virtual std::string getId() const;
+
+ virtual bool validate(zval* TSRMLS_DC);
+
+ virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap* TSRMLS_DC);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
+ zval*, void* TSRMLS_DC);
+
+ virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC);
+
+ virtual void destroy();
+
+ std::string id;
+ ClassInfoPtr cls;
+};
+typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr;
+
+//
+// Exception information.
+//
+class ExceptionInfo : public IceUtil::Shared
+{
+public:
+
+ zval* unmarshal(const Ice::InputStreamPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
+
+ void print(zval*, IceUtilInternal::Output& TSRMLS_DC);
+ void printMembers(zval*, IceUtilInternal::Output&, PrintObjectHistory* TSRMLS_DC);
+
+ bool isA(const std::string&) const;
+
+ std::string id;
+ std::string name; // PHP class name
+ ExceptionInfoPtr base;
+ DataMemberList members;
+ bool usesClasses;
+ zend_class_entry* zce;
+};
+
+ClassInfoPtr getClassInfoById(const std::string& TSRMLS_DC);
+ClassInfoPtr getClassInfoByName(const std::string& TSRMLS_DC);
+ExceptionInfoPtr getExceptionInfo(const std::string& TSRMLS_DC);
+
+bool typesInit(TSRMLS_D);
+bool typesRequestInit(TSRMLS_D);
+bool typesRequestShutdown(TSRMLS_D);
+
+//
+// ObjectWriter wraps a PHP object for marshaling.
+//
+class ObjectWriter : public Ice::ObjectWriter
+{
+public:
+
+ ObjectWriter(const ClassInfoPtr&, zval*, ObjectMap* TSRMLS_DC);
+ ~ObjectWriter();
+
+ virtual void ice_preMarshal();
+
+ virtual void write(const Ice::OutputStreamPtr&) const;
+
+private:
+
+ ClassInfoPtr _info;
+ zval* _object;
+ ObjectMap* _map;
+#if ZTS
+ TSRMLS_D;
+#endif
+};
+
+//
+// ObjectReader unmarshals the state of an Ice object.
+//
+class ObjectReader : public Ice::ObjectReader
+{
+public:
+
+ ObjectReader(zval*, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
+ ~ObjectReader();
+
+ virtual void ice_postUnmarshal();
+
+ virtual void read(const Ice::InputStreamPtr&, bool);
+
+ virtual ClassInfoPtr getInfo() const;
+
+ zval* getObject() const;
+
+private:
+
+ zval* _object;
+ ClassInfoPtr _info;
+ CommunicatorInfoPtr _communicator;
+#if ZTS
+ TSRMLS_D;
+#endif
+};
+typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr;
+
+} // End of namespace IcePHP
+
+#endif
diff --git a/php/src/IcePHP/Util.cpp b/php/src/IcePHP/Util.cpp
index 693d8a5385c..da6e282e4ff 100644
--- a/php/src/IcePHP/Util.cpp
+++ b/php/src/IcePHP/Util.cpp
@@ -8,86 +8,97 @@
// **********************************************************************
#include <Util.h>
-#include <IceUtil/DisableWarnings.h>
+#include <IceUtil/UUID.h>
+#include <Slice/PHPUtil.h>
#include <algorithm>
#include <ctype.h>
using namespace std;
using namespace IcePHP;
+using namespace Slice::PHP;
-static string
-lookupKwd(const string& name)
+#ifdef _WIN32
+extern "C"
+#endif
+static void
+dtor_wrapper(void* p)
{
- string lower = lowerCase(name); // PHP is case insensitive.
+ zval_ptr_dtor(static_cast<zval**>(p));
+}
- //
- // Keyword list. *Must* be kept in alphabetical order.
- //
- static const string keywordList[] =
- {
- "abstract", "and", "array", "as", "break", "case", "catch", "class", "clone", "const", "continue", "declare",
- "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif",
- "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "if",
- "implements", "include", "include_once", "interface", "isset", "list", "new", "or", "print", "private",
- "protected", "public", "require", "require_once", "return", "static", "switch", "this", "throw", "try",
- "unset", "use", "var", "while", "xor"
- };
- bool found = binary_search(&keywordList[0],
- &keywordList[sizeof(keywordList) / sizeof(*keywordList)],
- lower);
- return found ? "_" + name : name;
+void*
+IcePHP::createWrapper(zend_class_entry* ce, size_t sz TSRMLS_DC)
+{
+ zend_object* obj;
+ zval* tmp;
+
+ obj = static_cast<zend_object*>(emalloc(sz));
+ obj->ce = ce;
+ obj->guards = 0;
+
+ obj->properties = static_cast<HashTable*>(emalloc(sizeof(HashTable)));
+ zend_hash_init(obj->properties, 0, 0, dtor_wrapper, 0);
+ zend_hash_copy(obj->properties, &ce->default_properties, (copy_ctor_func_t)zval_add_ref, &tmp, sizeof(zval*));
+
+ return obj;
}
-//
-// Split a scoped name into its components and return the components as a list of (unscoped) identifiers.
-//
-static vector<string>
-splitScopedName(const string& scoped)
+void*
+IcePHP::extractWrapper(zval* zv TSRMLS_DC)
{
- assert(scoped[0] == ':');
- vector<string> ids;
- string::size_type next = 0;
- string::size_type pos;
- while((pos = scoped.find("::", next)) != string::npos)
- {
- pos += 2;
- if(pos != scoped.size())
- {
- string::size_type endpos = scoped.find("::", pos);
- if(endpos != string::npos)
- {
- ids.push_back(scoped.substr(pos, endpos - pos));
- }
- }
- next = pos;
- }
- if(next != scoped.size())
+ if(!zv)
{
- ids.push_back(scoped.substr(next));
+ runtimeError("method %s() must be invoked on an object" TSRMLS_CC, get_active_function_name(TSRMLS_C));
+ return 0;
}
- else
+
+ zend_object* obj = static_cast<zend_object*>(zend_object_store_get_object(zv TSRMLS_CC));
+ if(!obj)
{
- ids.push_back("");
+ runtimeError("no object found in %s()" TSRMLS_CC, get_active_function_name(TSRMLS_C));
+ return 0;
}
- return ids;
+ return obj;
+}
+
+zend_class_entry*
+IcePHP::idToClass(const string& id TSRMLS_DC)
+{
+#ifdef ICEPHP_USE_NAMESPACES
+ string cls = scopedToName(id, true);
+#else
+ string cls = scopedToName(id, false);
+#endif
+
+ return nameToClass(cls TSRMLS_CC);
+}
+
+zend_class_entry*
+IcePHP::nameToClass(const string& name TSRMLS_DC)
+{
+ zend_class_entry** result;
+ if(zend_lookup_class(STRCAST(name.c_str()), name.length(), &result TSRMLS_CC) == FAILURE)
+ {
+ return 0;
+ }
+ return *result;
}
bool
IcePHP::createIdentity(zval* zv, const Ice::Identity& id TSRMLS_DC)
{
- zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC);
+ zend_class_entry* cls = idToClass("::Ice::Identity" TSRMLS_CC);
assert(cls);
if(object_init_ex(zv, cls) != SUCCESS)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to initialize Ice::Identity");
+ runtimeError("unable to initialize Ice::Identity" TSRMLS_CC);
return false;
}
- zend_update_property_string(cls, zv, "name", sizeof("name") - 1, const_cast<char*>(id.name.c_str()) TSRMLS_CC);
- zend_update_property_string(cls, zv, "category", sizeof("category") - 1,
- const_cast<char*>(id.category.c_str()) TSRMLS_CC);
+ zend_update_property_string(cls, zv, "name", sizeof("name") - 1, STRCAST(id.name.c_str()) TSRMLS_CC);
+ zend_update_property_string(cls, zv, "category", sizeof("category") - 1, STRCAST(id.category.c_str()) TSRMLS_CC);
return true;
}
@@ -97,17 +108,17 @@ IcePHP::extractIdentity(zval* zv, Ice::Identity& id TSRMLS_DC)
{
if(Z_TYPE_P(zv) != IS_OBJECT)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "value does not contain an object");
+ invalidArgument("value does not contain an object" TSRMLS_CC);
return false;
}
- zend_class_entry* cls = findClass("Ice_Identity" TSRMLS_CC);
+ zend_class_entry* cls = idToClass("::Ice::Identity" TSRMLS_CC);
assert(cls);
zend_class_entry* ce = Z_OBJCE_P(zv);
if(ce != cls)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected an identity but received %s", ce->name);
+ invalidArgument("expected an identity but received %s" TSRMLS_CC, ce->name);
return false;
}
@@ -118,7 +129,7 @@ IcePHP::extractIdentity(zval* zv, Ice::Identity& id TSRMLS_DC)
void* nameData;
if(zend_hash_find(Z_OBJPROP_P(zv), "name", sizeof("name"), &nameData) == FAILURE)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "identity value does not contain member `name'");
+ invalidArgument("identity value does not contain member `name'" TSRMLS_CC);
return false;
}
zend_hash_find(Z_OBJPROP_P(zv), "category", sizeof("category"), &categoryData);
@@ -128,16 +139,14 @@ IcePHP::extractIdentity(zval* zv, Ice::Identity& id TSRMLS_DC)
if(Z_TYPE_PP(nameVal) != IS_STRING)
{
string s = zendTypeToString(Z_TYPE_PP(nameVal));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected a string value for identity member `name' but received %s",
- s.c_str());
+ invalidArgument("expected a string value for identity member `name' but received %s" TSRMLS_CC, s.c_str());
return false;
}
if(categoryVal && Z_TYPE_PP(categoryVal) != IS_STRING && Z_TYPE_PP(categoryVal) != IS_NULL)
{
string s = zendTypeToString(Z_TYPE_PP(categoryVal));
- php_error_docref(0 TSRMLS_CC, E_ERROR,
- "expected a string value for identity member `category' but received %s", s.c_str());
+ invalidArgument("expected a string value for identity member `category' but received %s" TSRMLS_CC, s.c_str());
return false;
}
@@ -155,28 +164,28 @@ IcePHP::extractIdentity(zval* zv, Ice::Identity& id TSRMLS_DC)
}
bool
-IcePHP::createContext(zval* zv, const Ice::Context& ctx TSRMLS_DC)
+IcePHP::createStringMap(zval* zv, const map<string, string>& ctx TSRMLS_DC)
{
array_init(zv);
- for(Ice::Context::const_iterator p = ctx.begin(); p != ctx.end(); ++p)
+ for(map<string, string>::const_iterator p = ctx.begin(); p != ctx.end(); ++p)
{
- zval* val;
- MAKE_STD_ZVAL(val);
- ZVAL_STRINGL(val, const_cast<char*>(p->second.c_str()), p->second.length(), 1);
- add_assoc_zval_ex(zv, const_cast<char*>(p->first.c_str()), p->first.length() + 1, val);
+ if(add_assoc_stringl_ex(zv, const_cast<char*>(p->first.c_str()), p->first.length() + 1,
+ const_cast<char*>(p->second.c_str()), p->second.length(), 1) == FAILURE)
+ {
+ return false;
+ }
}
return true;
}
bool
-IcePHP::extractContext(zval* zv, Ice::Context& ctx TSRMLS_DC)
+IcePHP::extractStringMap(zval* zv, map<string, string>& ctx TSRMLS_DC)
{
if(Z_TYPE_P(zv) != IS_ARRAY)
{
string s = zendTypeToString(Z_TYPE_P(zv));
- php_error_docref(0 TSRMLS_CC, E_ERROR, "expected an array for the context argument but received %s",
- s.c_str());
+ invalidArgument("expected an associative array but received %s" TSRMLS_CC, s.c_str());
return false;
}
@@ -202,13 +211,13 @@ IcePHP::extractContext(zval* zv, Ice::Context& ctx TSRMLS_DC)
//
if(keyType != HASH_KEY_IS_STRING)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "context key must be a string");
+ invalidArgument("array key must be a string" TSRMLS_CC);
return false;
}
if(Z_TYPE_PP(val) != IS_STRING)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "context value must be a string");
+ invalidArgument("array value must be a string" TSRMLS_CC);
return false;
}
@@ -220,384 +229,288 @@ IcePHP::extractContext(zval* zv, Ice::Context& ctx TSRMLS_DC)
return true;
}
-#ifdef _WIN32
-extern "C"
-#endif
-static void
-dtor_wrapper(void* p)
-{
- zval_ptr_dtor(static_cast<zval**>(p));
-}
-
-ice_object*
-IcePHP::newObject(zend_class_entry* ce TSRMLS_DC)
+bool
+IcePHP::createStringArray(zval* zv, const Ice::StringSeq& seq TSRMLS_DC)
{
- ice_object* obj;
- zval* tmp;
-
- obj = static_cast<ice_object*>(emalloc(sizeof(ice_object)));
- obj->zobj.ce = ce;
- obj->zobj.guards = 0;
- obj->ptr = 0;
-
- obj->zobj.properties = static_cast<HashTable*>(emalloc(sizeof(HashTable)));
- zend_hash_init(obj->zobj.properties, 0, 0, dtor_wrapper, 0);
- zend_hash_copy(obj->zobj.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, &tmp,
- sizeof(zval*));
+ array_init(zv);
+ for(Ice::StringSeq::const_iterator p = seq.begin(); p != seq.end(); ++p)
+ {
+ if(add_next_index_stringl(zv, STRCAST(p->c_str()), p->length(), 1) == FAILURE)
+ {
+ return false;
+ }
+ }
- return obj;
+ return true;
}
-ice_object*
-IcePHP::getObject(zval* zv TSRMLS_DC)
+bool
+IcePHP::extractStringArray(zval* zv, Ice::StringSeq& seq TSRMLS_DC)
{
- if(!zv)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "method %s() must be invoked on an object",
- get_active_function_name(TSRMLS_C));
- return 0;
- }
-
- ice_object* obj = static_cast<ice_object*>(zend_object_store_get_object(zv TSRMLS_CC));
- if(!obj)
+ if(Z_TYPE_P(zv) != IS_ARRAY)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "no object found in %s()", get_active_function_name(TSRMLS_C));
- return 0;
+ string s = zendTypeToString(Z_TYPE_P(zv));
+ invalidArgument("expected an array of strings but received %s" TSRMLS_CC, s.c_str());
+ return false;
}
- return obj;
-}
+ HashTable* arr = Z_ARRVAL_P(zv);
+ void* data;
+ HashPosition pos;
-void
-IcePHP::throwException(const IceUtil::Exception& ex TSRMLS_DC)
-{
- try
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+ while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
{
- try
+ zval** val = reinterpret_cast<zval**>(data);
+
+ if(Z_TYPE_PP(val) != IS_STRING)
{
- ex.ice_throw();
+ invalidArgument("array element must be a string" TSRMLS_CC);
+ return false;
}
- catch(const Ice::TwowayOnlyException& e)
- {
- string name = e.ice_name();
- zend_class_entry* cls = findClassScoped(name TSRMLS_CC);
- if(!cls)
- {
- throw;
- }
- zval* zex;
- MAKE_STD_ZVAL(zex);
- if(object_init_ex(zex, cls) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return;
- }
+ string s(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
+ seq.push_back(s);
- //
- // Set the unknown member.
- //
- zend_update_property_string(cls, zex, "operation", sizeof("operation") - 1,
- const_cast<char*>(e.operation.c_str()) TSRMLS_CC);
+ zend_hash_move_forward_ex(arr, &pos);
+ }
- //
- // Throw the exception.
- //
- zend_throw_exception_object(zex TSRMLS_CC);
- }
- catch(const Ice::UnknownException& e)
- {
- string name = e.ice_name();
- zend_class_entry* cls = findClassScoped(name TSRMLS_CC);
- if(!cls)
- {
- throw;
- }
+ return true;
+}
- zval* zex;
- MAKE_STD_ZVAL(zex);
- if(object_init_ex(zex, cls) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return;
- }
+static void
+setStringMember(zval* obj, const string& name, const string& val TSRMLS_DC)
+{
+ zend_class_entry* cls = Z_OBJCE_P(obj);
+ assert(cls);
+ zend_update_property_stringl(cls, obj, const_cast<char*>(name.c_str()), static_cast<int>(name.size()),
+ const_cast<char*>(val.c_str()), static_cast<int>(val.size()) TSRMLS_CC);
+}
- //
- // Set the unknown member.
- //
- zend_update_property_string(cls, zex, "unknown", sizeof("unknown") - 1,
- const_cast<char*>(e.unknown.c_str()) TSRMLS_CC);
+static bool
+convertLocalException(const Ice::LocalException& ex, zval* zex TSRMLS_DC)
+{
+ zend_class_entry* cls = Z_OBJCE_P(zex);
+ assert(cls);
- //
- // Throw the exception.
- //
- zend_throw_exception_object(zex TSRMLS_CC);
- }
- catch(const Ice::RequestFailedException& e)
+ //
+ // Transfer data members from Ice exception to PHP object.
+ //
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const Ice::InitializationException& e)
+ {
+ setStringMember(zex, "reason", e.reason TSRMLS_CC);
+ }
+ catch(const Ice::PluginInitializationException& e)
+ {
+ setStringMember(zex, "reason", e.reason TSRMLS_CC);
+ }
+ catch(const Ice::AlreadyRegisteredException& e)
+ {
+ setStringMember(zex, "kindOfObject", e.kindOfObject TSRMLS_CC);
+ setStringMember(zex, "id", e.id TSRMLS_CC);
+ }
+ catch(const Ice::NotRegisteredException& e)
+ {
+ setStringMember(zex, "kindOfObject", e.kindOfObject TSRMLS_CC);
+ setStringMember(zex, "id", e.id TSRMLS_CC);
+ }
+ catch(const Ice::TwowayOnlyException& e)
+ {
+ setStringMember(zex, "operation", e.operation TSRMLS_CC);
+ }
+ catch(const Ice::UnknownException& e)
+ {
+ setStringMember(zex, "unknown", e.unknown TSRMLS_CC);
+ }
+ catch(const Ice::ObjectAdapterDeactivatedException& e)
+ {
+ setStringMember(zex, "name", e.name TSRMLS_CC);
+ }
+ catch(const Ice::ObjectAdapterIdInUseException& e)
+ {
+ setStringMember(zex, "id", e.id TSRMLS_CC);
+ }
+ catch(const Ice::NoEndpointException& e)
+ {
+ setStringMember(zex, "proxy", e.proxy TSRMLS_CC);
+ }
+ catch(const Ice::EndpointParseException& e)
+ {
+ setStringMember(zex, "str", e.str TSRMLS_CC);
+ }
+ catch(const Ice::IdentityParseException& e)
+ {
+ setStringMember(zex, "str", e.str TSRMLS_CC);
+ }
+ catch(const Ice::ProxyParseException& e)
+ {
+ setStringMember(zex, "str", e.str TSRMLS_CC);
+ }
+ catch(const Ice::IllegalIdentityException& e)
+ {
+ zval* id;
+ MAKE_STD_ZVAL(id);
+ if(!createIdentity(id, e.id TSRMLS_CC))
{
- string name = e.ice_name();
- zend_class_entry* cls = findClassScoped(name TSRMLS_CC);
- if(!cls)
- {
- throw;
- }
-
- zval* zex;
- MAKE_STD_ZVAL(zex);
- if(object_init_ex(zex, cls) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return;
- }
-
- //
- // Set the id member.
- //
- zval* id;
- MAKE_STD_ZVAL(id);
- if(!createIdentity(id, e.id TSRMLS_CC))
- {
- return;
- }
- zend_update_property(cls, zex, "id", sizeof("id") - 1, id TSRMLS_CC);
-
- //
- // Set the facet member.
- //
- zval* facet;
- MAKE_STD_ZVAL(facet);
- ZVAL_STRINGL(facet, const_cast<char*>(e.facet.c_str()), e.facet.length(), 1);
- zend_update_property(cls, zex, "facet", sizeof("facet") - 1, facet TSRMLS_CC);
-
- //
- // Set the operation member.
- //
- zend_update_property_string(cls, zex, "operation", sizeof("operation") - 1,
- const_cast<char*>(e.operation.c_str()) TSRMLS_CC);
-
- //
- // Throw the exception.
- //
- zend_throw_exception_object(zex TSRMLS_CC);
+ zval_ptr_dtor(&id);
+ return false;
}
- catch(const Ice::NoObjectFactoryException& e)
+ zend_update_property(cls, zex, "id", sizeof("id") - 1, id TSRMLS_CC);
+ }
+ catch(const Ice::RequestFailedException& e)
+ {
+ zval* id;
+ MAKE_STD_ZVAL(id);
+ if(!createIdentity(id, e.id TSRMLS_CC))
{
- string name = e.ice_name();
- zend_class_entry* cls = findClassScoped(name TSRMLS_CC);
- if(!cls)
- {
- throw;
- }
-
- zval* zex;
- MAKE_STD_ZVAL(zex);
- if(object_init_ex(zex, cls) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return;
- }
-
- //
- // Set the reason member.
- //
- zend_update_property_string(cls, zex, "reason", sizeof("reason") - 1,
- const_cast<char*>(e.reason.c_str()) TSRMLS_CC);
-
- //
- // Set the type member.
- //
- zend_update_property_string(cls, zex, "type", sizeof("type") - 1, const_cast<char*>(e.type.c_str())
- TSRMLS_CC);
-
- //
- // Throw the exception.
- //
- zend_throw_exception_object(zex TSRMLS_CC);
+ zval_ptr_dtor(&id);
+ return false;
}
- catch(const Ice::UnexpectedObjectException& e)
- {
- string name = e.ice_name();
- zend_class_entry* cls = findClassScoped(name TSRMLS_CC);
- if(!cls)
- {
- throw;
- }
-
- zval* zex;
- MAKE_STD_ZVAL(zex);
- if(object_init_ex(zex, cls) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return;
- }
+ zend_update_property(cls, zex, "id", sizeof("id") - 1, id TSRMLS_CC);
+ setStringMember(zex, "facet", e.facet TSRMLS_CC);
+ setStringMember(zex, "operation", e.operation TSRMLS_CC);
+ }
+ catch(const Ice::FileException& e)
+ {
+ zend_update_property_long(cls, zex, "error", sizeof("error") - 1, e.error TSRMLS_CC);
+ setStringMember(zex, "path", e.path TSRMLS_CC);
+ }
+ catch(const Ice::SyscallException& e) // This must appear after all subclasses of SyscallException.
+ {
+ zend_update_property_long(cls, zex, "error", sizeof("error") - 1, e.error TSRMLS_CC);
+ }
+ catch(const Ice::DNSException& e)
+ {
+ zend_update_property_long(cls, zex, "error", sizeof("error") - 1, e.error TSRMLS_CC);
+ setStringMember(zex, "host", e.host TSRMLS_CC);
+ }
+ catch(const Ice::UnsupportedProtocolException& e)
+ {
+ zend_update_property_long(cls, zex, "badMajor", sizeof("badMajor") - 1, e.badMajor TSRMLS_CC);
+ zend_update_property_long(cls, zex, "badMinor", sizeof("badMinor") - 1, e.badMinor TSRMLS_CC);
+ zend_update_property_long(cls, zex, "major", sizeof("major") - 1, e.major TSRMLS_CC);
+ zend_update_property_long(cls, zex, "minor", sizeof("minor") - 1, e.minor TSRMLS_CC);
+ }
+ catch(const Ice::UnsupportedEncodingException& e)
+ {
+ zend_update_property_long(cls, zex, "badMajor", sizeof("badMajor") - 1, e.badMajor TSRMLS_CC);
+ zend_update_property_long(cls, zex, "badMinor", sizeof("badMinor") - 1, e.badMinor TSRMLS_CC);
+ zend_update_property_long(cls, zex, "major", sizeof("major") - 1, e.major TSRMLS_CC);
+ zend_update_property_long(cls, zex, "minor", sizeof("minor") - 1, e.minor TSRMLS_CC);
+ }
+ catch(const Ice::NoObjectFactoryException& e)
+ {
+ setStringMember(zex, "reason", e.reason TSRMLS_CC);
+ setStringMember(zex, "type", e.type TSRMLS_CC);
+ }
+ catch(const Ice::UnexpectedObjectException& e)
+ {
+ setStringMember(zex, "reason", e.reason TSRMLS_CC);
+ setStringMember(zex, "type", e.type TSRMLS_CC);
+ setStringMember(zex, "expectedType", e.expectedType TSRMLS_CC);
+ }
+ catch(const Ice::ProtocolException& e) // This must appear after all subclasses of ProtocolException.
+ {
+ setStringMember(zex, "reason", e.reason TSRMLS_CC);
+ }
+ catch(const Ice::FeatureNotSupportedException& e)
+ {
+ setStringMember(zex, "unsupportedFeature", e.unsupportedFeature TSRMLS_CC);
+ }
+ catch(const Ice::SecurityException& e)
+ {
+ setStringMember(zex, "reason", e.reason TSRMLS_CC);
+ }
+ catch(const Ice::LocalException&)
+ {
+ //
+ // Nothing to do.
+ //
+ }
- //
- // Set the reason member.
- //
- zend_update_property_string(cls, zex, "reason", sizeof("reason") - 1,
- const_cast<char*>(e.reason.c_str()) TSRMLS_CC);
-
- //
- // Set the type and exptected type members.
- //
- zend_update_property_string(cls, zex, "type", sizeof("type") - 1, const_cast<char*>(e.type.c_str())
- TSRMLS_CC);
- zend_update_property_string(cls, zex, "expectedType", sizeof("expectedType") - 1,
- const_cast<char*>(e.expectedType.c_str()) TSRMLS_CC);
-
- //
- // Throw the exception.
- //
- zend_throw_exception_object(zex TSRMLS_CC);
- }
- catch(const Ice::MarshalException& e)
- {
- string name = e.ice_name();
- zend_class_entry* cls = findClassScoped(name TSRMLS_CC);
- if(!cls)
- {
- throw;
- }
+ return true;
+}
- zval* zex;
- MAKE_STD_ZVAL(zex);
- if(object_init_ex(zex, cls) != SUCCESS)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return;
- }
+zval*
+IcePHP::convertException(const Ice::Exception& ex TSRMLS_DC)
+{
+ zval* zex;
+ MAKE_STD_ZVAL(zex);
+ AutoDestroy destroy(zex);
- //
- // Set the reason member.
- //
- zend_update_property_string(cls, zex, "reason", sizeof("reason") - 1,
- const_cast<char*>(e.reason.c_str()) TSRMLS_CC);
+ ostringstream ostr;
+ ostr << ex;
+ string str = ostr.str();
- //
- // Throw the exception.
- //
- zend_throw_exception_object(zex TSRMLS_CC);
- }
+ try
+ {
+ ex.ice_throw();
}
catch(const Ice::LocalException& e)
{
- zval* zex;
- MAKE_STD_ZVAL(zex);
-
- //
- // See if we have a PHP class for the exception, otherwise raise UnknownLocalException.
- //
- string name = e.ice_name();
- zend_class_entry* cls = findClassScoped(name TSRMLS_CC);
+ zend_class_entry* cls = idToClass(e.ice_name() TSRMLS_CC);
if(cls)
{
if(object_init_ex(zex, cls) != SUCCESS)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return;
+ runtimeError("unable to create exception %s" TSRMLS_CC, cls->name);
+ return 0;
+ }
+ if(!convertLocalException(e, zex TSRMLS_CC))
+ {
+ return 0;
}
}
else
{
- cls = findClass("Ice_UnknownLocalException" TSRMLS_CC);
- if(!cls)
- {
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to find class Ice_UnknownLocalException");
- return;
- }
-
+ cls = idToClass("Ice::UnknownLocalException" TSRMLS_CC);
+ assert(cls);
if(object_init_ex(zex, cls) != SUCCESS)
{
- php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create exception %s", cls->name);
- return;
+ runtimeError("unable to create exception %s" TSRMLS_CC, cls->name);
+ return 0;
}
-
- //
- // Set the unknown member.
- //
- ostringstream ostr;
- e.ice_print(ostr);
- string str = ostr.str();
- zend_update_property_string(cls, zex, "unknown", sizeof("unknown") - 1,
- const_cast<char*>(str.c_str()) TSRMLS_CC);
+ setStringMember(zex, "unknown", str TSRMLS_CC);
}
-
- //
- // Throw the exception.
- //
- zend_throw_exception_object(zex TSRMLS_CC);
}
catch(const Ice::UserException&)
{
- assert(false);
- }
- catch(const IceUtil::Exception& e)
- {
- ostringstream ostr;
- e.ice_print(ostr);
- php_error_docref(0 TSRMLS_CC, E_ERROR, "exception: %s", ostr.str().c_str());
- }
-}
-
-zend_class_entry*
-IcePHP::findClass(const string& flat TSRMLS_DC)
-{
- zend_class_entry** result;
- string lower = lowerCase(flat);
- if(zend_lookup_class(const_cast<char*>(lower.c_str()), lower.length(), &result TSRMLS_CC) == FAILURE)
- {
- return 0;
- }
- return *result;
-}
-
-zend_class_entry*
-IcePHP::findClassScoped(const string& scoped TSRMLS_DC)
-{
- return findClass(flatten(scoped) TSRMLS_CC);
-}
-
-string
-IcePHP::lowerCase(const string& s)
-{
- string result(s);
- transform(result.begin(), result.end(), result.begin(), ::tolower);
- return result;
-}
-
-string
-IcePHP::flatten(const string& scoped)
-{
- string result = scoped;
- if(result.find("::") == 0)
- {
- result.erase(0, 2);
+ zend_class_entry* cls = idToClass("Ice::UnknownUserException" TSRMLS_CC);
+ assert(cls);
+ if(object_init_ex(zex, cls) != SUCCESS)
+ {
+ runtimeError("unable to create exception %s" TSRMLS_CC, cls->name);
+ return 0;
+ }
+ setStringMember(zex, "unknown", str TSRMLS_CC);
}
-
- string::size_type pos;
- while((pos = result.find("::")) != string::npos)
+ catch(const Ice::Exception&)
{
- result.replace(pos, 2, "_");
+ zend_class_entry* cls = idToClass("Ice::UnknownException" TSRMLS_CC);
+ assert(cls);
+ if(object_init_ex(zex, cls) != SUCCESS)
+ {
+ runtimeError("unable to create exception %s" TSRMLS_CC, cls->name);
+ return 0;
+ }
+ setStringMember(zex, "unknown", str TSRMLS_CC);
}
- return fixIdent(result);
+ return destroy.release();
}
-string
-IcePHP::fixIdent(const string& ident)
+void
+IcePHP::throwException(const Ice::Exception& ex TSRMLS_DC)
{
- if(ident[0] != ':')
- {
- return lookupKwd(ident);
- }
- vector<string> ids = splitScopedName(ident);
- transform(ids.begin(), ids.end(), ids.begin(), ptr_fun(lookupKwd));
- stringstream result;
- for(vector<string>::const_iterator i = ids.begin(); i != ids.end(); ++i)
+ zval* zex = convertException(ex TSRMLS_CC);
+ if(zex)
{
- result << "::" + *i;
+ zend_throw_exception_object(zex TSRMLS_CC);
}
- return result.str();
}
std::string
@@ -643,36 +556,128 @@ IcePHP::zendTypeToString(int type)
return result;
}
-bool
-IcePHP::isNativeKey(const Slice::TypePtr& type)
+static void
+throwError(const string& name, const string& msg TSRMLS_DC)
{
+ zval* ex;
+ MAKE_STD_ZVAL(ex);
+ AutoDestroy destroy(ex);
+
+ zend_class_entry* cls;
+ {
+ zend_class_entry** p;
+ if(zend_lookup_class(STRCAST(name.c_str()), name.size(), &p TSRMLS_CC) == FAILURE)
+ {
+ assert(false);
+ }
+ cls = *p;
+ }
+ if(object_init_ex(ex, cls) == FAILURE)
+ {
+ assert(false);
+ }
+
//
- // PHP's native associative array supports only integer and string types for the key.
- // For Slice dictionaries that meet this criteria, we use the native array type.
+ // Invoke constructor.
//
- Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type);
- if(b)
+ if(!invokeMethod(ex, ZEND_CONSTRUCTOR_FUNC_NAME, msg TSRMLS_CC))
{
- switch(b->kind())
- {
- case Slice::Builtin::KindByte:
- case Slice::Builtin::KindBool: // We allow bool even though PHP doesn't support it directly.
- case Slice::Builtin::KindShort:
- case Slice::Builtin::KindInt:
- case Slice::Builtin::KindLong:
- case Slice::Builtin::KindString:
- return true;
+ assert(false);
+ }
- case Slice::Builtin::KindFloat:
- case Slice::Builtin::KindDouble:
- case Slice::Builtin::KindObject:
- case Slice::Builtin::KindObjectProxy:
- case Slice::Builtin::KindLocalObject:
- break;
- }
+ zend_throw_exception_object(ex TSRMLS_CC);
+ destroy.release();
+}
+
+void
+IcePHP::runtimeError(const char* fmt TSRMLS_DC, ...)
+{
+ va_list args;
+ char msg[1024];
+
+#if ZTS
+ va_start(args, TSRMLS_C);
+#else
+ va_start(args, fmt);
+#endif
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+ vsprintf_s(msg, fmt, args);
+#else
+ vsprintf(msg, fmt, args);
+#endif
+
+ va_end(args);
+
+ throwError("RuntimeException", msg TSRMLS_CC);
+}
+
+void
+IcePHP::invalidArgument(const char* fmt TSRMLS_DC, ...)
+{
+ va_list args;
+ char msg[1024];
+
+#if ZTS
+ va_start(args, TSRMLS_C);
+#else
+ va_start(args, fmt);
+#endif
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+ vsprintf_s(msg, fmt, args);
+#else
+ vsprintf(msg, fmt, args);
+#endif
+
+ va_end(args);
+
+ throwError("InvalidArgumentException", msg TSRMLS_CC);
+}
+
+static bool
+invokeMethodHelper(zval* obj, const string& name, zval* param TSRMLS_DC)
+{
+ assert(zend_hash_exists(&Z_OBJCE_P(obj)->function_table, STRCAST(name.c_str()), name.size() + 1));
+ zval ret, method;
+ INIT_ZVAL(ret);
+ INIT_ZVAL(method);
+ ZVAL_STRING(&method, STRCAST(name.c_str()), 1);
+ zend_uint numParams = param ? 1 : 0;
+ zval** params = param ? &param : 0;
+ int status = 0;
+ zend_try
+ {
+ status = call_user_function(0, &obj, &method, &ret, numParams, params TSRMLS_CC);
+ }
+ zend_catch
+ {
+ status = FAILURE;
}
+ zend_end_try();
+ zval_dtor(&method);
+ zval_dtor(&ret);
+ if(status == FAILURE || EG(exception))
+ {
+ return false;
+ }
+ return true;
+}
- return false;
+bool
+IcePHP::invokeMethod(zval* obj, const string& name TSRMLS_DC)
+{
+ return invokeMethodHelper(obj, name, 0 TSRMLS_CC);
+}
+
+bool
+IcePHP::invokeMethod(zval* obj, const string& name, const string& arg TSRMLS_DC)
+{
+ zval* param;
+ MAKE_STD_ZVAL(param);
+ ZVAL_STRINGL(param, STRCAST(arg.c_str()), arg.size(), 1);
+ AutoDestroy destroy(param);
+ return invokeMethodHelper(obj, name, param TSRMLS_CC);
}
bool
@@ -698,3 +703,34 @@ IcePHP::checkClass(zend_class_entry* ce, zend_class_entry* base)
return false;
}
+
+ZEND_FUNCTION(Ice_stringVersion)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_STRINGL(STRCAST(ICE_STRING_VERSION), strlen(ICE_STRING_VERSION), 1);
+}
+
+ZEND_FUNCTION(Ice_intVersion)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_LONG(ICE_INT_VERSION);
+}
+
+ZEND_FUNCTION(Ice_generateUUID)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ string uuid = IceUtil::generateUUID();
+ RETURN_STRINGL(STRCAST(uuid.c_str()), uuid.size(), 1);
+}
diff --git a/php/src/IcePHP/Util.h b/php/src/IcePHP/Util.h
index 2e20ee6cced..d71f31955ed 100644
--- a/php/src/IcePHP/Util.h
+++ b/php/src/IcePHP/Util.h
@@ -7,85 +7,122 @@
//
// **********************************************************************
-#ifndef ICE_PHP_UTIL_H
-#define ICE_PHP_UTIL_H
+#ifndef ICEPHP_UTIL_H
+#define ICEPHP_UTIL_H
#include <Config.h>
-namespace IcePHP
+//
+// Global functions.
+//
+extern "C"
{
+ZEND_FUNCTION(Ice_stringVersion);
+ZEND_FUNCTION(Ice_intVersion);
+ZEND_FUNCTION(Ice_generateUUID);
+}
+
+#define ICEPHP_UTIL_FUNCTIONS \
+ ZEND_FE(Ice_stringVersion, NULL) \
+ ZEND_FE(Ice_intVersion, NULL) \
+ ZEND_FE(Ice_generateUUID, NULL)
+
+#ifdef ICEPHP_USE_NAMESPACES
+# define ICEPHP_UTIL_NS_FUNCTIONS \
+ ZEND_NS_FALIAS("Ice", stringVersion, Ice_stringVersion, NULL) \
+ ZEND_NS_FALIAS("Ice", intVersion, Ice_intVersion, NULL) \
+ ZEND_NS_FALIAS("Ice", generateUUID, Ice_generateUUID, NULL)
+#else
+# define ICEPHP_UTIL_NS_FUNCTIONS
+#endif
-bool createIdentity(zval*, const Ice::Identity& TSRMLS_DC);
-bool extractIdentity(zval*, Ice::Identity& TSRMLS_DC);
+namespace IcePHP
+{
-bool createContext(zval*, const Ice::Context& TSRMLS_DC);
-bool extractContext(zval*, Ice::Context& TSRMLS_DC);
+void* createWrapper(zend_class_entry*, size_t TSRMLS_DC);
+void* extractWrapper(zval* TSRMLS_DC);
//
-// PHP wrapper for C++ objects.
+// Wraps a C++ pointer inside a PHP object.
//
-struct ice_object
+template<typename T>
+struct Wrapper
{
zend_object zobj;
- void* ptr; // For object data.
+ T* ptr;
+
+ static Wrapper<T>* create(zend_class_entry* ce TSRMLS_DC)
+ {
+ Wrapper<T>* w = static_cast<Wrapper<T>*>(createWrapper(ce, sizeof(Wrapper<T>) TSRMLS_CC));
+ w->ptr = 0;
+ return w;
+ }
+
+ static Wrapper<T>* extract(zval* zv TSRMLS_DC)
+ {
+ return static_cast<Wrapper<T>*>(extractWrapper(zv TSRMLS_CC));
+ }
+
+ static T value(zval* zv TSRMLS_DC)
+ {
+ Wrapper<T>* w = extract(zv TSRMLS_CC);
+ if(w)
+ {
+ return *w->ptr;
+ }
+ return 0;
+ }
};
-//
-// Create a new ice_object for a class entry. The allocator registered for the
-// class entry will be invoked, but the C++ object is not created here.
-//
-ice_object* newObject(zend_class_entry* TSRMLS_DC);
+zend_class_entry* idToClass(const std::string& TSRMLS_DC);
+zend_class_entry* nameToClass(const std::string& TSRMLS_DC);
-//
-// Retrieve the ice_object given a zval.
-//
-ice_object* getObject(zval* TSRMLS_DC);
+bool createIdentity(zval*, const Ice::Identity& TSRMLS_DC);
+bool extractIdentity(zval*, Ice::Identity& TSRMLS_DC);
-//
-// Convert the given exception into a PHP equivalent and "throw" it.
-//
-void throwException(const IceUtil::Exception& TSRMLS_DC);
+bool createStringMap(zval*, const std::map<std::string, std::string>& TSRMLS_DC);
+bool extractStringMap(zval*, std::map<std::string, std::string>& TSRMLS_DC);
+
+bool createStringArray(zval*, const Ice::StringSeq& TSRMLS_DC);
+bool extractStringArray(zval*, Ice::StringSeq& TSRMLS_DC);
//
-// Find the class entry for a flattened type name.
+// Convert the given exception into its PHP equivalent.
//
-zend_class_entry* findClass(const std::string& TSRMLS_DC);
+zval* convertException(const Ice::Exception& TSRMLS_DC);
//
-// Find the class entry for a scoped type with suffix.
+// Convert the exception and "throw" it.
//
-zend_class_entry* findClassScoped(const std::string& TSRMLS_DC);
+void throwException(const Ice::Exception& TSRMLS_DC);
//
-// Convert a string to lowercase.
+// Convert a Zend type (e.g., IS_BOOL, etc.) to a string for use in error messages.
//
-std::string lowerCase(const std::string&);
+std::string zendTypeToString(int);
//
-// Flatten a scoped name. Leading "::" is removed, and all remaining "::"
-// are replaced with underscores. The resulting string is then escaped if it
-// conflicts with a PHP keyword.
+// Raise RuntimeException with the given message.
//
-std::string flatten(const std::string&);
+void runtimeError(const char* TSRMLS_DC, ...);
//
-// Check the given identifier against PHP's list of reserved words. If it matches
-// a reserved word, then an escaped version is returned with a leading underscore.
+// Raise InvalidArgumentException with the given message.
//
-std::string fixIdent(const std::string&);
+void invalidArgument(const char* TSRMLS_DC, ...);
//
-// Convert a Zend type (e.g., IS_BOOL, etc.) to a string for use in error messages.
+// Invoke a method on a PHP object. The method must not take any arguments.
//
-std::string zendTypeToString(int);
+bool invokeMethod(zval*, const std::string& TSRMLS_DC);
//
-// Returns true if the given type is valid for use as a key in a native PHP associative array.
+// Invoke a method on a PHP object. The method must take one string argument.
//
-bool isNativeKey(const Slice::TypePtr&);
+bool invokeMethod(zval*, const std::string&, const std::string& TSRMLS_DC);
//
-// Determines whether a class (or interface) inherits from a base class (or interface).
+// Check inheritance.
//
bool checkClass(zend_class_entry*, zend_class_entry*);
@@ -111,6 +148,8 @@ public:
AutoDestroy(zval* zv) : _zv(zv) {}
~AutoDestroy() { if(_zv) zval_ptr_dtor(&_zv); }
+ zval* release() { zval* z = _zv; _zv = 0; return z; }
+
private:
zval* _zv;
};
diff --git a/php/test/Ice/Makefile b/php/test/Ice/Makefile
new file mode 100644
index 00000000000..7dbd7bf554f
--- /dev/null
+++ b/php/test/Ice/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = binding checksum exceptions facets inheritance objects operations proxy slicing
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/php/test/Ice/Makefile.mak b/php/test/Ice/Makefile.mak
new file mode 100644
index 00000000000..80bfa6388c6
--- /dev/null
+++ b/php/test/Ice/Makefile.mak
@@ -0,0 +1,19 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = binding checksum exceptions facets inheritance objects operations proxy slicing
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/test/Ice/binding/.gitignore b/php/test/Ice/binding/.gitignore
new file mode 100644
index 00000000000..bed01730acc
--- /dev/null
+++ b/php/test/Ice/binding/.gitignore
@@ -0,0 +1 @@
+Test.php
diff --git a/php/test/Ice/binding/Client.php b/php/test/Ice/binding/Client.php
index d5c709a0177..b88a1f8017d 100644
--- a/php/test/Ice/binding/Client.php
+++ b/php/test/Ice/binding/Client.php
@@ -15,7 +15,9 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
+
+require 'Ice.php';
+require 'Test.php';
function test($b)
{
@@ -51,12 +53,10 @@ function deactivate($com, $adapters)
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
$ref = "communicator:default -p 12010";
- $com = $ICE->stringToProxy($ref)->ice_uncheckedCast("::Test::RemoteCommunicator");
+ $com = $communicator->stringToProxy($ref)->ice_uncheckedCast("::Test::RemoteCommunicator");
echo "testing binding with single endpoint... ";
flush();
@@ -430,7 +430,7 @@ function allTests()
}
echo "ok" . "\n";
- if(strlen($ICE->getProperty("Ice.Plugin.IceSSL")) > 0)
+ if(strlen($communicator->getProperties()->getProperty("Ice.Plugin.IceSSL")) > 0)
{
echo "testing unsecure vs. secure endpoints... ";
flush();
@@ -489,6 +489,8 @@ function allTests()
$com->shutdown();
}
-allTests();
+$communicator = Ice_initialize(&$argv);
+allTests($communicator);
+$communicator->destroy();
exit();
?>
diff --git a/php/test/Ice/binding/Makefile b/php/test/Ice/binding/Makefile
new file mode 100644
index 00000000000..83671f131ec
--- /dev/null
+++ b/php/test/Ice/binding/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/binding/Makefile.mak b/php/test/Ice/binding/Makefile.mak
new file mode 100644
index 00000000000..ef0c8acea4a
--- /dev/null
+++ b/php/test/Ice/binding/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/binding/php.ini b/php/test/Ice/binding/php.ini
deleted file mode 100644
index 8a0b2f9f6e9..00000000000
--- a/php/test/Ice/binding/php.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-ice.slice=Test.ice
-display_startup_errors=1
diff --git a/php/test/Ice/checksum/.gitignore b/php/test/Ice/checksum/.gitignore
new file mode 100644
index 00000000000..66cc0dff1cf
--- /dev/null
+++ b/php/test/Ice/checksum/.gitignore
@@ -0,0 +1,2 @@
+CTypes.php
+Test.php
diff --git a/php/test/Ice/checksum/CTypes.ice b/php/test/Ice/checksum/CTypes.ice
new file mode 100644
index 00000000000..f9f05a43e4c
--- /dev/null
+++ b/php/test/Ice/checksum/CTypes.ice
@@ -0,0 +1,440 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef CLASS_ICE
+#define CLASS_ICE
+
+module Test
+{
+
+//
+// TEST: Same
+//
+const int IntConst1 = 100;
+
+//
+// TEST: Value changed
+//
+const int IntConst2 = 100;
+
+//
+// TEST: Type changed
+//
+const int IntConst3 = 100;
+
+//
+// TEST: Same
+//
+enum Enum1 { Enum11, Enum12, Enum13 };
+
+//
+// TEST: Add enumerator
+//
+enum Enum2 { Enum21, Enum22, Enum23 };
+
+//
+// TEST: Remove enumerator
+//
+enum Enum3 { Enum31, Enum32, Enum33 };
+
+//
+// TEST: Change to a different type
+//
+enum Enum4 { Enum41, Enum42, Enum43 };
+
+//
+// TEST: Same
+//
+sequence<int> Sequence1;
+
+//
+// TEST: Change sequence type
+//
+sequence<int> Sequence2;
+
+//
+// TEST: Change to a different type
+//
+sequence<int> Sequence3;
+
+//
+// TEST: Same
+//
+dictionary<string, int> Dictionary1;
+
+//
+// TEST: Change key type
+//
+dictionary<string, int> Dictionary2;
+
+//
+// TEST: Change value type
+//
+dictionary<string, int> Dictionary3;
+
+//
+// TEST: Change to a different type
+//
+dictionary<string, int> Dictionary4;
+
+//
+// TEST: Same
+//
+struct Struct1
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Add member
+//
+struct Struct2
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Change member type
+//
+struct Struct3
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Remove member
+//
+struct Struct4
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Change to a different type
+//
+struct Struct5
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Same
+//
+interface Interface1
+{
+};
+
+//
+// TEST: Change interface to class
+//
+interface Interface2
+{
+};
+
+//
+// TEST: Add base interface
+//
+interface Interface3
+{
+};
+
+//
+// TEST: Add operation
+//
+interface Interface4
+{
+};
+
+//
+// TEST: Same
+//
+class EmptyClass1
+{
+};
+
+//
+// TEST: Add data member
+//
+class EmptyClass2
+{
+};
+
+//
+// TEST: Add operation
+//
+class EmptyClass3
+{
+};
+
+//
+// TEST: Add base class
+//
+class EmptyClass4
+{
+};
+
+//
+// TEST: Add interface
+//
+class EmptyClass5
+{
+};
+
+//
+// TEST: Same
+//
+class SimpleClass1
+{
+ string str;
+ float f;
+};
+
+//
+// TEST: Add operation
+//
+class SimpleClass2
+{
+ string str;
+ float f;
+};
+
+//
+// TEST: Rename member
+//
+class SimpleClass3
+{
+ string str;
+ float f;
+};
+
+//
+// TEST: Add member
+//
+class SimpleClass4
+{
+ string str;
+ float f;
+};
+
+//
+// TEST: Remove member
+//
+class SimpleClass5
+{
+ string str;
+ float f;
+};
+
+//
+// TEST: Reorder members
+//
+class SimpleClass6
+{
+ string str;
+ float f;
+};
+
+//
+// TEST: Change member type
+//
+class SimpleClass7
+{
+ string str;
+ float f;
+};
+
+//
+// TEST: Same
+//
+exception Exception1
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Add member
+//
+exception Exception2
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Change member type
+//
+exception Exception3
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Remove member
+//
+exception Exception4
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Add base exception
+//
+exception Exception5
+{
+};
+
+//
+// TEST: Change to a different type
+//
+exception Exception6
+{
+ string str;
+ bool b;
+};
+
+//
+// TEST: Same
+//
+class BaseClass1
+{
+ void baseOp1();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Change return type
+//
+class BaseClass2
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Add parameter
+//
+class BaseClass3
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Add exception
+//
+class BaseClass4
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Change out parameter to in parameter
+//
+class BaseClass5
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Remove parameter
+//
+class BaseClass6
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Remove exception
+//
+class BaseClass7
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Remove operation
+//
+class BaseClass8
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Add base class
+//
+class BaseClass9
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Add interface
+//
+class BaseClass10
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Add base class and interface
+//
+class BaseClass11
+{
+ void baseOp();
+ void baseOp2(int i, out string s) throws Exception1;
+};
+
+//
+// TEST: Local
+//
+local enum LocalEnum { LocalEnum1, LocalEnum2, LocalEnum3 };
+
+//
+// TEST: Local
+//
+local sequence<string> LocalSequence;
+
+//
+// TEST: Local
+//
+local dictionary<string, string> LocalDictionary;
+
+//
+// TEST: Local
+//
+local struct LocalStruct
+{
+ string str;
+};
+
+//
+// TEST: Local
+//
+local class LocalClass
+{
+};
+
+};
+
+#endif
diff --git a/php/test/Ice/checksum/Client.php b/php/test/Ice/checksum/Client.php
new file mode 100755
index 00000000000..b43d5f16797
--- /dev/null
+++ b/php/test/Ice/checksum/Client.php
@@ -0,0 +1,95 @@
+<?
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+error_reporting(E_ALL | E_STRICT);
+
+if(!extension_loaded("ice"))
+{
+ echo "\nerror: Ice extension is not loaded.\n\n";
+ exit(1);
+}
+
+require 'Ice.php';
+require 'Test.php';
+require 'CTypes.php';
+
+function test($b)
+{
+ if(!$b)
+ {
+ $bt = debug_backtrace();
+ die("\ntest failed in ".$bt[0]["file"]." line ".$bt[0]["line"]."\n");
+ }
+}
+
+function allTests($communicator)
+{
+ global $Ice_sliceChecksums;
+
+ $ref = "test:default -p 12010";
+ $base = $communicator->stringToProxy($ref);
+ test($base);
+
+ $checksum = Test_ChecksumPrxHelper::checkedCast($base);
+ test($checksum);
+
+ //
+ // Verify that no checksums are present for local types.
+ //
+ echo "testing checksums... ";
+ flush();
+ test(count($Ice_sliceChecksums) > 0);
+ foreach($Ice_sliceChecksums as $i => $value)
+ {
+ test(!strpos($i, "Local"));
+ }
+
+ //
+ // Get server's Slice checksums.
+ //
+ $d = $checksum->getSliceChecksums();
+
+ //
+ // Compare the checksums. For a type FooN whose name ends in an integer N,
+ // we assume that the server's type does not change for N = 1, and does
+ // change for N > 1.
+ //
+ foreach($d as $i => $value)
+ {
+ $n = 0;
+ preg_match("/\\d+/", $i, $matches);
+ if($matches)
+ {
+ $n = (int)$matches[0];
+ }
+
+ test(isset($Ice_sliceChecksums[$i]));
+
+ if($n <= 1)
+ {
+ test($Ice_sliceChecksums[$i] == $d[$i]);
+ }
+ else
+ {
+ test($Ice_sliceChecksums[$i] != $d[$i]);
+ }
+ }
+
+ echo "ok\n";
+
+ return $checksum;
+}
+
+$communicator = Ice_initialize(&$argv);
+$checksum = allTests($communicator);
+$checksum->shutdown();
+$communicator->destroy();
+exit();
+?>
diff --git a/php/test/Ice/checksum/Makefile b/php/test/Ice/checksum/Makefile
new file mode 100644
index 00000000000..8a0d0bc816b
--- /dev/null
+++ b/php/test/Ice/checksum/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Test.php CTypes.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) --checksum $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/checksum/Makefile.mak b/php/test/Ice/checksum/Makefile.mak
new file mode 100644
index 00000000000..83eef33cc49
--- /dev/null
+++ b/php/test/Ice/checksum/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php CTypes.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) --checksum $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/checksum/Test.ice b/php/test/Ice/checksum/Test.ice
new file mode 100644
index 00000000000..cf9b2a4d554
--- /dev/null
+++ b/php/test/Ice/checksum/Test.ice
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef TEST_ICE
+#define TEST_ICE
+
+#include <Ice/SliceChecksumDict.ice>
+
+module Test
+{
+
+interface Checksum
+{
+ idempotent Ice::SliceChecksumDict getSliceChecksums();
+
+ void shutdown();
+};
+
+};
+
+#endif
diff --git a/php/test/Ice/checksum/run.py b/php/test/Ice/checksum/run.py
new file mode 100755
index 00000000000..0e1d22c8b58
--- /dev/null
+++ b/php/test/Ice/checksum/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import os, sys
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(os.path.join(path[0]))
+from scripts import *
+
+TestUtil.clientServerTest(server='server/server')
+
+TestUtil.cleanup()
diff --git a/php/test/Ice/exceptions/.gitignore b/php/test/Ice/exceptions/.gitignore
new file mode 100644
index 00000000000..bed01730acc
--- /dev/null
+++ b/php/test/Ice/exceptions/.gitignore
@@ -0,0 +1 @@
+Test.php
diff --git a/php/test/Ice/exceptions/Client.php b/php/test/Ice/exceptions/Client.php
index 445c5b8c023..0d69b9cd045 100644
--- a/php/test/Ice/exceptions/Client.php
+++ b/php/test/Ice/exceptions/Client.php
@@ -8,6 +8,9 @@
//
// **********************************************************************
+require 'Ice.php';
+require 'Test.php';
+
error_reporting(E_ALL | E_STRICT);
if(!extension_loaded("ice"))
@@ -15,7 +18,6 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
function test($b)
{
@@ -26,14 +28,12 @@ function test($b)
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
echo "testing stringToProxy... ";
flush();
$ref = "thrower:default -p 12010";
- $base = $ICE->stringToProxy($ref);
+ $base = $communicator->stringToProxy($ref);
test($base != null);
echo "ok\n";
@@ -206,7 +206,7 @@ function allTests()
echo "catching object not exist exception... ";
flush();
- $id = Ice_stringToIdentity("does not exist");
+ $id = $communicator->stringToIdentity("does not exist");
try
{
$thrower2 = $thrower->ice_identity($id)->ice_uncheckedCast("::Test::Thrower");
@@ -285,7 +285,9 @@ function allTests()
return $thrower;
}
-$thrower = allTests();
+$communicator = Ice_initialize(&$argv);
+$thrower = allTests($communicator);
$thrower->shutdown();
+$communicator->destroy();
exit();
?>
diff --git a/php/test/Ice/exceptions/Makefile b/php/test/Ice/exceptions/Makefile
new file mode 100644
index 00000000000..83671f131ec
--- /dev/null
+++ b/php/test/Ice/exceptions/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/exceptions/Makefile.mak b/php/test/Ice/exceptions/Makefile.mak
new file mode 100644
index 00000000000..ef0c8acea4a
--- /dev/null
+++ b/php/test/Ice/exceptions/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/exceptions/php.ini b/php/test/Ice/exceptions/php.ini
deleted file mode 100644
index 8a0b2f9f6e9..00000000000
--- a/php/test/Ice/exceptions/php.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-ice.slice=Test.ice
-display_startup_errors=1
diff --git a/php/test/Ice/facets/.gitignore b/php/test/Ice/facets/.gitignore
new file mode 100644
index 00000000000..bed01730acc
--- /dev/null
+++ b/php/test/Ice/facets/.gitignore
@@ -0,0 +1 @@
+Test.php
diff --git a/php/test/Ice/facets/Client.php b/php/test/Ice/facets/Client.php
index f6797c06624..8c936eb7361 100644
--- a/php/test/Ice/facets/Client.php
+++ b/php/test/Ice/facets/Client.php
@@ -15,7 +15,9 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
+
+require 'Ice.php';
+require 'Test.php';
function test($b)
{
@@ -26,14 +28,12 @@ function test($b)
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
echo "testing stringToProxy... ";
flush();
$ref = "d:default -p 12010";
- $db = $ICE->stringToProxy($ref);
+ $db = $communicator->stringToProxy($ref);
test($db != null);
echo "ok\n";
@@ -88,7 +88,9 @@ function allTests()
return $gf;
}
-$g = allTests();
+$communicator = Ice_initialize(&$argv);
+$g = allTests($communicator);
$g->shutdown();
+$communicator->destroy();
exit();
?>
diff --git a/php/test/Ice/facets/Makefile b/php/test/Ice/facets/Makefile
new file mode 100644
index 00000000000..83671f131ec
--- /dev/null
+++ b/php/test/Ice/facets/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/facets/Makefile.mak b/php/test/Ice/facets/Makefile.mak
new file mode 100644
index 00000000000..ef0c8acea4a
--- /dev/null
+++ b/php/test/Ice/facets/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/facets/php.ini b/php/test/Ice/facets/php.ini
deleted file mode 100644
index 8a0b2f9f6e9..00000000000
--- a/php/test/Ice/facets/php.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-ice.slice=Test.ice
-display_startup_errors=1
diff --git a/php/test/Ice/inheritance/.gitignore b/php/test/Ice/inheritance/.gitignore
new file mode 100644
index 00000000000..bed01730acc
--- /dev/null
+++ b/php/test/Ice/inheritance/.gitignore
@@ -0,0 +1 @@
+Test.php
diff --git a/php/test/Ice/inheritance/Client.php b/php/test/Ice/inheritance/Client.php
index d9634df6638..8a86b363cb4 100644
--- a/php/test/Ice/inheritance/Client.php
+++ b/php/test/Ice/inheritance/Client.php
@@ -15,7 +15,9 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
+
+require 'Ice.php';
+require 'Test.php';
function test($b)
{
@@ -26,14 +28,12 @@ function test($b)
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
echo "testing stringToProxy... ";
flush();
$ref = "initial:default -p 12010";
- $base = $ICE->stringToProxy($ref);
+ $base = $communicator->stringToProxy($ref);
test($base != null);
echo "ok\n";
@@ -235,7 +235,9 @@ function allTests()
return $initial;
}
-$initial = allTests();
+$communicator = Ice_initialize(&$argv);
+$initial = allTests($communicator);
$initial->shutdown();
+$communicator->destroy();
exit();
?>
diff --git a/php/test/Ice/inheritance/Makefile b/php/test/Ice/inheritance/Makefile
new file mode 100644
index 00000000000..83671f131ec
--- /dev/null
+++ b/php/test/Ice/inheritance/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/inheritance/Makefile.mak b/php/test/Ice/inheritance/Makefile.mak
new file mode 100644
index 00000000000..ef0c8acea4a
--- /dev/null
+++ b/php/test/Ice/inheritance/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/inheritance/php.ini b/php/test/Ice/inheritance/php.ini
deleted file mode 100644
index 8a0b2f9f6e9..00000000000
--- a/php/test/Ice/inheritance/php.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-ice.slice=Test.ice
-display_startup_errors=1
diff --git a/php/test/Ice/objects/.gitignore b/php/test/Ice/objects/.gitignore
new file mode 100644
index 00000000000..bed01730acc
--- /dev/null
+++ b/php/test/Ice/objects/.gitignore
@@ -0,0 +1 @@
+Test.php
diff --git a/php/test/Ice/objects/Client.php b/php/test/Ice/objects/Client.php
index 491ae8b4656..aaf231acadd 100644
--- a/php/test/Ice/objects/Client.php
+++ b/php/test/Ice/objects/Client.php
@@ -15,7 +15,9 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
+
+require 'Ice.php';
+require 'Test.php';
class BI extends Test_B
{
@@ -29,7 +31,7 @@ class BI extends Test_B
return $this->_postUnmarshalInvoked;
}
- var $_postUnmarshalInvoked = false;
+ private $_postUnmarshalInvoked = false;
}
class CI extends Test_C
@@ -44,7 +46,7 @@ class CI extends Test_C
return $this->_postUnmarshalInvoked;
}
- var $_postUnmarshalInvoked = false;
+ private $_postUnmarshalInvoked = false;
}
class DI extends Test_D
@@ -59,7 +61,7 @@ class DI extends Test_D
return $this->_postUnmarshalInvoked;
}
- var $_postUnmarshalInvoked = false;
+ private $_postUnmarshalInvoked = false;
}
class EI extends Test_E
@@ -94,6 +96,12 @@ class II extends Ice_ObjectImpl implements Test_I
{
}
+interface Foo1 {}
+interface Foo2 {}
+interface Foo3 {}
+class Foo4 extends Ice_ObjectImpl implements Foo3, Foo2, Foo1 {}
+class Foo5 extends Foo4 implements Test_I {}
+
class JI extends Ice_ObjectImpl implements Test_J
{
}
@@ -155,14 +163,12 @@ function test($b)
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
echo "testing stringToProxy... ";
flush();
$ref = "initial:default -p 12010";
- $base = $ICE->stringToProxy($ref);
+ $base = $communicator->stringToProxy($ref);
test($base != null);
echo "ok\n";
@@ -329,7 +335,8 @@ function allTests()
echo "setting I... ";
flush();
- $initial->setI($i);
+ //$initial->setI($i);
+ $initial->setI(new Foo5);
$initial->setI($j);
$initial->setI($h);
echo "ok\n";
@@ -337,7 +344,7 @@ function allTests()
echo "testing UnexpectedObjectException... ";
flush();
$ref = "uoet:default -p 12010";
- $base = $ICE->stringToProxy($ref);
+ $base = $communicator->stringToProxy($ref);
test($base != null);
$uoet = $base->ice_uncheckedCast("::Test::UnexpectedObjectExceptionTest");
test($uoet != null);
@@ -360,16 +367,18 @@ function allTests()
return $initial;
}
+$communicator = Ice_initialize(&$argv);
$factory = new MyObjectFactory();
-$ICE->addObjectFactory($factory, "::Test::B");
-$ICE->addObjectFactory($factory, "::Test::C");
-$ICE->addObjectFactory($factory, "::Test::D");
-$ICE->addObjectFactory($factory, "::Test::E");
-$ICE->addObjectFactory($factory, "::Test::F");
-$ICE->addObjectFactory($factory, "::Test::I");
-$ICE->addObjectFactory($factory, "::Test::J");
-$ICE->addObjectFactory($factory, "::Test::H");
-$initial = allTests();
+$communicator->addObjectFactory($factory, "::Test::B");
+$communicator->addObjectFactory($factory, "::Test::C");
+$communicator->addObjectFactory($factory, "::Test::D");
+$communicator->addObjectFactory($factory, "::Test::E");
+$communicator->addObjectFactory($factory, "::Test::F");
+$communicator->addObjectFactory($factory, "::Test::I");
+$communicator->addObjectFactory($factory, "::Test::J");
+$communicator->addObjectFactory($factory, "::Test::H");
+$initial = allTests($communicator);
$initial->shutdown();
+$communicator->destroy();
exit();
?>
diff --git a/php/test/Ice/objects/Makefile b/php/test/Ice/objects/Makefile
new file mode 100644
index 00000000000..83671f131ec
--- /dev/null
+++ b/php/test/Ice/objects/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/objects/Makefile.mak b/php/test/Ice/objects/Makefile.mak
new file mode 100644
index 00000000000..ef0c8acea4a
--- /dev/null
+++ b/php/test/Ice/objects/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/objects/php.ini b/php/test/Ice/objects/php.ini
deleted file mode 100644
index 8a0b2f9f6e9..00000000000
--- a/php/test/Ice/objects/php.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-ice.slice=Test.ice
-display_startup_errors=1
diff --git a/php/test/Ice/operations/.gitignore b/php/test/Ice/operations/.gitignore
new file mode 100644
index 00000000000..bed01730acc
--- /dev/null
+++ b/php/test/Ice/operations/.gitignore
@@ -0,0 +1 @@
+Test.php
diff --git a/php/test/Ice/operations/Client.php b/php/test/Ice/operations/Client.php
index 1a2da5ac957..0afd1dd76ce 100644
--- a/php/test/Ice/operations/Client.php
+++ b/php/test/Ice/operations/Client.php
@@ -15,7 +15,9 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
+
+require 'Ice.php';
+require 'Test.php';
function test($b)
{
@@ -28,8 +30,6 @@ function test($b)
function twoways($communicator, $p)
{
- global $ICE;
-
{
$p->opVoid();
}
@@ -103,9 +103,9 @@ function twoways($communicator, $p)
{
$r = $p->opMyClass($p, $c1, $c2);
// TODO: Identity tests
- test($c1->ice_getIdentity() == $ICE->stringToIdentity("test"));
- test($c2->ice_getIdentity() == $ICE->stringToIdentity("noSuchIdentity"));
- test($r->ice_getIdentity() == $ICE->stringToIdentity("test"));
+ test($c1->ice_getIdentity() == $communicator->stringToIdentity("test"));
+ test($c2->ice_getIdentity() == $communicator->stringToIdentity("noSuchIdentity"));
+ test($r->ice_getIdentity() == $communicator->stringToIdentity("test"));
$r->opVoid();
$c1->opVoid();
try
@@ -417,26 +417,26 @@ function twoways($communicator, $p)
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
$ref = "test:default -p 12010";
- $base = $ICE->stringToProxy($ref);
+ $base = $communicator->stringToProxy($ref);
$cl = $base->ice_checkedCast("::Test::MyClass");
$derived = $cl->ice_checkedCast("::Test::MyDerivedClass");
echo "testing twoway operations... ";
flush();
- twoways($ICE, $cl);
- twoways($ICE, $derived);
+ twoways($communicator, $cl);
+ twoways($communicator, $derived);
$derived->opDerived();
echo "ok\n";
return $cl;
}
-$myClass = allTests();
+$communicator = Ice_initialize();
+
+$myClass = allTests($communicator);
echo "testing server shutdown... ";
flush();
@@ -451,5 +451,7 @@ catch(Ice_LocalException $ex)
echo "ok\n";
}
+$communicator->destroy();
+
exit();
?>
diff --git a/php/test/Ice/operations/Makefile b/php/test/Ice/operations/Makefile
new file mode 100644
index 00000000000..83671f131ec
--- /dev/null
+++ b/php/test/Ice/operations/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/operations/Makefile.mak b/php/test/Ice/operations/Makefile.mak
new file mode 100644
index 00000000000..ef0c8acea4a
--- /dev/null
+++ b/php/test/Ice/operations/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/operations/php.ini b/php/test/Ice/operations/php.ini
deleted file mode 100644
index 8a0b2f9f6e9..00000000000
--- a/php/test/Ice/operations/php.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-ice.slice=Test.ice
-display_startup_errors=1
diff --git a/php/test/Ice/proxy/.gitignore b/php/test/Ice/proxy/.gitignore
new file mode 100644
index 00000000000..bed01730acc
--- /dev/null
+++ b/php/test/Ice/proxy/.gitignore
@@ -0,0 +1 @@
+Test.php
diff --git a/php/test/Ice/proxy/Client.php b/php/test/Ice/proxy/Client.php
index cb2ed79280f..a1606c87e90 100644
--- a/php/test/Ice/proxy/Client.php
+++ b/php/test/Ice/proxy/Client.php
@@ -15,7 +15,9 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
+
+require 'Ice.php';
+require 'Test.php';
function test($b)
{
@@ -26,216 +28,214 @@ function test($b)
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
echo "testing stringToProxy... ";
flush();
$ref = "test:default -p 12010";
- $base = $ICE->stringToProxy($ref);
+ $base = $communicator->stringToProxy($ref);
test($base != null);
- $b1 = $ICE->stringToProxy("test");
+ $b1 = $communicator->stringToProxy("test");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getAdapterId() == "" && $b1->ice_getFacet() == "");
- $b1 = $ICE->stringToProxy("test ");
+ $b1 = $communicator->stringToProxy("test ");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "");
- $b1 = $ICE->stringToProxy(" test ");
+ $b1 = $communicator->stringToProxy(" test ");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "");
- $b1 = $ICE->stringToProxy(" test");
+ $b1 = $communicator->stringToProxy(" test");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "");
- $b1 = $ICE->stringToProxy("'test -f facet'");
+ $b1 = $communicator->stringToProxy("'test -f facet'");
test($b1->ice_getIdentity()->name == "test -f facet" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "");
try
{
- $b1 = $ICE->stringToProxy("\"test -f facet'");
+ $b1 = $communicator->stringToProxy("\"test -f facet'");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex)
+ catch(Ice_ProxyParseException $ex)
{
}
- $b1 = $ICE->stringToProxy("\"test -f facet\"");
+ $b1 = $communicator->stringToProxy("\"test -f facet\"");
test($b1->ice_getIdentity()->name == "test -f facet" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "");
- $b1 = $ICE->stringToProxy("\"test -f facet@test\"");
+ $b1 = $communicator->stringToProxy("\"test -f facet@test\"");
test($b1->ice_getIdentity()->name == "test -f facet@test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "");
- $b1 = $ICE->stringToProxy("\"test -f facet@test @test\"");
+ $b1 = $communicator->stringToProxy("\"test -f facet@test @test\"");
test($b1->ice_getIdentity()->name == "test -f facet@test @test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "");
try
{
- $b1 = $ICE->stringToProxy("test test");
+ $b1 = $communicator->stringToProxy("test test");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex)
+ catch(Ice_ProxyParseException $ex)
{
}
- $b1 = $ICE->stringToProxy("test\\040test");
+ $b1 = $communicator->stringToProxy("test\\040test");
test($b1->ice_getIdentity()->name == "test test" && $b1->ice_getIdentity()->category == "");
try
{
- $b1 = $ICE->stringToProxy("test\\777");
+ $b1 = $communicator->stringToProxy("test\\777");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_IdentityParseException $ex)
+ catch(Ice_IdentityParseException $ex)
{
}
- $b1 = $ICE->stringToProxy("test\\40test");
+ $b1 = $communicator->stringToProxy("test\\40test");
test($b1->ice_getIdentity()->name == "test test");
// Test some octal and hex corner cases.
- $b1 = $ICE->stringToProxy("test\\4test");
+ $b1 = $communicator->stringToProxy("test\\4test");
test($b1->ice_getIdentity()->name == "test\4test");
- $b1 = $ICE->stringToProxy("test\\04test");
+ $b1 = $communicator->stringToProxy("test\\04test");
test($b1->ice_getIdentity()->name == "test\4test");
- $b1 = $ICE->stringToProxy("test\\004test");
+ $b1 = $communicator->stringToProxy("test\\004test");
test($b1->ice_getIdentity()->name == "test\4test");
- $b1 = $ICE->stringToProxy("test\\1114test");
+ $b1 = $communicator->stringToProxy("test\\1114test");
test($b1->ice_getIdentity()->name == "test\1114test");
- $b1 = $ICE->stringToProxy("test\\b\\f\\n\\r\\t\\'\\\"\\\\test");
+ $b1 = $communicator->stringToProxy("test\\b\\f\\n\\r\\t\\'\\\"\\\\test");
test($b1->ice_getIdentity()->name == "test\x08\x0c\n\r\t'\"\\test" && $b1->ice_getIdentity()->category == "");
- $b1 = $ICE->stringToProxy("category/test");
+ $b1 = $communicator->stringToProxy("category/test");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category" &&
$b1->ice_getAdapterId() == "");
- $b1 = $ICE->stringToProxy("test@adapter");
+ $b1 = $communicator->stringToProxy("test@adapter");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getAdapterId() == "adapter");
try
{
- $b1 = $ICE->stringToProxy("id@adapter test");
+ $b1 = $communicator->stringToProxy("id@adapter test");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex)
+ catch(Ice_ProxyParseException $ex)
{
}
- $b1 = $ICE->stringToProxy("category/test@adapter");
+ $b1 = $communicator->stringToProxy("category/test@adapter");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category" &&
$b1->ice_getAdapterId() == "adapter");
- $b1 = $ICE->stringToProxy("category/test@adapter:tcp");
+ $b1 = $communicator->stringToProxy("category/test@adapter:tcp");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category" &&
$b1->ice_getAdapterId() == "adapter:tcp");
- $b1 = $ICE->stringToProxy("'category 1/test'@adapter");
+ $b1 = $communicator->stringToProxy("'category 1/test'@adapter");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category 1" &&
$b1->ice_getAdapterId() == "adapter");
- $b1 = $ICE->stringToProxy("'category/test 1'@adapter");
+ $b1 = $communicator->stringToProxy("'category/test 1'@adapter");
test($b1->ice_getIdentity()->name == "test 1" && $b1->ice_getIdentity()->category == "category" &&
$b1->ice_getAdapterId() == "adapter");
- $b1 = $ICE->stringToProxy("'category/test'@'adapter 1'");
+ $b1 = $communicator->stringToProxy("'category/test'@'adapter 1'");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category" &&
$b1->ice_getAdapterId() == "adapter 1");
- $b1 = $ICE->stringToProxy("\"category \\/test@foo/test\"@adapter");
+ $b1 = $communicator->stringToProxy("\"category \\/test@foo/test\"@adapter");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category /test@foo" &&
$b1->ice_getAdapterId() == "adapter");
- $b1 = $ICE->stringToProxy("\"category \\/test@foo/test\"@\"adapter:tcp\"");
+ $b1 = $communicator->stringToProxy("\"category \\/test@foo/test\"@\"adapter:tcp\"");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "category /test@foo" &&
$b1->ice_getAdapterId() == "adapter:tcp");
- $b1 = $ICE->stringToProxy("id -f facet");
+ $b1 = $communicator->stringToProxy("id -f facet");
test($b1->ice_getIdentity()->name == "id" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "facet");
- $b1 = $ICE->stringToProxy("id -f 'facet x'");
+ $b1 = $communicator->stringToProxy("id -f 'facet x'");
test($b1->ice_getIdentity()->name == "id" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "facet x");
- $b1 = $ICE->stringToProxy("id -f \"facet x\"");
+ $b1 = $communicator->stringToProxy("id -f \"facet x\"");
test($b1->ice_getIdentity()->name == "id" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "facet x");
try
{
- $b1 = $ICE->stringToProxy("id -f \"facet x");
+ $b1 = $communicator->stringToProxy("id -f \"facet x");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex)
+ catch(Ice_ProxyParseException $ex)
{
}
try
{
- $b1 = $ICE->stringToProxy("id -f \'facet x");
+ $b1 = $communicator->stringToProxy("id -f \'facet x");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex)
+ catch(Ice_ProxyParseException $ex)
{
}
- $b1 = $ICE->stringToProxy("test -f facet:tcp");
+ $b1 = $communicator->stringToProxy("test -f facet:tcp");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "facet" && $b1->ice_getAdapterId() == "");
- $b1 = $ICE->stringToProxy("test -f \"facet:tcp\"");
+ $b1 = $communicator->stringToProxy("test -f \"facet:tcp\"");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "facet:tcp" && $b1->ice_getAdapterId() == "");
- $b1 = $ICE->stringToProxy("test -f facet@test");
+ $b1 = $communicator->stringToProxy("test -f facet@test");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "facet" && $b1->ice_getAdapterId() == "test");
- $b1 = $ICE->stringToProxy("test -f 'facet@test'");
+ $b1 = $communicator->stringToProxy("test -f 'facet@test'");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "facet@test" && $b1->ice_getAdapterId() == "");
- $b1 = $ICE->stringToProxy("test -f 'facet@test'@test");
+ $b1 = $communicator->stringToProxy("test -f 'facet@test'@test");
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getFacet() == "facet@test" && $b1->ice_getAdapterId() == "test");
try
{
- $b1 = $ICE->stringToProxy("test -f facet@test @test");
+ $b1 = $communicator->stringToProxy("test -f facet@test @test");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_ProxyParseException $ex)
+ catch(Ice_ProxyParseException $ex)
{
}
- $b1 = $ICE->stringToProxy("test");
+ $b1 = $communicator->stringToProxy("test");
test($b1->ice_isTwoway());
- $b1 = $ICE->stringToProxy("test -t");
+ $b1 = $communicator->stringToProxy("test -t");
test($b1->ice_isTwoway());
- $b1 = $ICE->stringToProxy("test -o");
+ $b1 = $communicator->stringToProxy("test -o");
test($b1->ice_isOneway());
- $b1 = $ICE->stringToProxy("test -O");
+ $b1 = $communicator->stringToProxy("test -O");
test($b1->ice_isBatchOneway());
- $b1 = $ICE->stringToProxy("test -d");
+ $b1 = $communicator->stringToProxy("test -d");
test($b1->ice_isDatagram());
- $b1 = $ICE->stringToProxy("test -D");
+ $b1 = $communicator->stringToProxy("test -D");
test($b1->ice_isBatchDatagram());
- $b1 = $ICE->stringToProxy("test");
+ $b1 = $communicator->stringToProxy("test");
test(!$b1->ice_isSecure());
- $b1 = $ICE->stringToProxy("test -s");
+ $b1 = $communicator->stringToProxy("test -s");
test($b1->ice_isSecure());
try
{
- $b1 = $ICE->stringToProxy("test:tcp@adapterId");
+ $b1 = $communicator->stringToProxy("test:tcp@adapterId");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
// This is an unknown endpoint warning, not a parse exception.
//
//try
//{
- // $b1 = $ICE->stringToProxy("test -f the:facet:tcp");
+ // $b1 = $communicator->stringToProxy("test -f the:facet:tcp");
// test(false);
//}
- //catch(Ice_EndpointParseException $ex) //catch(Ice_UnknownLocalException $ex)
+ //catch(Ice_EndpointParseException $ex)
//{
//}
try
{
- $b1 = $ICE->stringToProxy("test::tcp");
+ $b1 = $communicator->stringToProxy("test::tcp");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
echo "ok\n";
echo "testing propertyToProxy... ";
$propertyPrefix = "Foo.Proxy";
- $ICE->setProperty($propertyPrefix, "test:default -p 12010");
- $b1 = $ICE->propertyToProxy($propertyPrefix);
+ $communicator->getProperties()->setProperty($propertyPrefix, "test:default -p 12010");
+ $b1 = $communicator->propertyToProxy($propertyPrefix);
test($b1->ice_getIdentity()->name == "test" && $b1->ice_getIdentity()->category == "" &&
$b1->ice_getAdapterId() == "" && $b1->ice_getFacet() == "");
@@ -247,86 +247,86 @@ function allTests()
//
// $property = $propertyPrefix . ".Locator";
// test(!$b1->ice_getLocator());
- // $ICE->setProperty($property, "locator:default -p 10000");
- // $b1 = $ICE->propertyToProxy($propertyPrefix);
+ // $communicator->getProperties()->setProperty($property, "locator:default -p 10000");
+ // $b1 = $communicator->propertyToProxy($propertyPrefix);
// test(!$b1->ice_getLocator());
- // $ICE->setProperty($property, "");
+ // $communicator->getProperties()->setProperty($property, "");
// $property = $propertyPrefix . ".LocatorCacheTimeout";
// test($b1->ice_getLocatorCacheTimeout() == 0);
- // $ICE->setProperty($property, "1");
- // $b1 = $ICE->propertyToProxy($propertyPrefix);
+ // $communicator->getProperties()->setProperty($property, "1");
+ // $b1 = $communicator->propertyToProxy($propertyPrefix);
// test($b1->ice_getLocatorCacheTimeout() == 0);
- // $ICE->setProperty($property, "");
+ // $communicator->getProperties()->setProperty($property, "");
// Now retest with an indirect proxy.
- $ICE->setProperty($propertyPrefix, "test");
+ $communicator->getProperties()->setProperty($propertyPrefix, "test");
$property = $propertyPrefix . ".Locator";
- $ICE->setProperty($property, "locator:default -p 10000");
- $b1 = $ICE->propertyToProxy($propertyPrefix);
+ $communicator->getProperties()->setProperty($property, "locator:default -p 10000");
+ $b1 = $communicator->propertyToProxy($propertyPrefix);
test($b1->ice_getLocator() && $b1->ice_getLocator()->ice_getIdentity()->name == "locator");
- $ICE->setProperty($property, "");
+ $communicator->getProperties()->setProperty($property, "");
$property = $propertyPrefix . ".LocatorCacheTimeout";
test($b1->ice_getLocatorCacheTimeout() == -1);
- $ICE->setProperty($property, "1");
- $b1 = $ICE->propertyToProxy($propertyPrefix);
+ $communicator->getProperties()->setProperty($property, "1");
+ $b1 = $communicator->propertyToProxy($propertyPrefix);
test($b1->ice_getLocatorCacheTimeout() == 1);
- $ICE->setProperty($property, "");
+ $communicator->getProperties()->setProperty($property, "");
// This cannot be tested so easily because the $property is cached
- // on $ICE initialization.
+ // on communicator initialization.
//
- //$ICE->setProperty("Ice.Default.LocatorCacheTimeout", "60");
- //$b1 = $ICE->propertyToProxy($propertyPrefix);
+ //$communicator->getProperties()->setProperty("Ice.Default.LocatorCacheTimeout", "60");
+ //$b1 = $communicator->propertyToProxy($propertyPrefix);
//test($b1->ice_getLocatorCacheTimeout() == 60);
- //$ICE->setProperty("Ice.Default.LocatorCacheTimeout", "");
+ //$communicator->getProperties()->setProperty("Ice.Default.LocatorCacheTimeout", "");
- $ICE->setProperty($propertyPrefix, "test:default -p 12010");
+ $communicator->getProperties()->setProperty($propertyPrefix, "test:default -p 12010");
$property = $propertyPrefix . ".Router";
test(!$b1->ice_getRouter());
- $ICE->setProperty($property, "router:default -p 10000");
- $b1 = $ICE->propertyToProxy($propertyPrefix);
+ $communicator->getProperties()->setProperty($property, "router:default -p 10000");
+ $b1 = $communicator->propertyToProxy($propertyPrefix);
test($b1->ice_getRouter() && $b1->ice_getRouter()->ice_getIdentity()->name == "router");
- $ICE->setProperty($property, "");
+ $communicator->getProperties()->setProperty($property, "");
$property = $propertyPrefix . ".PreferSecure";
test(!$b1->ice_isPreferSecure());
- $ICE->setProperty($property, "1");
- $b1 = $ICE->propertyToProxy($propertyPrefix);
+ $communicator->getProperties()->setProperty($property, "1");
+ $b1 = $communicator->propertyToProxy($propertyPrefix);
test($b1->ice_isPreferSecure());
- $ICE->setProperty($property, "");
+ $communicator->getProperties()->setProperty($property, "");
$property = $propertyPrefix . ".ConnectionCached";
test($b1->ice_isConnectionCached());
- $ICE->setProperty($property, "0");
- $b1 = $ICE->propertyToProxy($propertyPrefix);
+ $communicator->getProperties()->setProperty($property, "0");
+ $b1 = $communicator->propertyToProxy($propertyPrefix);
test(!$b1->ice_isConnectionCached());
- $ICE->setProperty($property, "");
+ $communicator->getProperties()->setProperty($property, "");
$property = $propertyPrefix . ".EndpointSelection";
test($b1->ice_getEndpointSelection() == Ice_EndpointSelectionType::Random);
- $ICE->setProperty($property, "Random");
- $b1 = $ICE->propertyToProxy($propertyPrefix);
+ $communicator->getProperties()->setProperty($property, "Random");
+ $b1 = $communicator->propertyToProxy($propertyPrefix);
test($b1->ice_getEndpointSelection() == Ice_EndpointSelectionType::Random);
- $ICE->setProperty($property, "Ordered");
- $b1 = $ICE->propertyToProxy($propertyPrefix);
+ $communicator->getProperties()->setProperty($property, "Ordered");
+ $b1 = $communicator->propertyToProxy($propertyPrefix);
test($b1->ice_getEndpointSelection() == Ice_EndpointSelectionType::Ordered);
- $ICE->setProperty($property, "");
+ $communicator->getProperties()->setProperty($property, "");
//$property = $propertyPrefix . ".CollocationOptimized";
//test($b1->ice_isCollocationOptimized());
- //$ICE->setProperty($property, "0");
- //$b1 = $ICE->propertyToProxy($propertyPrefix);
+ //$communicator->getProperties()->setProperty($property, "0");
+ //$b1 = $communicator->propertyToProxy($propertyPrefix);
//test(!$b1->ice_isCollocationOptimized());
- //$ICE->setProperty($property, "");
+ //$communicator->getProperties()->setProperty($property, "");
echo "ok\n";
echo "testing proxy methods... ";
flush();
- test($ICE->identityToString($base->ice_identity($ICE->stringToIdentity("other"))->ice_getIdentity()) == "other");
+ test($communicator->identityToString($base->ice_identity($communicator->stringToIdentity("other"))->ice_getIdentity()) == "other");
test($base->ice_facet("facet")->ice_getFacet() == "facet");
test($base->ice_adapterId("id")->ice_getAdapterId() == "id");
test($base->ice_twoway()->ice_isTwoway());
@@ -340,7 +340,7 @@ function allTests()
echo "testing ice_getCommunicator... ";
flush();
- test($base->ice_getCommunicator() === $ICE);
+ test($base->ice_getCommunicator() === $communicator);
echo "ok\n";
echo "testing checked cast... ";
@@ -372,138 +372,139 @@ function allTests()
try
{
// Invalid -x option
- $p = $ICE->stringToProxy("id:opaque -t 99 -v abc -x abc");
+ $p = $communicator->stringToProxy("id:opaque -t 99 -v abc -x abc");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// Missing -t and -v
- $p = $ICE->stringToProxy("id:opaque");
+ $p = $communicator->stringToProxy("id:opaque");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// Repeated -t
- $p = $ICE->stringToProxy("id:opaque -t 1 -t 1 -v abc");
+ $p = $communicator->stringToProxy("id:opaque -t 1 -t 1 -v abc");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// Repeated -v
- $p = $ICE->stringToProxy("id:opaque -t 1 -v abc -v abc");
+ $p = $communicator->stringToProxy("id:opaque -t 1 -v abc -v abc");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// Missing -t
- $p = $ICE->stringToProxy("id:opaque -v abc");
+ $p = $communicator->stringToProxy("id:opaque -v abc");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// Missing -v
- $p = $ICE->stringToProxy("id:opaque -t 1");
+ $p = $communicator->stringToProxy("id:opaque -t 1");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// Missing arg for -t
- $p = $ICE->stringToProxy("id:opaque -t -v abc");
+ $p = $communicator->stringToProxy("id:opaque -t -v abc");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// Missing arg for -v
- $p = $ICE->stringToProxy("id:opaque -t 1 -v");
+ $p = $communicator->stringToProxy("id:opaque -t 1 -v");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// Not a number for -t
- $p = $ICE->stringToProxy("id:opaque -t x -v abc");
+ $p = $communicator->stringToProxy("id:opaque -t x -v abc");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// < 0 for -t
- $p = $ICE->stringToProxy("id:opaque -t -1 -v abc");
+ $p = $communicator->stringToProxy("id:opaque -t -1 -v abc");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
try
{
// Invalid char for -v
- $p = $ICE->stringToProxy("id:opaque -t 99 -v x?c");
+ $p = $communicator->stringToProxy("id:opaque -t 99 -v x?c");
test(false);
}
- catch(Ice_UnknownLocalException $ex) //catch(Ice_EndpointParseException $ex)
+ catch(Ice_EndpointParseException $ex)
{
}
// Legal TCP endpoint expressed as opaque endpoint
- $p1 = $ICE->stringToProxy("test:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==");
- $pstr = $ICE->proxyToString($p1);
+ $p1 = $communicator->stringToProxy("test:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==");
+ $pstr = $communicator->proxyToString($p1);
test($pstr == "test -t:tcp -h 127.0.0.1 -p 12010 -t 10000");
// Working?
- if($ICE->getProperty("Ice.IPv6") == "" || $ICE->getProperty("Ice.IPv6") == "0")
+ if($communicator->getProperties()->getProperty("Ice.IPv6") == "" ||
+ $communicator->getProperties()->getProperty("Ice.IPv6") == "0")
{
- $ssl = $ICE->getProperty("Ice.Default.Protocol") == "ssl";
+ $ssl = $communicator->getProperties()->getProperty("Ice.Default.Protocol") == "ssl";
if(!$ssl)
{
$p1->ice_ping();
}
// Two legal TCP endpoints expressed as opaque endpoints
- $p1 = $ICE->stringToProxy("test:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==:opaque -t 1 -v CTEyNy4wLjAuMusuAAAQJwAAAA==");
- $pstr = $ICE->proxyToString($p1);
+ $p1 = $communicator->stringToProxy("test:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==:opaque -t 1 -v CTEyNy4wLjAuMusuAAAQJwAAAA==");
+ $pstr = $communicator->proxyToString($p1);
test($pstr == "test -t:tcp -h 127.0.0.1 -p 12010 -t 10000:tcp -h 127.0.0.2 -p 12011 -t 10000");
//
// Test that an SSL endpoint and a nonsense endpoint get written
// back out as an opaque endpoint.
//
- $p1 = $ICE->stringToProxy("test:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch");
- $pstr = $ICE->proxyToString($p1);
+ $p1 = $communicator->stringToProxy("test:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch");
+ $pstr = $communicator->proxyToString($p1);
if(!$ssl)
{
test($pstr == "test -t:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch");
@@ -523,8 +524,13 @@ function allTests()
$p1->ice_ping();
test(false);
}
- catch(Ice_UnknownLocalException $ex)
+ catch(Ice_NoEndpointException $ex)
+ {
+ test(!$ssl);
+ }
+ catch(Ice_ConnectionRefusedException $ex)
{
+ test($ssl);
}
//
@@ -534,7 +540,7 @@ function allTests()
// the opaque endpoints.
//
$p2 = $derived->_echo($p1);
- $pstr = $ICE->proxyToString($p2);
+ $pstr = $communicator->proxyToString($p2);
if(!$ssl)
{
test($pstr == "test -t:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch");
@@ -549,8 +555,10 @@ function allTests()
return $cl;
}
-$myClass = allTests();
+$communicator = Ice_initialize(&$argv);
+$myClass = allTests($communicator);
$myClass->shutdown();
+$communicator->destroy();
exit();
?>
diff --git a/php/test/Ice/proxy/Makefile b/php/test/Ice/proxy/Makefile
new file mode 100644
index 00000000000..83671f131ec
--- /dev/null
+++ b/php/test/Ice/proxy/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/proxy/Makefile.mak b/php/test/Ice/proxy/Makefile.mak
new file mode 100644
index 00000000000..ef0c8acea4a
--- /dev/null
+++ b/php/test/Ice/proxy/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/proxy/Test.ice b/php/test/Ice/proxy/Test.ice
index 7d47f52364b..1fc2f21aa23 100644
--- a/php/test/Ice/proxy/Test.ice
+++ b/php/test/Ice/proxy/Test.ice
@@ -10,18 +10,16 @@
#ifndef TEST_ICE
#define TEST_ICE
-#include <Ice/Router.ice>
-#include <Ice/Locator.ice>
-#include <Ice/Current.ice>
-
module Test
{
+dictionary<string, string> Context;
+
class MyClass
{
void shutdown();
- Ice::Context getContext();
+ Context getContext();
};
class MyDerivedClass extends MyClass
diff --git a/php/test/Ice/proxy/php.ini b/php/test/Ice/proxy/php.ini
deleted file mode 100644
index 1fa3edc94d1..00000000000
--- a/php/test/Ice/proxy/php.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-# The test script replaces ICE_HOME by the contents of the environment
-# variable.
-ice.slice=-IICE_HOME/slice -w Test.ice
-display_startup_errors=1
diff --git a/php/test/Ice/slicing/Makefile b/php/test/Ice/slicing/Makefile
new file mode 100644
index 00000000000..4051ad37775
--- /dev/null
+++ b/php/test/Ice/slicing/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = exceptions objects
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/php/test/Ice/slicing/Makefile.mak b/php/test/Ice/slicing/Makefile.mak
new file mode 100644
index 00000000000..bfce9275893
--- /dev/null
+++ b/php/test/Ice/slicing/Makefile.mak
@@ -0,0 +1,19 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = exceptions objects
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/test/Ice/slicing/exceptions/.gitignore b/php/test/Ice/slicing/exceptions/.gitignore
new file mode 100644
index 00000000000..bed01730acc
--- /dev/null
+++ b/php/test/Ice/slicing/exceptions/.gitignore
@@ -0,0 +1 @@
+Test.php
diff --git a/php/test/Ice/slicing/exceptions/Client.php b/php/test/Ice/slicing/exceptions/Client.php
index 2b739bc37fa..28c9c631936 100644
--- a/php/test/Ice/slicing/exceptions/Client.php
+++ b/php/test/Ice/slicing/exceptions/Client.php
@@ -6,7 +6,9 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
+
+require 'Ice.php';
+require 'Test.php';
function test($b)
{
@@ -17,11 +19,9 @@ function test($b)
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
- $obj = $ICE->stringToProxy("Test:default -p 12010");
+ $obj = $communicator->stringToProxy("Test:default -p 12010");
$test = $obj->ice_checkedCast("::Test::TestIntf");
echo "testing throwing a base exception... ";
@@ -247,7 +247,9 @@ function allTests()
return $test;
}
-$test = allTests();
+$communicator = Ice_initialize(&$argv);
+$test = allTests($communicator);
$test->shutdown();
+$communicator->destroy();
exit();
?>
diff --git a/php/test/Ice/slicing/exceptions/Makefile b/php/test/Ice/slicing/exceptions/Makefile
new file mode 100644
index 00000000000..94ebb9296a1
--- /dev/null
+++ b/php/test/Ice/slicing/exceptions/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/slicing/exceptions/Makefile.mak b/php/test/Ice/slicing/exceptions/Makefile.mak
new file mode 100644
index 00000000000..43c21364d6c
--- /dev/null
+++ b/php/test/Ice/slicing/exceptions/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/slicing/exceptions/php.ini b/php/test/Ice/slicing/exceptions/php.ini
deleted file mode 100644
index 8a0b2f9f6e9..00000000000
--- a/php/test/Ice/slicing/exceptions/php.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-ice.slice=Test.ice
-display_startup_errors=1
diff --git a/php/test/Ice/slicing/objects/.gitignore b/php/test/Ice/slicing/objects/.gitignore
new file mode 100644
index 00000000000..cde67ff9c11
--- /dev/null
+++ b/php/test/Ice/slicing/objects/.gitignore
@@ -0,0 +1,3 @@
+ClientPrivate.php
+Forward.php
+Test.php
diff --git a/php/test/Ice/slicing/objects/Client.php b/php/test/Ice/slicing/objects/Client.php
index 533ac71488b..0a08991bd5e 100644
--- a/php/test/Ice/slicing/objects/Client.php
+++ b/php/test/Ice/slicing/objects/Client.php
@@ -6,7 +6,10 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
+
+require 'Ice.php';
+require 'Forward.php';
+require 'ClientPrivate.php';
function test($b)
{
@@ -17,11 +20,9 @@ function test($b)
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
- $obj = $ICE->stringToProxy("Test:default -p 12010");
+ $obj = $communicator->stringToProxy("Test:default -p 12010");
$test = $obj->ice_checkedCast("::Test::TestIntf");
echo "testing base as Object... ";
@@ -799,7 +800,9 @@ function allTests()
return $test;
}
-$test = allTests();
+$communicator = Ice_initialize(&$argv);
+$test = allTests($communicator);
$test->shutdown();
+$communicator->destroy();
exit();
?>
diff --git a/php/test/Ice/slicing/objects/Makefile b/php/test/Ice/slicing/objects/Makefile
new file mode 100644
index 00000000000..3188bc0d0cd
--- /dev/null
+++ b/php/test/Ice/slicing/objects/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = ClientPrivate.php Forward.php Test.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) -I. $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Ice/slicing/objects/Makefile.mak b/php/test/Ice/slicing/objects/Makefile.mak
new file mode 100644
index 00000000000..fd3f76e1e8a
--- /dev/null
+++ b/php/test/Ice/slicing/objects/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = ClientPrivate.php Forward.php Test.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) -I. $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Ice/slicing/objects/php.ini b/php/test/Ice/slicing/objects/php.ini
deleted file mode 100644
index 45d7ad539f4..00000000000
--- a/php/test/Ice/slicing/objects/php.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-ice.slice=-w -I. Forward.ice ClientPrivate.ice
-display_startup_errors=1
diff --git a/php/test/Makefile b/php/test/Makefile
new file mode 100644
index 00000000000..39339188bdd
--- /dev/null
+++ b/php/test/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = Ice Slice
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/php/test/Makefile.mak b/php/test/Makefile.mak
new file mode 100644
index 00000000000..a7b8d7dc641
--- /dev/null
+++ b/php/test/Makefile.mak
@@ -0,0 +1,19 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = Ice Slice
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/test/Slice/Makefile b/php/test/Slice/Makefile
new file mode 100644
index 00000000000..5abb0e85b0f
--- /dev/null
+++ b/php/test/Slice/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = keyword
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/php/test/Slice/Makefile.mak b/php/test/Slice/Makefile.mak
new file mode 100644
index 00000000000..ccb852a2b71
--- /dev/null
+++ b/php/test/Slice/Makefile.mak
@@ -0,0 +1,19 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SUBDIRS = keyword
+
+$(EVERYTHING)::
+ @for %i in ( $(SUBDIRS) ) do \
+ @echo "making $@ in %i" && \
+ cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1
diff --git a/php/test/Slice/keyword/.gitignore b/php/test/Slice/keyword/.gitignore
new file mode 100644
index 00000000000..a4492f0fe05
--- /dev/null
+++ b/php/test/Slice/keyword/.gitignore
@@ -0,0 +1 @@
+Key.php
diff --git a/php/test/Slice/keyword/Client.php b/php/test/Slice/keyword/Client.php
index f50f28fc409..fb96804944c 100644
--- a/php/test/Slice/keyword/Client.php
+++ b/php/test/Slice/keyword/Client.php
@@ -15,7 +15,9 @@ if(!extension_loaded("ice"))
echo "\nerror: Ice extension is not loaded.\n\n";
exit(1);
}
-Ice_loadProfileWithArgs($argv);
+
+require 'Ice.php';
+require 'Key.php';
function test($b)
{
@@ -28,28 +30,28 @@ function test($b)
class echoI extends and_echo
{
- function _else($a, &$b)
+ public function _else($a, $b)
{
}
}
class enddeclareI extends and_enddeclare
{
- function _else($a, &$b)
+ function _else($a, $b)
{
}
+
function _continue($a, $b)
{
}
+
function _do()
{
}
}
-function allTests()
+function allTests($communicator)
{
- global $ICE;
-
echo "testing type names... ";
flush();
$a = and_array::_as;
@@ -63,11 +65,12 @@ function allTests()
test($b->_throw == 0);
test($b->_use == 0);
test($b->_var == 0);
- $c = $ICE->stringToProxy("test:tcp -p 10000")->ice_uncheckedCast("::and::function");
- $d = $ICE->stringToProxy("test:tcp -p 10000")->ice_uncheckedCast("::and::die");
- $e = $ICE->stringToProxy("test:tcp -p 10000")->ice_uncheckedCast("::and::echo");
+ $p = $communicator->stringToProxy("test:tcp -p 10000");
+ $c = and_functionPrxHelper::uncheckedCast($p);
+ $d = and_diePrxHelper::uncheckedCast($p);
+ $e = and_echoPrxHelper::uncheckedCast($p);
$e1 = new echoI();
- $f = $ICE->stringToProxy("test:tcp -p 10000")->ice_uncheckedCast("::and::enddeclare");
+ $f = and_enddeclarePrxHelper::uncheckedCast($p);
$f1 = new enddeclareI();
$g = new and_endif();
$h = new and_endwhile();
@@ -76,7 +79,9 @@ function allTests()
echo "ok\n";
}
-allTests();
+$communicator = Ice_initialize(&$argv);
+allTests($communicator);
+$communicator->destroy();
exit();
?>
diff --git a/php/test/Slice/keyword/Makefile b/php/test/Slice/keyword/Makefile
new file mode 100644
index 00000000000..c1fd7498cfd
--- /dev/null
+++ b/php/test/Slice/keyword/Makefile
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SRCS = Key.php
+
+all:: $(SRCS)
+
+%.php: %.ice
+ $(SLICE2PHP) $(SLICE2PHPFLAGS) $<
+
+clean::
+ rm -f $(SRCS)
diff --git a/php/test/Slice/keyword/Makefile.mak b/php/test/Slice/keyword/Makefile.mak
new file mode 100644
index 00000000000..8dca133fc19
--- /dev/null
+++ b/php/test/Slice/keyword/Makefile.mak
@@ -0,0 +1,22 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+SRCS = Key.php
+
+all:: $(SRCS)
+
+$(SRCS): $*.ice
+ -$(SLICE2PHP) $(SLICE2PHPFLAGS) $*.ice
+
+clean::
+ del /q $(SRCS)
diff --git a/php/test/Slice/keyword/php.ini b/php/test/Slice/keyword/php.ini
deleted file mode 100644
index 91dfdfddefd..00000000000
--- a/php/test/Slice/keyword/php.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-ice.slice=Key.ice
-display_startup_errors=1
diff --git a/py/bin/.gitignore b/py/bin/.gitignore
deleted file mode 100644
index 39af5887579..00000000000
--- a/py/bin/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-# Dummy file, so that git retains this otherwise empty directory.
diff --git a/rb/bin/.gitignore b/rb/bin/.gitignore
deleted file mode 100644
index 39af5887579..00000000000
--- a/rb/bin/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-# Dummy file, so that git retains this otherwise empty directory.
diff --git a/rb/ruby/Ice.rb b/rb/ruby/Ice.rb
index 014be0c7dc2..a54c616efc1 100644
--- a/rb/ruby/Ice.rb
+++ b/rb/ruby/Ice.rb
@@ -560,7 +560,7 @@ module Ice
def Ice.proxyIdentityAndFacetCompare(lhs, rhs)
n = proxyIdentityCompare(lhs, rhs)
- if n == 0
+ if n == 0 && lhs && rhs
n = lhs.ice_getFacet() <=> rhs.ice_getFacet()
end
return n
diff --git a/scripts/TestUtil.py b/scripts/TestUtil.py
index 3c2cbcc49fa..1bee4fd4937 100755
--- a/scripts/TestUtil.py
+++ b/scripts/TestUtil.py
@@ -421,9 +421,10 @@ def getIceDir(subdir = None):
else:
return toplevel
-def writePhpIni(src, dst):
+def phpSetup():
extDir = None
ext = None
+ incDir = None
#
# TODO
@@ -436,7 +437,8 @@ def writePhpIni(src, dst):
#
if isWin32():
ext = "php_ice.dll"
- extDir = os.path.abspath(os.path.join(getIceDir("php"), "bin"))
+ extDir = os.path.abspath(os.path.join(getIceDir("php"), "lib"))
+ incDir = extDir
else:
ext = "IcePHP.so"
if not iceHome:
@@ -460,16 +462,21 @@ def writePhpIni(src, dst):
print "unable to find IcePHP extension!"
sys.exit(1)
- ini = open(src, "r").readlines()
- for i in range(0, len(ini)):
- ini[i] = ini[i].replace("ICE_HOME", os.path.join(toplevel))
- tmpini = open(dst, "w")
- tmpini.writelines(ini)
+ incDir = extDir
+
+ tmpini = open("tmp.ini", "w")
+ tmpini.write("; Automatically generated by Ice test driver.\n")
if extDir:
tmpini.write("extension_dir=%s\n" % extDir)
tmpini.write("extension=%s\n" % ext)
+ if incDir:
+ tmpini.write("include_path=%s\n" % incDir)
tmpini.close()
+def phpCleanup():
+ if os.path.exists("tmp.ini"):
+ os.remove("tmp.ini")
+
def getIceSoVersion():
config = open(os.path.join(toplevel, "cpp", "include", "IceUtil", "Config.h"), "r")
@@ -791,7 +798,7 @@ def isDebug():
return debug
import Expect
-def spawn(cmd, env = None, cwd = None, startReader = True,lang=None):
+def spawn(cmd, env=None, cwd=None, startReader=True, lang=None):
# Start/Reset the watch dog thread
global watchDog
if watchDog == None:
@@ -803,15 +810,15 @@ def spawn(cmd, env = None, cwd = None, startReader = True,lang=None):
print "(%s)" % cmd,
if printenv:
dumpenv(env, lang)
- return Expect.Expect(cmd, startReader = startReader, env = env, logfile=tracefile, cwd = cwd)
+ return Expect.Expect(cmd, startReader=startReader, env=env, logfile=tracefile, cwd=cwd)
-def spawnClient(cmd, env = None, cwd = None, echo = True, startReader = True,lang=None):
- client = spawn(cmd, env, cwd, startReader = startReader,lang = lang)
+def spawnClient(cmd, env=None, cwd=None, echo=True, startReader=True, lang=None):
+ client = spawn(cmd, env, cwd, startReader=startReader, lang=lang)
if echo:
client.trace()
return client
-def spawnServer(cmd, env = None, cwd = None, count = 1, adapter = None, echo = True, lang=None):
+def spawnServer(cmd, env=None, cwd=None, count=1, adapter=None, echo=True, lang=None):
server = spawn(cmd, env, cwd, lang=lang)
if adapter:
server.expect("%s ready\n" % adapter)
@@ -888,6 +895,9 @@ def clientServerTest(additionalServerOptions = "", additionalClientOptions = "",
if clientenv is None:
clientenv = getTestEnv(clientLang, clientdir)
+ if lang == "php":
+ phpSetup()
+
print "starting " + serverDesc + "...",
serverCfg = DriverConfig("server")
if lang in ["rb", "php"]:
@@ -896,9 +906,6 @@ def clientServerTest(additionalServerOptions = "", additionalClientOptions = "",
serverProc = spawnServer(server, env = serverenv, lang=serverCfg.lang)
print "ok"
- if lang == "php":
- writePhpIni("php.ini", "tmp.ini")
-
if clientLang == lang:
print "starting %s..." % clientDesc,
else:
@@ -942,7 +949,7 @@ def startClient(exe, args = "", config=None, env=None, echo = True, startReader
env = getTestEnv(getDefaultMapping(), os.getcwd())
cmd = getCommandLine(exe, config) + ' ' + args
if config.lang == "php":
- writePhpIni("php.ini", "tmp.ini")
+ phpSetup()
return spawnClient(cmd, env = env, echo = echo, startReader = startReader, lang=config.lang)
def startServer(exe, args = "", config=None, env=None, adapter = None, count = 1, echo = True):
@@ -1057,6 +1064,10 @@ def cleanup():
watchDog.join()
watchDog = None
+ lang = getDefaultMapping()
+ if lang == "php":
+ phpCleanup()
+
def processCmdLine():
def usage():
print "usage: " + sys.argv[0] + """