summaryrefslogtreecommitdiff
path: root/ruby/src
diff options
context:
space:
mode:
Diffstat (limited to 'ruby/src')
-rw-r--r--ruby/src/IceRuby/.depend.mak13
-rw-r--r--ruby/src/IceRuby/Communicator.cpp596
-rw-r--r--ruby/src/IceRuby/Communicator.h25
-rw-r--r--ruby/src/IceRuby/Config.h90
-rw-r--r--ruby/src/IceRuby/Connection.cpp433
-rw-r--r--ruby/src/IceRuby/Connection.h26
-rw-r--r--ruby/src/IceRuby/Endpoint.cpp332
-rw-r--r--ruby/src/IceRuby/Endpoint.h27
-rw-r--r--ruby/src/IceRuby/ImplicitContext.cpp152
-rw-r--r--ruby/src/IceRuby/ImplicitContext.h25
-rw-r--r--ruby/src/IceRuby/Init.cpp59
-rw-r--r--ruby/src/IceRuby/Logger.cpp151
-rw-r--r--ruby/src/IceRuby/Logger.h28
-rw-r--r--ruby/src/IceRuby/Makefile50
-rw-r--r--ruby/src/IceRuby/ObjectFactory.cpp140
-rw-r--r--ruby/src/IceRuby/ObjectFactory.h50
-rw-r--r--ruby/src/IceRuby/Operation.cpp676
-rw-r--r--ruby/src/IceRuby/Operation.h36
-rw-r--r--ruby/src/IceRuby/Properties.cpp369
-rw-r--r--ruby/src/IceRuby/Properties.h25
-rw-r--r--ruby/src/IceRuby/Proxy.cpp1354
-rw-r--r--ruby/src/IceRuby/Proxy.h27
-rw-r--r--ruby/src/IceRuby/Slice.cpp223
-rw-r--r--ruby/src/IceRuby/Slice.h22
-rw-r--r--ruby/src/IceRuby/Types.cpp3189
-rw-r--r--ruby/src/IceRuby/Types.h546
-rw-r--r--ruby/src/IceRuby/Util.cpp783
-rw-r--r--ruby/src/IceRuby/Util.h511
-rw-r--r--ruby/src/Makefile24
29 files changed, 9982 insertions, 0 deletions
diff --git a/ruby/src/IceRuby/.depend.mak b/ruby/src/IceRuby/.depend.mak
new file mode 100644
index 00000000000..5112d16c440
--- /dev/null
+++ b/ruby/src/IceRuby/.depend.mak
@@ -0,0 +1,13 @@
+Communicator$(OBJEXT): Communicator.cpp Communicator.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" ImplicitContext.h "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/Identity.h" "$(ice_cpp_dir)/include/Ice/Version.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Current.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ConnectionF.h" Logger.h "$(ice_cpp_dir)/include/Ice/Logger.h" ObjectFactory.h "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/IceUtil/Mutex.h" "$(ice_cpp_dir)/include/IceUtil/Lock.h" "$(ice_cpp_dir)/include/IceUtil/ThreadException.h" "$(ice_cpp_dir)/include/IceUtil/Time.h" "$(ice_cpp_dir)/include/IceUtil/MutexProtocol.h" Properties.h "$(ice_cpp_dir)/include/Ice/PropertiesF.h" "$(ice_cpp_dir)/include/Ice/Proxy.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" Proxy.h Types.h Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/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/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h" "$(ice_cpp_dir)/include/IceUtil/OutputUtil.h"
+Connection$(OBJEXT): Connection.cpp Connection.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.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/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/Endpoint.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" Endpoint.h Types.h Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.h" "$(ice_cpp_dir)/include/Ice/PropertiesF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapter.h" "$(ice_cpp_dir)/include/Ice/FacetMap.h" "$(ice_cpp_dir)/include/Ice/ServantLocator.h" "$(ice_cpp_dir)/include/Ice/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h" "$(ice_cpp_dir)/include/IceUtil/OutputUtil.h"
+Endpoint$(OBJEXT): Endpoint.cpp Endpoint.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.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/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/Endpoint.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.h" "$(ice_cpp_dir)/include/Ice/PropertiesF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapter.h" "$(ice_cpp_dir)/include/Ice/FacetMap.h" "$(ice_cpp_dir)/include/Ice/ServantLocator.h" "$(ice_cpp_dir)/include/Ice/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h"
+ImplicitContext$(OBJEXT): ImplicitContext.cpp ImplicitContext.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/Identity.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" "$(ice_cpp_dir)/include/Ice/Version.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Current.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ConnectionF.h" Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h"
+Init$(OBJEXT): Init.cpp Communicator.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" ImplicitContext.h "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/Identity.h" "$(ice_cpp_dir)/include/Ice/Version.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Current.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ConnectionF.h" Logger.h "$(ice_cpp_dir)/include/Ice/Logger.h" Operation.h Properties.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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" Proxy.h Slice.h Types.h Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h" "$(ice_cpp_dir)/include/IceUtil/OutputUtil.h" Connection.h Endpoint.h
+Logger$(OBJEXT): Logger.cpp Logger.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h"
+ObjectFactory$(OBJEXT): ObjectFactory.cpp ObjectFactory.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.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/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" "$(ice_cpp_dir)/include/IceUtil/Mutex.h" "$(ice_cpp_dir)/include/IceUtil/Lock.h" "$(ice_cpp_dir)/include/IceUtil/ThreadException.h" "$(ice_cpp_dir)/include/IceUtil/Time.h" "$(ice_cpp_dir)/include/IceUtil/MutexProtocol.h" Types.h Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.h" "$(ice_cpp_dir)/include/Ice/PropertiesF.h" "$(ice_cpp_dir)/include/Ice/Proxy.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/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/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h" "$(ice_cpp_dir)/include/IceUtil/OutputUtil.h"
+Operation$(OBJEXT): Operation.cpp Operation.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" Proxy.h Types.h Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h" "$(ice_cpp_dir)/include/IceUtil/OutputUtil.h" "$(ice_cpp_dir)/include/Slice/RubyUtil.h" "$(ice_cpp_dir)/include/Slice/Parser.h"
+Properties$(OBJEXT): Properties.cpp Properties.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/PropertiesF.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.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/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h"
+Proxy$(OBJEXT): Proxy.cpp "$(ice_cpp_dir)/include/IceUtil/DisableWarnings.h" Proxy.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" Communicator.h Connection.h "$(ice_cpp_dir)/include/Ice/Connection.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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/Endpoint.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" Endpoint.h Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.h" "$(ice_cpp_dir)/include/Ice/PropertiesF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapter.h" "$(ice_cpp_dir)/include/Ice/FacetMap.h" "$(ice_cpp_dir)/include/Ice/ServantLocator.h" "$(ice_cpp_dir)/include/Ice/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h"
+Slice$(OBJEXT): Slice.cpp Slice.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h" "$(ice_cpp_dir)/include/Slice/Preprocessor.h" "$(ice_cpp_dir)/include/Slice/RubyUtil.h" "$(ice_cpp_dir)/include/Slice/Parser.h" "$(ice_cpp_dir)/include/IceUtil/OutputUtil.h" "$(ice_cpp_dir)/include/IceUtil/Options.h" "$(ice_cpp_dir)/include/IceUtil/RecMutex.h"
+Types$(OBJEXT): Types.cpp Types.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" Util.h "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h" "$(ice_cpp_dir)/include/IceUtil/OutputUtil.h" Proxy.h "$(ice_cpp_dir)/include/IceUtil/InputUtil.h"
+Util$(OBJEXT): Util.cpp Util.h Config.h "$(ice_cpp_dir)/include/Ice/Config.h" "$(ice_cpp_dir)/include/IceUtil/Config.h" "$(ice_cpp_dir)/include/Ice/Ice.h" "$(ice_cpp_dir)/include/Ice/DeprecatedStringConverter.h" "$(ice_cpp_dir)/include/Ice/CommunicatorF.h" "$(ice_cpp_dir)/include/Ice/ProxyF.h" "$(ice_cpp_dir)/include/IceUtil/Shared.h" "$(ice_cpp_dir)/include/Ice/ProxyHandle.h" "$(ice_cpp_dir)/include/IceUtil/Handle.h" "$(ice_cpp_dir)/include/IceUtil/Exception.h" "$(ice_cpp_dir)/include/Ice/ObjectF.h" "$(ice_cpp_dir)/include/Ice/Handle.h" "$(ice_cpp_dir)/include/Ice/Exception.h" "$(ice_cpp_dir)/include/Ice/Format.h" "$(ice_cpp_dir)/include/Ice/StreamF.h" "$(ice_cpp_dir)/include/Ice/LocalObject.h" "$(ice_cpp_dir)/include/Ice/LocalObjectF.h" "$(ice_cpp_dir)/include/Ice/StreamHelpers.h" "$(ice_cpp_dir)/include/IceUtil/ScopedArray.h" "$(ice_cpp_dir)/include/IceUtil/Iterator.h" "$(ice_cpp_dir)/include/IceUtil/Optional.h" "$(ice_cpp_dir)/include/IceUtil/UndefSysMacros.h" "$(ice_cpp_dir)/include/IceUtil/StringConverter.h" "$(ice_cpp_dir)/include/Ice/Initialize.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/IceUtil/MutexProtocol.h" "$(ice_cpp_dir)/include/Ice/ProxyFactoryF.h" "$(ice_cpp_dir)/include/Ice/ConnectionIF.h" "$(ice_cpp_dir)/include/Ice/RequestHandlerF.h" "$(ice_cpp_dir)/include/Ice/EndpointF.h" "$(ice_cpp_dir)/include/Ice/EndpointTypes.h" "$(ice_cpp_dir)/include/Ice/ObjectAdapterF.h" "$(ice_cpp_dir)/include/Ice/ReferenceF.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsync.h" "$(ice_cpp_dir)/include/IceUtil/Monitor.h" "$(ice_cpp_dir)/include/IceUtil/Cond.h" "$(ice_cpp_dir)/include/IceUtil/Timer.h" "$(ice_cpp_dir)/include/IceUtil/Thread.h" "$(ice_cpp_dir)/include/IceUtil/UniquePtr.h" "$(ice_cpp_dir)/include/Ice/OutgoingAsyncF.h" "$(ice_cpp_dir)/include/Ice/InstanceF.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/Version.h" "$(ice_cpp_dir)/include/Ice/BasicStream.h" "$(ice_cpp_dir)/include/Ice/Object.h" "$(ice_cpp_dir)/include/Ice/IncomingAsyncF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryF.h" "$(ice_cpp_dir)/include/Ice/ObjectFactoryManagerF.h" "$(ice_cpp_dir)/include/Ice/Buffer.h" "$(ice_cpp_dir)/include/Ice/Protocol.h" "$(ice_cpp_dir)/include/Ice/SlicedDataF.h" "$(ice_cpp_dir)/include/Ice/UserExceptionFactory.h" "$(ice_cpp_dir)/include/Ice/FactoryTable.h" "$(ice_cpp_dir)/include/Ice/ObserverHelper.h" "$(ice_cpp_dir)/include/Ice/Instrumentation.h" "$(ice_cpp_dir)/include/Ice/ThreadPoolF.h" "$(ice_cpp_dir)/include/Ice/LoggerF.h" "$(ice_cpp_dir)/include/Ice/InstrumentationF.h" "$(ice_cpp_dir)/include/Ice/Dispatcher.h" "$(ice_cpp_dir)/include/Ice/BuiltinSequences.h" "$(ice_cpp_dir)/include/Ice/Plugin.h" "$(ice_cpp_dir)/include/Ice/LocalException.h" "$(ice_cpp_dir)/include/Ice/PropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/GCObject.h" "$(ice_cpp_dir)/include/IceUtil/MutexPtrLock.h" "$(ice_cpp_dir)/include/Ice/Outgoing.h" "$(ice_cpp_dir)/include/Ice/Incoming.h" "$(ice_cpp_dir)/include/Ice/ServantLocatorF.h" "$(ice_cpp_dir)/include/Ice/ServantManagerF.h" "$(ice_cpp_dir)/include/Ice/ResponseHandlerF.h" "$(ice_cpp_dir)/include/Ice/IncomingAsync.h" "$(ice_cpp_dir)/include/Ice/Properties.h" "$(ice_cpp_dir)/include/Ice/Logger.h" "$(ice_cpp_dir)/include/Ice/LoggerUtil.h" "$(ice_cpp_dir)/include/Ice/RemoteLogger.h" "$(ice_cpp_dir)/include/Ice/FactoryTableInit.h" "$(ice_cpp_dir)/include/Ice/DefaultObjectFactory.h" "$(ice_cpp_dir)/include/Ice/ObjectFactory.h" "$(ice_cpp_dir)/include/Ice/Communicator.h" "$(ice_cpp_dir)/include/Ice/RouterF.h" "$(ice_cpp_dir)/include/Ice/LocatorF.h" "$(ice_cpp_dir)/include/Ice/PluginF.h" "$(ice_cpp_dir)/include/Ice/ImplicitContextF.h" "$(ice_cpp_dir)/include/Ice/CommunicatorAsync.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/SlicedData.h" "$(ice_cpp_dir)/include/Ice/Process.h" "$(ice_cpp_dir)/include/Ice/Application.h" "$(ice_cpp_dir)/include/Ice/Connection.h" "$(ice_cpp_dir)/include/Ice/ConnectionAsync.h" "$(ice_cpp_dir)/include/Ice/Functional.h" "$(ice_cpp_dir)/include/IceUtil/Functional.h" "$(ice_cpp_dir)/include/Ice/Stream.h" "$(ice_cpp_dir)/include/Ice/ImplicitContext.h" "$(ice_cpp_dir)/include/Ice/Locator.h" "$(ice_cpp_dir)/include/Ice/ProcessF.h" "$(ice_cpp_dir)/include/Ice/Router.h" "$(ice_cpp_dir)/include/Ice/DispatchInterceptor.h" "$(ice_cpp_dir)/include/Ice/NativePropertiesAdmin.h" "$(ice_cpp_dir)/include/Ice/Metrics.h" "$(ice_cpp_dir)/include/Ice/Service.h"
diff --git a/ruby/src/IceRuby/Communicator.cpp b/ruby/src/IceRuby/Communicator.cpp
new file mode 100644
index 00000000000..24d9629a847
--- /dev/null
+++ b/ruby/src/IceRuby/Communicator.cpp
@@ -0,0 +1,596 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Communicator.h>
+#include <ImplicitContext.h>
+#include <Logger.h>
+#include <ObjectFactory.h>
+#include <Properties.h>
+#include <Proxy.h>
+#include <Types.h>
+#include <Util.h>
+#include <Ice/Communicator.h>
+#include <Ice/Initialize.h>
+#include <Ice/Locator.h>
+#include <Ice/ObjectFactory.h>
+#include <Ice/Properties.h>
+#include <Ice/Router.h>
+
+using namespace std;
+using namespace IceRuby;
+
+static VALUE _communicatorClass;
+
+typedef map<Ice::CommunicatorPtr, VALUE> CommunicatorMap;
+static CommunicatorMap _communicatorMap;
+
+extern "C"
+void
+IceRuby_Communicator_mark(Ice::CommunicatorPtr* p)
+{
+ assert(p);
+ try
+ {
+ ObjectFactoryPtr pof = ObjectFactoryPtr::dynamicCast((*p)->findObjectFactory(""));
+ assert(pof);
+ pof->mark();
+ }
+ catch(const Ice::CommunicatorDestroyedException&)
+ {
+ // Ignore. This is expected.
+ }
+}
+
+extern "C"
+void
+IceRuby_Communicator_free(Ice::CommunicatorPtr* p)
+{
+ assert(p);
+ delete p;
+}
+
+extern "C"
+VALUE
+IceRuby_initialize(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ volatile VALUE initDataCls = callRuby(rb_path2class, "Ice::InitializationData");
+ volatile VALUE args = Qnil, initData = Qnil;
+ if(argc == 1)
+ {
+ if(isArray(argv[0]))
+ {
+ args = argv[0];
+ }
+ else if(callRuby(rb_obj_is_instance_of, argv[0], initDataCls) == Qtrue)
+ {
+ initData = argv[0];
+ }
+ else
+ {
+ throw RubyException(rb_eTypeError, "invalid argument to Ice::initialize");
+ }
+ }
+ else if(argc == 2)
+ {
+ if(!isArray(argv[0]) || callRuby(rb_obj_is_instance_of, argv[1], initDataCls) == Qfalse)
+ {
+ throw RubyException(rb_eTypeError, "invalid argument to Ice::initialize");
+ }
+ args = argv[0];
+ initData = argv[1];
+ }
+ else if(argc > 0)
+ {
+ throw RubyException(rb_eArgError, "invalid number of arguments to Ice::initialize");
+ }
+
+ Ice::StringSeq seq;
+ if(!NIL_P(args) && !arrayToStringSeq(args, seq))
+ {
+ throw RubyException(rb_eTypeError, "invalid array argument to Ice::initialize");
+ }
+
+ //
+ // Use the with-args or the without-args version of initialize()?
+ //
+ bool hasArgs = !NIL_P(args);
+
+ Ice::InitializationData data;
+ if(!NIL_P(initData))
+ {
+ volatile VALUE properties = callRuby(rb_iv_get, initData, "@properties");
+ volatile VALUE logger = callRuby(rb_iv_get, initData, "@logger");
+
+ if(!NIL_P(properties))
+ {
+ data.properties = getProperties(properties);
+ }
+
+ if(!NIL_P(logger))
+ {
+ throw RubyException(rb_eArgError, "custom logger is not supported");
+ }
+ }
+
+ //
+ // Insert the program name (stored in the Ruby global variable $0) as the first
+ // element of the sequence.
+ //
+ volatile VALUE progName = callRuby(rb_gv_get, "$0");
+ seq.insert(seq.begin(), getString(progName));
+
+ data.compactIdResolver = new IdResolver;
+
+ if(hasArgs)
+ {
+ data.properties = Ice::createProperties(seq, data.properties);
+ }
+ else if(!data.properties)
+ {
+ data.properties = Ice::createProperties();
+ }
+ //
+ // Disable collocation optimization, otherwise an invocation on a
+ // collocated servant results in a CollocationOptimizationException
+ // (because Ruby uses the blobject API).
+ //
+ // TODO: Enable if a server mapping is added.
+ //
+ //data.properties->setProperty("Ice.Default.CollocationOptimization", "0");
+
+ //
+ // Remaining command line options are passed to the communicator
+ // as an argument vector in case they contain plugin properties.
+ //
+ int ac = static_cast<int>(seq.size());
+ char** av = new char*[ac + 1];
+ int i = 0;
+ for(Ice::StringSeq::const_iterator s = seq.begin(); s != seq.end(); ++s, ++i)
+ {
+ av[i] = strdup(s->c_str());
+ }
+ av[ac] = 0;
+
+ Ice::CommunicatorPtr communicator;
+ try
+ {
+ if(hasArgs)
+ {
+ communicator = Ice::initialize(ac, av, data);
+ }
+ else
+ {
+ communicator = Ice::initialize(data);
+ }
+ }
+ catch(...)
+ {
+ for(i = 0; i < ac + 1; ++i)
+ {
+ free(av[i]);
+ }
+ delete[] av;
+
+ throw;
+ }
+
+ //
+ // Replace the contents of the given argument list with the filtered arguments.
+ //
+ if(!NIL_P(args))
+ {
+ callRuby(rb_ary_clear, args);
+
+ //
+ // We start at index 1 in order to skip the element that we inserted earlier.
+ //
+ for(i = 1; i < ac; ++i)
+ {
+ volatile VALUE str = createString(av[i]);
+ callRuby(rb_ary_push, args, str);
+ }
+ }
+
+ for(i = 0; i < ac + 1; ++i)
+ {
+ free(av[i]);
+ }
+ delete[] av;
+
+ ObjectFactoryPtr factory = new ObjectFactory;
+ communicator->addObjectFactory(factory, "");
+
+ VALUE result = Data_Wrap_Struct(_communicatorClass, IceRuby_Communicator_mark,
+ IceRuby_Communicator_free, new Ice::CommunicatorPtr(communicator));
+
+ CommunicatorMap::iterator p = _communicatorMap.find(communicator);
+ if(p != _communicatorMap.end())
+ {
+ _communicatorMap.erase(p);
+ }
+ _communicatorMap.insert(CommunicatorMap::value_type(communicator, reinterpret_cast<const VALUE&>(result)));
+
+ return result;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_destroy(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ p->destroy();
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_shutdown(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ p->shutdown();
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_isShutdown(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ return p->isShutdown() ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_stringToProxy(VALUE self, VALUE str)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ string s = getString(str);
+ Ice::ObjectPrx proxy = p->stringToProxy(s);
+ if(proxy)
+ {
+ return createProxy(proxy);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_proxyToString(VALUE self, VALUE proxy)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::ObjectPrx prx;
+ if(!NIL_P(proxy))
+ {
+ if(!checkProxy(proxy))
+ {
+ throw RubyException(rb_eTypeError, "argument must be a proxy");
+ }
+ prx = getProxy(proxy);
+ }
+ string str = p->proxyToString(prx);
+ return createString(str);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_propertyToProxy(VALUE self, VALUE str)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ string s = getString(str);
+ Ice::ObjectPrx proxy = p->propertyToProxy(s);
+ if(proxy)
+ {
+ return createProxy(proxy);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_proxyToProperty(VALUE self, VALUE obj, VALUE str)
+{
+ ICE_RUBY_TRY
+ {
+ if(!checkProxy(obj))
+ {
+ throw RubyException(rb_eTypeError, "argument must be a proxy");
+ }
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::ObjectPrx o = getProxy(obj);
+ string s = getString(str);
+ Ice::PropertyDict dict = p->proxyToProperty(o, s);
+ volatile VALUE result = callRuby(rb_hash_new);
+ for(Ice::PropertyDict::const_iterator q = dict.begin(); q != dict.end(); ++q)
+ {
+ volatile VALUE key = createString(q->first);
+ volatile VALUE value = createString(q->second);
+ callRuby(rb_hash_aset, result, key, value);
+ }
+ return result;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_stringToIdentity(VALUE self, VALUE str)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ string s = getString(str);
+ Ice::Identity ident = p->stringToIdentity(s);
+ return createIdentity(ident);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_identityToString(VALUE self, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::Identity ident = getIdentity(id);
+ string str = p->identityToString(ident);
+ return createString(str);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_addObjectFactory(VALUE self, VALUE factory, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ ObjectFactoryPtr pof = ObjectFactoryPtr::dynamicCast(p->findObjectFactory(""));
+ assert(pof);
+ string idstr = getString(id);
+ pof->add(factory, idstr);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_findObjectFactory(VALUE self, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ ObjectFactoryPtr pof = ObjectFactoryPtr::dynamicCast(p->findObjectFactory(""));
+ assert(pof);
+ string idstr = getString(id);
+ return pof->find(idstr);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_getImplicitContext(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::ImplicitContextPtr implicitContext = p->getImplicitContext();
+ return createImplicitContext(implicitContext);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+
+extern "C"
+VALUE
+IceRuby_Communicator_getProperties(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::PropertiesPtr props = p->getProperties();
+ return createProperties(props);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_getLogger(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::LoggerPtr logger = p->getLogger();
+ return createLogger(logger);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_getDefaultRouter(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::RouterPrx router = p->getDefaultRouter();
+ if(router)
+ {
+ volatile VALUE cls = callRuby(rb_path2class, "Ice::RouterPrx");
+ assert(!NIL_P(cls));
+ return createProxy(router, cls);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_setDefaultRouter(VALUE self, VALUE router)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::RouterPrx proxy;
+ if(!NIL_P(router))
+ {
+ if(!checkProxy(router))
+ {
+ throw RubyException(rb_eTypeError, "argument must be a proxy");
+ }
+ proxy = Ice::RouterPrx::uncheckedCast(getProxy(router));
+ }
+ p->setDefaultRouter(proxy);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_getDefaultLocator(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::LocatorPrx locator = p->getDefaultLocator();
+ if(locator)
+ {
+ volatile VALUE cls = callRuby(rb_path2class, "Ice::LocatorPrx");
+ assert(!NIL_P(cls));
+ return createProxy(locator, cls);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_setDefaultLocator(VALUE self, VALUE locator)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ Ice::LocatorPrx proxy;
+ if(!NIL_P(locator))
+ {
+ if(!checkProxy(locator))
+ {
+ throw RubyException(rb_eTypeError, "argument must be a proxy");
+ }
+ proxy = Ice::LocatorPrx::uncheckedCast(getProxy(locator));
+ }
+ p->setDefaultLocator(proxy);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_flushBatchRequests(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ p->flushBatchRequests();
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+void
+IceRuby::initCommunicator(VALUE iceModule)
+{
+ rb_define_module_function(iceModule, "initialize", CAST_METHOD(IceRuby_initialize), -1);
+
+ _communicatorClass = rb_define_class_under(iceModule, "CommunicatorI", rb_cObject);
+ rb_define_method(_communicatorClass, "destroy", CAST_METHOD(IceRuby_Communicator_destroy), 0);
+ rb_define_method(_communicatorClass, "shutdown", CAST_METHOD(IceRuby_Communicator_shutdown), 0);
+ rb_define_method(_communicatorClass, "isShutdown", CAST_METHOD(IceRuby_Communicator_isShutdown), 0);
+ rb_define_method(_communicatorClass, "stringToProxy", CAST_METHOD(IceRuby_Communicator_stringToProxy), 1);
+ rb_define_method(_communicatorClass, "proxyToString", CAST_METHOD(IceRuby_Communicator_proxyToString), 1);
+ rb_define_method(_communicatorClass, "propertyToProxy", CAST_METHOD(IceRuby_Communicator_propertyToProxy), 1);
+ rb_define_method(_communicatorClass, "proxyToProperty", CAST_METHOD(IceRuby_Communicator_proxyToProperty), 2);
+ rb_define_method(_communicatorClass, "stringToIdentity", CAST_METHOD(IceRuby_Communicator_stringToIdentity), 1);
+ rb_define_method(_communicatorClass, "identityToString", CAST_METHOD(IceRuby_Communicator_identityToString), 1);
+ rb_define_method(_communicatorClass, "addObjectFactory", CAST_METHOD(IceRuby_Communicator_addObjectFactory), 2);
+ rb_define_method(_communicatorClass, "findObjectFactory", CAST_METHOD(IceRuby_Communicator_findObjectFactory), 1);
+ rb_define_method(_communicatorClass, "getImplicitContext", CAST_METHOD(IceRuby_Communicator_getImplicitContext), 0);
+ rb_define_method(_communicatorClass, "getProperties", CAST_METHOD(IceRuby_Communicator_getProperties), 0);
+ rb_define_method(_communicatorClass, "getLogger", CAST_METHOD(IceRuby_Communicator_getLogger), 0);
+ rb_define_method(_communicatorClass, "getDefaultRouter", CAST_METHOD(IceRuby_Communicator_getDefaultRouter), 0);
+ rb_define_method(_communicatorClass, "setDefaultRouter", CAST_METHOD(IceRuby_Communicator_setDefaultRouter), 1);
+ rb_define_method(_communicatorClass, "getDefaultLocator", CAST_METHOD(IceRuby_Communicator_getDefaultLocator), 0);
+ rb_define_method(_communicatorClass, "setDefaultLocator", CAST_METHOD(IceRuby_Communicator_setDefaultLocator), 1);
+ rb_define_method(_communicatorClass, "flushBatchRequests", CAST_METHOD(IceRuby_Communicator_flushBatchRequests), 0);
+}
+
+Ice::CommunicatorPtr
+IceRuby::getCommunicator(VALUE v)
+{
+ Ice::CommunicatorPtr* p = reinterpret_cast<Ice::CommunicatorPtr*>(DATA_PTR(v));
+ assert(p);
+ return *p;
+}
+
+VALUE
+IceRuby::lookupCommunicator(const Ice::CommunicatorPtr& p)
+{
+ CommunicatorMap::iterator q = _communicatorMap.find(p.get());
+ if(q != _communicatorMap.end())
+ {
+ return q->second;
+ }
+ return Qnil;
+}
diff --git a/ruby/src/IceRuby/Communicator.h b/ruby/src/IceRuby/Communicator.h
new file mode 100644
index 00000000000..8cb5576cf02
--- /dev/null
+++ b/ruby/src/IceRuby/Communicator.h
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_COMMUNICATOR_H
+#define ICE_RUBY_COMMUNICATOR_H
+
+#include <Config.h>
+#include <Ice/CommunicatorF.h>
+
+namespace IceRuby
+{
+
+void initCommunicator(VALUE);
+Ice::CommunicatorPtr getCommunicator(VALUE);
+VALUE lookupCommunicator(const Ice::CommunicatorPtr&);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Config.h b/ruby/src/IceRuby/Config.h
new file mode 100644
index 00000000000..82e755a4fe9
--- /dev/null
+++ b/ruby/src/IceRuby/Config.h
@@ -0,0 +1,90 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_CONFIG_H
+#define ICE_RUBY_CONFIG_H
+
+//
+// This file includes <ruby.h> and should always be included first.
+//
+
+#include <Ice/Config.h>
+
+//
+// COMPILERFIX: This is required to prevent annoying warnings with aCC.
+// The aCC -mt option causes the definition of the _POSIX_C_SOURCE macro
+// (with another lower value.) and this is causing a warning because of
+// the redefinition.
+//
+//#if defined(__HP_aCC) && defined(_POSIX_C_SOURCE)
+//# undef _POSIX_C_SOURCE
+//#endif
+
+//
+// Ruby defines _FILE_OFFSET_BITS without a guard; we undefine it to
+// avoid a warning
+//
+#if defined(__SUNPRO_CC) && defined(_FILE_OFFSET_BITS)
+ #undef _FILE_OFFSET_BITS
+#endif
+
+//
+// COMPILERFIX: Mingw headers fail to find some definitions if
+// wincrypt.h isn't included before ruby.h
+//
+#ifdef _WIN32
+# include <wincrypt.h>
+#endif
+
+#include <ruby.h>
+
+//
+// The Ruby header file win32/win32.h defines a number of macros for
+// functions like shutdown() and close() that wreak havoc.
+//
+#ifdef _WIN32
+# undef shutdown
+# undef close
+# undef read
+# undef write
+# undef sleep
+#endif
+
+extern "C"
+{
+typedef VALUE(*ICE_RUBY_ENTRY_POINT)(...);
+}
+
+#define CAST_METHOD(X) reinterpret_cast<ICE_RUBY_ENTRY_POINT>(X)
+
+//
+// These macros are defined in Ruby 1.9 but not in 1.8. We define them here
+// to maintain compatibility with 1.8.
+//
+#ifndef RARRAY_PTR
+# define RARRAY_PTR(v) RARRAY(v)->ptr
+#endif
+
+#ifndef RARRAY_LEN
+# define RARRAY_LEN(v) RARRAY(v)->len
+#endif
+
+#ifndef RSTRING_PTR
+# define RSTRING_PTR(v) RSTRING(v)->ptr
+#endif
+
+#ifndef RSTRING_LEN
+# define RSTRING_LEN(v) RSTRING(v)->len
+#endif
+
+#ifndef RFLOAT_VALUE
+# define RFLOAT_VALUE(v) RFLOAT(v)->value
+#endif
+
+#endif
diff --git a/ruby/src/IceRuby/Connection.cpp b/ruby/src/IceRuby/Connection.cpp
new file mode 100644
index 00000000000..ecc5209c0d5
--- /dev/null
+++ b/ruby/src/IceRuby/Connection.cpp
@@ -0,0 +1,433 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Connection.h>
+#include <Endpoint.h>
+#include <Types.h>
+#include <Util.h>
+#include <Ice/Object.h>
+
+using namespace std;
+using namespace IceRuby;
+
+static VALUE _connectionClass;
+
+static VALUE _connectionInfoClass;
+static VALUE _ipConnectionInfoClass;
+static VALUE _tcpConnectionInfoClass;
+static VALUE _udpConnectionInfoClass;
+static VALUE _wsConnectionInfoClass;
+
+// **********************************************************************
+// Connection
+// **********************************************************************
+
+extern "C"
+void
+IceRuby_Connection_free(Ice::ConnectionPtr* p)
+{
+ assert(p);
+ delete p;
+}
+
+VALUE
+IceRuby::createConnection(const Ice::ConnectionPtr& p)
+{
+ return Data_Wrap_Struct(_connectionClass, 0, IceRuby_Connection_free, new Ice::ConnectionPtr(p));
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_close(VALUE self, VALUE b)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ (*p)->close(RTEST(b));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_flushBatchRequests(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ (*p)->flushBatchRequests();
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_setACM(VALUE self, VALUE t, VALUE c, VALUE h)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ IceUtil::Optional<Ice::Int> timeout;
+ IceUtil::Optional<Ice::ACMClose> close;
+ IceUtil::Optional<Ice::ACMHeartbeat> heartbeat;
+
+ if(t != Unset)
+ {
+ timeout = static_cast<Ice::Int>(getInteger(t));
+ }
+
+ if(c != Unset)
+ {
+ volatile VALUE type = callRuby(rb_path2class, "Ice::ACMClose");
+ if(callRuby(rb_obj_is_instance_of, c, type) != Qtrue)
+ {
+ throw RubyException(rb_eTypeError,
+ "value for 'close' argument must be Unset or an enumerator of Ice.ACMClose");
+ }
+ volatile VALUE closeValue = callRuby(rb_funcall, c, rb_intern("to_i"), 0);
+ assert(TYPE(closeValue) == T_FIXNUM);
+ close = static_cast<Ice::ACMClose>(FIX2LONG(closeValue));
+ }
+
+ if(h != Unset)
+ {
+ volatile VALUE type = callRuby(rb_path2class, "Ice::ACMHeartbeat");
+ if(callRuby(rb_obj_is_instance_of, h, type) != Qtrue)
+ {
+ throw RubyException(rb_eTypeError,
+ "value for 'heartbeat' argument must be Unset or an enumerator of Ice.ACMHeartbeat");
+ }
+ volatile VALUE heartbeatValue = callRuby(rb_funcall, h, rb_intern("to_i"), 0);
+ assert(TYPE(heartbeatValue) == T_FIXNUM);
+ heartbeat = static_cast<Ice::ACMHeartbeat>(FIX2LONG(heartbeatValue));
+ }
+
+ (*p)->setACM(timeout, close, heartbeat);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_getACM(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ Ice::ACM acm = (*p)->getACM();
+ volatile VALUE type = callRuby(rb_path2class, "Ice::ACM");
+ assert(type != Qnil);
+ volatile VALUE r = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), type);
+ assert(r != Qnil);
+
+ callRuby(rb_ivar_set, r, rb_intern("@timeout"), LONG2FIX(acm.timeout));
+
+ type = callRuby(rb_path2class, "Ice::ACMClose");
+ assert(type != Qnil);
+ volatile VALUE c = callRuby(rb_funcall, type, rb_intern("from_int"), 1, LONG2NUM(static_cast<int>(acm.close)));
+ callRuby(rb_ivar_set, r, rb_intern("@close"), c);
+
+ type = callRuby(rb_path2class, "Ice::ACMHeartbeat");
+ assert(type != Qnil);
+ volatile VALUE h =
+ callRuby(rb_funcall, type, rb_intern("from_int"), 1, LONG2NUM(static_cast<int>(acm.heartbeat)));
+ callRuby(rb_ivar_set, r, rb_intern("@heartbeat"), h);
+
+ return r;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_type(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string s = (*p)->type();
+ return createString(s);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_timeout(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ Ice::Int timeout = (*p)->timeout();
+ return INT2FIX(timeout);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_getInfo(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ Ice::ConnectionInfoPtr info = (*p)->getInfo();
+ return createConnectionInfo(info);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_getEndpoint(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ Ice::EndpointPtr endpoint = (*p)->getEndpoint();
+ return createEndpoint(endpoint);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+extern "C"
+VALUE
+IceRuby_Connection_setBufferSize(VALUE self, VALUE r, VALUE s)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ int rcvSize = static_cast<int>(getInteger(r));
+ int sndSize = static_cast<int>(getInteger(s));
+
+ (*p)->setBufferSize(rcvSize, sndSize);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_toString(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ConnectionPtr* p = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string s = (*p)->toString();
+ return createString(s);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Connection_equals(VALUE self, VALUE other)
+{
+ ICE_RUBY_TRY
+ {
+ if(NIL_P(other))
+ {
+ return Qfalse;
+ }
+ if(callRuby(rb_obj_is_kind_of, other, _connectionClass) != Qtrue)
+ {
+ throw RubyException(rb_eTypeError, "argument must be a connection");
+ }
+ Ice::ConnectionPtr* p1 = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(self));
+ Ice::ConnectionPtr* p2 = reinterpret_cast<Ice::ConnectionPtr*>(DATA_PTR(other));
+ return *p1 == *p2 ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+// **********************************************************************
+// ConnectionInfo
+// **********************************************************************
+
+extern "C"
+void
+IceRuby_ConnectionInfo_free(Ice::ConnectionInfoPtr* p)
+{
+ assert(p);
+ delete p;
+}
+
+VALUE
+IceRuby::createConnectionInfo(const Ice::ConnectionInfoPtr& p)
+{
+ VALUE info;
+ if(Ice::TCPConnectionInfoPtr::dynamicCast(p))
+ {
+ info = Data_Wrap_Struct(_tcpConnectionInfoClass, 0, IceRuby_ConnectionInfo_free, new Ice::ConnectionInfoPtr(p));
+
+ Ice::TCPConnectionInfoPtr tcp = Ice::TCPConnectionInfoPtr::dynamicCast(p);
+ rb_ivar_set(info, rb_intern("@localAddress"), createString(tcp->localAddress));
+ rb_ivar_set(info, rb_intern("@localPort"), INT2FIX(tcp->localPort));
+ rb_ivar_set(info, rb_intern("@remoteAddress"), createString(tcp->remoteAddress));
+ rb_ivar_set(info, rb_intern("@remotePort"), INT2FIX(tcp->remotePort));
+ }
+ else if(Ice::UDPConnectionInfoPtr::dynamicCast(p))
+ {
+ info = Data_Wrap_Struct(_udpConnectionInfoClass, 0, IceRuby_ConnectionInfo_free, new Ice::ConnectionInfoPtr(p));
+
+ Ice::UDPConnectionInfoPtr udp = Ice::UDPConnectionInfoPtr::dynamicCast(p);
+ rb_ivar_set(info, rb_intern("@localAddress"), createString(udp->localAddress));
+ rb_ivar_set(info, rb_intern("@localPort"), INT2FIX(udp->localPort));
+ rb_ivar_set(info, rb_intern("@remoteAddress"), createString(udp->remoteAddress));
+ rb_ivar_set(info, rb_intern("@remotePort"), INT2FIX(udp->remotePort));
+ rb_ivar_set(info, rb_intern("@mcastAddress"), createString(udp->mcastAddress));
+ rb_ivar_set(info, rb_intern("@mcastPort"), INT2FIX(udp->mcastPort));
+ }
+ else if(Ice::WSConnectionInfoPtr::dynamicCast(p))
+ {
+ info = Data_Wrap_Struct(_wsConnectionInfoClass, 0, IceRuby_ConnectionInfo_free, new Ice::ConnectionInfoPtr(p));
+
+ Ice::WSConnectionInfoPtr ws = Ice::WSConnectionInfoPtr::dynamicCast(p);
+ rb_ivar_set(info, rb_intern("@localAddress"), createString(ws->localAddress));
+ rb_ivar_set(info, rb_intern("@localPort"), INT2FIX(ws->localPort));
+ rb_ivar_set(info, rb_intern("@remoteAddress"), createString(ws->remoteAddress));
+ rb_ivar_set(info, rb_intern("@remotePort"), INT2FIX(ws->remotePort));
+
+ volatile VALUE result = callRuby(rb_hash_new);
+ for(Ice::HeaderDict::const_iterator q = ws->headers.begin(); q != ws->headers.end(); ++q)
+ {
+ volatile VALUE key = createString(q->first);
+ volatile VALUE value = createString(q->second);
+ callRuby(rb_hash_aset, result, key, value);
+ }
+ rb_ivar_set(info, rb_intern("@headers"), result);
+ }
+ else if(Ice::IPConnectionInfoPtr::dynamicCast(p))
+ {
+ info = Data_Wrap_Struct(_ipConnectionInfoClass, 0, IceRuby_ConnectionInfo_free, new Ice::ConnectionInfoPtr(p));
+
+ Ice::IPConnectionInfoPtr ip = Ice::IPConnectionInfoPtr::dynamicCast(p);
+ rb_ivar_set(info, rb_intern("@localAddress"), createString(ip->localAddress));
+ rb_ivar_set(info, rb_intern("@localPort"), INT2FIX(ip->localPort));
+ rb_ivar_set(info, rb_intern("@remoteAddress"), createString(ip->remoteAddress));
+ rb_ivar_set(info, rb_intern("@remotePort"), INT2FIX(ip->remotePort));
+ }
+ else
+ {
+ info = Data_Wrap_Struct(_connectionInfoClass, 0, IceRuby_ConnectionInfo_free, new Ice::ConnectionInfoPtr(p));
+ }
+ rb_ivar_set(info, rb_intern("@incoming"), p->incoming ? Qtrue : Qfalse);
+ rb_ivar_set(info, rb_intern("@adapterName"), createString(p->adapterName));
+ rb_ivar_set(info, rb_intern("@rcvSize"), INT2FIX(p->rcvSize));
+ rb_ivar_set(info, rb_intern("@sndSize"), INT2FIX(p->sndSize));
+ return info;
+}
+
+void
+IceRuby::initConnection(VALUE iceModule)
+{
+ //
+ // Connection.
+ //
+ _connectionClass = rb_define_class_under(iceModule, "ConnectionI", rb_cObject);
+
+ //
+ // Instance methods.
+ //
+ rb_define_method(_connectionClass, "close", CAST_METHOD(IceRuby_Connection_close), 1);
+ rb_define_method(_connectionClass, "flushBatchRequests", CAST_METHOD(IceRuby_Connection_flushBatchRequests), 0);
+ rb_define_method(_connectionClass, "setACM", CAST_METHOD(IceRuby_Connection_setACM), 3);
+ rb_define_method(_connectionClass, "getACM", CAST_METHOD(IceRuby_Connection_getACM), 0);
+ rb_define_method(_connectionClass, "type", CAST_METHOD(IceRuby_Connection_type), 0);
+ rb_define_method(_connectionClass, "timeout", CAST_METHOD(IceRuby_Connection_timeout), 0);
+ rb_define_method(_connectionClass, "getInfo", CAST_METHOD(IceRuby_Connection_getInfo), 0);
+ rb_define_method(_connectionClass, "getEndpoint", CAST_METHOD(IceRuby_Connection_getEndpoint), 0);
+ rb_define_method(_connectionClass, "setBufferSize", CAST_METHOD(IceRuby_Connection_setBufferSize), 2);
+ rb_define_method(_connectionClass, "toString", CAST_METHOD(IceRuby_Connection_toString), 0);
+ rb_define_method(_connectionClass, "to_s", CAST_METHOD(IceRuby_Connection_toString), 0);
+ rb_define_method(_connectionClass, "inspect", CAST_METHOD(IceRuby_Connection_toString), 0);
+ rb_define_method(_connectionClass, "==", CAST_METHOD(IceRuby_Connection_equals), 1);
+ rb_define_method(_connectionClass, "eql?", CAST_METHOD(IceRuby_Connection_equals), 1);
+
+ //
+ // ConnectionInfo.
+ //
+ _connectionInfoClass = rb_define_class_under(iceModule, "ConnectionInfo", rb_cObject);
+
+ //
+ // Instance members.
+ //
+ rb_define_attr(_connectionInfoClass, "incoming", 1, 0);
+ rb_define_attr(_connectionInfoClass, "adapterName", 1, 0);
+ rb_define_attr(_connectionInfoClass, "rcvSize", 1, 0);
+ rb_define_attr(_connectionInfoClass, "sndSize", 1, 0);
+
+ //
+ // IPConnectionInfo
+ //
+ _ipConnectionInfoClass = rb_define_class_under(iceModule, "IPConnectionInfo", _connectionInfoClass);
+
+ //
+ // Instance members.
+ //
+ rb_define_attr(_ipConnectionInfoClass, "localAddress", 1, 0);
+ rb_define_attr(_ipConnectionInfoClass, "localPort", 1, 0);
+ rb_define_attr(_ipConnectionInfoClass, "remoteAddress", 1, 0);
+ rb_define_attr(_ipConnectionInfoClass, "remotePort", 1, 0);
+
+ //
+ // TCPConnectionInfo
+ //
+ _tcpConnectionInfoClass = rb_define_class_under(iceModule, "TCPConnectionInfo", _ipConnectionInfoClass);
+
+ //
+ // UDPConnectionInfo
+ //
+ _udpConnectionInfoClass = rb_define_class_under(iceModule, "UDPConnectionInfo", _ipConnectionInfoClass);
+
+ //
+ // Instance members.
+ //
+ rb_define_attr(_udpConnectionInfoClass, "mcastAddress", 1, 0);
+ rb_define_attr(_udpConnectionInfoClass, "mcastPort", 1, 0);
+
+ //
+ // WSConnectionInfo
+ //
+ _wsConnectionInfoClass = rb_define_class_under(iceModule, "WSConnectionInfo", _ipConnectionInfoClass);
+
+ //
+ // Instance members.
+ //
+ //rb_define_attr(_wsConnectionInfoClass, "headers", 1, 0);
+}
diff --git a/ruby/src/IceRuby/Connection.h b/ruby/src/IceRuby/Connection.h
new file mode 100644
index 00000000000..ec9ef7a8649
--- /dev/null
+++ b/ruby/src/IceRuby/Connection.h
@@ -0,0 +1,26 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_CONNECTION_H
+#define ICE_RUBY_CONNECTION_H
+
+#include <Config.h>
+#include <Ice/Connection.h>
+
+namespace IceRuby
+{
+
+void initConnection(VALUE);
+
+VALUE createConnection(const Ice::ConnectionPtr&);
+VALUE createConnectionInfo(const Ice::ConnectionInfoPtr&);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Endpoint.cpp b/ruby/src/IceRuby/Endpoint.cpp
new file mode 100644
index 00000000000..746f87c7ba0
--- /dev/null
+++ b/ruby/src/IceRuby/Endpoint.cpp
@@ -0,0 +1,332 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Endpoint.h>
+#include <Util.h>
+#include <Ice/Object.h>
+
+using namespace std;
+using namespace IceRuby;
+
+static VALUE _endpointClass;
+
+static VALUE _endpointInfoClass;
+static VALUE _ipEndpointInfoClass;
+static VALUE _tcpEndpointInfoClass;
+static VALUE _udpEndpointInfoClass;
+static VALUE _wsEndpointInfoClass;
+static VALUE _opaqueEndpointInfoClass;
+
+// **********************************************************************
+// Endpoint
+// **********************************************************************
+
+extern "C"
+void
+IceRuby_Endpoint_free(Ice::EndpointPtr* p)
+{
+ assert(p);
+ delete p;
+}
+
+VALUE
+IceRuby::createEndpoint(const Ice::EndpointPtr& p)
+{
+ return Data_Wrap_Struct(_endpointClass, 0, IceRuby_Endpoint_free, new Ice::EndpointPtr(p));
+}
+
+extern "C"
+VALUE
+IceRuby_Endpoint_toString(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::EndpointPtr* p = reinterpret_cast<Ice::EndpointPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string s = (*p)->toString();
+ return createString(s);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Endpoint_getInfo(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::EndpointPtr* p = reinterpret_cast<Ice::EndpointPtr*>(DATA_PTR(self));
+ assert(p);
+
+ Ice::EndpointInfoPtr info = (*p)->getInfo();
+ return createEndpointInfo(info);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Endpoint_cmp(VALUE self, VALUE other)
+{
+ ICE_RUBY_TRY
+ {
+ if(NIL_P(other))
+ {
+ return INT2NUM(1);
+ }
+ if(!checkEndpoint(other))
+ {
+ throw RubyException(rb_eTypeError, "argument must be a endpoint");
+ }
+ Ice::EndpointPtr p1 = Ice::EndpointPtr(*reinterpret_cast<Ice::EndpointPtr*>(DATA_PTR(self)));
+ Ice::EndpointPtr p2 = Ice::EndpointPtr(*reinterpret_cast<Ice::EndpointPtr*>(DATA_PTR(other)));
+ if(p1 < p2)
+ {
+ return INT2NUM(-1);
+ }
+ else if(p1 == p2)
+ {
+ return INT2NUM(0);
+ }
+ else
+ {
+ return INT2NUM(1);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Endpoint_equals(VALUE self, VALUE other)
+{
+ return IceRuby_Endpoint_cmp(self, other) == INT2NUM(0) ? Qtrue : Qfalse;
+}
+
+
+// **********************************************************************
+// EndpointInfo
+// **********************************************************************
+
+extern "C"
+void
+IceRuby_EndpointInfo_free(Ice::EndpointPtr* p)
+{
+ assert(p);
+ delete p;
+}
+
+VALUE
+IceRuby::createEndpointInfo(const Ice::EndpointInfoPtr& p)
+{
+ VALUE info;
+ if(Ice::TCPEndpointInfoPtr::dynamicCast(p))
+ {
+ info = Data_Wrap_Struct(_tcpEndpointInfoClass, 0, IceRuby_EndpointInfo_free, new Ice::EndpointInfoPtr(p));
+
+ Ice::TCPEndpointInfoPtr tcp = Ice::TCPEndpointInfoPtr::dynamicCast(p);
+ rb_ivar_set(info, rb_intern("@host"), createString(tcp->host));
+ rb_ivar_set(info, rb_intern("@port"), INT2FIX(tcp->port));
+ rb_ivar_set(info, rb_intern("@sourceAddress"), createString(tcp->sourceAddress));
+ }
+ else if(Ice::UDPEndpointInfoPtr::dynamicCast(p))
+ {
+ info = Data_Wrap_Struct(_udpEndpointInfoClass, 0, IceRuby_EndpointInfo_free, new Ice::EndpointInfoPtr(p));
+
+ Ice::UDPEndpointInfoPtr udp = Ice::UDPEndpointInfoPtr::dynamicCast(p);
+ rb_ivar_set(info, rb_intern("@host"), createString(udp->host));
+ rb_ivar_set(info, rb_intern("@port"), INT2FIX(udp->port));
+ rb_ivar_set(info, rb_intern("@sourceAddress"), createString(udp->sourceAddress));
+ rb_ivar_set(info, rb_intern("@mcastInterface"), createString(udp->mcastInterface));
+ rb_ivar_set(info, rb_intern("@mcastTtl"), INT2FIX(udp->mcastTtl));
+ }
+ else if(Ice::WSEndpointInfoPtr::dynamicCast(p))
+ {
+ info = Data_Wrap_Struct(_wsEndpointInfoClass, 0, IceRuby_EndpointInfo_free, new Ice::EndpointInfoPtr(p));
+
+ Ice::WSEndpointInfoPtr ws = Ice::WSEndpointInfoPtr::dynamicCast(p);
+ rb_ivar_set(info, rb_intern("@host"), createString(ws->host));
+ rb_ivar_set(info, rb_intern("@port"), INT2FIX(ws->port));
+ rb_ivar_set(info, rb_intern("@sourceAddress"), createString(ws->sourceAddress));
+ rb_ivar_set(info, rb_intern("@resource"), createString(ws->resource));
+ }
+ else if(Ice::OpaqueEndpointInfoPtr::dynamicCast(p))
+ {
+ info = Data_Wrap_Struct(_opaqueEndpointInfoClass, 0, IceRuby_EndpointInfo_free, new Ice::EndpointInfoPtr(p));
+
+ Ice::OpaqueEndpointInfoPtr opaque = Ice::OpaqueEndpointInfoPtr::dynamicCast(p);
+ Ice::ByteSeq b = opaque->rawBytes;
+ volatile VALUE v = callRuby(rb_str_new, reinterpret_cast<const char*>(&b[0]), static_cast<long>(b.size()));
+ rb_ivar_set(info, rb_intern("@rawBytes"), v);
+ rb_ivar_set(info, rb_intern("@rawEncoding"), createEncodingVersion(opaque->rawEncoding));
+ }
+ else if(Ice::IPEndpointInfoPtr::dynamicCast(p))
+ {
+ info = Data_Wrap_Struct(_ipEndpointInfoClass, 0, IceRuby_EndpointInfo_free, new Ice::EndpointInfoPtr(p));
+
+ Ice::IPEndpointInfoPtr ip = Ice::IPEndpointInfoPtr::dynamicCast(p);
+ rb_ivar_set(info, rb_intern("@host"), createString(ip->host));
+ rb_ivar_set(info, rb_intern("@port"), INT2FIX(ip->port));
+ rb_ivar_set(info, rb_intern("@sourceAddress"), createString(ip->sourceAddress));
+ }
+ else
+ {
+ info = Data_Wrap_Struct(_endpointInfoClass, 0, IceRuby_EndpointInfo_free, new Ice::EndpointInfoPtr(p));
+ }
+ rb_ivar_set(info, rb_intern("@timeout"), INT2FIX(p->timeout));
+ rb_ivar_set(info, rb_intern("@compress"), p->compress ? Qtrue : Qfalse);
+ return info;
+}
+
+extern "C"
+VALUE
+IceRuby_EndpointInfo_type(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::EndpointInfoPtr* p = reinterpret_cast<Ice::EndpointInfoPtr*>(DATA_PTR(self));
+ assert(p);
+
+ Ice::Short type = (*p)->type();
+ return INT2FIX(type);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_EndpointInfo_datagram(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::EndpointInfoPtr* p = reinterpret_cast<Ice::EndpointInfoPtr*>(DATA_PTR(self));
+ assert(p);
+
+ bool result = (*p)->datagram();
+ return result ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_EndpointInfo_secure(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::EndpointInfoPtr* p = reinterpret_cast<Ice::EndpointInfoPtr*>(DATA_PTR(self));
+ assert(p);
+
+ bool result = (*p)->secure();
+ return result ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+void
+IceRuby::initEndpoint(VALUE iceModule)
+{
+ //
+ // Endpoint.
+ //
+ _endpointClass = rb_define_class_under(iceModule, "Endpoint", rb_cObject);
+
+ //
+ // Instance methods.
+ //
+ rb_define_method(_endpointClass, "toString", CAST_METHOD(IceRuby_Endpoint_toString), 0);
+ rb_define_method(_endpointClass, "getInfo", CAST_METHOD(IceRuby_Endpoint_getInfo), 0);
+ rb_define_method(_endpointClass, "to_s", CAST_METHOD(IceRuby_Endpoint_toString), 0);
+ rb_define_method(_endpointClass, "inspect", CAST_METHOD(IceRuby_Endpoint_toString), 0);
+ rb_define_method(_endpointClass, "<=>", CAST_METHOD(IceRuby_Endpoint_cmp), 1);
+ rb_define_method(_endpointClass, "==", CAST_METHOD(IceRuby_Endpoint_equals), 1);
+ rb_define_method(_endpointClass, "eql?", CAST_METHOD(IceRuby_Endpoint_equals), 1);
+
+ //
+ // EndpointInfo.
+ //
+ _endpointInfoClass = rb_define_class_under(iceModule, "EndpointInfo", rb_cObject);
+
+ //
+ // Instance methods.
+ //
+ rb_define_method(_endpointInfoClass, "type", CAST_METHOD(IceRuby_EndpointInfo_type), 0);
+ rb_define_method(_endpointInfoClass, "datagram", CAST_METHOD(IceRuby_EndpointInfo_datagram), 0);
+ rb_define_method(_endpointInfoClass, "secure", CAST_METHOD(IceRuby_EndpointInfo_secure), 0);
+
+ //
+ // Instance members.
+ //
+ rb_define_attr(_endpointInfoClass, "protocol", 1, 0);
+ rb_define_attr(_endpointInfoClass, "encoding", 1, 0);
+ rb_define_attr(_endpointInfoClass, "timeout", 1, 0);
+ rb_define_attr(_endpointInfoClass, "compress", 1, 0);
+
+ //
+ // IPEndpointInfo
+ //
+ _ipEndpointInfoClass = rb_define_class_under(iceModule, "IPEndpointInfo", _endpointInfoClass);
+
+ //
+ // Instance members.
+ //
+ rb_define_attr(_ipEndpointInfoClass, "host", 1, 0);
+ rb_define_attr(_ipEndpointInfoClass, "port", 1, 0);
+ rb_define_attr(_ipEndpointInfoClass, "sourceAddress", 1, 0);
+
+ //
+ // TCPEndpointInfo
+ //
+ _tcpEndpointInfoClass = rb_define_class_under(iceModule, "TCPEndpointInfo", _ipEndpointInfoClass);
+
+ //
+ // UDPEndpointInfo
+ //
+ _udpEndpointInfoClass = rb_define_class_under(iceModule, "UDPEndpointInfo", _ipEndpointInfoClass);
+
+ //
+ // Instance members.
+ //
+ rb_define_attr(_udpEndpointInfoClass, "mcastInterface", 1, 0);
+ rb_define_attr(_udpEndpointInfoClass, "mcastTtl", 1, 0);
+
+ //
+ // WSEndpointInfo
+ //
+ _wsEndpointInfoClass = rb_define_class_under(iceModule, "WSEndpointInfo", _ipEndpointInfoClass);
+
+ //
+ // Instance members.
+ //
+ rb_define_attr(_wsEndpointInfoClass, "resource", 1, 0);
+
+ //
+ // OpaqueEndpointInfo
+ //
+ _opaqueEndpointInfoClass = rb_define_class_under(iceModule, "OpaqueEndpointInfo", _endpointInfoClass);
+
+ //
+ // Instance members.
+ //
+ rb_define_attr(_opaqueEndpointInfoClass, "rawBytes", 1, 0);
+ rb_define_attr(_opaqueEndpointInfoClass, "rawEncoding", 1, 0);
+}
+
+bool
+IceRuby::checkEndpoint(VALUE v)
+{
+ return callRuby(rb_obj_is_kind_of, v, _endpointClass) == Qtrue;
+}
diff --git a/ruby/src/IceRuby/Endpoint.h b/ruby/src/IceRuby/Endpoint.h
new file mode 100644
index 00000000000..d316487f147
--- /dev/null
+++ b/ruby/src/IceRuby/Endpoint.h
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_ENDPOINT_H
+#define ICE_RUBY_ENDPOINT_H
+
+#include <Config.h>
+#include <Ice/Connection.h>
+
+namespace IceRuby
+{
+
+void initEndpoint(VALUE);
+
+VALUE createEndpoint(const Ice::EndpointPtr&);
+VALUE createEndpointInfo(const Ice::EndpointInfoPtr&);
+bool checkEndpoint(VALUE);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/ImplicitContext.cpp b/ruby/src/IceRuby/ImplicitContext.cpp
new file mode 100644
index 00000000000..a69cbe3a373
--- /dev/null
+++ b/ruby/src/IceRuby/ImplicitContext.cpp
@@ -0,0 +1,152 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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 <ImplicitContext.h>
+#include <Util.h>
+#include <Ice/Initialize.h>
+#include <Ice/ImplicitContext.h>
+
+using namespace std;
+using namespace IceRuby;
+
+static VALUE _implicitContextClass;
+
+extern "C"
+void
+IceRuby_ImplicitContext_free(Ice::ImplicitContextPtr* p)
+{
+ assert(p);
+ delete p;
+}
+
+
+extern "C"
+VALUE
+IceRuby_ImplicitContext_getContext(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ImplicitContextPtr p = getImplicitContext(self);
+ return contextToHash(p->getContext());
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ImplicitContext_setContext(VALUE self, VALUE context)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::Context ctx;
+ if(!hashToContext(context, ctx))
+ {
+ throw RubyException(rb_eTypeError, "argument must be a hash");
+ }
+ Ice::ImplicitContextPtr p = getImplicitContext(self);
+ p->setContext(ctx);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ImplicitContext_containsKey(VALUE self, VALUE key)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ImplicitContextPtr p = getImplicitContext(self);
+ string k = getString(key);
+ if(p->containsKey(k))
+ {
+ return Qtrue;
+ }
+ else
+ {
+ return Qfalse;
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+
+extern "C"
+VALUE
+IceRuby_ImplicitContext_get(VALUE self, VALUE key)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ImplicitContextPtr p = getImplicitContext(self);
+ string k = getString(key);
+ string v = p->get(k);
+ return createString(v);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+
+extern "C"
+VALUE
+IceRuby_ImplicitContext_put(VALUE self, VALUE key, VALUE value)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ImplicitContextPtr p = getImplicitContext(self);
+ string k = getString(key);
+ string v = getString(value);
+ return createString(p->put(k, v));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ImplicitContext_remove(VALUE self, VALUE key)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ImplicitContextPtr p = getImplicitContext(self);
+ string k = getString(key);
+ return createString(p->remove(k));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+
+void
+IceRuby::initImplicitContext(VALUE iceModule)
+{
+ _implicitContextClass = rb_define_class_under(iceModule, "ImplicitContextI", rb_cObject);
+ rb_define_method(_implicitContextClass, "getContext", CAST_METHOD(IceRuby_ImplicitContext_getContext), 0);
+ rb_define_method(_implicitContextClass, "setContext", CAST_METHOD(IceRuby_ImplicitContext_setContext), 1);
+ rb_define_method(_implicitContextClass, "containsKey", CAST_METHOD(IceRuby_ImplicitContext_containsKey), 1);
+ rb_define_method(_implicitContextClass, "get", CAST_METHOD(IceRuby_ImplicitContext_get), 1);
+ rb_define_method(_implicitContextClass, "put", CAST_METHOD(IceRuby_ImplicitContext_put), 2);
+ rb_define_method(_implicitContextClass, "remove", CAST_METHOD(IceRuby_ImplicitContext_remove), 1);
+}
+
+Ice::ImplicitContextPtr
+IceRuby::getImplicitContext(VALUE v)
+{
+ Ice::ImplicitContextPtr* p = reinterpret_cast<Ice::ImplicitContextPtr*>(DATA_PTR(v));
+ assert(p);
+ return *p;
+}
+
+VALUE
+IceRuby::createImplicitContext(const Ice::ImplicitContextPtr& p)
+{
+ return Data_Wrap_Struct(_implicitContextClass, 0, IceRuby_ImplicitContext_free, new Ice::ImplicitContextPtr(p));
+}
diff --git a/ruby/src/IceRuby/ImplicitContext.h b/ruby/src/IceRuby/ImplicitContext.h
new file mode 100644
index 00000000000..76aa3568fb7
--- /dev/null
+++ b/ruby/src/IceRuby/ImplicitContext.h
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_IMPLICIT_CONTEXT_H
+#define ICE_RUBY_IMPLICIT_CONTEXT_H
+
+#include <Config.h>
+#include <Ice/ImplicitContext.h>
+
+namespace IceRuby
+{
+
+void initImplicitContext(VALUE);
+Ice::ImplicitContextPtr getImplicitContext(VALUE);
+VALUE createImplicitContext(const Ice::ImplicitContextPtr&);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Init.cpp b/ruby/src/IceRuby/Init.cpp
new file mode 100644
index 00000000000..2086f163383
--- /dev/null
+++ b/ruby/src/IceRuby/Init.cpp
@@ -0,0 +1,59 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Communicator.h>
+#include <ImplicitContext.h>
+#include <Logger.h>
+#include <Operation.h>
+#include <Properties.h>
+#include <Proxy.h>
+#include <Slice.h>
+#include <Types.h>
+#include <Connection.h>
+#include <Endpoint.h>
+
+using namespace std;
+using namespace IceRuby;
+
+static VALUE iceModule;
+
+extern "C"
+{
+
+#ifdef ICE_STATIC_LIBS
+Ice::Plugin* createIceSSL(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&);
+Ice::Plugin* createIceDiscovery(const Ice::CommunicatorPtr&, const string&, const Ice::StringSeq&);
+Ice::Plugin* createIceLocatorDiscovery(const Ice::CommunicatorPtr&, const string&, const Ice::StringSeq&);
+#endif
+
+void
+ICE_DECLSPEC_EXPORT Init_IceRuby()
+{
+#ifdef ICE_STATIC_LIBS
+ // Register the plugins manually if we're building with static libraries.
+ Ice::registerPluginFactory("IceSSL", createIceSSL, false);
+ Ice::registerPluginFactory("IceDiscovery", createIceDiscovery, false);
+ Ice::registerPluginFactory("IceLocatorDiscovery", createIceLocatorDiscovery, false);
+#endif
+
+ iceModule = rb_define_module("Ice");
+ initCommunicator(iceModule);
+ initLogger(iceModule);
+ initOperation(iceModule);
+ initProperties(iceModule);
+ initProxy(iceModule);
+ initSlice(iceModule);
+ initTypes(iceModule);
+ initImplicitContext(iceModule);
+ initUtil(iceModule);
+ initConnection(iceModule);
+ initEndpoint(iceModule);
+}
+
+}
diff --git a/ruby/src/IceRuby/Logger.cpp b/ruby/src/IceRuby/Logger.cpp
new file mode 100644
index 00000000000..6b70881e6e8
--- /dev/null
+++ b/ruby/src/IceRuby/Logger.cpp
@@ -0,0 +1,151 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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>
+#include <Ice/Initialize.h>
+
+using namespace std;
+using namespace IceRuby;
+
+static VALUE _loggerClass;
+
+extern "C"
+void
+IceRuby_Logger_free(Ice::LoggerPtr* p)
+{
+ assert(p);
+ delete p;
+}
+
+VALUE
+IceRuby::createLogger(const Ice::LoggerPtr& p)
+{
+ return Data_Wrap_Struct(_loggerClass, 0, IceRuby_Logger_free, new Ice::LoggerPtr(p));
+}
+
+extern "C"
+VALUE
+IceRuby_Logger_print(VALUE self, VALUE message)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::LoggerPtr* p = reinterpret_cast<Ice::LoggerPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string msg = getString(message);
+ (*p)->print(msg);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Logger_trace(VALUE self, VALUE category, VALUE message)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::LoggerPtr* p = reinterpret_cast<Ice::LoggerPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string cat = getString(category);
+ string msg = getString(message);
+ (*p)->trace(cat, msg);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Logger_warning(VALUE self, VALUE message)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::LoggerPtr* p = reinterpret_cast<Ice::LoggerPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string msg = getString(message);
+ (*p)->warning(msg);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Logger_error(VALUE self, VALUE message)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::LoggerPtr* p = reinterpret_cast<Ice::LoggerPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string msg = getString(message);
+ (*p)->error(msg);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Logger_cloneWithPrefix(VALUE self, VALUE prefix)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::LoggerPtr* p = reinterpret_cast<Ice::LoggerPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string pfx = getString(prefix);
+ Ice::LoggerPtr clone = (*p)->cloneWithPrefix(pfx);
+ return createLogger(clone);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_getProcessLogger()
+{
+ ICE_RUBY_TRY
+ {
+ Ice::LoggerPtr logger = Ice::getProcessLogger();
+ return createLogger(logger);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+bool
+IceRuby::initLogger(VALUE iceModule)
+{
+ //
+ // Logger.
+ //
+ _loggerClass = rb_define_class_under(iceModule, "LoggerI", rb_cObject);
+
+ //
+ // Instance methods.
+ //
+ rb_define_method(_loggerClass, "print", CAST_METHOD(IceRuby_Logger_print), 1);
+ rb_define_method(_loggerClass, "trace", CAST_METHOD(IceRuby_Logger_trace), 2);
+ rb_define_method(_loggerClass, "warning", CAST_METHOD(IceRuby_Logger_warning), 1);
+ rb_define_method(_loggerClass, "error", CAST_METHOD(IceRuby_Logger_error), 1);
+ rb_define_method(_loggerClass, "cloneWithPrefix", CAST_METHOD(IceRuby_Logger_cloneWithPrefix), 1);
+
+ //
+ // Global methods.
+ //
+ rb_define_module_function(iceModule, "getProcessLogger", CAST_METHOD(IceRuby_getProcessLogger), 0);
+
+ return true;
+}
diff --git a/ruby/src/IceRuby/Logger.h b/ruby/src/IceRuby/Logger.h
new file mode 100644
index 00000000000..9234928fa9e
--- /dev/null
+++ b/ruby/src/IceRuby/Logger.h
@@ -0,0 +1,28 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_LOGGER_H
+#define ICE_RUBY_LOGGER_H
+
+#include <Config.h>
+#include <Ice/Logger.h>
+
+namespace IceRuby
+{
+
+bool initLogger(VALUE);
+
+//
+// Create an object that delegates to a C++ implementation.
+//
+VALUE createLogger(const Ice::LoggerPtr&);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Makefile b/ruby/src/IceRuby/Makefile
new file mode 100644
index 00000000000..a75e70b58aa
--- /dev/null
+++ b/ruby/src/IceRuby/Makefile
@@ -0,0 +1,50 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2015 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 = ../..
+
+LIBFILENAME = $(call mkrblibfilename,IceRuby,$(VERSION))
+SONAME = $(call mkrbsoname,IceRuby,$(SOVERSION))
+LIBNAME = $(call mkrblibname,IceRuby)
+TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME))
+
+OBJS = Communicator.o \
+ Connection.o \
+ Endpoint.o \
+ ImplicitContext.o \
+ Init.o \
+ Logger.o \
+ ObjectFactory.o \
+ Operation.o \
+ Properties.o \
+ Proxy.o \
+ Slice.o \
+ Types.o \
+ Util.o
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. $(CPPFLAGS) $(ICE_FLAGS) $(RUBY_FLAGS)
+LINKWITH := -L"$(libdir)" $(ICE_LIBS) $(RUBY_LIBS) $(CXXLIBS)
+
+$(libdir)/$(LIBFILENAME): $(OBJS)
+ rm -f $@
+ $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH))
+
+$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME)
+ rm -f $@
+ ln -s $(LIBFILENAME) $@
+
+$(libdir)/$(LIBNAME): $(libdir)/$(SONAME)
+ rm -f $@
+ ln -s $(SONAME) $@
+
+install:: all
+ $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME))
+
diff --git a/ruby/src/IceRuby/ObjectFactory.cpp b/ruby/src/IceRuby/ObjectFactory.cpp
new file mode 100644
index 00000000000..588158a64e3
--- /dev/null
+++ b/ruby/src/IceRuby/ObjectFactory.cpp
@@ -0,0 +1,140 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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 <ObjectFactory.h>
+#include <Types.h>
+#include <Util.h>
+#include <Ice/LocalException.h>
+
+using namespace std;
+using namespace IceRuby;
+
+IceRuby::ObjectFactory::ObjectFactory()
+{
+}
+
+IceRuby::ObjectFactory::~ObjectFactory()
+{
+ assert(_factoryMap.empty());
+}
+
+Ice::ObjectPtr
+IceRuby::ObjectFactory::create(const string& id)
+{
+ Lock sync(*this);
+
+ //
+ // Get the type information.
+ //
+ ClassInfoPtr info;
+ if(id == Ice::Object::ice_staticId())
+ {
+ //
+ // When the ID is that of Ice::Object, it indicates that the stream has not
+ // found a factory and is providing us an opportunity to preserve the object.
+ //
+ info = lookupClassInfo("::Ice::UnknownSlicedObject");
+ }
+ else
+ {
+ info = lookupClassInfo(id);
+ }
+
+ if(!info)
+ {
+ return 0;
+ }
+
+ //
+ // Check if the application has registered a factory for this id.
+ //
+ FactoryMap::iterator p = _factoryMap.find(id);
+ if(p != _factoryMap.end())
+ {
+ //
+ // Invoke the create method on the Ruby factory object.
+ //
+ volatile VALUE str = createString(id);
+ volatile VALUE obj = callRuby(rb_funcall, p->second, rb_intern("create"), 1, str);
+ if(NIL_P(obj))
+ {
+ return 0;
+ }
+ return new ObjectReader(obj, info);
+ }
+
+ //
+ // Instantiate the object.
+ //
+ volatile VALUE obj = callRuby(rb_class_new_instance, 0, reinterpret_cast<VALUE*>(0), info->rubyClass);
+ assert(!NIL_P(obj));
+ return new ObjectReader(obj, info);
+}
+
+void
+IceRuby::ObjectFactory::destroy()
+{
+ Lock sync(*this);
+
+ for(FactoryMap::iterator p = _factoryMap.begin(); p != _factoryMap.end(); ++p)
+ {
+ //
+ // Invoke the destroy method on each registered Ruby factory.
+ //
+ try
+ {
+ callRuby(rb_funcall, p->second, rb_intern("destroy"), 0);
+ }
+ catch(const RubyException&)
+ {
+ // Ignore.
+ }
+ }
+ _factoryMap.clear();
+}
+
+void
+IceRuby::ObjectFactory::add(VALUE factory, const string& id)
+{
+ Lock sync(*this);
+
+ FactoryMap::iterator p = _factoryMap.find(id);
+ if(p != _factoryMap.end())
+ {
+ Ice::AlreadyRegisteredException ex(__FILE__, __LINE__);
+ ex.kindOfObject = "object factory";
+ ex.id = id;
+ throw ex;
+ }
+
+ _factoryMap.insert(FactoryMap::value_type(id, factory));
+}
+
+VALUE
+IceRuby::ObjectFactory::find(const string& id)
+{
+ Lock sync(*this);
+
+ FactoryMap::iterator p = _factoryMap.find(id);
+ if(p == _factoryMap.end())
+ {
+ return Qnil;
+ }
+
+ return p->second;
+}
+
+void
+IceRuby::ObjectFactory::mark()
+{
+ for(FactoryMap::iterator p = _factoryMap.begin(); p != _factoryMap.end(); ++p)
+ {
+ rb_gc_mark(p->second);
+ }
+}
diff --git a/ruby/src/IceRuby/ObjectFactory.h b/ruby/src/IceRuby/ObjectFactory.h
new file mode 100644
index 00000000000..152f73f8425
--- /dev/null
+++ b/ruby/src/IceRuby/ObjectFactory.h
@@ -0,0 +1,50 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_OBJECT_FACTORY_H
+#define ICE_RUBY_OBJECT_FACTORY_H
+
+#include <Config.h>
+#include <Ice/ObjectF.h>
+#include <Ice/ObjectFactory.h>
+#include <IceUtil/Mutex.h>
+
+namespace IceRuby
+{
+
+//
+// Each communicator registers an instance of ObjectFactory as its
+// default object factory. This instance delegates to registered Ruby
+// objects, and instantiates concrete classes when no factory is present.
+//
+class ObjectFactory : public Ice::ObjectFactory, public IceUtil::Mutex
+{
+public:
+
+ ObjectFactory();
+ ~ObjectFactory();
+
+ virtual Ice::ObjectPtr create(const std::string&);
+
+ virtual void destroy();
+
+ void add(VALUE, const std::string&);
+ VALUE find(const std::string&);
+ void mark();
+
+private:
+
+ typedef std::map<std::string, VALUE> FactoryMap;
+ FactoryMap _factoryMap;
+};
+typedef IceUtil::Handle<ObjectFactory> ObjectFactoryPtr;
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Operation.cpp b/ruby/src/IceRuby/Operation.cpp
new file mode 100644
index 00000000000..cbfa9581070
--- /dev/null
+++ b/ruby/src/IceRuby/Operation.cpp
@@ -0,0 +1,676 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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 <Proxy.h>
+#include <Types.h>
+#include <Util.h>
+#include <Ice/Communicator.h>
+#include <Ice/Initialize.h>
+#include <Ice/LocalException.h>
+#include <Ice/Logger.h>
+#include <Ice/Properties.h>
+#include <Ice/Proxy.h>
+#include <Slice/RubyUtil.h>
+
+using namespace std;
+using namespace IceRuby;
+using namespace Slice::Ruby;
+
+static VALUE _operationClass;
+
+namespace IceRuby
+{
+
+class ParamInfo : public UnmarshalCallback
+{
+public:
+
+ virtual void unmarshaled(VALUE, VALUE, void*);
+
+ TypeInfoPtr type;
+ bool optional;
+ int tag;
+ int pos;
+};
+typedef IceUtil::Handle<ParamInfo> ParamInfoPtr;
+typedef list<ParamInfoPtr> ParamInfoList;
+
+class OperationI : public Operation
+{
+public:
+
+ OperationI(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
+
+ virtual VALUE invoke(const Ice::ObjectPrx&, VALUE, VALUE);
+ virtual void deprecate(const string&);
+
+private:
+
+ string _name;
+ Ice::OperationMode _mode;
+ Ice::OperationMode _sendMode;
+ bool _amd;
+ Ice::FormatType _format;
+ ParamInfoList _inParams;
+ ParamInfoList _optionalInParams;
+ ParamInfoList _outParams;
+ ParamInfoList _optionalOutParams;
+ ParamInfoPtr _returnType;
+ ExceptionInfoList _exceptions;
+ string _dispatchName;
+ bool _sendsClasses;
+ bool _returnsClasses;
+ string _deprecateMessage;
+
+ void convertParams(VALUE, ParamInfoList&, int, bool&);
+ ParamInfoPtr convertParam(VALUE, int);
+ void prepareRequest(const Ice::ObjectPrx&, VALUE, Ice::OutputStreamPtr&, pair<const Ice::Byte*, const Ice::Byte*>&);
+ VALUE unmarshalResults(const vector<Ice::Byte>&, const Ice::CommunicatorPtr&);
+ VALUE unmarshalException(const vector<Ice::Byte>&, const Ice::CommunicatorPtr&);
+ bool validateException(VALUE) const;
+ void checkTwowayOnly(const Ice::ObjectPrx&) const;
+};
+typedef IceUtil::Handle<OperationI> OperationIPtr;
+
+class UserExceptionReaderFactoryI : public Ice::UserExceptionReaderFactory
+{
+public:
+
+ UserExceptionReaderFactoryI(const Ice::CommunicatorPtr& communicator) :
+ _communicator(communicator)
+ {
+ }
+
+ virtual void createAndThrow(const string& id) const
+ {
+ ExceptionInfoPtr info = lookupExceptionInfo(id);
+ if(info)
+ {
+ throw ExceptionReader(_communicator, info);
+ }
+ }
+
+private:
+
+ const Ice::CommunicatorPtr _communicator;
+};
+
+}
+
+extern "C"
+void
+IceRuby_Operation_free(OperationPtr* p)
+{
+ delete p;
+}
+
+extern "C"
+VALUE
+IceRuby_defineOperation(VALUE /*self*/, VALUE name, VALUE mode, VALUE sendMode, VALUE amd, VALUE format, VALUE inParams,
+ VALUE outParams, VALUE returnType, VALUE exceptions)
+{
+ ICE_RUBY_TRY
+ {
+ OperationIPtr op = new OperationI(name, mode, sendMode, amd, format, inParams, outParams, returnType,
+ exceptions);
+ return Data_Wrap_Struct(_operationClass, 0, IceRuby_Operation_free, new OperationPtr(op));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Operation_invoke(VALUE self, VALUE proxy, VALUE opArgs, VALUE ctx)
+{
+ ICE_RUBY_TRY
+ {
+ assert(TYPE(opArgs) == T_ARRAY);
+
+ OperationPtr op = getOperation(self);
+ assert(op);
+ return op->invoke(getProxy(proxy), opArgs, ctx);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Operation_deprecate(VALUE self, VALUE msg)
+{
+ ICE_RUBY_TRY
+ {
+ OperationPtr op = getOperation(self);
+ assert(op);
+ op->deprecate(getString(msg));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+//
+// Operation implementation.
+//
+IceRuby::Operation::~Operation()
+{
+}
+
+//
+// ParamInfo implementation.
+//
+void
+IceRuby::ParamInfo::unmarshaled(VALUE val, VALUE target, void* closure)
+{
+ assert(TYPE(target) == T_ARRAY);
+#ifdef ICE_64
+ long i = static_cast<long>(reinterpret_cast<long long>(closure));
+#else
+ long i = reinterpret_cast<long>(closure);
+#endif
+ RARRAY_PTR(target)[i] = val;
+}
+
+//
+// OperationI implementation.
+//
+IceRuby::OperationI::OperationI(VALUE name, VALUE mode, VALUE sendMode, VALUE amd, VALUE format, VALUE inParams,
+ VALUE outParams, VALUE returnType, VALUE exceptions)
+{
+ _name = getString(name);
+ _amd = amd == Qtrue;
+ if(_amd)
+ {
+ _dispatchName = fixIdent(_name, IdentNormal) + "_async";
+ }
+ else
+ {
+ _dispatchName = fixIdent(_name, IdentNormal);
+ }
+
+ //
+ // mode
+ //
+ volatile VALUE modeValue = callRuby(rb_funcall, mode, rb_intern("to_i"), 0);
+ assert(TYPE(modeValue) == T_FIXNUM);
+ _mode = static_cast<Ice::OperationMode>(FIX2LONG(modeValue));
+
+ //
+ // sendMode
+ //
+ volatile VALUE sendModeValue = callRuby(rb_funcall, sendMode, rb_intern("to_i"), 0);
+ assert(TYPE(sendModeValue) == T_FIXNUM);
+ _sendMode = static_cast<Ice::OperationMode>(FIX2LONG(sendModeValue));
+
+ //
+ // format
+ //
+ if(format == Qnil)
+ {
+ _format = Ice::DefaultFormat;
+ }
+ else
+ {
+ volatile VALUE formatValue = callRuby(rb_funcall, format, rb_intern("to_i"), 0);
+ assert(TYPE(formatValue) == T_FIXNUM);
+ _format = static_cast<Ice::FormatType>(FIX2LONG(formatValue));
+ }
+
+ //
+ // returnType
+ //
+ _returnsClasses = false;
+ if(!NIL_P(returnType))
+ {
+ _returnType = convertParam(returnType, 0);
+ if(!_returnType->optional)
+ {
+ _returnsClasses = _returnType->type->usesClasses();
+ }
+ }
+
+ //
+ // inParams
+ //
+ _sendsClasses = false;
+ convertParams(inParams, _inParams, 0, _sendsClasses);
+
+ //
+ // outParams
+ //
+ convertParams(outParams, _outParams, NIL_P(returnType) ? 0 : 1, _returnsClasses);
+
+ class SortFn
+ {
+ public:
+ static bool compare(const ParamInfoPtr& lhs, const ParamInfoPtr& rhs)
+ {
+ return lhs->tag < rhs->tag;
+ }
+
+ static bool isRequired(const ParamInfoPtr& i)
+ {
+ return !i->optional;
+ }
+ };
+
+ //
+ // The inParams list represents the parameters in the order of declaration.
+ // We also need a sorted list of optional parameters.
+ //
+ ParamInfoList l = _inParams;
+ copy(l.begin(), remove_if(l.begin(), l.end(), SortFn::isRequired), back_inserter(_optionalInParams));
+ _optionalInParams.sort(SortFn::compare);
+
+ //
+ // The outParams list represents the parameters in the order of declaration.
+ // We also need a sorted list of optional parameters. If the return value is
+ // optional, we must include it in this list.
+ //
+ l = _outParams;
+ copy(l.begin(), remove_if(l.begin(), l.end(), SortFn::isRequired), back_inserter(_optionalOutParams));
+ if(_returnType && _returnType->optional)
+ {
+ _optionalOutParams.push_back(_returnType);
+ }
+ _optionalOutParams.sort(SortFn::compare);
+
+ //
+ // exceptions
+ //
+ for(long i = 0; i < RARRAY_LEN(exceptions); ++i)
+ {
+ _exceptions.push_back(getException(RARRAY_PTR(exceptions)[i]));
+ }
+}
+
+VALUE
+IceRuby::OperationI::invoke(const Ice::ObjectPrx& proxy, VALUE args, VALUE hctx)
+{
+ Ice::CommunicatorPtr communicator = proxy->ice_getCommunicator();
+
+ //
+ // Marshal the input parameters to a byte sequence.
+ //
+ Ice::OutputStreamPtr os;
+ pair<const Ice::Byte*, const Ice::Byte*> params;
+ prepareRequest(proxy, args, os, params);
+
+ if(!_deprecateMessage.empty())
+ {
+ rb_warning("%s", _deprecateMessage.c_str());
+ _deprecateMessage.clear(); // Only show the warning once.
+ }
+
+ checkTwowayOnly(proxy);
+
+ //
+ // Invoke the operation.
+ //
+ Ice::ByteSeq result;
+ bool status;
+
+ if(!NIL_P(hctx))
+ {
+ Ice::Context ctx;
+ if(!hashToContext(hctx, ctx))
+ {
+ throw RubyException(rb_eArgError, "context argument must be nil or a hash");
+ }
+
+ status = proxy->ice_invoke(_name, _sendMode, params, result, ctx);
+ }
+ else
+ {
+ status = proxy->ice_invoke(_name, _sendMode, params, result);
+ }
+
+ //
+ // Process the reply.
+ //
+ if(proxy->ice_isTwoway())
+ {
+ if(!status)
+ {
+ //
+ // Unmarshal a user exception.
+ //
+ volatile VALUE ex = unmarshalException(result, communicator);
+ throw RubyException(ex);
+ }
+ else if(_outParams.size() > 0 || _returnType)
+ {
+ //
+ // Unmarshal the results. If there is more than one value to be returned, then return them
+ // in an array of the form [result, outParam1, ...]. Otherwise just return the value.
+ //
+ volatile VALUE results = unmarshalResults(result, communicator);
+
+ if(RARRAY_LEN(results)> 1)
+ {
+ return results;
+ }
+ else
+ {
+ return RARRAY_PTR(results)[0];
+ }
+ }
+ }
+
+ return Qnil;
+}
+
+void
+IceRuby::OperationI::deprecate(const string& msg)
+{
+ if(!msg.empty())
+ {
+ _deprecateMessage = msg;
+ }
+ else
+ {
+ _deprecateMessage = "operation " + _name + " is deprecated";
+ }
+}
+
+void
+IceRuby::OperationI::convertParams(VALUE v, ParamInfoList& params, int posOffset, bool& usesClasses)
+{
+ assert(TYPE(v) == T_ARRAY);
+
+ for(long i = 0; i < RARRAY_LEN(v); ++i)
+ {
+ ParamInfoPtr param = convertParam(RARRAY_PTR(v)[i], i + posOffset);
+ params.push_back(param);
+ if(!param->optional && !usesClasses)
+ {
+ usesClasses = param->type->usesClasses();
+ }
+ }
+}
+
+ParamInfoPtr
+IceRuby::OperationI::convertParam(VALUE v, int pos)
+{
+ assert(TYPE(v) == T_ARRAY);
+ ParamInfoPtr param = new ParamInfo;
+ param->type = getType(RARRAY_PTR(v)[0]);
+ param->optional = static_cast<bool>(RTEST(RARRAY_PTR(v)[1]));
+ param->tag = static_cast<int>(getInteger(RARRAY_PTR(v)[2]));
+ param->pos = pos;
+ return param;
+}
+
+void
+IceRuby::OperationI::prepareRequest(const Ice::ObjectPrx& proxy, VALUE args, Ice::OutputStreamPtr& os,
+ pair<const Ice::Byte*, const Ice::Byte*>& params)
+{
+ params.first = params.second = static_cast<const Ice::Byte*>(0);
+
+ //
+ // Validate the number of arguments.
+ //
+ long argc = RARRAY_LEN(args);
+ long paramCount = static_cast<long>(_inParams.size());
+ if(argc != paramCount)
+ {
+ string fixedName = fixIdent(_name, IdentNormal);
+ throw RubyException(rb_eArgError, "%s expects %ld in parameters", fixedName.c_str(), paramCount);
+ }
+
+ if(!_inParams.empty())
+ {
+ //
+ // Marshal the in parameters.
+ //
+ os = Ice::createOutputStream(proxy->ice_getCommunicator());
+ os->startEncapsulation(proxy->ice_getEncodingVersion(), _format);
+
+ ObjectMap objectMap;
+ ParamInfoList::iterator p;
+
+ //
+ // Validate the supplied arguments.
+ //
+ for(p = _inParams.begin(); p != _inParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ volatile VALUE arg = RARRAY_PTR(args)[info->pos];
+ if((!info->optional || arg != Unset) && !info->type->validate(arg))
+ {
+ string opName = fixIdent(_name, IdentNormal);
+ throw RubyException(rb_eTypeError, "invalid value for argument %ld in operation `%s'", info->pos + 1,
+ opName.c_str());
+ }
+ }
+
+ //
+ // Marshal the required parameters.
+ //
+ for(p = _inParams.begin(); p != _inParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ if(!info->optional)
+ {
+ volatile VALUE arg = RARRAY_PTR(args)[info->pos];
+ info->type->marshal(arg, os, &objectMap, false);
+ }
+ }
+
+ //
+ // Marshal the optional parameters.
+ //
+ for(p = _optionalInParams.begin(); p != _optionalInParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ volatile VALUE arg = RARRAY_PTR(args)[info->pos];
+ if(arg != Unset && os->writeOptional(info->tag, info->type->optionalFormat()))
+ {
+ info->type->marshal(arg, os, &objectMap, true);
+ }
+ }
+
+ if(_sendsClasses)
+ {
+ os->writePendingObjects();
+ }
+
+ os->endEncapsulation();
+ params = os->finished();
+ }
+}
+
+VALUE
+IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice::CommunicatorPtr& communicator)
+{
+ int numResults = static_cast<int>(_outParams.size());
+ if(_returnType)
+ {
+ numResults++;
+ }
+ assert(numResults > 0);
+
+ volatile VALUE results = createArray(numResults);
+
+ //
+ // Unmarshal the results. If there is more than one value to be returned, then return them
+ // in a tuple of the form (result, outParam1, ...). Otherwise just return the value.
+ //
+ Ice::InputStreamPtr is = Ice::wrapInputStream(communicator, bytes);
+
+ //
+ // Store a pointer to a local SlicedDataUtil object as the stream's closure.
+ // This is necessary to support object unmarshaling (see ObjectReader).
+ //
+ SlicedDataUtil util;
+ assert(!is->closure());
+ is->closure(&util);
+
+ is->startEncapsulation();
+
+ ParamInfoList::iterator p;
+
+ //
+ // Unmarshal the required out parameters.
+ //
+ for(p = _outParams.begin(); p != _outParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ if(!info->optional)
+ {
+ void* closure = reinterpret_cast<void*>(info->pos);
+ info->type->unmarshal(is, info, results, closure, false);
+ }
+ }
+
+ //
+ // Unmarshal the required return value, if any.
+ //
+ if(_returnType && !_returnType->optional)
+ {
+ assert(_returnType->pos == 0);
+ void* closure = reinterpret_cast<void*>(_returnType->pos);
+ _returnType->type->unmarshal(is, _returnType, results, closure, false);
+ }
+
+ //
+ // Unmarshal the optional results. This includes an optional return value.
+ //
+ for(p = _optionalOutParams.begin(); p != _optionalOutParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ if(is->readOptional(info->tag, info->type->optionalFormat()))
+ {
+ void* closure = reinterpret_cast<void*>(info->pos);
+ info->type->unmarshal(is, info, results, closure, true);
+ }
+ else
+ {
+ RARRAY_PTR(results)[info->pos] = Unset;
+ }
+ }
+
+ if(_returnsClasses)
+ {
+ is->readPendingObjects();
+ }
+
+ is->endEncapsulation();
+
+ util.update();
+
+ return results;
+}
+
+VALUE
+IceRuby::OperationI::unmarshalException(const vector<Ice::Byte>& bytes, const Ice::CommunicatorPtr& communicator)
+{
+ Ice::InputStreamPtr is = Ice::wrapInputStream(communicator, bytes);
+
+ //
+ // Store a pointer to a local SlicedDataUtil object as the stream's closure.
+ // This is necessary to support object unmarshaling (see ObjectReader).
+ //
+ SlicedDataUtil util;
+ assert(!is->closure());
+ is->closure(&util);
+
+ is->startEncapsulation();
+
+ try
+ {
+ Ice::UserExceptionReaderFactoryPtr factory = new UserExceptionReaderFactoryI(communicator);
+ is->throwException(factory);
+ }
+ catch(const ExceptionReader& r)
+ {
+ is->endEncapsulation();
+
+ volatile VALUE ex = r.getException();
+
+ if(validateException(ex))
+ {
+ util.update();
+
+ Ice::SlicedDataPtr slicedData = r.getSlicedData();
+ if(slicedData)
+ {
+ SlicedDataUtil::setMember(ex, slicedData);
+ }
+
+ return ex;
+ }
+ else
+ {
+ volatile VALUE cls = CLASS_OF(ex);
+ volatile VALUE path = callRuby(rb_class_path, cls);
+ assert(TYPE(path) == T_STRING);
+ Ice::UnknownUserException e(__FILE__, __LINE__);
+ e.unknown = RSTRING_PTR(path);
+ throw e;
+ }
+ }
+
+ throw Ice::UnknownUserException(__FILE__, __LINE__, "unknown exception");
+#ifdef __SUNPRO_CC
+ return 0;
+#endif
+
+}
+
+bool
+IceRuby::OperationI::validateException(VALUE ex) const
+{
+ for(ExceptionInfoList::const_iterator p = _exceptions.begin(); p != _exceptions.end(); ++p)
+ {
+ if(callRuby(rb_obj_is_kind_of, ex, (*p)->rubyClass))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+IceRuby::OperationI::checkTwowayOnly(const Ice::ObjectPrx& proxy) const
+{
+ if((_returnType != 0 || !_outParams.empty()) && !proxy->ice_isTwoway())
+ {
+ Ice::TwowayOnlyException ex(__FILE__, __LINE__);
+ ex.operation = _name;
+ throw ex;
+ }
+}
+
+bool
+IceRuby::initOperation(VALUE iceModule)
+{
+ rb_define_module_function(iceModule, "__defineOperation", CAST_METHOD(IceRuby_defineOperation), 9);
+
+ //
+ // Define a class to represent an operation.
+ //
+ _operationClass = rb_define_class_under(iceModule, "IceRuby_Operation", rb_cObject);
+
+ rb_define_method(_operationClass, "invoke", CAST_METHOD(IceRuby_Operation_invoke), 3);
+ rb_define_method(_operationClass, "deprecate", CAST_METHOD(IceRuby_Operation_deprecate), 1);
+
+ return true;
+}
+
+IceRuby::OperationPtr
+IceRuby::getOperation(VALUE obj)
+{
+ assert(TYPE(obj) == T_DATA);
+ assert(rb_obj_is_instance_of(obj, _operationClass) == Qtrue);
+ OperationPtr* p = reinterpret_cast<OperationPtr*>(DATA_PTR(obj));
+ return *p;
+}
diff --git a/ruby/src/IceRuby/Operation.h b/ruby/src/IceRuby/Operation.h
new file mode 100644
index 00000000000..97da32e0125
--- /dev/null
+++ b/ruby/src/IceRuby/Operation.h
@@ -0,0 +1,36 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_OPERATION_H
+#define ICE_RUBY_OPERATION_H
+
+#include <Config.h>
+#include <Ice/CommunicatorF.h>
+
+namespace IceRuby
+{
+
+class Operation : public IceUtil::Shared
+{
+public:
+
+ virtual ~Operation();
+
+ virtual VALUE invoke(const Ice::ObjectPrx&, VALUE, VALUE) = 0;
+ virtual void deprecate(const std::string&) = 0;
+};
+typedef IceUtil::Handle<Operation> OperationPtr;
+
+bool initOperation(VALUE);
+
+OperationPtr getOperation(VALUE);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Properties.cpp b/ruby/src/IceRuby/Properties.cpp
new file mode 100644
index 00000000000..815a9f37a16
--- /dev/null
+++ b/ruby/src/IceRuby/Properties.cpp
@@ -0,0 +1,369 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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>
+#include <Ice/Initialize.h>
+#include <Ice/Properties.h>
+
+using namespace std;
+using namespace IceRuby;
+
+static VALUE _propertiesClass;
+
+extern "C"
+void
+IceRuby_Properties_free(Ice::PropertiesPtr* p)
+{
+ assert(p);
+ delete p;
+}
+
+extern "C"
+VALUE
+IceRuby_createProperties(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::StringSeq seq;
+ if(argc >= 1 && !NIL_P(argv[0]) && !arrayToStringSeq(argv[0], seq))
+ {
+ throw RubyException(rb_eTypeError, "invalid array argument to Ice::createProperties");
+ }
+
+ Ice::PropertiesPtr defaults;
+ if(argc == 2)
+ {
+ if(!NIL_P(argv[1]) && callRuby(rb_obj_is_instance_of, argv[1], _propertiesClass) == Qfalse)
+ {
+ throw RubyException(rb_eTypeError, "invalid properties argument to Ice::createProperties");
+ }
+ defaults = getProperties(argv[1]);
+ }
+
+ //
+ // Insert the program name (stored in the Ruby global variable $0) as the first
+ // element of the sequence.
+ //
+ volatile VALUE progName = callRuby(rb_gv_get, "$0");
+ seq.insert(seq.begin(), getString(progName));
+
+ Ice::PropertiesPtr obj;
+ if(argc >= 1)
+ {
+ obj = Ice::createProperties(seq, defaults);
+ }
+ else
+ {
+ obj = Ice::createProperties();
+ }
+
+ //
+ // Replace the contents of the given argument list with the filtered arguments.
+ //
+ if(argc > 0 && !NIL_P(argv[0]))
+ {
+ callRuby(rb_ary_clear, argv[0]);
+
+ //
+ // We start at index 1 in order to skip the element that we inserted earlier.
+ //
+ for(Ice::StringSeq::size_type i = 1; i < seq.size(); ++i)
+ {
+ volatile VALUE str = createString(seq[i]);
+ callRuby(rb_ary_push, argv[0], str);
+ }
+ }
+
+ return createProperties(obj);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_getProperty(VALUE self, VALUE key)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string k = getString(key);
+ string v = p->getProperty(k);
+ return createString(v);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_getPropertyWithDefault(VALUE self, VALUE key, VALUE def)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string k = getString(key);
+ string d = getString(def);
+ string v = p->getPropertyWithDefault(k, d);
+ return createString(v);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_getPropertyAsInt(VALUE self, VALUE key)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string k = getString(key);
+ Ice::Int v = p->getPropertyAsInt(k);
+ return INT2FIX(v);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_getPropertyAsIntWithDefault(VALUE self, VALUE key, VALUE def)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string k = getString(key);
+ Ice::Int d = getInteger(def);
+ Ice::Int v = p->getPropertyAsIntWithDefault(k, d);
+ return INT2FIX(v);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_getPropertyAsList(VALUE self, VALUE key)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string k = getString(key);
+ Ice::StringSeq v = p->getPropertyAsList(k);
+ return stringSeqToArray(v);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_getPropertyAsListWithDefault(VALUE self, VALUE key, VALUE def)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string k = getString(key);
+ Ice::StringSeq d;
+ if(!arrayToStringSeq(def, d))
+ {
+ throw RubyException(rb_eTypeError, "invalid array argument to Ice::getPropertyAsListWithDefault");
+ }
+ Ice::StringSeq v = p->getPropertyAsListWithDefault(k, d);
+ return stringSeqToArray(v);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_getPropertiesForPrefix(VALUE self, VALUE prefix)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string pfx = getString(prefix);
+ Ice::PropertyDict dict = p->getPropertiesForPrefix(pfx);
+ volatile VALUE result = callRuby(rb_hash_new);
+ for(Ice::PropertyDict::const_iterator q = dict.begin(); q != dict.end(); ++q)
+ {
+ volatile VALUE key = createString(q->first);
+ volatile VALUE value = createString(q->second);
+ callRuby(rb_hash_aset, result, key, value);
+ }
+ return result;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_setProperty(VALUE self, VALUE key, VALUE value)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string k = getString(key);
+ string v = getString(value);
+ p->setProperty(k, v);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_getCommandLineOptions(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ Ice::StringSeq options = p->getCommandLineOptions();
+ return stringSeqToArray(options);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_parseCommandLineOptions(VALUE self, VALUE prefix, VALUE options)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string pfx = getString(prefix);
+ Ice::StringSeq seq;
+ if(!arrayToStringSeq(options, seq))
+ {
+ throw RubyException(rb_eTypeError, "invalid array argument to Ice::parseCommandLineOptions");
+ }
+ Ice::StringSeq filtered = p->parseCommandLineOptions(pfx, seq);
+ return stringSeqToArray(filtered);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_parseIceCommandLineOptions(VALUE self, VALUE options)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ Ice::StringSeq seq;
+ if(!arrayToStringSeq(options, seq))
+ {
+ throw RubyException(rb_eTypeError, "invalid array argument to Ice::parseIceCommandLineOptions");
+ }
+ Ice::StringSeq filtered = p->parseIceCommandLineOptions(seq);
+ return stringSeqToArray(filtered);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_load(VALUE self, VALUE file)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ string f = getString(file);
+ p->load(f);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_clone(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ Ice::PropertiesPtr props = p->clone();
+ return createProperties(props);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Properties_to_s(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::PropertiesPtr p = getProperties(self);
+ Ice::PropertyDict dict = p->getPropertiesForPrefix("");
+ string str;
+ for(Ice::PropertyDict::const_iterator q = dict.begin(); q != dict.end(); ++q)
+ {
+ if(q != dict.begin())
+ {
+ str.append("\n");
+ }
+ str.append(q->first + "=" + q->second);
+ }
+ return createString(str);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+void
+IceRuby::initProperties(VALUE iceModule)
+{
+ rb_define_module_function(iceModule, "createProperties", CAST_METHOD(IceRuby_createProperties), -1);
+
+ _propertiesClass = rb_define_class_under(iceModule, "PropertiesI", rb_cObject);
+ rb_define_method(_propertiesClass, "getProperty", CAST_METHOD(IceRuby_Properties_getProperty), 1);
+ rb_define_method(_propertiesClass, "getPropertyWithDefault",
+ CAST_METHOD(IceRuby_Properties_getPropertyWithDefault), 2);
+ rb_define_method(_propertiesClass, "getPropertyAsInt", CAST_METHOD(IceRuby_Properties_getPropertyAsInt), 1);
+ rb_define_method(_propertiesClass, "getPropertyAsIntWithDefault",
+ CAST_METHOD(IceRuby_Properties_getPropertyAsIntWithDefault), 2);
+ rb_define_method(_propertiesClass, "getPropertyAsList", CAST_METHOD(IceRuby_Properties_getPropertyAsList), 1);
+ rb_define_method(_propertiesClass, "getPropertyAsListWithDefault",
+ CAST_METHOD(IceRuby_Properties_getPropertyAsListWithDefault), 2);
+ rb_define_method(_propertiesClass, "getPropertiesForPrefix",
+ CAST_METHOD(IceRuby_Properties_getPropertiesForPrefix), 1);
+ rb_define_method(_propertiesClass, "setProperty", CAST_METHOD(IceRuby_Properties_setProperty), 2);
+ rb_define_method(_propertiesClass, "getCommandLineOptions", CAST_METHOD(IceRuby_Properties_getCommandLineOptions),
+ 0);
+ rb_define_method(_propertiesClass, "parseCommandLineOptions",
+ CAST_METHOD(IceRuby_Properties_parseCommandLineOptions), 2);
+ rb_define_method(_propertiesClass, "parseIceCommandLineOptions",
+ CAST_METHOD(IceRuby_Properties_parseIceCommandLineOptions), 1);
+ rb_define_method(_propertiesClass, "load", CAST_METHOD(IceRuby_Properties_load), 1);
+ rb_define_method(_propertiesClass, "clone", CAST_METHOD(IceRuby_Properties_clone), 0);
+ rb_define_method(_propertiesClass, "to_s", CAST_METHOD(IceRuby_Properties_to_s), 0);
+}
+
+Ice::PropertiesPtr
+IceRuby::getProperties(VALUE v)
+{
+ Ice::PropertiesPtr* p = reinterpret_cast<Ice::PropertiesPtr*>(DATA_PTR(v));
+ assert(p);
+ return *p;
+}
+
+VALUE
+IceRuby::createProperties(const Ice::PropertiesPtr& p)
+{
+ return Data_Wrap_Struct(_propertiesClass, 0, IceRuby_Properties_free, new Ice::PropertiesPtr(p));
+}
diff --git a/ruby/src/IceRuby/Properties.h b/ruby/src/IceRuby/Properties.h
new file mode 100644
index 00000000000..84b51f474c2
--- /dev/null
+++ b/ruby/src/IceRuby/Properties.h
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_PROPERTIES_H
+#define ICE_RUBY_PROPERTIES_H
+
+#include <Config.h>
+#include <Ice/PropertiesF.h>
+
+namespace IceRuby
+{
+
+void initProperties(VALUE);
+Ice::PropertiesPtr getProperties(VALUE);
+VALUE createProperties(const Ice::PropertiesPtr&);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Proxy.cpp b/ruby/src/IceRuby/Proxy.cpp
new file mode 100644
index 00000000000..76d4d836285
--- /dev/null
+++ b/ruby/src/IceRuby/Proxy.cpp
@@ -0,0 +1,1354 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/DisableWarnings.h>
+#include <Proxy.h>
+#include <Communicator.h>
+#include <Connection.h>
+#include <Endpoint.h>
+#include <Util.h>
+#include <Ice/LocalException.h>
+#include <Ice/Locator.h>
+#include <Ice/Proxy.h>
+#include <Ice/Router.h>
+
+using namespace std;
+using namespace IceRuby;
+
+static VALUE _proxyClass;
+
+// **********************************************************************
+// ObjectPrx
+// **********************************************************************
+
+extern "C"
+void
+IceRuby_ObjectPrx_mark(Ice::ObjectPrx* p)
+{
+ //
+ // We need to mark the communicator associated with this proxy.
+ //
+ assert(p);
+ volatile VALUE communicator = lookupCommunicator((*p)->ice_getCommunicator());
+ assert(!NIL_P(communicator));
+ rb_gc_mark(communicator);
+}
+
+extern "C"
+void
+IceRuby_ObjectPrx_free(Ice::ObjectPrx* p)
+{
+ assert(p);
+ delete p;
+}
+
+//
+// Returns true if a context was provided.
+//
+static bool
+checkArgs(const char* name, int numArgs, int argc, VALUE* argv, Ice::Context& ctx)
+{
+ if(argc < numArgs || argc > numArgs + 1)
+ {
+ throw RubyException(rb_eArgError, "%s expects %d argument%s including an optional context hash", name,
+ numArgs + 1, numArgs + 1 == 1 ? "" : "s");
+ }
+ if(argc == numArgs + 1)
+ {
+ if(!hashToContext(argv[numArgs], ctx))
+ {
+ throw RubyException(rb_eArgError, "%s: invalid context hash", name);
+ }
+ return true;
+ }
+ return false;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_hash(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return INT2FIX(p->__hash());
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getCommunicator(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ Ice::CommunicatorPtr communicator = p->ice_getCommunicator();
+ return lookupCommunicator(communicator);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_toString(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ string s = p->ice_toString();
+ return createString(s);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_isA(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::Context ctx;
+ bool haveContext = checkArgs("ice_isA", 1, argc, argv, ctx);
+
+ string id = getString(argv[0]);
+
+ bool result;
+ if(haveContext)
+ {
+ result = p->ice_isA(id, ctx);
+ }
+ else
+ {
+ result = p->ice_isA(id);
+ }
+ return result ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_ping(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::Context ctx;
+ bool haveContext = checkArgs("ice_ping", 0, argc, argv, ctx);
+
+ if(haveContext)
+ {
+ p->ice_ping(ctx);
+ }
+ else
+ {
+ p->ice_ping();
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_ids(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::Context ctx;
+ bool haveContext = checkArgs("ice_ids", 0, argc, argv, ctx);
+
+ vector<string> ids;
+ if(haveContext)
+ {
+ ids = p->ice_ids(ctx);
+ }
+ else
+ {
+ ids = p->ice_ids();
+ }
+
+ volatile VALUE result = createArray(ids.size());
+ long i = 0;
+ for(vector<string>::iterator q = ids.begin(); q != ids.end(); ++q, ++i)
+ {
+ RARRAY_PTR(result)[i] = createString(*q);
+ }
+
+ return result;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_id(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::Context ctx;
+ bool haveContext = checkArgs("ice_id", 0, argc, argv, ctx);
+
+ string id;
+ if(haveContext)
+ {
+ id = p->ice_id(ctx);
+ }
+ else
+ {
+ id = p->ice_id();
+ }
+
+ return createString(id);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getIdentity(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createIdentity(p->ice_getIdentity());
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_identity(VALUE self, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ Ice::Identity ident = getIdentity(id);
+ return createProxy(p->ice_identity(ident));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getContext(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return contextToHash(p->ice_getContext());
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_context(VALUE self, VALUE ctx)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::Context context;
+ if(!NIL_P(ctx) && !hashToContext(ctx, context))
+ {
+ throw RubyException(rb_eTypeError, "argument is not a context hash");
+ }
+ return createProxy(p->ice_context(context), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getFacet(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ string facet = p->ice_getFacet();
+ return createString(facet);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_facet(VALUE self, VALUE facet)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ string f = getString(facet);
+ return createProxy(p->ice_facet(f));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getAdapterId(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ string id = p->ice_getAdapterId();
+ return createString(id);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_adapterId(VALUE self, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ string idstr = getString(id);
+ return createProxy(p->ice_adapterId(idstr), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getEndpoints(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::EndpointSeq seq = p->ice_getEndpoints();
+ volatile VALUE result = createArray(seq.size());
+ long i = 0;
+ for(Ice::EndpointSeq::iterator q = seq.begin(); q != seq.end(); ++q, ++i)
+ {
+ RARRAY_PTR(result)[i] = createEndpoint(*q);
+ }
+ return result;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_endpoints(VALUE self, VALUE seq)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ if(!NIL_P(seq) && !isArray(seq))
+ {
+ throw RubyException(rb_eTypeError, "ice_endpoints requires an array of endpoints");
+ }
+
+ Ice::EndpointSeq endpoints;
+ if(!NIL_P(seq))
+ {
+ volatile VALUE arr = callRuby(rb_check_array_type, seq);
+ if(NIL_P(seq))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to an array of endpoints");
+ }
+ for(long i = 0; i < RARRAY_LEN(arr); ++i)
+ {
+ if(!checkEndpoint(RARRAY_PTR(arr)[i]))
+ {
+ throw RubyException(rb_eTypeError, "array element is not an Ice::Endpoint");
+ }
+ Ice::EndpointPtr* e = reinterpret_cast<Ice::EndpointPtr*>(DATA_PTR(RARRAY_PTR(arr)[i]));
+ assert(e);
+ endpoints.push_back(*e);
+ }
+ }
+ return createProxy(p->ice_endpoints(endpoints), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getLocatorCacheTimeout(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ Ice::Int t = p->ice_getLocatorCacheTimeout();
+ return INT2FIX(t);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getInvocationTimeout(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ Ice::Int t = p->ice_getInvocationTimeout();
+ return INT2FIX(t);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getConnectionId(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ string connectionId = p->ice_getConnectionId();
+ return createString(connectionId);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_locatorCacheTimeout(VALUE self, VALUE timeout)
+{
+ ICE_RUBY_TRY
+ {
+ try
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ long t = getInteger(timeout);
+ return createProxy(p->ice_locatorCacheTimeout(static_cast<Ice::Int>(t)), rb_class_of(self));
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ throw RubyException(rb_eArgError, ex.reason().c_str());
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_invocationTimeout(VALUE self, VALUE timeout)
+{
+ ICE_RUBY_TRY
+ {
+ try
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ long t = getInteger(timeout);
+ return createProxy(p->ice_invocationTimeout(static_cast<Ice::Int>(t)), rb_class_of(self));
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ throw RubyException(rb_eArgError, ex.reason().c_str());
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_isConnectionCached(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return p->ice_isConnectionCached() ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_connectionCached(VALUE self, VALUE b)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_connectionCached(RTEST(b)), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getEndpointSelection(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::EndpointSelectionType type = p->ice_getEndpointSelection();
+ volatile VALUE cls = callRuby(rb_path2class, "Ice::EndpointSelectionType");
+ assert(!NIL_P(cls));
+ return callRuby(rb_funcall, cls, rb_intern("from_int"), 1, INT2NUM(static_cast<int>(type)));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_endpointSelection(VALUE self, VALUE type)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ volatile VALUE cls = callRuby(rb_path2class, "Ice::EndpointSelectionType");
+ assert(!NIL_P(cls));
+ if(callRuby(rb_obj_is_instance_of, type, cls) == Qfalse)
+ {
+ throw RubyException(rb_eTypeError, "argument must be an Ice::EndpointSelectionType enumerator");
+ }
+
+ volatile VALUE val = callRuby(rb_funcall, type, rb_intern("to_i"), 0);
+ Ice::EndpointSelectionType t = static_cast<Ice::EndpointSelectionType>(getInteger(val));
+ return createProxy(p->ice_endpointSelection(t), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_isSecure(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return p->ice_isSecure() ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_secure(VALUE self, VALUE b)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_secure(RTEST(b)), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getEncodingVersion(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createEncodingVersion(p->ice_getEncodingVersion());
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_encodingVersion(VALUE self, VALUE v)
+{
+ Ice::EncodingVersion val;
+ if(getEncodingVersion(v, val))
+ {
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_encodingVersion(val), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ }
+
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_isPreferSecure(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return p->ice_isPreferSecure() ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_preferSecure(VALUE self, VALUE b)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_preferSecure(RTEST(b)), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getRouter(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::RouterPrx router = p->ice_getRouter();
+ if(router)
+ {
+ volatile VALUE cls = callRuby(rb_path2class, "Ice::RouterPrx");
+ assert(!NIL_P(cls));
+ return createProxy(router, cls);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_router(VALUE self, VALUE router)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::RouterPrx proxy;
+ if(!NIL_P(router))
+ {
+ if(!checkProxy(router))
+ {
+ throw RubyException(rb_eTypeError, "argument must be a proxy");
+ }
+ proxy = Ice::RouterPrx::uncheckedCast(getProxy(router));
+ }
+ return createProxy(p->ice_router(proxy), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getLocator(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::LocatorPrx locator = p->ice_getLocator();
+ if(locator)
+ {
+ volatile VALUE cls = callRuby(rb_path2class, "Ice::LocatorPrx");
+ assert(!NIL_P(cls));
+ return createProxy(locator, cls);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_locator(VALUE self, VALUE locator)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+
+ Ice::LocatorPrx proxy;
+ if(!NIL_P(locator))
+ {
+ if(!checkProxy(locator))
+ {
+ throw RubyException(rb_eTypeError, "argument must be a proxy");
+ }
+ proxy = Ice::LocatorPrx::uncheckedCast(getProxy(locator));
+ }
+ return createProxy(p->ice_locator(proxy), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_twoway(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_twoway(), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_isTwoway(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return p->ice_isTwoway() ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_oneway(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_oneway(), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_isOneway(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return p->ice_isOneway() ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_batchOneway(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_batchOneway(), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_isBatchOneway(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return p->ice_isBatchOneway() ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_datagram(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_datagram(), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_isDatagram(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return p->ice_isDatagram() ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_batchDatagram(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_batchDatagram(), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_isBatchDatagram(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return p->ice_isBatchDatagram() ? Qtrue : Qfalse;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_compress(VALUE self, VALUE b)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ return createProxy(p->ice_compress(RTEST(b)), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_timeout(VALUE self, VALUE t)
+{
+ ICE_RUBY_TRY
+ {
+ try
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ Ice::Int timeout = static_cast<Ice::Int>(getInteger(t));
+ return createProxy(p->ice_timeout(timeout), rb_class_of(self));
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ throw RubyException(rb_eArgError, ex.reason().c_str());
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_connectionId(VALUE self, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ string idstr = getString(id);
+ return createProxy(p->ice_connectionId(idstr), rb_class_of(self));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getConnection(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ Ice::ConnectionPtr conn = p->ice_getConnection();
+ return createConnection(conn);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_getCachedConnection(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ Ice::ConnectionPtr conn = p->ice_getCachedConnection();
+ if(conn)
+ {
+ return createConnection(conn);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_flushBatchRequests(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::ObjectPrx p = getProxy(self);
+ p->ice_flushBatchRequests();
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_cmp(VALUE self, VALUE other)
+{
+ ICE_RUBY_TRY
+ {
+ if(NIL_P(other))
+ {
+ return INT2NUM(1);
+ }
+ if(!checkProxy(other))
+ {
+ throw RubyException(rb_eTypeError, "argument must be a proxy");
+ }
+ Ice::ObjectPrx p1 = getProxy(self);
+ Ice::ObjectPrx p2 = getProxy(other);
+ if(p1 < p2)
+ {
+ return INT2NUM(-1);
+ }
+ else if(p1 == p2)
+ {
+ return INT2NUM(0);
+ }
+ else
+ {
+ return INT2NUM(1);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_equals(VALUE self, VALUE other)
+{
+ return IceRuby_ObjectPrx_cmp(self, other) == INT2NUM(0) ? Qtrue : Qfalse;
+}
+
+static VALUE
+checkedCastImpl(const Ice::ObjectPrx& p, const string& id, VALUE facet, VALUE ctx, VALUE type)
+{
+ Ice::ObjectPrx target;
+ if(NIL_P(facet))
+ {
+ target = p;
+ }
+ else
+ {
+ target = p->ice_facet(getString(facet));
+ }
+
+ try
+ {
+ if(NIL_P(ctx))
+ {
+ if(target->ice_isA(id))
+ {
+ return createProxy(target, type);
+ }
+ }
+ else
+ {
+ Ice::Context c;
+#ifndef NDEBUG
+ bool b =
+#endif
+ hashToContext(ctx, c);
+ assert(b);
+
+ if(target->ice_isA(id, c))
+ {
+ return createProxy(target, type);
+ }
+ }
+ }
+ catch(const Ice::FacetNotExistException&)
+ {
+ // Ignore.
+ }
+
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_checkedCast(int argc, VALUE* args, VALUE self)
+{
+ //
+ // ice_checkedCast is called from generated code, therefore we always expect
+ // to receive all four arguments.
+ //
+ ICE_RUBY_TRY
+ {
+ if(argc < 1 || argc > 3)
+ {
+ throw RubyException(rb_eArgError, "checkedCast requires a proxy argument and optional facet and context");
+ }
+
+ if(NIL_P(args[0]))
+ {
+ return Qnil;
+ }
+
+ if(!checkProxy(args[0]))
+ {
+ throw RubyException(rb_eArgError, "checkedCast requires a proxy argument");
+ }
+
+ Ice::ObjectPrx p = getProxy(args[0]);
+
+ volatile VALUE facet = Qnil;
+ volatile VALUE ctx = Qnil;
+
+ if(argc == 3)
+ {
+ if(!NIL_P(args[1]) && !isString(args[1]))
+ {
+ throw RubyException(rb_eArgError, "facet argument to checkedCast must be a string");
+ }
+ facet = args[1];
+
+ if(!NIL_P(args[2]) && !isHash(args[2]))
+ {
+ throw RubyException(rb_eArgError, "context argument to checkedCast must be a hash");
+ }
+ ctx = args[2];
+ }
+ else if(argc == 2)
+ {
+ if(isString(args[1]))
+ {
+ facet = args[1];
+ }
+ else if(isHash(args[1]))
+ {
+ ctx = args[1];
+ }
+ else
+ {
+ throw RubyException(rb_eArgError, "second argument to checkedCast must be a facet or context");
+ }
+ }
+
+ return checkedCastImpl(p, "::Ice::Object", facet, ctx, Qnil);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_uncheckedCast(int argc, VALUE* args, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ if(argc < 1 || argc > 2)
+ {
+ throw RubyException(rb_eArgError, "uncheckedCast requires a proxy argument and an optional facet");
+ }
+
+ if(NIL_P(args[0]))
+ {
+ return Qnil;
+ }
+
+ if(!checkProxy(args[0]))
+ {
+ throw RubyException(rb_eArgError, "uncheckedCast requires a proxy argument");
+ }
+
+ volatile VALUE facet = Qnil;
+ if(argc == 2)
+ {
+ facet = args[1];
+ }
+
+ Ice::ObjectPrx p = getProxy(args[0]);
+
+ if(!NIL_P(facet))
+ {
+ return createProxy(p->ice_facet(getString(facet)));
+ }
+ else
+ {
+ return createProxy(p);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_checkedCast(VALUE self, VALUE obj, VALUE id, VALUE facetOrCtx, VALUE ctx)
+{
+ //
+ // ice_checkedCast is called from generated code, therefore we always expect
+ // to receive all four arguments.
+ //
+ ICE_RUBY_TRY
+ {
+ if(NIL_P(obj))
+ {
+ return Qnil;
+ }
+
+ if(!checkProxy(obj))
+ {
+ throw RubyException(rb_eArgError, "checkedCast requires a proxy argument");
+ }
+
+ Ice::ObjectPrx p = getProxy(obj);
+
+ string idstr = getString(id);
+
+ volatile VALUE facet = Qnil;
+ if(isString(facetOrCtx))
+ {
+ facet = facetOrCtx;
+ }
+ else if(isHash(facetOrCtx))
+ {
+ if(!NIL_P(ctx))
+ {
+ throw RubyException(rb_eArgError, "facet argument to checkedCast must be a string");
+ }
+ ctx = facetOrCtx;
+ }
+ else if(!NIL_P(facetOrCtx))
+ {
+ throw RubyException(rb_eArgError, "second argument to checkedCast must be a facet or context");
+ }
+
+ if(!NIL_P(ctx) && !isHash(ctx))
+ {
+ throw RubyException(rb_eArgError, "context argument to checkedCast must be a hash");
+ }
+
+ return checkedCastImpl(p, idstr, facet, ctx, self);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_uncheckedCast(VALUE self, VALUE obj, VALUE facet)
+{
+ ICE_RUBY_TRY
+ {
+ if(NIL_P(obj))
+ {
+ return Qnil;
+ }
+
+ if(!checkProxy(obj))
+ {
+ throw RubyException(rb_eArgError, "uncheckedCast requires a proxy argument");
+ }
+
+ Ice::ObjectPrx p = getProxy(obj);
+
+ if(!NIL_P(facet))
+ {
+ return createProxy(p->ice_facet(getString(facet)), self);
+ }
+ else
+ {
+ return createProxy(p, self);
+ }
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_ice_staticId(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ return createString(Ice::Object::ice_staticId());
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ObjectPrx_new(int /*argc*/, VALUE* /*args*/, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ throw RubyException(rb_eRuntimeError, "a proxy cannot be created via new");
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+void
+IceRuby::initProxy(VALUE iceModule)
+{
+ //
+ // ObjectPrx.
+ //
+ _proxyClass = rb_define_class_under(iceModule, "ObjectPrx", rb_cObject);
+
+ //
+ // Instance methods.
+ //
+ rb_define_method(_proxyClass, "ice_getCommunicator", CAST_METHOD(IceRuby_ObjectPrx_ice_getCommunicator), 0);
+ rb_define_method(_proxyClass, "ice_toString", CAST_METHOD(IceRuby_ObjectPrx_ice_toString), 0);
+ rb_define_method(_proxyClass, "ice_isA", CAST_METHOD(IceRuby_ObjectPrx_ice_isA), -1);
+ rb_define_method(_proxyClass, "ice_ping", CAST_METHOD(IceRuby_ObjectPrx_ice_ping), -1);
+ rb_define_method(_proxyClass, "ice_ids", CAST_METHOD(IceRuby_ObjectPrx_ice_ids), -1);
+ rb_define_method(_proxyClass, "ice_id", CAST_METHOD(IceRuby_ObjectPrx_ice_id), -1);
+ rb_define_method(_proxyClass, "ice_getIdentity", CAST_METHOD(IceRuby_ObjectPrx_ice_getIdentity), 0);
+ rb_define_method(_proxyClass, "ice_identity", CAST_METHOD(IceRuby_ObjectPrx_ice_identity), 1);
+ rb_define_method(_proxyClass, "ice_getContext", CAST_METHOD(IceRuby_ObjectPrx_ice_getContext), 0);
+ rb_define_method(_proxyClass, "ice_context", CAST_METHOD(IceRuby_ObjectPrx_ice_context), 1);
+ rb_define_method(_proxyClass, "ice_getFacet", CAST_METHOD(IceRuby_ObjectPrx_ice_getFacet), 0);
+ rb_define_method(_proxyClass, "ice_facet", CAST_METHOD(IceRuby_ObjectPrx_ice_facet), 1);
+ rb_define_method(_proxyClass, "ice_getAdapterId", CAST_METHOD(IceRuby_ObjectPrx_ice_getAdapterId), 0);
+ rb_define_method(_proxyClass, "ice_adapterId", CAST_METHOD(IceRuby_ObjectPrx_ice_adapterId), 1);
+ rb_define_method(_proxyClass, "ice_getEndpoints", CAST_METHOD(IceRuby_ObjectPrx_ice_getEndpoints), 0);
+ rb_define_method(_proxyClass, "ice_endpoints", CAST_METHOD(IceRuby_ObjectPrx_ice_endpoints), 1);
+ rb_define_method(_proxyClass, "ice_getLocatorCacheTimeout",
+ CAST_METHOD(IceRuby_ObjectPrx_ice_getLocatorCacheTimeout), 0);
+ rb_define_method(_proxyClass, "ice_getInvocationTimeout",
+ CAST_METHOD(IceRuby_ObjectPrx_ice_getInvocationTimeout), 0);
+ rb_define_method(_proxyClass, "ice_getConnectionId", CAST_METHOD(IceRuby_ObjectPrx_ice_getConnectionId), 0);
+ rb_define_method(_proxyClass, "ice_locatorCacheTimeout", CAST_METHOD(IceRuby_ObjectPrx_ice_locatorCacheTimeout), 1);
+ rb_define_method(_proxyClass, "ice_invocationTimeout", CAST_METHOD(IceRuby_ObjectPrx_ice_invocationTimeout), 1);
+ rb_define_method(_proxyClass, "ice_isConnectionCached", CAST_METHOD(IceRuby_ObjectPrx_ice_isConnectionCached), 0);
+ rb_define_method(_proxyClass, "ice_connectionCached", CAST_METHOD(IceRuby_ObjectPrx_ice_connectionCached), 1);
+ rb_define_method(_proxyClass, "ice_getEndpointSelection",
+ CAST_METHOD(IceRuby_ObjectPrx_ice_getEndpointSelection), 0);
+ rb_define_method(_proxyClass, "ice_endpointSelection", CAST_METHOD(IceRuby_ObjectPrx_ice_endpointSelection), 1);
+ rb_define_method(_proxyClass, "ice_isSecure", CAST_METHOD(IceRuby_ObjectPrx_ice_isSecure), 0);
+ rb_define_method(_proxyClass, "ice_secure", CAST_METHOD(IceRuby_ObjectPrx_ice_secure), 1);
+ rb_define_method(_proxyClass, "ice_getEncodingVersion", CAST_METHOD(IceRuby_ObjectPrx_ice_getEncodingVersion), 0);
+ rb_define_method(_proxyClass, "ice_encodingVersion", CAST_METHOD(IceRuby_ObjectPrx_ice_encodingVersion), 1);
+ rb_define_method(_proxyClass, "ice_isPreferSecure", CAST_METHOD(IceRuby_ObjectPrx_ice_isPreferSecure), 0);
+ rb_define_method(_proxyClass, "ice_preferSecure", CAST_METHOD(IceRuby_ObjectPrx_ice_preferSecure), 1);
+ rb_define_method(_proxyClass, "ice_getRouter", CAST_METHOD(IceRuby_ObjectPrx_ice_getRouter), 0);
+ rb_define_method(_proxyClass, "ice_router", CAST_METHOD(IceRuby_ObjectPrx_ice_router), 1);
+ rb_define_method(_proxyClass, "ice_getLocator", CAST_METHOD(IceRuby_ObjectPrx_ice_getLocator), 0);
+ rb_define_method(_proxyClass, "ice_locator", CAST_METHOD(IceRuby_ObjectPrx_ice_locator), 1);
+ rb_define_method(_proxyClass, "ice_twoway", CAST_METHOD(IceRuby_ObjectPrx_ice_twoway), 0);
+ rb_define_method(_proxyClass, "ice_isTwoway", CAST_METHOD(IceRuby_ObjectPrx_ice_isTwoway), 0);
+ rb_define_method(_proxyClass, "ice_oneway", CAST_METHOD(IceRuby_ObjectPrx_ice_oneway), 0);
+ rb_define_method(_proxyClass, "ice_isOneway", CAST_METHOD(IceRuby_ObjectPrx_ice_isOneway), 0);
+ rb_define_method(_proxyClass, "ice_batchOneway", CAST_METHOD(IceRuby_ObjectPrx_ice_batchOneway), 0);
+ rb_define_method(_proxyClass, "ice_isBatchOneway", CAST_METHOD(IceRuby_ObjectPrx_ice_isBatchOneway), 0);
+ rb_define_method(_proxyClass, "ice_datagram", CAST_METHOD(IceRuby_ObjectPrx_ice_datagram), 0);
+ rb_define_method(_proxyClass, "ice_isDatagram", CAST_METHOD(IceRuby_ObjectPrx_ice_isDatagram), 0);
+ rb_define_method(_proxyClass, "ice_batchDatagram", CAST_METHOD(IceRuby_ObjectPrx_ice_batchDatagram), 0);
+ rb_define_method(_proxyClass, "ice_isBatchDatagram", CAST_METHOD(IceRuby_ObjectPrx_ice_isBatchDatagram), 0);
+ rb_define_method(_proxyClass, "ice_compress", CAST_METHOD(IceRuby_ObjectPrx_ice_compress), 1);
+ rb_define_method(_proxyClass, "ice_timeout", CAST_METHOD(IceRuby_ObjectPrx_ice_timeout), 1);
+ rb_define_method(_proxyClass, "ice_connectionId", CAST_METHOD(IceRuby_ObjectPrx_ice_connectionId), 1);
+ rb_define_method(_proxyClass, "ice_getConnection", CAST_METHOD(IceRuby_ObjectPrx_ice_getConnection), 0);
+ rb_define_method(_proxyClass, "ice_getCachedConnection", CAST_METHOD(IceRuby_ObjectPrx_ice_getCachedConnection), 0);
+ rb_define_method(_proxyClass, "ice_flushBatchRequests", CAST_METHOD(IceRuby_ObjectPrx_ice_flushBatchRequests), 0);
+
+ rb_define_method(_proxyClass, "hash", CAST_METHOD(IceRuby_ObjectPrx_hash), 0);
+ rb_define_method(_proxyClass, "to_s", CAST_METHOD(IceRuby_ObjectPrx_ice_toString), 0);
+ rb_define_method(_proxyClass, "inspect", CAST_METHOD(IceRuby_ObjectPrx_ice_toString), 0);
+ rb_define_method(_proxyClass, "<=>", CAST_METHOD(IceRuby_ObjectPrx_cmp), 1);
+ rb_define_method(_proxyClass, "==", CAST_METHOD(IceRuby_ObjectPrx_equals), 1);
+ rb_define_method(_proxyClass, "eql?", CAST_METHOD(IceRuby_ObjectPrx_equals), 1);
+
+ //
+ // Static methods.
+ //
+ rb_define_singleton_method(_proxyClass, "checkedCast", CAST_METHOD(IceRuby_ObjectPrx_checkedCast), -1);
+ rb_define_singleton_method(_proxyClass, "uncheckedCast", CAST_METHOD(IceRuby_ObjectPrx_uncheckedCast), -1);
+ rb_define_singleton_method(_proxyClass, "ice_checkedCast", CAST_METHOD(IceRuby_ObjectPrx_ice_checkedCast), 4);
+ rb_define_singleton_method(_proxyClass, "ice_uncheckedCast", CAST_METHOD(IceRuby_ObjectPrx_ice_uncheckedCast), 2);
+ rb_define_singleton_method(_proxyClass, "ice_staticId", CAST_METHOD(IceRuby_ObjectPrx_ice_staticId), 0);
+ rb_define_singleton_method(_proxyClass, "new", CAST_METHOD(IceRuby_ObjectPrx_new), -1);
+}
+
+VALUE
+IceRuby::createProxy(const Ice::ObjectPrx& p, VALUE cls)
+{
+ //
+ // If cls is nil then the proxy has the base type Ice::ObjectPrx.
+ //
+ if(NIL_P(cls))
+ {
+ return Data_Wrap_Struct(_proxyClass, IceRuby_ObjectPrx_mark, IceRuby_ObjectPrx_free, new Ice::ObjectPrx(p));
+ }
+ else
+ {
+ return Data_Wrap_Struct(cls, IceRuby_ObjectPrx_mark, IceRuby_ObjectPrx_free, new Ice::ObjectPrx(p));
+ }
+}
+
+Ice::ObjectPrx
+IceRuby::getProxy(VALUE v)
+{
+ Ice::ObjectPrx* p = reinterpret_cast<Ice::ObjectPrx*>(DATA_PTR(v));
+ return *p;
+}
+
+bool
+IceRuby::checkProxy(VALUE v)
+{
+ return callRuby(rb_obj_is_kind_of, v, _proxyClass) == Qtrue;
+}
diff --git a/ruby/src/IceRuby/Proxy.h b/ruby/src/IceRuby/Proxy.h
new file mode 100644
index 00000000000..843d022a160
--- /dev/null
+++ b/ruby/src/IceRuby/Proxy.h
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_PROXY_H
+#define ICE_RUBY_PROXY_H
+
+#include <Config.h>
+#include <Ice/ProxyF.h>
+#include <Ice/CommunicatorF.h>
+
+namespace IceRuby
+{
+
+void initProxy(VALUE);
+VALUE createProxy(const Ice::ObjectPrx&, VALUE = Qnil);
+Ice::ObjectPrx getProxy(VALUE);
+bool checkProxy(VALUE);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Slice.cpp b/ruby/src/IceRuby/Slice.cpp
new file mode 100644
index 00000000000..06f1d232866
--- /dev/null
+++ b/ruby/src/IceRuby/Slice.cpp
@@ -0,0 +1,223 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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.h>
+#include <Util.h>
+#include <Slice/Preprocessor.h>
+#include <Slice/RubyUtil.h>
+#include <Slice/Util.h>
+#include <IceUtil/Options.h>
+
+using namespace std;
+using namespace IceRuby;
+using namespace Slice;
+using namespace Slice::Ruby;
+
+extern "C"
+VALUE
+IceRuby_loadSlice(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ if(argc < 1 || argc > 2)
+ {
+ throw RubyException(rb_eArgError, "wrong number of arguments");
+ }
+
+ string cmd = getString(argv[0]);
+ vector<string> argSeq;
+ try
+ {
+ argSeq = IceUtilInternal::Options::split(cmd);
+ }
+ catch(const IceUtilInternal::BadOptException& ex)
+ {
+ throw RubyException(rb_eArgError, "error in Slice options: %s", ex.reason.c_str());
+ }
+ catch(const IceUtilInternal::APIException& ex)
+ {
+ throw RubyException(rb_eArgError, "error in Slice options: %s", ex.reason.c_str());
+ }
+
+ if(argc > 1)
+ {
+ if(!arrayToStringSeq(argv[1], argSeq))
+ {
+ throw RubyException(rb_eTypeError, "argument 2 is not an array");
+ }
+ }
+
+ 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("", "underscore");
+ opts.addOpt("", "checksum");
+ opts.addOpt("", "all");
+
+ vector<string> files;
+ try
+ {
+ argSeq.insert(argSeq.begin(), ""); // dummy argv[0]
+ files = opts.parse(argSeq);
+ if(files.empty())
+ {
+ throw RubyException(rb_eArgError, "no Slice files specified in `%s'", cmd.c_str());
+ }
+ }
+ catch(const IceUtilInternal::BadOptException& ex)
+ {
+ throw RubyException(rb_eArgError, "error in Slice options: %s", ex.reason.c_str());
+ }
+ catch(const IceUtilInternal::APIException& ex)
+ {
+ throw RubyException(rb_eArgError, "error in Slice options: %s", ex.reason.c_str());
+ }
+
+ vector<string> cppArgs;
+ vector<string> includePaths;
+ bool debug = false;
+ bool ice = true; // This must be true so that we can create Ice::Identity when necessary.
+ bool underscore = opts.isSet("underscore");
+ bool all = false;
+ bool checksum = false;
+ 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"))
+ {
+ includePaths = opts.argVec("I");
+ for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i)
+ {
+ cppArgs.push_back("-I" + *i);
+ }
+ }
+ debug = opts.isSet("d") || opts.isSet("debug");
+ all = opts.isSet("all");
+ checksum = opts.isSet("checksum");
+
+ bool ignoreRedefs = false;
+
+ for(vector<string>::const_iterator p = files.begin(); p != files.end(); ++p)
+ {
+ string file = *p;
+ Slice::PreprocessorPtr icecpp = Slice::Preprocessor::create("icecpp", file, cppArgs);
+ FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2RB__");
+
+ if(cppHandle == 0)
+ {
+ throw RubyException(rb_eArgError, "Slice preprocessing failed for `%s'", cmd.c_str());
+ }
+
+ UnitPtr u = Slice::Unit::createUnit(ignoreRedefs, all, ice, underscore);
+ int parseStatus = u->parse(file, cppHandle, debug);
+
+ if(!icecpp->close() || parseStatus == EXIT_FAILURE)
+ {
+ u->destroy();
+ throw RubyException(rb_eArgError, "Slice parsing failed for `%s'", cmd.c_str());
+ }
+
+ //
+ // Generate the Ruby code into a string stream.
+ //
+ ostringstream codeStream;
+ IceUtilInternal::Output out(codeStream);
+ out.setUseTab(false);
+ generate(u, all, checksum, includePaths, out);
+ u->destroy();
+
+ string code = codeStream.str();
+ callRuby(rb_eval_string, code.c_str());
+ }
+ }
+ ICE_RUBY_CATCH
+
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_compile(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ if(argc != 1)
+ {
+ throw RubyException(rb_eArgError, "wrong number of arguments");
+ }
+
+ vector<string> argSeq;
+ if(!arrayToStringSeq(argv[0], argSeq))
+ {
+ throw RubyException(rb_eTypeError, "argument is not an array");
+ }
+ char** argv = new char*[argSeq.size()+1];
+ // Manufacture a fake argv[0].
+ argv[0] = const_cast<char*>("slice2rb");
+ for(size_t i = 0; i < argSeq.size(); ++i)
+ {
+ argv[i+1] = const_cast<char*>(argSeq[i].c_str());
+ }
+
+ int rc;
+ try
+ {
+ rc = Slice::Ruby::compile(argSeq.size()+1, argv);
+ }
+ catch(const std::exception& ex)
+ {
+ getErrorStream() << argv[0] << ": error:" << ex.what() << endl;
+ rc = EXIT_FAILURE;
+ }
+ catch(const std::string& msg)
+ {
+ getErrorStream() << argv[0] << ": error:" << msg << endl;
+ rc = EXIT_FAILURE;
+ }
+ catch(const char* msg)
+ {
+ getErrorStream() << argv[0] << ": error:" << msg << endl;
+ rc = EXIT_FAILURE;
+ }
+ catch(...)
+ {
+ getErrorStream() << argv[0] << ": error:" << "unknown exception" << endl;
+ rc = EXIT_FAILURE;
+ }
+
+ delete[] argv;
+ return INT2FIX(rc);
+ }
+ ICE_RUBY_CATCH
+
+ return Qnil;
+}
+
+void
+IceRuby::initSlice(VALUE iceModule)
+{
+ rb_define_module_function(iceModule, "loadSlice", CAST_METHOD(IceRuby_loadSlice), -1);
+ rb_define_module_function(iceModule, "compile", CAST_METHOD(IceRuby_compile), -1);
+}
diff --git a/ruby/src/IceRuby/Slice.h b/ruby/src/IceRuby/Slice.h
new file mode 100644
index 00000000000..e2844922f9f
--- /dev/null
+++ b/ruby/src/IceRuby/Slice.h
@@ -0,0 +1,22 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_SLICE_H
+#define ICE_RUBY_SLICE_H
+
+#include <Config.h>
+
+namespace IceRuby
+{
+
+void initSlice(VALUE);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Types.cpp b/ruby/src/IceRuby/Types.cpp
new file mode 100644
index 00000000000..18bf6ca517b
--- /dev/null
+++ b/ruby/src/IceRuby/Types.cpp
@@ -0,0 +1,3189 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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 <Ice/LocalException.h>
+#include <Ice/SlicedData.h>
+#include <list>
+#include <limits>
+
+//
+// Required for RHASH_SIZE to work properly with Ruby 1.8.x.
+// T_ZOMBIE is only defined in Ruby 1.9.
+//
+#ifndef T_ZOMBIE
+# include "st.h"
+#endif
+
+#ifndef RHASH_SIZE
+# define RHASH_SIZE(v) RHASH(v)->tbl->num_entries
+#endif
+
+using namespace std;
+using namespace IceRuby;
+using namespace IceUtil;
+using namespace IceUtilInternal;
+
+static VALUE _typeInfoClass, _exceptionInfoClass, _unsetTypeClass;
+
+typedef map<string, ClassInfoPtr> ClassInfoMap;
+static ClassInfoMap _classInfoMap;
+
+typedef map<Ice::Int, ClassInfoPtr> CompactIdMap;
+static CompactIdMap _compactIdMap;
+
+typedef map<string, ProxyInfoPtr> ProxyInfoMap;
+static ProxyInfoMap _proxyInfoMap;
+
+typedef map<string, ExceptionInfoPtr> ExceptionInfoMap;
+static ExceptionInfoMap _exceptionInfoMap;
+
+namespace IceRuby
+{
+
+VALUE Unset;
+
+class InfoMapDestroyer
+{
+public:
+
+ ~InfoMapDestroyer();
+};
+static InfoMapDestroyer infoMapDestroyer;
+
+class ReadObjectCallback : public Ice::ReadObjectCallback
+{
+public:
+
+ ReadObjectCallback(const ClassInfoPtr&, const UnmarshalCallbackPtr&, VALUE, void*);
+
+ virtual void invoke(const Ice::ObjectPtr&);
+
+private:
+
+ ClassInfoPtr _info;
+ UnmarshalCallbackPtr _cb;
+ VALUE _target;
+ void* _closure;
+};
+
+string
+escapeString(const string& str)
+{
+ static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789"
+ "_{}[]#()<>%:;.?*+-/^&|~!=,\\\"' ";
+ static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end());
+
+ ostringstream out;
+
+ for(string::const_iterator c = str.begin(); c != str.end(); ++c)
+ {
+ if(charSet.find(*c) == charSet.end())
+ {
+ unsigned char uc = *c; // char may be signed, so make it positive
+ ostringstream s;
+ s << "\\"; // Print as octal if not in basic source character set
+ s.width(3);
+ s.fill('0');
+ s << oct;
+ s << static_cast<unsigned>(uc);
+ out << s.str();
+ }
+ else
+ {
+ out << *c; // Print normally if in basic source character set
+ }
+ }
+
+ return out.str();
+}
+
+}
+
+//
+// addClassInfo()
+//
+static void
+addClassInfo(const string& id, const ClassInfoPtr& info)
+{
+ //
+ // Do not assert. An application may load statically-
+ // translated definitions and then dynamically load
+ // duplicate definitions.
+ //
+// assert(_classInfoMap.find(id) == _classInfoMap.end());
+ ClassInfoMap::iterator p = _classInfoMap.find(id);
+ if(p != _classInfoMap.end())
+ {
+ _classInfoMap.erase(p);
+ }
+ _classInfoMap.insert(ClassInfoMap::value_type(id, info));
+}
+
+//
+// addProxyInfo()
+//
+static void
+addProxyInfo(const string& id, const ProxyInfoPtr& info)
+{
+ //
+ // Do not assert. An application may load statically-
+ // translated definitions and then dynamically load
+ // duplicate definitions.
+ //
+// assert(_proxyInfoMap.find(id) == _proxyInfoMap.end());
+ ProxyInfoMap::iterator p = _proxyInfoMap.find(id);
+ if(p != _proxyInfoMap.end())
+ {
+ _proxyInfoMap.erase(p);
+ }
+ _proxyInfoMap.insert(ProxyInfoMap::value_type(id, info));
+}
+
+//
+// lookupProxyInfo()
+//
+static IceRuby::ProxyInfoPtr
+lookupProxyInfo(const string& id)
+{
+ ProxyInfoMap::iterator p = _proxyInfoMap.find(id);
+ if(p != _proxyInfoMap.end())
+ {
+ return p->second;
+ }
+ return 0;
+}
+
+//
+// addExceptionInfo()
+//
+static void
+addExceptionInfo(const string& id, const ExceptionInfoPtr& info)
+{
+ //
+ // Do not assert. An application may load statically-
+ // translated definitions and then dynamically load
+ // duplicate definitions.
+ //
+// assert(_exceptionInfoMap.find(id) == _exceptionInfoMap.end());
+ _exceptionInfoMap.insert(ExceptionInfoMap::value_type(id, info));
+}
+
+//
+// SlicedDataUtil implementation
+//
+VALUE IceRuby::SlicedDataUtil::_slicedDataType = Qnil;
+VALUE IceRuby::SlicedDataUtil::_sliceInfoType = Qnil;
+
+IceRuby::SlicedDataUtil::SlicedDataUtil()
+{
+}
+
+IceRuby::SlicedDataUtil::~SlicedDataUtil()
+{
+ //
+ // Make sure we break any cycles among the ObjectReaders in preserved slices.
+ //
+ for(set<ObjectReaderPtr>::iterator p = _readers.begin(); p != _readers.end(); ++p)
+ {
+ Ice::SlicedDataPtr slicedData = (*p)->getSlicedData();
+ for(Ice::SliceInfoSeq::const_iterator q = slicedData->slices.begin(); q != slicedData->slices.end(); ++q)
+ {
+ //
+ // Don't just call (*q)->objects.clear(), as releasing references
+ // to the objects could have unexpected side effects. We exchange
+ // the vector into a temporary and then let the temporary fall out
+ // of scope.
+ //
+ vector<Ice::ObjectPtr> tmp;
+ tmp.swap((*q)->objects);
+ }
+ }
+}
+
+void
+IceRuby::SlicedDataUtil::add(const ObjectReaderPtr& reader)
+{
+ assert(reader->getSlicedData());
+ _readers.insert(reader);
+}
+
+void
+IceRuby::SlicedDataUtil::update()
+{
+ for(set<ObjectReaderPtr>::iterator p = _readers.begin(); p != _readers.end(); ++p)
+ {
+ setMember((*p)->getObject(), (*p)->getSlicedData());
+ }
+}
+
+void
+IceRuby::SlicedDataUtil::setMember(VALUE obj, const Ice::SlicedDataPtr& slicedData)
+{
+ //
+ // Create a Ruby equivalent of the SlicedData object.
+ //
+
+ assert(slicedData);
+
+ if(_slicedDataType == Qnil)
+ {
+ _slicedDataType = callRuby(rb_path2class, "Ice::SlicedData");
+ assert(!NIL_P(_slicedDataType));
+ }
+ if(_sliceInfoType == Qnil)
+ {
+ _sliceInfoType = callRuby(rb_path2class, "Ice::SliceInfo");
+ assert(!NIL_P(_sliceInfoType));
+ }
+
+ volatile VALUE sd = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), _slicedDataType);
+
+ Ice::Int sz = slicedData->slices.size();
+ volatile VALUE slices = createArray(sz);
+
+ callRuby(rb_iv_set, sd, "@slices", slices);
+
+ //
+ // Translate each SliceInfo object into its Ruby equivalent.
+ //
+ int i = 0;
+ for(vector<Ice::SliceInfoPtr>::const_iterator p = slicedData->slices.begin(); p != slicedData->slices.end(); ++p)
+ {
+ volatile VALUE slice = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), _sliceInfoType);
+
+ RARRAY_PTR(slices)[i++] = slice;
+
+ //
+ // typeId
+ //
+ volatile VALUE typeId = createString((*p)->typeId);
+ callRuby(rb_iv_set, slice, "@typeId", typeId);
+
+ //
+ // compactId
+ //
+ volatile VALUE compactId = INT2FIX((*p)->compactId);
+ callRuby(rb_iv_set, slice, "@compactId", compactId);
+
+ //
+ // bytes
+ //
+ volatile VALUE bytes = callRuby(rb_str_new, reinterpret_cast<const char*>(&(*p)->bytes[0]), (*p)->bytes.size());
+ callRuby(rb_iv_set, slice, "@bytes", bytes);
+
+ //
+ // objects
+ //
+ volatile VALUE objects = createArray((*p)->objects.size());
+ callRuby(rb_iv_set, slice, "@objects", objects);
+
+ int j = 0;
+ for(vector<Ice::ObjectPtr>::iterator q = (*p)->objects.begin(); q != (*p)->objects.end(); ++q)
+ {
+ //
+ // Each element in the objects list is an instance of ObjectReader that wraps a Ruby object.
+ //
+ assert(*q);
+ ObjectReaderPtr r = ObjectReaderPtr::dynamicCast(*q);
+ assert(r);
+ VALUE o = r->getObject();
+ assert(o != Qnil); // Should be non-nil.
+ RARRAY_PTR(objects)[j++] = o;
+ }
+
+ //
+ // hasOptionalMembers
+ //
+ callRuby(rb_iv_set, slice, "@hasOptionalMembers", (*p)->hasOptionalMembers ? Qtrue : Qfalse);
+
+ //
+ // isLastSlice
+ //
+ callRuby(rb_iv_set, slice, "@isLastSlice", (*p)->isLastSlice ? Qtrue : Qfalse);
+ }
+
+ callRuby(rb_iv_set, obj, "@_ice_slicedData", sd);
+}
+
+//
+// Instances of preserved class and exception types may have a data member
+// named _ice_slicedData which is an instance of the Ruby class Ice::SlicedData.
+//
+Ice::SlicedDataPtr
+IceRuby::SlicedDataUtil::getMember(VALUE obj, ObjectMap* objectMap)
+{
+ Ice::SlicedDataPtr slicedData;
+
+ if(callRuby(rb_ivar_defined, obj, rb_intern("@_ice_slicedData")) == Qtrue)
+ {
+ volatile VALUE sd = callRuby(rb_iv_get, obj, "@_ice_slicedData");
+
+ if(sd != Qnil)
+ {
+ //
+ // The "slices" member is an array of Ice::SliceInfo objects.
+ //
+ volatile VALUE sl = callRuby(rb_iv_get, sd, "@slices");
+ assert(TYPE(sl) == T_ARRAY);
+
+ Ice::SliceInfoSeq slices;
+
+ long sz = RARRAY_LEN(sl);
+ for(long i = 0; i < sz; ++i)
+ {
+ volatile VALUE s = RARRAY_PTR(sl)[i];
+
+ Ice::SliceInfoPtr info = new Ice::SliceInfo;
+
+ volatile VALUE typeId = callRuby(rb_iv_get, s, "@typeId");
+ info->typeId = getString(typeId);
+
+ volatile VALUE compactId = callRuby(rb_iv_get, s, "@compactId");
+ info->compactId = static_cast<Ice::Int>(getInteger(compactId));
+
+ volatile VALUE bytes = callRuby(rb_iv_get, s, "@bytes");
+ assert(TYPE(bytes) == T_STRING);
+ const char* str = RSTRING_PTR(bytes);
+ const long len = RSTRING_LEN(bytes);
+ if(str != 0 && len != 0)
+ {
+ vector<Ice::Byte> vtmp(reinterpret_cast<const Ice::Byte*>(str),
+ reinterpret_cast<const Ice::Byte*>(str + len));
+ info->bytes.swap(vtmp);
+ }
+
+ volatile VALUE objects = callRuby(rb_iv_get, s, "@objects");
+ assert(TYPE(objects) == T_ARRAY);
+ long osz = RARRAY_LEN(objects);
+ for(long j = 0; j < osz; ++j)
+ {
+ VALUE o = RARRAY_PTR(objects)[j];
+
+ Ice::ObjectPtr writer;
+
+ ObjectMap::iterator i = objectMap->find(o);
+ if(i == objectMap->end())
+ {
+ writer = new ObjectWriter(o, objectMap);
+ objectMap->insert(ObjectMap::value_type(o, writer));
+ }
+ else
+ {
+ writer = i->second;
+ }
+
+ info->objects.push_back(writer);
+ }
+
+ volatile VALUE hasOptionalMembers = callRuby(rb_iv_get, s, "@hasOptionalMembers");
+ info->hasOptionalMembers = hasOptionalMembers == Qtrue;
+
+ volatile VALUE isLastSlice = callRuby(rb_iv_get, s, "@isLastSlice");
+ info->isLastSlice = isLastSlice == Qtrue;
+
+ slices.push_back(info);
+ }
+
+ slicedData = new Ice::SlicedData(slices);
+ }
+ }
+
+ return slicedData;
+}
+
+//
+// UnmarshalCallback implementation.
+//
+IceRuby::UnmarshalCallback::~UnmarshalCallback()
+{
+}
+
+//
+// TypeInfo implementation.
+//
+IceRuby::TypeInfo::TypeInfo()
+{
+}
+
+bool
+IceRuby::TypeInfo::usesClasses() const
+{
+ return false;
+}
+
+void
+IceRuby::TypeInfo::unmarshaled(VALUE, VALUE, void*)
+{
+ assert(false);
+}
+
+void
+IceRuby::TypeInfo::destroy()
+{
+}
+
+//
+// PrimitiveInfo implementation.
+//
+IceRuby::PrimitiveInfo::PrimitiveInfo()
+{
+}
+
+IceRuby::PrimitiveInfo::PrimitiveInfo(Kind k) : kind(k)
+{
+}
+
+string
+IceRuby::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
+IceRuby::PrimitiveInfo::validate(VALUE)
+{
+ //
+ // Ruby supports type coercion, such that it's technically possible for any
+ // value to be coerced to a primitive type. It would be expensive to perform
+ // this coercion twice, once to validate and again to marshal, so we skip
+ // the validation here.
+ //
+ return true;
+}
+
+bool
+IceRuby::PrimitiveInfo::variableLength() const
+{
+ return kind == KindString;
+}
+
+int
+IceRuby::PrimitiveInfo::wireSize() const
+{
+ switch(kind)
+ {
+ case KindBool:
+ case KindByte:
+ return 1;
+ case KindShort:
+ return 2;
+ case KindInt:
+ return 4;
+ case KindLong:
+ return 8;
+ case KindFloat:
+ return 4;
+ case KindDouble:
+ return 8;
+ case KindString:
+ return 1;
+ }
+ assert(false);
+ return 0;
+}
+
+Ice::OptionalFormat
+IceRuby::PrimitiveInfo::optionalFormat() const
+{
+ switch(kind)
+ {
+ case KindBool:
+ case KindByte:
+ return Ice::OptionalFormatF1;
+ case KindShort:
+ return Ice::OptionalFormatF2;
+ case KindInt:
+ return Ice::OptionalFormatF4;
+ case KindLong:
+ return Ice::OptionalFormatF8;
+ case KindFloat:
+ return Ice::OptionalFormatF4;
+ case KindDouble:
+ return Ice::OptionalFormatF8;
+ case KindString:
+ return Ice::OptionalFormatVSize;
+ }
+
+ assert(false);
+ return Ice::OptionalFormatF1;
+}
+
+void
+IceRuby::PrimitiveInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*, bool)
+{
+ switch(kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ os->write(static_cast<bool>(RTEST(p)));
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ long i = getInteger(p);
+ if(i >= 0 && i <= 255)
+ {
+ os->write(static_cast<Ice::Byte>(i));
+ break;
+ }
+ throw RubyException(rb_eTypeError, "value is out of range for a byte");
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ long i = getInteger(p);
+ if(i >= SHRT_MIN && i <= SHRT_MAX)
+ {
+ os->write(static_cast<Ice::Short>(i));
+ break;
+ }
+ throw RubyException(rb_eTypeError, "value is out of range for a short");
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ long i = getInteger(p);
+ if(i >= INT_MIN && i <= INT_MAX)
+ {
+ os->write(static_cast<Ice::Int>(i));
+ break;
+ }
+ throw RubyException(rb_eTypeError, "value is out of range for an int");
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ os->write(getLong(p));
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ volatile VALUE val = callRuby(rb_Float, p);
+ if(NIL_P(val))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to a float");
+ }
+ assert(TYPE(val) == T_FLOAT);
+ double d = static_cast<double>(RFLOAT_VALUE(val));
+ if(d > numeric_limits<float>::max() || d < -numeric_limits<float>::max())
+ {
+ throw RubyException(rb_eTypeError, "value is out of range for a float");
+ }
+ os->write(static_cast<float>(d));
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ volatile VALUE val = callRuby(rb_Float, p);
+ if(NIL_P(val))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to a double");
+ }
+ assert(TYPE(val) == T_FLOAT);
+ os->write(static_cast<double>(RFLOAT_VALUE(val)));
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ string val = getString(p);
+ os->write(val);
+ break;
+ }
+ }
+}
+
+void
+IceRuby::PrimitiveInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+ void* closure, bool)
+{
+ volatile VALUE val = Qnil;
+ switch(kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ bool b;
+ is->read(b);
+ val = b ? Qtrue : Qfalse;
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ Ice::Byte b;
+ is->read(b);
+ val = callRuby(rb_int2inum, b);
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ Ice::Short sh;
+ is->read(sh);
+ val = callRuby(rb_int2inum, sh);
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ Ice::Int i;
+ is->read(i);
+ val = callRuby(rb_int2inum, i);
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ Ice::Long l;
+ is->read(l);
+ val = callRuby(rb_ll2inum, l);
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ Ice::Float f;
+ is->read(f);
+ val = callRuby(rb_float_new, f);
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ Ice::Double d;
+ is->read(d);
+ val = callRuby(rb_float_new, d);
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ string str;
+ is->read(str);
+ val = createString(str);
+ break;
+ }
+ }
+ cb->unmarshaled(val, target, closure);
+}
+
+void
+IceRuby::PrimitiveInfo::print(VALUE value, IceUtilInternal::Output& out, PrintObjectHistory*)
+{
+ switch(kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ out << (RTEST(value) ? "true" : "false");
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ case PrimitiveInfo::KindShort:
+ case PrimitiveInfo::KindInt:
+ {
+ out << getInteger(value);
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ Ice::Long l = getLong(value);
+ out << IceUtilInternal::int64ToString(l);
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ case PrimitiveInfo::KindDouble:
+ {
+ double d = toDouble(value);
+ out << d;
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ out << "'" << getString(value) << "'";
+ break;
+ }
+ }
+}
+
+double
+IceRuby::PrimitiveInfo::toDouble(VALUE v)
+{
+ volatile VALUE val = callRuby(rb_Float, v);
+ if(NIL_P(val))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to a double");
+ }
+ assert(TYPE(val) == T_FLOAT);
+ return RFLOAT_VALUE(val);
+}
+
+//
+// EnumInfo implementation.
+//
+
+namespace
+{
+struct EnumDefinitionIterator : public IceRuby::HashIterator
+{
+ EnumDefinitionIterator() :
+ maxValue(0)
+ {
+ }
+
+ virtual void element(VALUE key, VALUE value)
+ {
+ const Ice::Int v = static_cast<Ice::Int>(getInteger(key));
+ assert(enumerators.find(v) == enumerators.end());
+ enumerators[v] = value;
+
+ if(v > maxValue)
+ {
+ maxValue = v;
+ }
+ }
+
+ Ice::Int maxValue;
+ IceRuby::EnumeratorMap enumerators;
+};
+}
+
+IceRuby::EnumInfo::EnumInfo(VALUE ident, VALUE t, VALUE e) :
+ rubyClass(t), maxValue(0)
+{
+ const_cast<string&>(id) = getString(ident);
+
+ EnumDefinitionIterator iter;
+ hashIterate(e, iter);
+
+ const_cast<Ice::Int&>(maxValue) = iter.maxValue;
+ const_cast<EnumeratorMap&>(enumerators) = iter.enumerators;
+}
+
+string
+IceRuby::EnumInfo::getId() const
+{
+ return id;
+}
+
+bool
+IceRuby::EnumInfo::validate(VALUE val)
+{
+ return callRuby(rb_obj_is_instance_of, val, rubyClass) == Qtrue;
+}
+
+bool
+IceRuby::EnumInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IceRuby::EnumInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IceRuby::EnumInfo::optionalFormat() const
+{
+ return Ice::OptionalFormatSize;
+}
+
+void
+IceRuby::EnumInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*, bool)
+{
+ assert(callRuby(rb_obj_is_instance_of, p, rubyClass) == Qtrue); // validate() should have caught this.
+
+ //
+ // Validate value.
+ //
+ volatile VALUE val = callRuby(rb_iv_get, p, "@value");
+ const Ice::Int ival = static_cast<Ice::Int>(getInteger(val));
+ if(enumerators.find(ival) == enumerators.end())
+ {
+ throw RubyException(rb_eRangeError, "invalid enumerator %ld for enum %s", ival, id.c_str());
+ }
+
+ os->writeEnum(ival, maxValue);
+}
+
+void
+IceRuby::EnumInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target, void* closure,
+ bool)
+{
+ Ice::Int val = is->readEnum(maxValue);
+
+ EnumeratorMap::const_iterator p = enumerators.find(val);
+ if(p == enumerators.end())
+ {
+ ostringstream ostr;
+ ostr << "invalid enumerator " << val << " for enum " << id;
+ throw Ice::MarshalException(__FILE__, __LINE__, ostr.str());
+ }
+
+ cb->unmarshaled(p->second, target, closure);
+}
+
+void
+IceRuby::EnumInfo::print(VALUE value, IceUtilInternal::Output& out, PrintObjectHistory*)
+{
+ if(!validate(value))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+ volatile VALUE str = callRuby(rb_funcall, value, rb_intern("inspect"), 0);
+ out << getString(str);
+}
+
+//
+// DataMember implementation.
+//
+void
+IceRuby::DataMember::unmarshaled(VALUE val, VALUE target, void*)
+{
+ callRuby(rb_ivar_set, target, rubyID, val);
+}
+
+static void
+convertDataMembers(VALUE members, DataMemberList& reqMembers, DataMemberList& optMembers, bool allowOptional)
+{
+ list<DataMemberPtr> optList;
+
+ volatile VALUE arr = callRuby(rb_check_array_type, members);
+ assert(!NIL_P(arr));
+ for(long i = 0; i < RARRAY_LEN(arr); ++i)
+ {
+ volatile VALUE m = callRuby(rb_check_array_type, RARRAY_PTR(arr)[i]);
+ assert(!NIL_P(m));
+ assert(RARRAY_LEN(m) == allowOptional ? 4 : 2);
+
+ DataMemberPtr member = new DataMember;
+
+ member->name = getString(RARRAY_PTR(m)[0]);
+ member->type = getType(RARRAY_PTR(m)[1]);
+ string s = "@" + member->name;
+ member->rubyID = rb_intern(s.c_str());
+
+ if(allowOptional)
+ {
+ member->optional = RTEST(RARRAY_PTR(m)[2]);
+ member->tag = static_cast<int>(getInteger(RARRAY_PTR(m)[3]));
+ }
+ else
+ {
+ member->optional = false;
+ member->tag = 0;
+ }
+
+ if(member->optional)
+ {
+ optList.push_back(member);
+ }
+ else
+ {
+ reqMembers.push_back(member);
+ }
+ }
+
+ if(allowOptional)
+ {
+ class SortFn
+ {
+ public:
+ static bool compare(const DataMemberPtr& lhs, const DataMemberPtr& rhs)
+ {
+ return lhs->tag < rhs->tag;
+ }
+ };
+
+ optList.sort(SortFn::compare);
+ copy(optList.begin(), optList.end(), back_inserter(optMembers));
+ }
+}
+
+//
+// StructInfo implementation.
+//
+IceRuby::StructInfo::StructInfo(VALUE ident, VALUE t, VALUE m) :
+ rubyClass(t), _nullMarshalValue(Qnil)
+{
+ const_cast<string&>(id) = getString(ident);
+
+ DataMemberList opt;
+ convertDataMembers(m, const_cast<DataMemberList&>(members), opt, false);
+ assert(opt.empty());
+
+ _variableLength = false;
+ _wireSize = 0;
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ if(!_variableLength && (*p)->type->variableLength())
+ {
+ _variableLength = true;
+ }
+ _wireSize += (*p)->type->wireSize();
+ }
+}
+
+string
+IceRuby::StructInfo::getId() const
+{
+ return id;
+}
+
+bool
+IceRuby::StructInfo::validate(VALUE val)
+{
+ return NIL_P(val) || callRuby(rb_obj_is_kind_of, val, rubyClass) == Qtrue;
+}
+
+bool
+IceRuby::StructInfo::variableLength() const
+{
+ return _variableLength;
+}
+
+int
+IceRuby::StructInfo::wireSize() const
+{
+ return _wireSize;
+}
+
+Ice::OptionalFormat
+IceRuby::StructInfo::optionalFormat() const
+{
+ return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
+}
+
+bool
+IceRuby::StructInfo::usesClasses() const
+{
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ if((*p)->type->usesClasses())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+IceRuby::StructInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
+{
+ assert(NIL_P(p) || callRuby(rb_obj_is_kind_of, p, rubyClass) == Qtrue); // validate() should have caught this.
+
+ if(NIL_P(p))
+ {
+ if(NIL_P(_nullMarshalValue))
+ {
+ _nullMarshalValue = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), rubyClass);
+ rb_gc_register_address(&_nullMarshalValue); // Prevent garbage collection
+ }
+ p = _nullMarshalValue;
+ }
+
+ Ice::OutputStream::size_type sizePos = -1;
+ if(optional)
+ {
+ if(_variableLength)
+ {
+ sizePos = os->startSize();
+ }
+ else
+ {
+ os->writeSize(_wireSize);
+ }
+ }
+
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ volatile VALUE val = callRuby(rb_ivar_get, p, member->rubyID);
+ if(!member->type->validate(val))
+ {
+ throw RubyException(rb_eTypeError, "invalid value for %s member `%s'", const_cast<char*>(id.c_str()),
+ member->name.c_str());
+ }
+ member->type->marshal(val, os, objectMap, false);
+ }
+
+ if(optional && _variableLength)
+ {
+ os->endSize(sizePos);
+ }
+}
+
+void
+IceRuby::StructInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+ void* closure, bool optional)
+{
+ volatile VALUE obj = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), rubyClass);
+
+ if(optional)
+ {
+ if(_variableLength)
+ {
+ is->skip(4);
+ }
+ else
+ {
+ is->skipSize();
+ }
+ }
+
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ member->type->unmarshal(is, member, obj, 0, false);
+ }
+
+ cb->unmarshaled(obj, target, closure);
+}
+
+void
+IceRuby::StructInfo::print(VALUE value, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(!validate(value))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(NIL_P(value))
+ {
+ out << "<nil>";
+ }
+ else
+ {
+ out.sb();
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ out << nl << member->name << " = ";
+ if(callRuby(rb_ivar_defined, value, member->rubyID) == Qfalse)
+ {
+ out << "<not defined>";
+ }
+ else
+ {
+ volatile VALUE val = callRuby(rb_ivar_get, value, member->rubyID);
+ member->type->print(val, out, history);
+ }
+ }
+ out.eb();
+ }
+}
+
+void
+IceRuby::StructInfo::destroy()
+{
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ (*p)->type->destroy();
+ }
+ const_cast<DataMemberList&>(members).clear();
+ if(!NIL_P(_nullMarshalValue))
+ {
+ rb_gc_unregister_address(&_nullMarshalValue); // Prevent garbage collection
+ _nullMarshalValue = Qnil;
+ }
+}
+
+//
+// SequenceInfo implementation.
+//
+IceRuby::SequenceInfo::SequenceInfo(VALUE ident, VALUE t)
+{
+ const_cast<string&>(id) = getString(ident);
+ const_cast<TypeInfoPtr&>(elementType) = getType(t);
+}
+
+string
+IceRuby::SequenceInfo::getId() const
+{
+ return id;
+}
+
+bool
+IceRuby::SequenceInfo::validate(VALUE val)
+{
+ //
+ // Accept nil, an array, a string (for sequence<byte>), or any object that responds to to_ary.
+ //
+ if(NIL_P(val) || TYPE(val) == T_ARRAY)
+ {
+ return true;
+ }
+ if(TYPE(val) == T_STRING)
+ {
+ PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
+ if(pi && pi->kind == PrimitiveInfo::KindByte)
+ {
+ return true;
+ }
+ }
+ ID id = rb_intern("to_ary");
+ return callRuby(rb_respond_to, val, id) != 0;
+}
+
+bool
+IceRuby::SequenceInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IceRuby::SequenceInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IceRuby::SequenceInfo::optionalFormat() const
+{
+ return elementType->variableLength() ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
+}
+
+bool
+IceRuby::SequenceInfo::usesClasses() const
+{
+ return elementType->usesClasses();
+}
+
+void
+IceRuby::SequenceInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
+{
+ PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
+
+ volatile VALUE arr = Qnil;
+
+ Ice::OutputStream::size_type sizePos = -1;
+ if(optional)
+ {
+ if(elementType->variableLength())
+ {
+ sizePos = os->startSize();
+ }
+ else if(elementType->wireSize() > 1)
+ {
+ //
+ // Determine the sequence size.
+ //
+ int sz = 0;
+ if(!NIL_P(p))
+ {
+ if(TYPE(p) == T_ARRAY)
+ {
+ sz = static_cast<int>(RARRAY_LEN(p));
+ }
+ else
+ {
+ arr = callRuby(rb_Array, p);
+ if(NIL_P(arr))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to an array");
+ }
+ sz = static_cast<int>(RARRAY_LEN(arr));
+ }
+ }
+ os->writeSize(sz == 0 ? 1 : sz * elementType->wireSize() + (sz > 254 ? 5 : 1));
+ }
+ }
+
+ if(NIL_P(p))
+ {
+ os->writeSize(0);
+ }
+ else if(pi)
+ {
+ marshalPrimitiveSequence(pi, p, os);
+ }
+ else
+ {
+ if(NIL_P(arr))
+ {
+ arr = callRuby(rb_Array, p);
+ if(NIL_P(arr))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to an array");
+ }
+ }
+
+ long sz = RARRAY_LEN(arr);
+ os->writeSize(static_cast<Ice::Int>(sz));
+ for(long i = 0; i < sz; ++i)
+ {
+ if(!elementType->validate(RARRAY_PTR(arr)[i]))
+ {
+ throw RubyException(rb_eTypeError, "invalid value for element %ld of `%s'", i,
+ const_cast<char*>(id.c_str()));
+ }
+ elementType->marshal(RARRAY_PTR(arr)[i], os, objectMap, false);
+ }
+ }
+
+ if(optional && elementType->variableLength())
+ {
+ os->endSize(sizePos);
+ }
+}
+
+void
+IceRuby::SequenceInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+ void* closure, bool optional)
+{
+ if(optional)
+ {
+ if(elementType->variableLength())
+ {
+ is->skip(4);
+ }
+ else if(elementType->wireSize() > 1)
+ {
+ is->skipSize();
+ }
+ }
+
+ PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
+ if(pi)
+ {
+ unmarshalPrimitiveSequence(pi, is, cb, target, closure);
+ return;
+ }
+
+ Ice::Int sz = is->readSize();
+ volatile VALUE arr = createArray(sz);
+
+ for(Ice::Int i = 0; i < sz; ++i)
+ {
+ void* cl = reinterpret_cast<void*>(i);
+ elementType->unmarshal(is, this, arr, cl, false);
+ }
+
+ cb->unmarshaled(arr, target, closure);
+}
+
+void
+IceRuby::SequenceInfo::unmarshaled(VALUE val, VALUE target, void* closure)
+{
+#ifdef ICE_64
+ long i = static_cast<long>(reinterpret_cast<long long>(closure));
+#else
+ long i = reinterpret_cast<long>(closure);
+#endif
+ RARRAY_PTR(target)[i] = val;
+}
+
+void
+IceRuby::SequenceInfo::print(VALUE value, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(!validate(value))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(NIL_P(value))
+ {
+ out << "{}";
+ }
+ else
+ {
+ if(TYPE(value) == T_STRING)
+ {
+ PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
+ if(pi && pi->kind == PrimitiveInfo::KindByte)
+ {
+ out << "'" << escapeString(getString(value)) << "'";
+ return;
+ }
+ }
+
+ volatile VALUE arr = callRuby(rb_Array, value);
+ if(NIL_P(arr))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to an array");
+ }
+
+ long sz = RARRAY_LEN(arr);
+
+ out.sb();
+ for(long i = 0; i < sz; ++i)
+ {
+ out << nl << '[' << i << "] = ";
+ elementType->print(RARRAY_PTR(arr)[i], out, history);
+ }
+ out.eb();
+ }
+}
+
+void
+IceRuby::SequenceInfo::destroy()
+{
+ if(elementType)
+ {
+ elementType->destroy();
+ const_cast<TypeInfoPtr&>(elementType) = 0;
+ }
+}
+
+void
+IceRuby::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, VALUE p, const Ice::OutputStreamPtr& os)
+{
+ volatile VALUE arr = Qnil;
+ volatile VALUE str = Qnil;
+
+ //
+ // Accept a string or an array for sequence<byte>.
+ //
+ if(pi->kind == PrimitiveInfo::KindByte)
+ {
+ if(TYPE(p) == T_STRING)
+ {
+ str = p;
+ }
+ else
+ {
+ arr = callRuby(rb_Array, p);
+ if(NIL_P(arr))
+ {
+ throw RubyException(rb_eTypeError, "argument is not a string or an array");
+ }
+ }
+ }
+ else
+ {
+ arr = callRuby(rb_Array, p);
+ if(NIL_P(arr))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to an array");
+ }
+ }
+
+ switch(pi->kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ long sz = RARRAY_LEN(arr);
+ Ice::BoolSeq seq(sz);
+ for(long i = 0; i < sz; ++i)
+ {
+ seq[i] = RTEST(RARRAY_PTR(arr)[i]);
+ }
+ os->write(seq);
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ if(!NIL_P(str))
+ {
+ const char* s = RSTRING_PTR(str);
+ const long len = RSTRING_LEN(str);
+ if(s == 0 || len == 0)
+ {
+ os->write(Ice::Int(0));
+ }
+ else
+ {
+ os->write(reinterpret_cast<const Ice::Byte*>(s), reinterpret_cast<const Ice::Byte*>(s + len));
+ }
+ }
+ else
+ {
+ long sz = RARRAY_LEN(arr);
+ Ice::ByteSeq seq(sz);
+ for(long i = 0; i < sz; ++i)
+ {
+ long val = getInteger(RARRAY_PTR(arr)[i]);
+ if(val < 0 || val > 255)
+ {
+ throw RubyException(rb_eTypeError, "invalid value for element %ld of sequence<byte>", i);
+ }
+ seq[i] = static_cast<Ice::Byte>(val);
+ }
+ os->write(&seq[0], &seq[0] + seq.size());
+ }
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ long sz = RARRAY_LEN(arr);
+ Ice::ShortSeq seq(sz);
+ for(long i = 0; i < sz; ++i)
+ {
+ long val = getInteger(RARRAY_PTR(arr)[i]);
+ if(val < SHRT_MIN || val > SHRT_MAX)
+ {
+ throw RubyException(rb_eTypeError, "invalid value for element %ld of sequence<short>", i);
+ }
+ seq[i] = static_cast<Ice::Short>(val);
+ }
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ long sz = RARRAY_LEN(arr);
+ Ice::IntSeq seq(sz);
+ for(long i = 0; i < sz; ++i)
+ {
+ long val = getInteger(RARRAY_PTR(arr)[i]);
+ if(val < INT_MIN || val > INT_MAX)
+ {
+ throw RubyException(rb_eTypeError, "invalid value for element %ld of sequence<int>", i);
+ }
+ seq[i] = static_cast<Ice::Int>(val);
+ }
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ long sz = RARRAY_LEN(arr);
+ Ice::LongSeq seq(sz);
+ for(long i = 0; i < sz; ++i)
+ {
+ seq[i] = getLong(RARRAY_PTR(arr)[i]);
+ }
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ long sz = RARRAY_LEN(arr);
+ Ice::FloatSeq seq(sz);
+ for(long i = 0; i < sz; ++i)
+ {
+ volatile VALUE v = callRuby(rb_Float, RARRAY_PTR(arr)[i]);
+ if(NIL_P(v))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert array element %ld to a float", i);
+ }
+ assert(TYPE(v) == T_FLOAT);
+ seq[i] = static_cast<Ice::Float>(RFLOAT_VALUE(v));
+ }
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ long sz = RARRAY_LEN(arr);
+ Ice::DoubleSeq seq(sz);
+ for(long i = 0; i < sz; ++i)
+ {
+ volatile VALUE v = callRuby(rb_Float, RARRAY_PTR(arr)[i]);
+ if(NIL_P(v))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert array element %ld to a double", i);
+ }
+ assert(TYPE(v) == T_FLOAT);
+ seq[i] = RFLOAT_VALUE(v);
+ }
+ os->write(&seq[0], &seq[0] + seq.size());
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ long sz = RARRAY_LEN(arr);
+ Ice::StringSeq seq(sz);
+ for(long i = 0; i < sz; ++i)
+ {
+ seq[i] = getString(RARRAY_PTR(arr)[i]);
+ }
+ os->write(seq, true);
+ break;
+ }
+ }
+}
+
+void
+IceRuby::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, const Ice::InputStreamPtr& is,
+ const UnmarshalCallbackPtr& cb, VALUE target, void* closure)
+{
+ volatile VALUE result = Qnil;
+
+ switch(pi->kind)
+ {
+ case PrimitiveInfo::KindBool:
+ {
+ pair<const bool*, const bool*> p;
+ IceUtil::ScopedArray<bool> sa;
+ is->read(p, sa);
+ long sz = static_cast<long>(p.second - p.first);
+ result = createArray(sz);
+
+ if(sz > 0)
+ {
+ for(long i = 0; i < sz; ++i)
+ {
+ RARRAY_PTR(result)[i] = p.first[i] ? Qtrue : Qfalse;
+ }
+ }
+ break;
+ }
+ case PrimitiveInfo::KindByte:
+ {
+ pair<const Ice::Byte*, const Ice::Byte*> p;
+ is->read(p);
+ result = callRuby(rb_str_new, reinterpret_cast<const char*>(p.first), static_cast<long>(p.second - p.first));
+ break;
+ }
+ case PrimitiveInfo::KindShort:
+ {
+ pair<const Ice::Short*, const Ice::Short*> p;
+ IceUtil::ScopedArray<Ice::Short> sa;
+ is->read(p, sa);
+ long sz = static_cast<long>(p.second - p.first);
+ result = createArray(sz);
+
+ if(sz > 0)
+ {
+ for(long i = 0; i < sz; ++i)
+ {
+ RARRAY_PTR(result)[i] = INT2FIX(p.first[i]);
+ }
+ }
+ break;
+ }
+ case PrimitiveInfo::KindInt:
+ {
+ pair<const Ice::Int*, const Ice::Int*> p;
+ IceUtil::ScopedArray<Ice::Int> sa;
+ is->read(p, sa);
+ long sz = static_cast<long>(p.second - p.first);
+ result = createArray(sz);
+
+ if(sz > 0)
+ {
+ for(long i = 0; i < sz; ++i)
+ {
+ RARRAY_PTR(result)[i] = INT2FIX(p.first[i]);
+ }
+ }
+ break;
+ }
+ case PrimitiveInfo::KindLong:
+ {
+ pair<const Ice::Long*, const Ice::Long*> p;
+ IceUtil::ScopedArray<Ice::Long> sa;
+ is->read(p, sa);
+ long sz = static_cast<long>(p.second - p.first);
+ result = createArray(sz);
+
+ if(sz > 0)
+ {
+ for(long i = 0; i < sz; ++i)
+ {
+ RARRAY_PTR(result)[i] = callRuby(rb_ll2inum, p.first[i]);
+ }
+ }
+ break;
+ }
+ case PrimitiveInfo::KindFloat:
+ {
+ pair<const Ice::Float*, const Ice::Float*> p;
+ IceUtil::ScopedArray<Ice::Float> sa;
+ is->read(p, sa);
+ long sz = static_cast<long>(p.second - p.first);
+ result = createArray(sz);
+
+ if(sz > 0)
+ {
+ for(long i = 0; i < sz; ++i)
+ {
+ RARRAY_PTR(result)[i] = callRuby(rb_float_new, p.first[i]);
+ }
+ }
+ break;
+ }
+ case PrimitiveInfo::KindDouble:
+ {
+ pair<const Ice::Double*, const Ice::Double*> p;
+ IceUtil::ScopedArray<Ice::Double> sa;
+ is->read(p, sa);
+ long sz = static_cast<long>(p.second - p.first);
+ result = createArray(sz);
+
+ if(sz > 0)
+ {
+ for(long i = 0; i < sz; ++i)
+ {
+ RARRAY_PTR(result)[i] = callRuby(rb_float_new, p.first[i]);
+ }
+ }
+ break;
+ }
+ case PrimitiveInfo::KindString:
+ {
+ Ice::StringSeq seq;
+ is->read(seq, true);
+ long sz = static_cast<long>(seq.size());
+ result = createArray(sz);
+
+ if(sz > 0)
+ {
+ for(long i = 0; i < sz; ++i)
+ {
+ RARRAY_PTR(result)[i] = createString(seq[i]);
+ }
+ }
+ break;
+ }
+ }
+ cb->unmarshaled(result, target, closure);
+}
+
+//
+// DictionaryInfo implementation.
+//
+IceRuby::DictionaryInfo::DictionaryInfo(VALUE ident, VALUE kt, VALUE vt)
+{
+ const_cast<string&>(id) = getString(ident);
+ const_cast<TypeInfoPtr&>(keyType) = getType(kt);
+ const_cast<TypeInfoPtr&>(valueType) = getType(vt);
+
+ _variableLength = keyType->variableLength() || valueType->variableLength();
+ _wireSize = keyType->wireSize() + valueType->wireSize();
+}
+
+string
+IceRuby::DictionaryInfo::getId() const
+{
+ return id;
+}
+
+bool
+IceRuby::DictionaryInfo::validate(VALUE val)
+{
+ //
+ // Accept nil, a hash, or any object that responds to to_hash.
+ //
+ if(NIL_P(val) || TYPE(val) == T_HASH)
+ {
+ return true;
+ }
+ ID id = rb_intern("to_hash");
+ return callRuby(rb_respond_to, val, id) != 0;
+}
+
+bool
+IceRuby::DictionaryInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IceRuby::DictionaryInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IceRuby::DictionaryInfo::optionalFormat() const
+{
+ return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
+}
+
+bool
+IceRuby::DictionaryInfo::usesClasses() const
+{
+ return valueType->usesClasses();
+}
+
+namespace
+{
+struct DictionaryMarshalIterator : public IceRuby::HashIterator
+{
+ DictionaryMarshalIterator(const IceRuby::DictionaryInfoPtr& d, const Ice::OutputStreamPtr o, IceRuby::ObjectMap* m)
+ : dict(d), os(o), objectMap(m)
+ {
+ }
+
+ virtual void element(VALUE key, VALUE value)
+ {
+ dict->marshalElement(key, value, os, objectMap);
+ }
+
+ IceRuby::DictionaryInfoPtr dict;
+ Ice::OutputStreamPtr os;
+ IceRuby::ObjectMap* objectMap;
+};
+}
+
+void
+IceRuby::DictionaryInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
+{
+ volatile VALUE hash = Qnil;
+
+ if(!NIL_P(p))
+ {
+ hash = callRuby(rb_convert_type, p, T_HASH, "Hash", "to_hash");
+ if(NIL_P(hash))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to a hash");
+ }
+ }
+
+ int sz = 0;
+ if(!NIL_P(hash))
+ {
+ sz = RHASH_SIZE(hash);
+ }
+
+ Ice::OutputStream::size_type sizePos = 0;
+ if(optional)
+ {
+ if(_variableLength)
+ {
+ sizePos = os->startSize();
+ }
+ else
+ {
+ os->writeSize(sz == 0 ? 1 : sz * _wireSize + (sz > 254 ? 5 : 1));
+ }
+ }
+
+ if(NIL_P(hash))
+ {
+ os->writeSize(0);
+ }
+ else
+ {
+ os->writeSize(sz);
+ if(sz > 0)
+ {
+ DictionaryMarshalIterator iter(this, os, objectMap);
+ hashIterate(hash, iter);
+ }
+ }
+
+ if(optional && _variableLength)
+ {
+ os->endSize(sizePos);
+ }
+}
+
+void
+IceRuby::DictionaryInfo::marshalElement(VALUE key, VALUE value, const Ice::OutputStreamPtr& os, ObjectMap* objectMap)
+{
+ if(!keyType->validate(key))
+ {
+ throw RubyException(rb_eTypeError, "invalid key in `%s' element", const_cast<char*>(id.c_str()));
+ }
+
+ if(!valueType->validate(value))
+ {
+ throw RubyException(rb_eTypeError, "invalid value in `%s' element", const_cast<char*>(id.c_str()));
+ }
+
+ keyType->marshal(key, os, objectMap, false);
+ valueType->marshal(value, os, objectMap, false);
+}
+
+void
+IceRuby::DictionaryInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+ void* closure, bool optional)
+{
+ if(optional)
+ {
+ if(_variableLength)
+ {
+ is->skip(4);
+ }
+ else
+ {
+ is->skipSize();
+ }
+ }
+
+ volatile VALUE hash = callRuby(rb_hash_new);
+
+ KeyCallbackPtr keyCB = new KeyCallback;
+ keyCB->key = Qnil;
+
+ 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, Qnil, 0, false);
+ assert(!NIL_P(keyCB->key));
+
+ //
+ // The callback will set the dictionary entry with the unmarshaled value,
+ // so we pass it the key.
+ //
+ void* cl = reinterpret_cast<void*>(keyCB->key);
+ valueType->unmarshal(is, this, hash, cl, false);
+ }
+
+ cb->unmarshaled(hash, target, closure);
+}
+
+void
+IceRuby::DictionaryInfo::unmarshaled(VALUE val, VALUE target, void* closure)
+{
+ volatile VALUE key = reinterpret_cast<VALUE>(closure);
+ callRuby(rb_hash_aset, target, key, val);
+}
+
+namespace
+{
+struct DictionaryPrintIterator : public IceRuby::HashIterator
+{
+ DictionaryPrintIterator(const DictionaryInfoPtr& d, IceUtilInternal::Output& o, PrintObjectHistory* h) :
+ dict(d), out(o), history(h)
+ {
+ }
+
+ virtual void element(VALUE key, VALUE value)
+ {
+ dict->printElement(key, value, out, history);
+ }
+
+ IceRuby::DictionaryInfoPtr dict;
+ IceUtilInternal::Output& out;
+ IceRuby::PrintObjectHistory* history;
+};
+}
+
+void
+IceRuby::DictionaryInfo::print(VALUE value, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(!validate(value))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(NIL_P(value))
+ {
+ out << "{}";
+ }
+ else
+ {
+ volatile VALUE hash = callRuby(rb_convert_type, value, T_HASH, "Hash", "to_hash");
+ if(NIL_P(hash))
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to a hash");
+ }
+
+ if(RHASH_SIZE(hash) == 0)
+ {
+ out << "{}";
+ return;
+ }
+
+ out.sb();
+ DictionaryPrintIterator iter(this, out, history);
+ hashIterate(hash, iter);
+ out.eb();
+ }
+}
+
+void
+IceRuby::DictionaryInfo::printElement(VALUE key, VALUE value, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ out << nl << "key = ";
+ keyType->print(key, out, history);
+ out << nl << "value = ";
+ valueType->print(value, out, history);
+}
+
+void
+IceRuby::DictionaryInfo::KeyCallback::unmarshaled(VALUE val, VALUE, void*)
+{
+ key = val;
+}
+
+void
+IceRuby::DictionaryInfo::destroy()
+{
+ if(keyType)
+ {
+ keyType->destroy();
+ const_cast<TypeInfoPtr&>(keyType) = 0;
+ }
+ if(valueType)
+ {
+ valueType->destroy();
+ const_cast<TypeInfoPtr&>(valueType) = 0;
+ }
+}
+
+//
+// ClassInfo implementation.
+//
+IceRuby::ClassInfo::ClassInfo(VALUE ident, bool loc) :
+ compactId(-1), isBase(false), isLocal(loc), isAbstract(false), preserve(false), rubyClass(Qnil), typeObj(Qnil),
+ defined(false)
+{
+ const_cast<string&>(id) = getString(ident);
+ if(isLocal)
+ {
+ const_cast<bool&>(isBase) = id == "::Ice::LocalObject";
+ }
+ else
+ {
+ const_cast<bool&>(isBase) = id == Ice::Object::ice_staticId();
+ }
+ const_cast<VALUE&>(typeObj) = createType(this);
+}
+
+void
+IceRuby::ClassInfo::define(VALUE t, VALUE compact, VALUE abstr, VALUE pres, VALUE b, VALUE i, VALUE m)
+{
+ if(!NIL_P(b))
+ {
+ const_cast<ClassInfoPtr&>(base) = ClassInfoPtr::dynamicCast(getType(b));
+ assert(base);
+ }
+
+ const_cast<Ice::Int&>(compactId) = static_cast<Ice::Int>(getInteger(compact));
+ const_cast<bool&>(isAbstract) = RTEST(abstr);
+ const_cast<bool&>(preserve) = RTEST(pres);
+
+ long n;
+ volatile VALUE arr;
+
+ arr = callRuby(rb_check_array_type, i);
+ assert(!NIL_P(arr));
+ for(n = 0; n < RARRAY_LEN(arr); ++n)
+ {
+ ClassInfoPtr iface = ClassInfoPtr::dynamicCast(getType(RARRAY_PTR(arr)[n]));
+ assert(iface);
+ const_cast<ClassInfoList&>(interfaces).push_back(iface);
+ }
+
+ convertDataMembers(m, const_cast<DataMemberList&>(members), const_cast<DataMemberList&>(optionalMembers), true);
+
+ const_cast<VALUE&>(rubyClass) = t;
+ const_cast<bool&>(defined) = true;
+}
+
+string
+IceRuby::ClassInfo::getId() const
+{
+ return id;
+}
+
+bool
+IceRuby::ClassInfo::validate(VALUE val)
+{
+ if(NIL_P(val))
+ {
+ return true;
+ }
+
+ //
+ // We consider an object to be an instance of this class if its class contains
+ // an ICE_TYPE constant that refers to this class, or a subclass of this class.
+ //
+ volatile VALUE cls = CLASS_OF(val);
+ volatile VALUE type = Qnil;
+ try
+ {
+ type = callRuby(rb_const_get, cls, rb_intern("ICE_TYPE"));
+ }
+ catch(const RubyException& ex)
+ {
+ if(callRuby(rb_obj_is_instance_of, ex.ex, rb_eNameError) == Qtrue)
+ {
+ //
+ // The ICE_TYPE constant will be missing from an instance of LocalObject
+ // if it does not implement a user-defined type. This means the user
+ // could potentially pass any kind of object; there isn't much we can do
+ // since LocalObject maps to the base object type.
+ //
+ return id == "::Ice::LocalObject";
+ }
+ else
+ {
+ throw;
+ }
+ }
+ assert(!NIL_P(type));
+ ClassInfoPtr info = ClassInfoPtr::dynamicCast(getType(type));
+ assert(info);
+ return info->isA(this);
+}
+
+bool
+IceRuby::ClassInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IceRuby::ClassInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IceRuby::ClassInfo::optionalFormat() const
+{
+ return Ice::OptionalFormatClass;
+}
+
+bool
+IceRuby::ClassInfo::usesClasses() const
+{
+ return true;
+}
+
+void
+IceRuby::ClassInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool)
+{
+ if(!defined)
+ {
+ throw RubyException(rb_eRuntimeError, "class %s is declared but not defined", id.c_str());
+ }
+
+ if(NIL_P(p))
+ {
+ os->writeObject(0);
+ return;
+ }
+
+ //
+ // Ice::ObjectWriter is a subclass of Ice::Object that wraps a Ruby object for marshaling.
+ // It is possible that this Ruby 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.
+ //
+ Ice::ObjectPtr writer;
+ assert(objectMap);
+ ObjectMap::iterator q = objectMap->find(p);
+ if(q == objectMap->end())
+ {
+ writer = new ObjectWriter(p, objectMap);
+ objectMap->insert(ObjectMap::value_type(p, writer));
+ }
+ else
+ {
+ writer = q->second;
+ }
+
+ //
+ // Give the writer to the stream. The stream will eventually call write() on it.
+ //
+ os->writeObject(writer);
+}
+
+void
+IceRuby::ClassInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+ void* closure, bool)
+{
+ if(!defined)
+ {
+ throw RubyException(rb_eRuntimeError, "class %s is declared but not defined", id.c_str());
+ }
+
+ is->readObject(new ReadObjectCallback(this, cb, target, closure));
+}
+
+void
+IceRuby::ClassInfo::print(VALUE value, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(!validate(value))
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ if(NIL_P(value))
+ {
+ out << "<nil>";
+ }
+ else
+ {
+ map<VALUE, int>::iterator q = history->objects.find(value);
+ if(q != history->objects.end())
+ {
+ out << "<object #" << q->second << ">";
+ }
+ else
+ {
+ volatile VALUE cls = CLASS_OF(value);
+ volatile VALUE type = Qnil;
+ ClassInfoPtr info;
+ try
+ {
+ type = callRuby(rb_const_get, cls, rb_intern("ICE_TYPE"));
+ info = ClassInfoPtr::dynamicCast(getType(type));
+ }
+ catch(const RubyException& ex)
+ {
+ if(callRuby(rb_obj_is_instance_of, ex.ex, rb_eNameError) == Qtrue)
+ {
+ //
+ // The ICE_TYPE constant will be missing from an instance of LocalObject
+ // if it does not implement a user-defined type. This means the user
+ // could potentially pass any kind of object; there isn't much we can do
+ // since LocalObject maps to the base object type.
+ //
+ if(id == "::Ice::LocalObject")
+ {
+ info = this;
+ }
+ else
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+ }
+ else
+ {
+ throw;
+ }
+ }
+ assert(info);
+ out << "object #" << history->index << " (" << info->id << ')';
+ history->objects.insert(map<VALUE, int>::value_type(value, history->index));
+ ++history->index;
+ out.sb();
+ info->printMembers(value, out, history);
+ out.eb();
+ }
+ }
+}
+
+void
+IceRuby::ClassInfo::destroy()
+{
+ const_cast<ClassInfoPtr&>(base) = 0;
+ const_cast<ClassInfoList&>(interfaces).clear();
+ if(!members.empty())
+ {
+ DataMemberList ml = members;
+ const_cast<DataMemberList&>(members).clear();
+ for(DataMemberList::iterator p = ml.begin(); p != ml.end(); ++p)
+ {
+ (*p)->type->destroy();
+ }
+ }
+}
+
+void
+IceRuby::ClassInfo::printMembers(VALUE value, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(base)
+ {
+ base->printMembers(value, out, history);
+ }
+
+ DataMemberList::const_iterator q;
+
+ for(q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ out << nl << member->name << " = ";
+ if(callRuby(rb_ivar_defined, value, member->rubyID) == Qfalse)
+ {
+ out << "<not defined>";
+ }
+ else
+ {
+ volatile VALUE val = callRuby(rb_ivar_get, value, member->rubyID);
+ member->type->print(val, out, history);
+ }
+ }
+
+ for(q = optionalMembers.begin(); q != optionalMembers.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ out << nl << member->name << " = ";
+ if(callRuby(rb_ivar_defined, value, member->rubyID) == Qfalse)
+ {
+ out << "<not defined>";
+ }
+ else
+ {
+ volatile VALUE val = callRuby(rb_ivar_get, value, member->rubyID);
+ if(val == Unset)
+ {
+ out << "<unset>";
+ }
+ else
+ {
+ member->type->print(val, out, history);
+ }
+ }
+ }
+}
+
+bool
+IceRuby::ClassInfo::isA(const ClassInfoPtr& info)
+{
+ //
+ // Return true if this class has an is-a relationship with info.
+ //
+ if(info->isBase && isLocal == info->isLocal)
+ {
+ return true;
+ }
+ else if(this == info.get())
+ {
+ return true;
+ }
+ else if(base && base->isA(info))
+ {
+ return true;
+ }
+ else if(!interfaces.empty())
+ {
+ for(ClassInfoList::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
+ {
+ if((*p)->isA(info))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+//
+// ProxyInfo implementation.
+//
+IceRuby::ProxyInfo::ProxyInfo(VALUE ident) :
+ rubyClass(Qnil), typeObj(Qnil)
+{
+ const_cast<string&>(id) = getString(ident);
+ const_cast<VALUE&>(typeObj) = createType(this);
+}
+
+void
+IceRuby::ProxyInfo::define(VALUE t, VALUE i)
+{
+ const_cast<VALUE&>(rubyClass) = t;
+ const_cast<ClassInfoPtr&>(classInfo) = ClassInfoPtr::dynamicCast(getType(i));
+ assert(classInfo);
+}
+
+string
+IceRuby::ProxyInfo::getId() const
+{
+ return id;
+}
+
+bool
+IceRuby::ProxyInfo::validate(VALUE val)
+{
+ if(!NIL_P(val))
+ {
+ if(!checkProxy(val))
+ {
+ return false;
+ }
+ volatile VALUE cls = CLASS_OF(val);
+ volatile VALUE type = callRuby(rb_const_get, cls, rb_intern("ICE_TYPE"));
+ assert(!NIL_P(type));
+ ProxyInfoPtr info = ProxyInfoPtr::dynamicCast(getType(type));
+ assert(info);
+ return info->classInfo->isA(classInfo);
+ }
+ return true;
+}
+
+bool
+IceRuby::ProxyInfo::variableLength() const
+{
+ return true;
+}
+
+int
+IceRuby::ProxyInfo::wireSize() const
+{
+ return 1;
+}
+
+Ice::OptionalFormat
+IceRuby::ProxyInfo::optionalFormat() const
+{
+ return Ice::OptionalFormatFSize;
+}
+
+void
+IceRuby::ProxyInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*, bool optional)
+{
+ Ice::OutputStream::size_type sizePos = -1;
+ if(optional)
+ {
+ sizePos = os->startSize();
+ }
+
+ if(NIL_P(p))
+ {
+ os->write(Ice::ObjectPrx());
+ }
+ else
+ {
+ assert(checkProxy(p)); // validate() should have caught this.
+ os->write(getProxy(p));
+ }
+
+ if(optional)
+ {
+ os->endSize(sizePos);
+ }
+}
+
+void
+IceRuby::ProxyInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+ void* closure, bool optional)
+{
+ if(optional)
+ {
+ is->skip(4);
+ }
+
+ Ice::ObjectPrx proxy;
+ is->read(proxy);
+
+ if(!proxy)
+ {
+ cb->unmarshaled(Qnil, target, closure);
+ return;
+ }
+
+ if(NIL_P(rubyClass))
+ {
+ throw RubyException(rb_eRuntimeError, "class %s is declared but not defined", id.c_str());
+ }
+
+ volatile VALUE p = createProxy(proxy, rubyClass);
+ cb->unmarshaled(p, target, closure);
+}
+
+void
+IceRuby::ProxyInfo::print(VALUE value, IceUtilInternal::Output& out, PrintObjectHistory*)
+{
+ if(!validate(value))
+ {
+ out << "<invalid value - expected " << getId() << ">";
+ return;
+ }
+
+ if(NIL_P(value))
+ {
+ out << "<nil>";
+ }
+ else
+ {
+ out << getString(value);
+ }
+}
+
+void
+IceRuby::ProxyInfo::destroy()
+{
+ const_cast<ClassInfoPtr&>(classInfo) = 0;
+}
+
+//
+// ObjectWriter implementation.
+//
+IceRuby::ObjectWriter::ObjectWriter(VALUE object, ObjectMap* objectMap) :
+ _object(object), _map(objectMap)
+{
+ volatile VALUE cls = CLASS_OF(object);
+ volatile VALUE type = callRuby(rb_const_get, cls, rb_intern("ICE_TYPE"));
+ assert(!NIL_P(type));
+ _info = ClassInfoPtr::dynamicCast(getType(type));
+ assert(_info);
+}
+
+void
+IceRuby::ObjectWriter::ice_preMarshal()
+{
+ ID id = rb_intern("ice_preMarshal");
+ if(callRuby(rb_respond_to, _object, id))
+ {
+ callRuby(rb_funcall, _object, id, 0);
+ }
+}
+
+void
+IceRuby::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
+{
+ Ice::SlicedDataPtr slicedData;
+
+ if(_info->preserve)
+ {
+ //
+ // Retrieve the SlicedData object that we stored as a hidden member of the Ruby object.
+ //
+ slicedData = SlicedDataUtil::getMember(_object, const_cast<ObjectMap*>(_map));
+ }
+
+ os->startObject(slicedData);
+
+ if(_info->id != "::Ice::UnknownSlicedObject")
+ {
+ ClassInfoPtr info = _info;
+ while(info)
+ {
+ os->startSlice(info->id, info->compactId, !info->base);
+
+ writeMembers(os, info->members);
+ writeMembers(os, info->optionalMembers); // The optional members have already been sorted by tag.
+
+ os->endSlice();
+
+ info = info->base;
+ }
+ }
+
+ os->endObject();
+}
+
+void
+IceRuby::ObjectWriter::writeMembers(const Ice::OutputStreamPtr& os, const DataMemberList& members) const
+{
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+
+ volatile VALUE val = callRuby(rb_ivar_get, _object, member->rubyID);
+
+ if(member->optional && (val == Unset || !os->writeOptional(member->tag, member->type->optionalFormat())))
+ {
+ continue;
+ }
+
+ if(!member->type->validate(val))
+ {
+ throw RubyException(rb_eTypeError, "invalid value for %s member `%s'", _info->id.c_str(),
+ member->name.c_str());
+ }
+
+ member->type->marshal(val, os, _map, member->optional);
+ }
+}
+
+//
+// ObjectReader implementation.
+//
+IceRuby::ObjectReader::ObjectReader(VALUE object, const ClassInfoPtr& info) :
+ _object(object), _info(info)
+{
+}
+
+void
+IceRuby::ObjectReader::ice_postUnmarshal()
+{
+ ID id = rb_intern("ice_postUnmarshal");
+ if(callRuby(rb_respond_to, _object, id))
+ {
+ callRuby(rb_funcall, _object, id, 0);
+ }
+}
+
+void
+IceRuby::ObjectReader::read(const Ice::InputStreamPtr& is)
+{
+ is->startObject();
+
+ const bool unknown = _info->id == "::Ice::UnknownSlicedObject";
+
+ //
+ // Unmarshal the slices of a user-defined class.
+ //
+ if(!unknown && _info->id != Ice::Object::ice_staticId())
+ {
+ ClassInfoPtr info = _info;
+ while(info)
+ {
+ is->startSlice();
+
+ DataMemberList::const_iterator p;
+
+ for(p = info->members.begin(); p != info->members.end(); ++p)
+ {
+ DataMemberPtr member = *p;
+ member->type->unmarshal(is, member, _object, 0, false);
+ }
+
+ //
+ // The optional members have already been sorted by tag.
+ //
+ for(p = info->optionalMembers.begin(); p != info->optionalMembers.end(); ++p)
+ {
+ DataMemberPtr member = *p;
+ if(is->readOptional(member->tag, member->type->optionalFormat()))
+ {
+ member->type->unmarshal(is, member, _object, 0, true);
+ }
+ else
+ {
+ callRuby(rb_ivar_set, _object, member->rubyID, Unset);
+ }
+ }
+
+ is->endSlice();
+
+ info = info->base;
+ }
+ }
+
+ _slicedData = is->endObject(_info->preserve);
+
+ if(_slicedData)
+ {
+ SlicedDataUtil* util = reinterpret_cast<SlicedDataUtil*>(is->closure());
+ assert(util);
+ util->add(this);
+
+ //
+ // Define the "unknownTypeId" member for an instance of UnknownSlicedObject.
+ //
+ if(unknown)
+ {
+ assert(!_slicedData->slices.empty());
+
+ volatile VALUE typeId = createString(_slicedData->slices[0]->typeId);
+ callRuby(rb_iv_set, _object, "@unknownTypeId", typeId);
+ }
+ }
+}
+
+ClassInfoPtr
+IceRuby::ObjectReader::getInfo() const
+{
+ return _info;
+}
+
+VALUE
+IceRuby::ObjectReader::getObject() const
+{
+ return _object;
+}
+
+Ice::SlicedDataPtr
+IceRuby::ObjectReader::getSlicedData() const
+{
+ return _slicedData;
+}
+
+//
+// InfoMapDestroyer implementation.
+//
+IceRuby::InfoMapDestroyer::~InfoMapDestroyer()
+{
+ {
+ for(ProxyInfoMap::iterator p = _proxyInfoMap.begin(); p != _proxyInfoMap.end(); ++p)
+ {
+ p->second->destroy();
+ }
+ }
+ {
+ for(ClassInfoMap::iterator p = _classInfoMap.begin(); p != _classInfoMap.end(); ++p)
+ {
+ p->second->destroy();
+ }
+ }
+ _compactIdMap.clear();
+ _exceptionInfoMap.clear();
+}
+
+//
+// ReadObjectCallback implementation.
+//
+IceRuby::ReadObjectCallback::ReadObjectCallback(const ClassInfoPtr& info, const UnmarshalCallbackPtr& cb,
+ VALUE target, void* closure) :
+ _info(info), _cb(cb), _target(target), _closure(closure)
+{
+}
+
+void
+IceRuby::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.
+ //
+ volatile VALUE obj = reader->getObject();
+ if(!_info->validate(obj))
+ {
+ Ice::UnexpectedObjectException ex(__FILE__, __LINE__);
+ ex.reason = "unmarshaled object is not an instance of " + _info->id;
+ ex.type = reader->getInfo()->getId();
+ ex.expectedType = _info->id;
+ throw ex;
+ }
+
+ _cb->unmarshaled(obj, _target, _closure);
+ }
+ else
+ {
+ _cb->unmarshaled(Qnil, _target, _closure);
+ }
+}
+
+//
+// ExceptionInfo implementation.
+//
+VALUE
+IceRuby::ExceptionInfo::unmarshal(const Ice::InputStreamPtr& is)
+{
+ volatile VALUE obj = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), rubyClass);
+
+ ExceptionInfoPtr info = this;
+ while(info)
+ {
+ is->startSlice();
+
+ DataMemberList::iterator q;
+
+ for(q = info->members.begin(); q != info->members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ member->type->unmarshal(is, member, obj, 0, false);
+ }
+
+ //
+ // The optional members have already been sorted by tag.
+ //
+ for(q = info->optionalMembers.begin(); q != info->optionalMembers.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ if(is->readOptional(member->tag, member->type->optionalFormat()))
+ {
+ member->type->unmarshal(is, member, obj, 0, true);
+ }
+ else
+ {
+ callRuby(rb_ivar_set, obj, member->rubyID, Unset);
+ }
+ }
+
+ is->endSlice();
+
+ info = info->base;
+ }
+
+ return obj;
+}
+
+void
+IceRuby::ExceptionInfo::print(VALUE value, IceUtilInternal::Output& out)
+{
+ if(callRuby(rb_obj_is_kind_of, value, rubyClass) == Qfalse)
+ {
+ out << "<invalid value - expected " << id << ">";
+ return;
+ }
+
+ PrintObjectHistory history;
+ history.index = 0;
+
+ out << "exception " << id;
+ out.sb();
+ printMembers(value, out, &history);
+ out.eb();
+}
+
+void
+IceRuby::ExceptionInfo::printMembers(VALUE value, IceUtilInternal::Output& out, PrintObjectHistory* history)
+{
+ if(base)
+ {
+ base->printMembers(value, out, history);
+ }
+
+ DataMemberList::const_iterator q;
+
+ for(q = members.begin(); q != members.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ out << nl << member->name << " = ";
+ if(callRuby(rb_ivar_defined, value, member->rubyID) == Qfalse)
+ {
+ out << "<not defined>";
+ }
+ else
+ {
+ volatile VALUE val = callRuby(rb_ivar_get, value, member->rubyID);
+ member->type->print(val, out, history);
+ }
+ }
+
+ for(q = optionalMembers.begin(); q != optionalMembers.end(); ++q)
+ {
+ DataMemberPtr member = *q;
+ out << nl << member->name << " = ";
+ if(callRuby(rb_ivar_defined, value, member->rubyID) == Qfalse)
+ {
+ out << "<not defined>";
+ }
+ else
+ {
+ volatile VALUE val = callRuby(rb_ivar_get, value, member->rubyID);
+ if(val == Unset)
+ {
+ out << "<unset>";
+ }
+ else
+ {
+ member->type->print(val, out, history);
+ }
+ }
+ }
+}
+
+//
+// ExceptionReader implementation.
+//
+IceRuby::ExceptionReader::ExceptionReader(const Ice::CommunicatorPtr& communicator, const ExceptionInfoPtr& info) :
+ Ice::UserExceptionReader(communicator), _info(info)
+{
+}
+
+IceRuby::ExceptionReader::~ExceptionReader()
+ throw()
+{
+}
+
+void
+IceRuby::ExceptionReader::read(const Ice::InputStreamPtr& is) const
+{
+ is->startException();
+
+ const_cast<VALUE&>(_ex) = _info->unmarshal(is);
+
+ const_cast<Ice::SlicedDataPtr&>(_slicedData) = is->endException(_info->preserve);
+}
+
+bool
+IceRuby::ExceptionReader::usesClasses() const
+{
+ return _info->usesClasses;
+}
+
+string
+IceRuby::ExceptionReader::ice_name() const
+{
+ return _info->id;
+}
+
+Ice::UserException*
+IceRuby::ExceptionReader::ice_clone() const
+{
+ assert(false);
+ return 0;
+}
+
+void
+IceRuby::ExceptionReader::ice_throw() const
+{
+ throw *this;
+}
+
+VALUE
+IceRuby::ExceptionReader::getException() const
+{
+ return _ex;
+}
+
+Ice::SlicedDataPtr
+IceRuby::ExceptionReader::getSlicedData() const
+{
+ return _slicedData;
+}
+
+//
+// IdResolver
+//
+string
+IceRuby::IdResolver::resolve(Ice::Int id) const
+{
+ CompactIdMap::iterator p = _compactIdMap.find(id);
+ if(p != _compactIdMap.end())
+ {
+ return p->second->id;
+ }
+ return string();
+}
+
+extern "C"
+VALUE
+IceRuby_defineEnum(VALUE /*self*/, VALUE id, VALUE type, VALUE enumerators)
+{
+ ICE_RUBY_TRY
+ {
+ EnumInfoPtr info = new EnumInfo(id, type, enumerators);
+ return createType(info);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_defineStruct(VALUE /*self*/, VALUE id, VALUE type, VALUE members)
+{
+ ICE_RUBY_TRY
+ {
+ StructInfoPtr info = new StructInfo(id, type, members);
+ return createType(info);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_defineSequence(VALUE /*self*/, VALUE id, VALUE elementType)
+{
+ ICE_RUBY_TRY
+ {
+ SequenceInfoPtr info = new SequenceInfo(id, elementType);
+ return createType(info);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_defineDictionary(VALUE /*self*/, VALUE id, VALUE keyType, VALUE valueType)
+{
+ ICE_RUBY_TRY
+ {
+ DictionaryInfoPtr info = new DictionaryInfo(id, keyType, valueType);
+ return createType(info);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_declareProxy(VALUE /*self*/, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ string proxyId = getString(id);
+ proxyId += "Prx";
+
+ ProxyInfoPtr info = lookupProxyInfo(proxyId);
+ if(!info)
+ {
+ info = new ProxyInfo(id);
+ addProxyInfo(proxyId, info);
+ }
+
+ return info->typeObj;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_declareClass(VALUE /*self*/, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ string idstr = getString(id);
+ ClassInfoPtr info = lookupClassInfo(idstr);
+ if(!info)
+ {
+ info = new ClassInfo(id, false);
+ addClassInfo(idstr, info);
+ }
+
+ return info->typeObj;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_declareLocalClass(VALUE /*self*/, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ string idstr = getString(id);
+ ClassInfoPtr info = lookupClassInfo(idstr);
+ if(!info)
+ {
+ info = new ClassInfo(id, true);
+ addClassInfo(idstr, info);
+ }
+
+ return info->typeObj;
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_defineException(VALUE /*self*/, VALUE id, VALUE type, VALUE preserve, VALUE base, VALUE members)
+{
+ ICE_RUBY_TRY
+ {
+ ExceptionInfoPtr info = new ExceptionInfo;
+ info->id = getString(id);
+
+ info->preserve = preserve == Qtrue;
+
+ if(!NIL_P(base))
+ {
+ info->base = ExceptionInfoPtr::dynamicCast(getException(base));
+ assert(info->base);
+ }
+
+ convertDataMembers(members, info->members, info->optionalMembers, true);
+
+ info->usesClasses = false;
+
+ //
+ // Only examine the required members to see if any use classes.
+ //
+ for(DataMemberList::iterator p = info->members.begin(); p != info->members.end(); ++p)
+ {
+ if(!info->usesClasses)
+ {
+ info->usesClasses = (*p)->type->usesClasses();
+ }
+ }
+
+ info->rubyClass = type;
+
+ addExceptionInfo(info->id, info);
+
+ return createException(info);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_TypeInfo_defineProxy(VALUE self, VALUE type, VALUE classInfo)
+{
+ ICE_RUBY_TRY
+ {
+ ProxyInfoPtr info = ProxyInfoPtr::dynamicCast(getType(self));
+ assert(info);
+
+ info->define(type, classInfo);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_TypeInfo_defineClass(VALUE self, VALUE type, VALUE compactId, VALUE isAbstract, VALUE preserve, VALUE base,
+ VALUE interfaces, VALUE members)
+{
+ ICE_RUBY_TRY
+ {
+ ClassInfoPtr info = ClassInfoPtr::dynamicCast(getType(self));
+ assert(info);
+
+ info->define(type, compactId, isAbstract, preserve, base, interfaces, members);
+
+ CompactIdMap::iterator q = _compactIdMap.find(info->compactId);
+ if(q != _compactIdMap.end())
+ {
+ _compactIdMap.erase(q);
+ }
+ _compactIdMap.insert(CompactIdMap::value_type(info->compactId, info));
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_stringify(VALUE /*self*/, VALUE obj, VALUE type)
+{
+ ICE_RUBY_TRY
+ {
+ TypeInfoPtr info = getType(type);
+
+ ostringstream ostr;
+ IceUtilInternal::Output out(ostr);
+ PrintObjectHistory history;
+ history.index = 0;
+ info->print(obj, out, &history);
+
+ string str = ostr.str();
+ return createString(str);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_stringifyException(VALUE /*self*/, VALUE ex)
+{
+ ICE_RUBY_TRY
+ {
+ volatile VALUE cls = CLASS_OF(ex);
+ volatile VALUE type = callRuby(rb_const_get, cls, rb_intern("ICE_TYPE"));
+ ExceptionInfoPtr info = getException(type);
+
+ ostringstream ostr;
+ IceUtilInternal::Output out(ostr);
+ info->print(ex, out);
+
+ string str = ostr.str();
+ return createString(str);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+//
+// lookupClassInfo()
+//
+IceRuby::ClassInfoPtr
+IceRuby::lookupClassInfo(const string& id)
+{
+ ClassInfoMap::iterator p = _classInfoMap.find(id);
+ if(p != _classInfoMap.end())
+ {
+ return p->second;
+ }
+ return 0;
+}
+
+//
+// lookupExceptionInfo()
+//
+IceRuby::ExceptionInfoPtr
+IceRuby::lookupExceptionInfo(const string& id)
+{
+ ExceptionInfoMap::iterator p = _exceptionInfoMap.find(id);
+ if(p != _exceptionInfoMap.end())
+ {
+ return p->second;
+ }
+ return 0;
+}
+
+bool
+IceRuby::initTypes(VALUE iceModule)
+{
+ //
+ // Define a class to represent TypeInfo, and another to represent ExceptionInfo.
+ //
+ _typeInfoClass = rb_define_class_under(iceModule, "Internal_TypeInfo", rb_cObject);
+ _exceptionInfoClass = rb_define_class_under(iceModule, "Internal_ExceptionInfo", rb_cObject);
+
+ rb_define_const(iceModule, "T_bool", createType(new PrimitiveInfo(PrimitiveInfo::KindBool)));
+ rb_define_const(iceModule, "T_byte", createType(new PrimitiveInfo(PrimitiveInfo::KindByte)));
+ rb_define_const(iceModule, "T_short", createType(new PrimitiveInfo(PrimitiveInfo::KindShort)));
+ rb_define_const(iceModule, "T_int", createType(new PrimitiveInfo(PrimitiveInfo::KindInt)));
+ rb_define_const(iceModule, "T_long", createType(new PrimitiveInfo(PrimitiveInfo::KindLong)));
+ rb_define_const(iceModule, "T_float", createType(new PrimitiveInfo(PrimitiveInfo::KindFloat)));
+ rb_define_const(iceModule, "T_double", createType(new PrimitiveInfo(PrimitiveInfo::KindDouble)));
+ rb_define_const(iceModule, "T_string", createType(new PrimitiveInfo(PrimitiveInfo::KindString)));
+
+ rb_define_module_function(iceModule, "__defineEnum", CAST_METHOD(IceRuby_defineEnum), 3);
+ rb_define_module_function(iceModule, "__defineStruct", CAST_METHOD(IceRuby_defineStruct), 3);
+ rb_define_module_function(iceModule, "__defineSequence", CAST_METHOD(IceRuby_defineSequence), 2);
+ rb_define_module_function(iceModule, "__defineDictionary", CAST_METHOD(IceRuby_defineDictionary), 3);
+ rb_define_module_function(iceModule, "__declareProxy", CAST_METHOD(IceRuby_declareProxy), 1);
+ rb_define_module_function(iceModule, "__declareClass", CAST_METHOD(IceRuby_declareClass), 1);
+ rb_define_module_function(iceModule, "__declareLocalClass", CAST_METHOD(IceRuby_declareLocalClass), 1);
+ rb_define_module_function(iceModule, "__defineException", CAST_METHOD(IceRuby_defineException), 5);
+
+ rb_define_method(_typeInfoClass, "defineClass", CAST_METHOD(IceRuby_TypeInfo_defineClass), 7);
+ rb_define_method(_typeInfoClass, "defineProxy", CAST_METHOD(IceRuby_TypeInfo_defineProxy), 2);
+
+ rb_define_module_function(iceModule, "__stringify", CAST_METHOD(IceRuby_stringify), 2);
+ rb_define_module_function(iceModule, "__stringifyException", CAST_METHOD(IceRuby_stringifyException), 1);
+
+ _unsetTypeClass = rb_define_class_under(iceModule, "Internal_UnsetType", rb_cObject);
+ Unset = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), _unsetTypeClass);
+ rb_define_const(iceModule, "Unset", Unset);
+
+ return true;
+}
+
+IceRuby::TypeInfoPtr
+IceRuby::getType(VALUE obj)
+{
+ assert(TYPE(obj) == T_DATA);
+ assert(rb_obj_is_instance_of(obj, _typeInfoClass) == Qtrue);
+ TypeInfoPtr* p = reinterpret_cast<TypeInfoPtr*>(DATA_PTR(obj));
+ return *p;
+}
+
+extern "C"
+void
+IceRuby_TypeInfo_free(TypeInfoPtr* p)
+{
+ delete p;
+}
+
+VALUE
+IceRuby::createType(const TypeInfoPtr& info)
+{
+ return Data_Wrap_Struct(_typeInfoClass, 0, IceRuby_TypeInfo_free, new TypeInfoPtr(info));
+}
+
+IceRuby::ExceptionInfoPtr
+IceRuby::getException(VALUE obj)
+{
+ assert(TYPE(obj) == T_DATA);
+ assert(rb_obj_is_instance_of(obj, _exceptionInfoClass) == Qtrue);
+ ExceptionInfoPtr* p = reinterpret_cast<ExceptionInfoPtr*>(DATA_PTR(obj));
+ return *p;
+}
+
+extern "C"
+void
+IceRuby_ExceptionInfo_free(ExceptionInfoPtr* p)
+{
+ delete p;
+}
+
+VALUE
+IceRuby::createException(const ExceptionInfoPtr& info)
+{
+ return Data_Wrap_Struct(_exceptionInfoClass, 0, IceRuby_ExceptionInfo_free, new ExceptionInfoPtr(info));
+}
diff --git a/ruby/src/IceRuby/Types.h b/ruby/src/IceRuby/Types.h
new file mode 100644
index 00000000000..e816d38758f
--- /dev/null
+++ b/ruby/src/IceRuby/Types.h
@@ -0,0 +1,546 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_TYPES_H
+#define ICE_RUBY_TYPES_H
+
+#include <Config.h>
+#include <Util.h>
+#include <Ice/Stream.h>
+#include <IceUtil/OutputUtil.h>
+
+namespace IceRuby
+{
+
+class ExceptionInfo;
+typedef IceUtil::Handle<ExceptionInfo> ExceptionInfoPtr;
+typedef std::vector<ExceptionInfoPtr> ExceptionInfoList;
+
+class ClassInfo;
+typedef IceUtil::Handle<ClassInfo> ClassInfoPtr;
+typedef std::vector<ClassInfoPtr> ClassInfoList;
+
+//
+// This class is raised as an exception when object marshaling needs to be aborted.
+//
+// TODO: Need an equivalent Ruby exception.
+//
+class AbortMarshaling
+{
+};
+
+typedef std::map<VALUE, Ice::ObjectPtr> ObjectMap;
+
+class ObjectReader;
+typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr;
+
+//
+// This class keeps track of Ruby objects (instances of Slice classes
+// and exceptions) that have preserved slices.
+//
+class SlicedDataUtil
+{
+public:
+
+ SlicedDataUtil();
+ ~SlicedDataUtil();
+
+ void add(const ObjectReaderPtr&);
+
+ void update();
+
+ static void setMember(VALUE, const Ice::SlicedDataPtr&);
+ static Ice::SlicedDataPtr getMember(VALUE, ObjectMap*);
+
+private:
+
+ std::set<ObjectReaderPtr> _readers;
+ static VALUE _slicedDataType;
+ static VALUE _sliceInfoType;
+};
+
+struct PrintObjectHistory
+{
+ int index;
+ std::map<VALUE, 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(VALUE, VALUE, void*) = 0;
+};
+typedef IceUtil::Handle<UnmarshalCallback> UnmarshalCallbackPtr;
+
+//
+// Base class for type information.
+//
+class TypeInfo : public UnmarshalCallback
+{
+public:
+
+ virtual std::string getId() const = 0;
+
+ virtual bool validate(VALUE) = 0;
+
+ virtual bool variableLength() const = 0;
+ virtual int wireSize() const = 0;
+ virtual Ice::OptionalFormat optionalFormat() const = 0;
+
+ virtual bool usesClasses() const; // Default implementation returns false.
+
+ virtual void unmarshaled(VALUE, VALUE, void*); // Default implementation is assert(false).
+
+ virtual void destroy();
+
+protected:
+
+ TypeInfo();
+
+public:
+
+ //
+ // The marshal and unmarshal functions can raise Ice exceptions, and may raise
+ // AbortMarshaling if an error occurs.
+ //
+ virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool) = 0;
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool) = 0;
+
+ virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*) = 0;
+};
+typedef IceUtil::Handle<TypeInfo> TypeInfoPtr;
+
+//
+// Primitive type information.
+//
+class PrimitiveInfo : public TypeInfo
+{
+public:
+
+ enum Kind
+ {
+ KindBool,
+ KindByte,
+ KindShort,
+ KindInt,
+ KindLong,
+ KindFloat,
+ KindDouble,
+ KindString
+ };
+
+ PrimitiveInfo();
+ PrimitiveInfo(Kind);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(VALUE);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
+
+ virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ static double toDouble(VALUE);
+
+ Kind kind;
+};
+typedef IceUtil::Handle<PrimitiveInfo> PrimitiveInfoPtr;
+
+//
+// Enum information.
+//
+typedef std::map<Ice::Int, VALUE> EnumeratorMap;
+
+class EnumInfo : public TypeInfo
+{
+public:
+
+ EnumInfo(VALUE, VALUE, VALUE);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(VALUE);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
+
+ virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ const std::string id;
+ const VALUE rubyClass;
+ const Ice::Int maxValue;
+ const EnumeratorMap enumerators;
+};
+typedef IceUtil::Handle<EnumInfo> EnumInfoPtr;
+
+class DataMember : public UnmarshalCallback
+{
+public:
+
+ virtual void unmarshaled(VALUE, VALUE, void*);
+
+ std::string name;
+ TypeInfoPtr type;
+ ID rubyID;
+ bool optional;
+ int tag;
+};
+typedef IceUtil::Handle<DataMember> DataMemberPtr;
+typedef std::vector<DataMemberPtr> DataMemberList;
+
+//
+// Struct information.
+//
+class StructInfo : public TypeInfo
+{
+public:
+
+ StructInfo(VALUE, VALUE, VALUE);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(VALUE);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual bool usesClasses() const; // Default implementation returns false.
+
+ virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
+
+ virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void destroy();
+
+ const std::string id;
+ const DataMemberList members;
+ const VALUE rubyClass;
+
+private:
+
+ bool _variableLength;
+ int _wireSize;
+ VALUE _nullMarshalValue;
+};
+typedef IceUtil::Handle<StructInfo> StructInfoPtr;
+
+//
+// Sequence information.
+//
+class SequenceInfo : public TypeInfo
+{
+public:
+
+ SequenceInfo(VALUE, VALUE);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(VALUE);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual bool usesClasses() const; // Default implementation returns false.
+
+ virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
+ virtual void unmarshaled(VALUE, VALUE, void*);
+
+ virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void destroy();
+
+ const std::string id;
+ const TypeInfoPtr elementType;
+
+private:
+
+ void marshalPrimitiveSequence(const PrimitiveInfoPtr&, VALUE, const Ice::OutputStreamPtr&);
+ void unmarshalPrimitiveSequence(const PrimitiveInfoPtr&, const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&,
+ VALUE, void*);
+};
+typedef IceUtil::Handle<SequenceInfo> SequenceInfoPtr;
+
+//
+// Dictionary information.
+//
+class DictionaryInfo : public TypeInfo
+{
+public:
+
+ DictionaryInfo(VALUE, VALUE, VALUE);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(VALUE);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual bool usesClasses() const; // Default implementation returns false.
+
+ virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
+ void marshalElement(VALUE, VALUE, const Ice::OutputStreamPtr&, ObjectMap*);
+ virtual void unmarshaled(VALUE, VALUE, void*);
+
+ virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+ void printElement(VALUE, VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void destroy();
+
+ class KeyCallback : public UnmarshalCallback
+ {
+ public:
+
+ virtual void unmarshaled(VALUE, VALUE, void*);
+
+ VALUE key;
+ };
+ typedef IceUtil::Handle<KeyCallback> KeyCallbackPtr;
+
+ const std::string id;
+ const TypeInfoPtr keyType;
+ const TypeInfoPtr valueType;
+
+private:
+
+ bool _variableLength;
+ int _wireSize;
+};
+typedef IceUtil::Handle<DictionaryInfo> DictionaryInfoPtr;
+
+typedef std::vector<TypeInfoPtr> TypeInfoList;
+
+class ClassInfo : public TypeInfo
+{
+public:
+
+ ClassInfo(VALUE, bool);
+
+ void define(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(VALUE);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual bool usesClasses() const; // Default implementation returns false.
+
+ virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
+
+ virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void destroy();
+
+ void printMembers(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ bool isA(const ClassInfoPtr&);
+
+ const std::string id;
+ const Ice::Int compactId;
+ const bool isBase; // Is this the ClassInfo for Ice::Object or Ice::LocalObject?
+ const bool isLocal;
+ const bool isAbstract;
+ const bool preserve;
+ const ClassInfoPtr base;
+ const ClassInfoList interfaces;
+ const DataMemberList members;
+ const DataMemberList optionalMembers;
+ const VALUE rubyClass;
+ const VALUE typeObj;
+ const bool defined;
+};
+
+//
+// Proxy information.
+//
+class ProxyInfo : public TypeInfo
+{
+public:
+
+ ProxyInfo(VALUE);
+
+ void define(VALUE, VALUE);
+
+ virtual std::string getId() const;
+
+ virtual bool validate(VALUE);
+
+ virtual bool variableLength() const;
+ virtual int wireSize() const;
+ virtual Ice::OptionalFormat optionalFormat() const;
+
+ virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
+ virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
+
+ virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ virtual void destroy();
+
+ const std::string id;
+ const VALUE rubyClass;
+ const ClassInfoPtr classInfo;
+ const VALUE typeObj;
+};
+typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr;
+
+//
+// Exception information.
+//
+class ExceptionInfo : public IceUtil::Shared
+{
+public:
+
+ VALUE unmarshal(const Ice::InputStreamPtr&);
+
+ void print(VALUE, IceUtilInternal::Output&);
+ void printMembers(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
+
+ std::string id;
+ bool preserve;
+ ExceptionInfoPtr base;
+ DataMemberList members;
+ DataMemberList optionalMembers;
+ bool usesClasses;
+ VALUE rubyClass;
+};
+
+//
+// ObjectWriter wraps a Ruby object for marshaling.
+//
+class ObjectWriter : public Ice::ObjectWriter
+{
+public:
+
+ ObjectWriter(VALUE, ObjectMap*);
+
+ virtual void ice_preMarshal();
+
+ virtual void write(const Ice::OutputStreamPtr&) const;
+
+private:
+
+ void writeMembers(const Ice::OutputStreamPtr&, const DataMemberList&) const;
+
+ VALUE _object;
+ ObjectMap* _map;
+ ClassInfoPtr _info;
+};
+
+//
+// ObjectReader unmarshals the state of an Ice object.
+//
+class ObjectReader : public Ice::ObjectReader
+{
+public:
+
+ ObjectReader(VALUE, const ClassInfoPtr&);
+
+ virtual void ice_postUnmarshal();
+
+ virtual void read(const Ice::InputStreamPtr&);
+
+ virtual ClassInfoPtr getInfo() const;
+
+ VALUE getObject() const; // Borrowed reference.
+
+ Ice::SlicedDataPtr getSlicedData() const;
+
+private:
+
+ VALUE _object;
+ ClassInfoPtr _info;
+ Ice::SlicedDataPtr _slicedData;
+};
+
+//
+// ExceptionReader creates a Ruby user exception and unmarshals it.
+//
+class ExceptionReader : public Ice::UserExceptionReader
+{
+public:
+
+ ExceptionReader(const Ice::CommunicatorPtr&, const ExceptionInfoPtr&);
+ ~ExceptionReader() throw();
+
+ virtual void read(const Ice::InputStreamPtr&) const;
+ virtual bool usesClasses() const;
+
+ virtual std::string ice_name() const;
+ virtual Ice::UserException* ice_clone() const;
+ virtual void ice_throw() const;
+
+ VALUE getException() const;
+
+ Ice::SlicedDataPtr getSlicedData() const;
+
+private:
+
+ ExceptionInfoPtr _info;
+ VALUE _ex;
+ Ice::SlicedDataPtr _slicedData;
+};
+
+class IdResolver : public Ice::CompactIdResolver
+{
+public:
+
+ virtual ::std::string resolve(Ice::Int) const;
+};
+
+ClassInfoPtr lookupClassInfo(const std::string&);
+ExceptionInfoPtr lookupExceptionInfo(const std::string&);
+
+extern VALUE Unset;
+
+bool initTypes(VALUE);
+
+VALUE createType(const TypeInfoPtr&);
+TypeInfoPtr getType(VALUE);
+
+VALUE createException(const ExceptionInfoPtr&);
+ExceptionInfoPtr getException(VALUE);
+
+}
+
+#endif
diff --git a/ruby/src/IceRuby/Util.cpp b/ruby/src/IceRuby/Util.cpp
new file mode 100644
index 00000000000..bac8daddec1
--- /dev/null
+++ b/ruby/src/IceRuby/Util.cpp
@@ -0,0 +1,783 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Util.h>
+#include <Ice/LocalException.h>
+#include <Ice/Protocol.h>
+#include <stdarg.h>
+
+#ifdef HAVE_RUBY_ENCODING_H
+# include <ruby/encoding.h>
+#endif
+
+using namespace std;
+using namespace IceRuby;
+
+namespace
+{
+
+#ifndef NDEBUG
+bool
+checkIsInstance(VALUE p, const char* type)
+{
+ volatile VALUE rbType = callRuby(rb_path2class, type);
+ assert(!NIL_P(rbType));
+ return callRuby(rb_obj_is_instance_of, p, rbType) == Qtrue;
+}
+#endif
+
+template<typename T>
+bool
+setVersion(VALUE p, const T& version, const char* type)
+{
+ assert(checkIsInstance(p, type));
+
+ volatile VALUE major = callRuby(rb_int2inum, version.major);
+ volatile VALUE minor = callRuby(rb_int2inum, version.minor);
+ rb_ivar_set(p, rb_intern("@major"), major);
+ rb_ivar_set(p, rb_intern("@minor"), minor);
+
+ return true;
+}
+
+template<typename T>
+bool
+getVersion(VALUE p, T& v, const char* type)
+{
+ assert(checkIsInstance(p, type));
+ volatile VALUE major = callRuby(rb_ivar_get, p, rb_intern("@major"));
+ volatile VALUE minor = callRuby(rb_ivar_get, p, rb_intern("@minor"));
+
+ long m;
+
+ m = getInteger(major);
+ if(m < 0 || m > 255)
+ {
+ throw RubyException(rb_eTypeError, "version major must be a value between 0 and 255");
+ return false;
+ }
+ v.major = m;
+
+ m = getInteger(minor);
+ if(m < 0 || m > 255)
+ {
+ throw RubyException(rb_eTypeError, "version minor must be a value between 0 and 255");
+ return false;
+ }
+ v.minor = m;
+
+ return true;
+}
+
+template<typename T>
+VALUE
+createVersion(const T& version, const char* type)
+{
+ volatile VALUE rbType = callRuby(rb_path2class, type);
+ assert(!NIL_P(rbType));
+
+ volatile VALUE obj = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), rbType);
+
+ if(!setVersion<T>(obj, version, type))
+ {
+ return Qnil;
+ }
+
+ return obj;
+}
+
+template<typename T>
+VALUE
+versionToString(VALUE p, const char* type)
+{
+ volatile VALUE rbType = callRuby(rb_path2class, type);
+ assert(!NIL_P(rbType));
+ if(callRuby(rb_obj_is_instance_of, p, rbType) != Qtrue)
+ {
+ throw RubyException(rb_eTypeError, "argument is not an instance of %s", type);
+ }
+
+ T v;
+ if(!getVersion<T>(p, v, type))
+ {
+ return Qnil;
+ }
+
+ ICE_RUBY_TRY
+ {
+ string s = IceInternal::versionToString<T>(v);
+ return createString(s);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+template<typename T>
+VALUE
+stringToVersion(VALUE p, const char* type)
+{
+ string str = getString(p);
+
+ ICE_RUBY_TRY
+ {
+ T v = IceInternal::stringToVersion<T>(str);
+ return createVersion<T>(v, type);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+char Ice_ProtocolVersion[] = "Ice::ProtocolVersion";
+char Ice_EncodingVersion[] = "Ice::EncodingVersion";
+
+}
+
+extern "C"
+VALUE
+IceRuby_stringVersion(int /*argc*/, VALUE* /*argv*/, VALUE /*self*/)
+{
+ ICE_RUBY_TRY
+ {
+ string s = ICE_STRING_VERSION;
+ return createString(s);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_intVersion(int /*argc*/, VALUE* /*argv*/, VALUE /*self*/)
+{
+ ICE_RUBY_TRY
+ {
+ return INT2FIX(ICE_INT_VERSION);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_currentProtocol(int /*argc*/, VALUE* /*argv*/, VALUE /*self*/)
+{
+ ICE_RUBY_TRY
+ {
+ return createProtocolVersion(Ice::currentProtocol);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_currentProtocolEncoding(int /*argc*/, VALUE* /*argv*/, VALUE /*self*/)
+{
+ ICE_RUBY_TRY
+ {
+ return createEncodingVersion(Ice::currentProtocolEncoding);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_currentEncoding(int /*argc*/, VALUE* /*argv*/, VALUE /*self*/)
+{
+ ICE_RUBY_TRY
+ {
+ return createEncodingVersion(Ice::currentEncoding);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_protocolVersionToString(VALUE /*self*/, VALUE v)
+{
+ return versionToString<Ice::ProtocolVersion>(v, Ice_ProtocolVersion);
+}
+
+extern "C"
+VALUE
+IceRuby_stringToProtocolVersion(VALUE /*self*/, VALUE v)
+{
+ return stringToVersion<Ice::ProtocolVersion>(v, Ice_ProtocolVersion);
+}
+
+extern "C"
+VALUE
+IceRuby_encodingVersionToString(VALUE /*self*/, VALUE v)
+{
+ return versionToString<Ice::EncodingVersion>(v, Ice_EncodingVersion);
+}
+
+extern "C"
+VALUE
+IceRuby_stringToEncodingVersion(VALUE /*self*/, VALUE v)
+{
+ return stringToVersion<Ice::EncodingVersion>(v, Ice_EncodingVersion);
+}
+
+void
+IceRuby::initUtil(VALUE iceModule)
+{
+ rb_define_module_function(iceModule, "stringVersion", CAST_METHOD(IceRuby_stringVersion), -1);
+ rb_define_module_function(iceModule, "intVersion", CAST_METHOD(IceRuby_intVersion), -1);
+ rb_define_module_function(iceModule, "currentProtocol", CAST_METHOD(IceRuby_currentProtocol), -1);
+ rb_define_module_function(iceModule, "currentProtocolEncoding", CAST_METHOD(IceRuby_currentProtocolEncoding), -1);
+ rb_define_module_function(iceModule, "currentEncoding", CAST_METHOD(IceRuby_currentEncoding), -1);
+ rb_define_module_function(iceModule, "protocolVersionToString", CAST_METHOD(IceRuby_protocolVersionToString), 1);
+ rb_define_module_function(iceModule, "stringToProtocolVersion", CAST_METHOD(IceRuby_stringToProtocolVersion), 1);
+ rb_define_module_function(iceModule, "encodingVersionToString", CAST_METHOD(IceRuby_encodingVersionToString), 1);
+ rb_define_module_function(iceModule, "stringToEncodingVersion", CAST_METHOD(IceRuby_stringToEncodingVersion), 1);
+}
+
+IceRuby::RubyException::RubyException()
+{
+ ex = rb_gv_get("$!");
+}
+
+IceRuby::RubyException::RubyException(VALUE exv) :
+ ex(exv)
+{
+}
+
+IceRuby::RubyException::RubyException(VALUE exClass, const char* fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZ];
+
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZ, fmt, args);
+ buf[BUFSIZ - 1] = '\0';
+ va_end(args);
+
+ ex = callRuby(rb_exc_new2, exClass, buf);
+}
+
+ostream&
+IceRuby::RubyException::operator<<(ostream& ostr) const
+{
+ volatile VALUE cls = rb_class_path(CLASS_OF(ex));
+ volatile VALUE msg = rb_obj_as_string(ex);
+ ostr << RSTRING_PTR(cls) << ": " << RSTRING_PTR(msg);
+ return ostr;
+}
+
+bool
+IceRuby::isString(VALUE val)
+{
+ return TYPE(val) == T_STRING || callRuby(rb_respond_to, val, rb_intern("to_str")) != 0;
+}
+
+bool
+IceRuby::isArray(VALUE val)
+{
+ return TYPE(val) == T_ARRAY || callRuby(rb_respond_to, val, rb_intern("to_arr")) != 0;
+}
+
+bool
+IceRuby::isHash(VALUE val)
+{
+ return TYPE(val) == T_HASH || callRuby(rb_respond_to, val, rb_intern("to_hash")) != 0;
+}
+
+string
+IceRuby::getString(VALUE val)
+{
+ volatile VALUE result = callRuby(rb_string_value, &val);
+ return string(RSTRING_PTR(result), RSTRING_LEN(result));
+}
+
+VALUE
+IceRuby::createString(const string& str)
+{
+#ifdef HAVE_RUBY_ENCODING_H
+ return callRuby(rb_enc_str_new, str.c_str(), static_cast<long>(str.size()), rb_utf8_encoding());
+#else
+ return callRuby(rb_str_new, str.c_str(), static_cast<long>(str.size()));
+#endif
+}
+
+namespace
+{
+
+template <typename T>
+struct RubyCallArgs
+{
+ volatile VALUE val;
+ T ret;
+};
+
+//
+// Wrapper function to call rb_num2long with rb_protect
+//
+VALUE
+rb_num2long_wrapper(VALUE val)
+{
+ RubyCallArgs<long>* data = (RubyCallArgs<long>*)val;
+ data->ret = rb_num2long(data->val);
+ return val;
+}
+
+//
+// Wrapper function to call rb_num2ll with rb_protect
+//
+VALUE
+rb_num2ll_wrapper(VALUE val)
+{
+ RubyCallArgs<Ice::Long>* data = (RubyCallArgs<Ice::Long>*)val;
+ data->ret = rb_num2ll(data->val);
+ return val;
+}
+
+}
+
+long
+IceRuby::getInteger(VALUE val)
+{
+ RubyCallArgs<long> arg= {val, -1};
+ int error = 0;
+ rb_protect(rb_num2long_wrapper, (VALUE)&arg, &error);
+ if(error)
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to an int");
+ }
+ return arg.ret;
+}
+
+Ice::Long
+IceRuby::getLong(VALUE val)
+{
+ RubyCallArgs<Ice::Long> arg= {val, -1};
+ int error = 0;
+ rb_protect(rb_num2ll_wrapper, (VALUE)&arg, &error);
+ if(error)
+ {
+ throw RubyException(rb_eTypeError, "unable to convert value to a long");
+ }
+ return arg.ret;
+}
+
+bool
+IceRuby::arrayToStringSeq(VALUE val, vector<string>& seq)
+{
+ volatile VALUE arr = callRuby(rb_check_array_type, val);
+ if(NIL_P(arr))
+ {
+ return false;
+ }
+ for(long i = 0; i < RARRAY_LEN(arr); ++i)
+ {
+ string s = getString(RARRAY_PTR(arr)[i]);
+ seq.push_back(getString(RARRAY_PTR(arr)[i]));
+ }
+ return true;
+}
+
+VALUE
+IceRuby::stringSeqToArray(const vector<string>& seq)
+{
+ volatile VALUE result = createArray(seq.size());
+ long i = 0;
+ if(seq.size() > 0)
+ {
+ for(vector<string>::const_iterator p = seq.begin(); p != seq.end(); ++p, ++i)
+ {
+ RARRAY_PTR(result)[i] = createString(*p);
+ }
+ }
+ return result;
+}
+
+namespace
+{
+
+struct HashToContextIterator : public IceRuby::HashIterator
+{
+ HashToContextIterator(Ice::Context& c) : ctx(c)
+ {
+ }
+
+ virtual void element(VALUE key, VALUE value)
+ {
+ string kstr = IceRuby::getString(key);
+ string vstr = IceRuby::getString(value);
+ ctx[kstr] = vstr;
+ }
+
+ Ice::Context& ctx;
+};
+
+}
+
+bool
+IceRuby::hashToContext(VALUE val, Ice::Context& ctx)
+{
+ if(TYPE(val) != T_HASH)
+ {
+ val = callRuby(rb_convert_type, val, T_HASH, "Hash", "to_hash");
+ if(NIL_P(val))
+ {
+ return false;
+ }
+ }
+ HashToContextIterator iter(ctx);
+ hashIterate(val, iter);
+ return true;
+}
+
+VALUE
+IceRuby::contextToHash(const Ice::Context& ctx)
+{
+ volatile VALUE result = callRuby(rb_hash_new);
+ for(Ice::Context::const_iterator p = ctx.begin(); p != ctx.end(); ++p)
+ {
+ volatile VALUE key = callRuby(rb_str_new, p->first.c_str(), static_cast<long>(p->first.size()));
+ volatile VALUE value = callRuby(rb_str_new, p->second.c_str(), static_cast<long>(p->second.size()));
+ callRuby(rb_hash_aset, result, key, value);
+ }
+ return result;
+}
+
+extern "C"
+VALUE
+IceRuby_Util_hash_foreach_callback(VALUE val, VALUE arg)
+{
+ VALUE key = rb_ary_entry(val, 0);
+ VALUE value = rb_ary_entry(val, 1);
+
+ //
+ // We can't allow any C++ exceptions to propagate out of this function.
+ //
+ ICE_RUBY_TRY
+ {
+ IceRuby::HashIterator* iter = reinterpret_cast<IceRuby::HashIterator*>(arg);
+ iter->element(key, value);
+ }
+ ICE_RUBY_CATCH
+ return val;
+}
+
+extern "C"
+{
+typedef VALUE (*ICE_RUBY_HASH_FOREACH_CALLBACK)(...);
+}
+
+void
+IceRuby::hashIterate(VALUE h, HashIterator& iter)
+{
+ assert(TYPE(h) == T_HASH);
+ callRuby(rb_iterate, rb_each, h,
+ reinterpret_cast<ICE_RUBY_HASH_FOREACH_CALLBACK>(IceRuby_Util_hash_foreach_callback),
+ reinterpret_cast<VALUE>(&iter));
+}
+
+Ice::Identity
+IceRuby::getIdentity(VALUE v)
+{
+ volatile VALUE cls = callRuby(rb_path2class, "Ice::Identity");
+ assert(!NIL_P(cls));
+
+ if(callRuby(rb_obj_is_kind_of, v, cls) == Qfalse)
+ {
+ throw RubyException(rb_eTypeError, "value is not an Ice::Identity");
+ }
+
+ volatile VALUE name = callRuby(rb_iv_get, v, "@name");
+ volatile VALUE category = callRuby(rb_iv_get, v, "@category");
+
+ if(!NIL_P(category) && !isString(category))
+ {
+ throw RubyException(rb_eTypeError, "identity category must be a string");
+ }
+
+ if(NIL_P(name) || !isString(name))
+ {
+ throw RubyException(rb_eTypeError, "identity name must be a string");
+ }
+
+ Ice::Identity result;
+ result.name = getString(name);
+ if(!NIL_P(category))
+ {
+ result.category = getString(category);
+ }
+ return result;
+}
+
+VALUE
+IceRuby::createIdentity(const Ice::Identity& id)
+{
+ volatile VALUE cls = callRuby(rb_path2class, "Ice::Identity");
+ assert(!NIL_P(cls));
+
+ volatile VALUE result = callRuby(rb_class_new_instance, 0, reinterpret_cast<VALUE*>(0), cls);
+ volatile VALUE name = callRuby(rb_str_new, id.name.c_str(), static_cast<long>(id.name.size()));
+ volatile VALUE category = callRuby(rb_str_new, id.category.c_str(), static_cast<long>(id.category.size()));
+ callRuby(rb_iv_set, result, "@name", name);
+ callRuby(rb_iv_set, result, "@category", category);
+ return result;
+}
+
+VALUE
+IceRuby::createProtocolVersion(const Ice::ProtocolVersion& v)
+{
+ return createVersion<Ice::ProtocolVersion>(v, Ice_ProtocolVersion);
+}
+
+VALUE
+IceRuby::createEncodingVersion(const Ice::EncodingVersion& v)
+{
+ return createVersion<Ice::EncodingVersion>(v, Ice_EncodingVersion);
+}
+
+bool
+IceRuby::getEncodingVersion(VALUE p, Ice::EncodingVersion& v)
+{
+ volatile VALUE cls = callRuby(rb_path2class, Ice_EncodingVersion);
+ assert(!NIL_P(cls));
+
+ if(callRuby(rb_obj_is_kind_of, p, cls) == Qfalse)
+ {
+ throw RubyException(rb_eTypeError, "value is not an Ice::EncodingVersion");
+ }
+
+ if(!getVersion<Ice::EncodingVersion>(p, v, Ice_EncodingVersion))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+VALUE
+IceRuby::callProtected(RubyFunction func, VALUE arg)
+{
+ int error = 0;
+ volatile VALUE result = rb_protect(func, arg, &error);
+ if(error)
+ {
+ throw RubyException();
+ }
+ return result;
+}
+
+static void
+setExceptionMembers(const Ice::LocalException& ex, VALUE p)
+{
+ //
+ // Transfer data members from Ice exception to Ruby exception.
+ //
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const Ice::InitializationException& e)
+ {
+ volatile VALUE v = createString(e.reason);
+ callRuby(rb_iv_set, p, "@reason", v);
+ }
+ catch(const Ice::PluginInitializationException& e)
+ {
+ volatile VALUE v = createString(e.reason);
+ callRuby(rb_iv_set, p, "@reason", v);
+ }
+ catch(const Ice::AlreadyRegisteredException& e)
+ {
+ volatile VALUE v;
+ v = createString(e.kindOfObject);
+ callRuby(rb_iv_set, p, "@kindOfObject", v);
+ v = createString(e.id);
+ callRuby(rb_iv_set, p, "@id", v);
+ }
+ catch(const Ice::NotRegisteredException& e)
+ {
+ volatile VALUE v;
+ v = createString(e.kindOfObject);
+ callRuby(rb_iv_set, p, "@kindOfObject", v);
+ v = createString(e.id);
+ callRuby(rb_iv_set, p, "@id", v);
+ }
+ catch(const Ice::TwowayOnlyException& e)
+ {
+ volatile VALUE v = createString(e.operation);
+ callRuby(rb_iv_set, p, "@operation", v);
+ }
+ catch(const Ice::UnknownException& e)
+ {
+ volatile VALUE v = createString(e.unknown);
+ callRuby(rb_iv_set, p, "@unknown", v);
+ }
+ catch(const Ice::ObjectAdapterDeactivatedException& e)
+ {
+ volatile VALUE v = createString(e.name);
+ callRuby(rb_iv_set, p, "@name", v);
+ }
+ catch(const Ice::ObjectAdapterIdInUseException& e)
+ {
+ volatile VALUE v = createString(e.id);
+ callRuby(rb_iv_set, p, "@id", v);
+ }
+ catch(const Ice::NoEndpointException& e)
+ {
+ volatile VALUE v = createString(e.proxy);
+ callRuby(rb_iv_set, p, "@proxy", v);
+ }
+ catch(const Ice::EndpointParseException& e)
+ {
+ volatile VALUE v = createString(e.str);
+ callRuby(rb_iv_set, p, "@str", v);
+ }
+ catch(const Ice::IdentityParseException& e)
+ {
+ volatile VALUE v = createString(e.str);
+ callRuby(rb_iv_set, p, "@str", v);
+ }
+ catch(const Ice::ProxyParseException& e)
+ {
+ volatile VALUE v = createString(e.str);
+ callRuby(rb_iv_set, p, "@str", v);
+ }
+ catch(const Ice::IllegalIdentityException& e)
+ {
+ volatile VALUE v = IceRuby::createIdentity(e.id);
+ callRuby(rb_iv_set, p, "@id", v);
+ }
+ catch(const Ice::RequestFailedException& e)
+ {
+ volatile VALUE v;
+ v = IceRuby::createIdentity(e.id);
+ callRuby(rb_iv_set, p, "@id", v);
+ v = createString(e.facet);
+ callRuby(rb_iv_set, p, "@facet", v);
+ v = createString(e.operation);
+ callRuby(rb_iv_set, p, "@operation", v);
+ }
+ catch(const Ice::FileException& e)
+ {
+ volatile VALUE v = INT2FIX(e.error);
+ callRuby(rb_iv_set, p, "@error", v);
+ v = createString(e.path);
+ callRuby(rb_iv_set, p, "@path", v);
+ }
+ catch(const Ice::SyscallException& e) // This must appear after all subclasses of SyscallException.
+ {
+ volatile VALUE v = INT2FIX(e.error);
+ callRuby(rb_iv_set, p, "@error", v);
+ }
+ catch(const Ice::DNSException& e)
+ {
+ volatile VALUE v;
+ v = INT2FIX(e.error);
+ callRuby(rb_iv_set, p, "@error", v);
+ v = createString(e.host);
+ callRuby(rb_iv_set, p, "@host", v);
+ }
+ catch(const Ice::UnsupportedProtocolException& e)
+ {
+ VALUE m;
+ m = createProtocolVersion(e.bad);
+ callRuby(rb_iv_set, p, "@bad", m);
+ m = createProtocolVersion(e.supported);
+ callRuby(rb_iv_set, p, "@supported", m);
+ }
+ catch(const Ice::UnsupportedEncodingException& e)
+ {
+ VALUE m;
+ m = createEncodingVersion(e.bad);
+ callRuby(rb_iv_set, p, "@bad", m);
+ m = createEncodingVersion(e.supported);
+ callRuby(rb_iv_set, p, "@supported", m);
+ }
+ catch(const Ice::NoObjectFactoryException& e)
+ {
+ volatile VALUE v;
+ v = createString(e.reason);
+ callRuby(rb_iv_set, p, "@reason", v);
+ v = createString(e.type);
+ callRuby(rb_iv_set, p, "@type", v);
+ }
+ catch(const Ice::UnexpectedObjectException& e)
+ {
+ volatile VALUE v;
+ v = createString(e.reason);
+ callRuby(rb_iv_set, p, "@reason", v);
+ v = createString(e.type);
+ callRuby(rb_iv_set, p, "@type", v);
+ v = createString(e.expectedType);
+ callRuby(rb_iv_set, p, "@expectedType", v);
+ }
+ catch(const Ice::ProtocolException& e) // This must appear after all subclasses of ProtocolException.
+ {
+ volatile VALUE v = createString(e.reason);
+ callRuby(rb_iv_set, p, "@reason", v);
+ }
+ catch(const Ice::FeatureNotSupportedException& e)
+ {
+ volatile VALUE v = createString(e.unsupportedFeature);
+ callRuby(rb_iv_set, p, "@unsupportedFeature", v);
+ }
+ catch(const Ice::SecurityException& e)
+ {
+ volatile VALUE v = createString(e.reason);
+ callRuby(rb_iv_set, p, "@reason", v);
+ }
+ catch(const Ice::LocalException&)
+ {
+ //
+ // Nothing to do.
+ //
+ }
+}
+
+VALUE
+IceRuby::createArrayHelper(long sz)
+{
+ volatile VALUE arr = callRuby(rb_ary_new2, sz);
+ if(sz > 0)
+ {
+ callRubyVoid(rb_ary_store, arr, sz - 1, Qnil);
+ }
+ return arr;
+}
+
+VALUE
+IceRuby::convertLocalException(const Ice::LocalException& ex)
+{
+ //
+ // We cannot throw a C++ exception or raise a Ruby exception. If an error
+ // occurs while we are converting the exception, we do our best to return
+ // an appropriate Ruby exception.
+ //
+ try
+ {
+ string name = ex.ice_name();
+ volatile VALUE cls = callRuby(rb_path2class, name.c_str());
+ if(NIL_P(cls))
+ {
+ throw RubyException(rb_eRuntimeError, "exception class `%s' not found", name.c_str());
+ }
+ volatile VALUE result = callRuby(rb_class_new_instance, 0, reinterpret_cast<VALUE*>(0), cls);
+ setExceptionMembers(ex, result);
+ return result;
+ }
+ catch(const RubyException& e)
+ {
+ return e.ex;
+ }
+ catch(...)
+ {
+ string msg = "failure occurred while converting exception " + ex.ice_name();
+ return rb_exc_new2(rb_eRuntimeError, msg.c_str());
+ }
+}
diff --git a/ruby/src/IceRuby/Util.h b/ruby/src/IceRuby/Util.h
new file mode 100644
index 00000000000..d69455fcb10
--- /dev/null
+++ b/ruby/src/IceRuby/Util.h
@@ -0,0 +1,511 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_RUBY_UTIL_H
+#define ICE_RUBY_UTIL_H
+
+#include <Config.h>
+#include <Ice/Ice.h>
+
+namespace IceRuby
+{
+
+void initUtil(VALUE);
+
+class RubyException
+{
+public:
+
+ //
+ // This constructor uses the interpreter's last error result as the exception.
+ //
+ RubyException();
+
+ //
+ // The Ruby exception object is supplied.
+ //
+ RubyException(VALUE);
+
+ //
+ // The Ruby exception object is supplied along with a message.
+ //
+ RubyException(VALUE, const char*, ...);
+
+ std::ostream& operator<<(std::ostream&) const;
+
+ VALUE ex;
+};
+
+//
+// Returns true if the value is a string or can be converted into a string.
+//
+bool isString(VALUE);
+
+//
+// Returns true if the value is an array or can be converted into an array.
+//
+bool isArray(VALUE);
+
+//
+// Returns true if the value is a hash or can be converted into a hash.
+//
+bool isHash(VALUE);
+
+//
+// Convert a Ruby value into a string. May raise RubyException.
+//
+std::string getString(VALUE);
+
+//
+// Create a Ruby string. May raise RubyException.
+//
+VALUE createString(const std::string&);
+
+//
+// Convert a Ruby value into a long. May raise RubyException.
+//
+long getInteger(VALUE);
+
+//
+// Convert a Ruby value into an Ice::Long. May raise RubyException.
+//
+Ice::Long getLong(VALUE);
+
+//
+// Convert a Ruby array into a vector<string>. Returns true on
+// success and false if the value is not an array. May raise
+// RubyException.
+//
+bool arrayToStringSeq(VALUE, std::vector<std::string>&);
+
+//
+// Convert a vector of strings into a Ruby array. May raise
+// RubyException.
+//
+VALUE stringSeqToArray(const std::vector<std::string>&);
+
+//
+// Convert a Ruby hash to Ice::Context. Returns true on success
+// and false if the value is not a hash. May raise RubyException.
+//
+bool hashToContext(VALUE, Ice::Context&);
+
+//
+// Convert Ice::Context to a hash. May raise RubyException.
+//
+VALUE contextToHash(const Ice::Context&);
+
+//
+// Abstract class representing an iterator for a Ruby hash collection.
+//
+class HashIterator
+{
+public:
+
+ virtual ~HashIterator() {}
+
+ virtual void element(VALUE, VALUE) = 0;
+};
+
+//
+// Iterate over the elements in a Ruby hash. The iterator's
+// element method is invoked for each entry. May raise
+// RubyException.
+//
+void hashIterate(VALUE, HashIterator&);
+
+//
+// Convert a Ruby value into Ice::Identity. May raise RubyException.
+//
+Ice::Identity getIdentity(VALUE);
+
+//
+// Create an instance of Ice::Identity. May raise RubyException.
+//
+VALUE createIdentity(const Ice::Identity&);
+
+//
+// Create a Ruby instance of Ice.ProtocolVersion.
+//
+VALUE createProtocolVersion(const Ice::ProtocolVersion&);
+
+//
+// Create a Ruby instance of Ice.EncodingVersion.
+//
+VALUE createEncodingVersion(const Ice::EncodingVersion&);
+
+//
+// Extracts the members of an encoding version.
+//
+bool getEncodingVersion(VALUE, Ice::EncodingVersion&);
+
+//
+// The callRuby functions are used to invoke Ruby C API functions
+// while translating any Ruby exception into RubyException so that
+// C++ objects are cleaned up properly. Overloadings are provided
+// to support API functions that accept multiple arguments.
+//
+template<typename Fun>
+VALUE callRuby(Fun fun);
+
+template<typename Fun, typename T1>
+VALUE callRuby(Fun fun, T1 t1);
+
+template<typename Fun, typename T1, typename T2>
+VALUE callRuby(Fun fun, T1 t1, T2 t2);
+
+template<typename Fun, typename T1, typename T2, typename T3>
+VALUE callRuby(Fun fun, T1 t1, T2 t2, T3 t3);
+
+template<typename Fun, typename T1, typename T2, typename T3, typename T4>
+VALUE callRuby(Fun fun, T1 t1, T2 t2, T3 t3, T4 t4);
+
+extern "C" typedef VALUE (*RubyFunction)(VALUE);
+
+VALUE callProtected(RubyFunction, VALUE);
+
+template<typename Fun>
+class RF_0
+{
+public:
+
+ RF_0(Fun f) : _f(f) {}
+ inline VALUE operator()() { return _f(); }
+ static inline VALUE call(RF_0* f) { return (*f)(); }
+
+private:
+
+ Fun _f;
+};
+
+template<typename Fun>
+inline VALUE callRuby(Fun fun)
+{
+ typedef RF_0<Fun> RF;
+ RF f(fun);
+ return callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+template<typename Fun, typename T1>
+class RF_1
+{
+public:
+
+ RF_1(Fun f, T1 t1) : _f(f), _t1(t1) {}
+ inline VALUE operator()() { return _f(_t1); }
+ static inline VALUE call(RF_1* f) { return (*f)(); }
+
+private:
+
+ Fun _f;
+ T1 _t1;
+};
+
+template<typename Fun, typename T1>
+inline VALUE callRuby(Fun fun, T1 t1)
+{
+ typedef RF_1<Fun, T1> RF;
+ RF f(fun, t1);
+ return callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+template<typename Fun, typename T1, typename T2>
+class RF_2
+{
+public:
+
+ RF_2(Fun f, T1 t1, T2 t2) : _f(f), _t1(t1), _t2(t2) {}
+ inline VALUE operator()() { return _f(_t1, _t2); }
+ static inline VALUE call(RF_2* f) { return (*f)(); }
+
+private:
+
+ Fun _f;
+ T1 _t1;
+ T2 _t2;
+};
+
+template<typename Fun, typename T1, typename T2>
+inline VALUE callRuby(Fun fun, T1 t1, T2 t2)
+{
+ typedef RF_2<Fun, T1, T2> RF;
+ RF f(fun, t1, t2);
+ return callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+template<typename Fun, typename T1, typename T2, typename T3>
+class RF_3
+{
+public:
+
+ RF_3(Fun f, T1 t1, T2 t2, T3 t3) : _f(f), _t1(t1), _t2(t2), _t3(t3) {}
+ inline VALUE operator()() { return _f(_t1, _t2, _t3); }
+ static inline VALUE call(RF_3* f) { return (*f)(); }
+
+private:
+
+ Fun _f;
+ T1 _t1;
+ T2 _t2;
+ T3 _t3;
+};
+
+template<typename Fun, typename T1, typename T2, typename T3>
+inline VALUE callRuby(Fun fun, T1 t1, T2 t2, T3 t3)
+{
+ typedef RF_3<Fun, T1, T2, T3> RF;
+ RF f(fun, t1, t2, t3);
+ return callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+template<typename Fun, typename T1, typename T2, typename T3, typename T4>
+class RF_4
+{
+public:
+
+ RF_4(Fun f, T1 t1, T2 t2, T3 t3, T4 t4) : _f(f), _t1(t1), _t2(t2), _t3(t3), _t4(t4) {}
+ inline VALUE operator()() { return _f(_t1, _t2, _t3, _t4); }
+ static inline VALUE call(RF_4* f) { return (*f)(); }
+
+private:
+
+ Fun _f;
+ T1 _t1;
+ T2 _t2;
+ T3 _t3;
+ T4 _t4;
+};
+
+template<typename Fun, typename T1, typename T2, typename T3, typename T4>
+inline VALUE callRuby(Fun fun, T1 t1, T2 t2, T3 t3, T4 t4)
+{
+ typedef RF_4<Fun, T1, T2, T3, T4> RF;
+ RF f(fun, t1, t2, t3, t4);
+ return callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+//
+// The callRubyVoid functions are used to invoke Ruby C API functions
+// while translating any Ruby exception into RubyException so that
+// C++ objects are cleaned up properly. Overloadings are provided
+// to support API functions that accept multiple arguments.
+//
+template<typename Fun>
+void callRubyVoid(Fun fun);
+
+template<typename Fun, typename T1>
+void callRubyVoid(Fun fun, T1 t1);
+
+template<typename Fun, typename T1, typename T2>
+void callRubyVoid(Fun fun, T1 t1, T2 t2);
+
+template<typename Fun, typename T1, typename T2, typename T3>
+void callRubyVoid(Fun fun, T1 t1, T2 t2, T3 t3);
+
+template<typename Fun, typename T1, typename T2, typename T3, typename T4>
+void callRubyVoid(Fun fun, T1 t1, T2 t2, T3 t3, T4 t4);
+
+template<typename Fun>
+class RFV_0
+{
+public:
+
+ RFV_0(Fun f) : _f(f) {}
+ inline void operator()() { _f(); }
+ static inline VALUE call(RFV_0* f) { (*f)(); return Qnil; }
+
+private:
+
+ Fun _f;
+};
+
+template<typename Fun>
+inline void callRubyVoid(Fun fun)
+{
+ typedef RFV_0<Fun> RF;
+ RF f(fun);
+ callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+template<typename Fun, typename T1>
+class RFV_1
+{
+public:
+
+ RFV_1(Fun f, T1 t1) : _f(f), _t1(t1) {}
+ inline void operator()() { _f(_t1); }
+ static inline VALUE call(RFV_1* f) { (*f)(); return Qnil; }
+
+private:
+
+ Fun _f;
+ T1 _t1;
+};
+
+template<typename Fun, typename T1>
+inline void callRubyVoid(Fun fun, T1 t1)
+{
+ typedef RFV_1<Fun, T1> RF;
+ RF f(fun, t1);
+ callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+template<typename Fun, typename T1, typename T2>
+class RFV_2
+{
+public:
+
+ RFV_2(Fun f, T1 t1, T2 t2) : _f(f), _t1(t1), _t2(t2) {}
+ inline void operator()() { _f(_t1, _t2); }
+ static inline VALUE call(RFV_2* f) { (*f)(); return Qnil; }
+
+private:
+
+ Fun _f;
+ T1 _t1;
+ T2 _t2;
+};
+
+template<typename Fun, typename T1, typename T2>
+inline void callRubyVoid(Fun fun, T1 t1, T2 t2)
+{
+ typedef RFV_2<Fun, T1, T2> RF;
+ RF f(fun, t1, t2);
+ callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+template<typename Fun, typename T1, typename T2, typename T3>
+class RFV_3
+{
+public:
+
+ RFV_3(Fun f, T1 t1, T2 t2, T3 t3) : _f(f), _t1(t1), _t2(t2), _t3(t3) {}
+ inline void operator()() { _f(_t1, _t2, _t3); }
+ static inline VALUE call(RFV_3* f) { (*f)(); return Qnil; }
+
+private:
+
+ Fun _f;
+ T1 _t1;
+ T2 _t2;
+ T3 _t3;
+};
+
+template<typename Fun, typename T1, typename T2, typename T3>
+inline void callRubyVoid(Fun fun, T1 t1, T2 t2, T3 t3)
+{
+ typedef RFV_3<Fun, T1, T2, T3> RF;
+ RF f(fun, t1, t2, t3);
+ callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+template<typename Fun, typename T1, typename T2, typename T3, typename T4>
+class RFV_4
+{
+public:
+
+ RFV_4(Fun f, T1 t1, T2 t2, T3 t3, T4 t4) : _f(f), _t1(t1), _t2(t2), _t3(t3), _t4(t4) {}
+ inline void operator()() { _f(_t1, _t2, _t3, _t4); }
+ static inline VALUE call(RFV_4* f) { (*f)(); return Qnil; }
+
+private:
+
+ Fun _f;
+ T1 _t1;
+ T2 _t2;
+ T3 _t3;
+ T4 _t4;
+};
+
+template<typename Fun, typename T1, typename T2, typename T3, typename T4>
+inline void callRubyVoid(Fun fun, T1 t1, T2 t2, T3 t3, T4 t4)
+{
+ typedef RFV_4<Fun, T1, T2, T3, T4> RF;
+ RF f(fun, t1, t2, t3, t4);
+ callProtected(RubyFunction(RF::call), reinterpret_cast<VALUE>(&f));
+}
+
+VALUE createArrayHelper(long);
+
+//
+// Create an array with the given size. May raise RubyException.
+//
+// Note that the length of the array returned by this function is already
+// set to the requested size. This prevents the array's elements from being
+// prematurely garbage-collected, but it means the array must be populated
+// via direct access to its buffer and not by pushing elements onto the
+// array using rb_ary_push:
+//
+// VALUE arr = createArray(size);
+// for(long i = 0; i < size; ++i)
+// {
+// RARRAY_PTR(arr)[i] = ...;
+// }
+//
+template<typename T>
+inline VALUE createArray(T sz)
+{
+ return createArrayHelper(static_cast<long>(sz));
+}
+
+//
+// Create the Ruby equivalent of an Ice local exception.
+//
+VALUE convertLocalException(const Ice::LocalException&);
+
+}
+
+//
+// The macros ICE_RUBY_TRY and ICE_RUBY_CATCH must be used in place of try/catch in
+// every entry point into the extension. They handle the translation of C++
+// exceptions into Ruby exceptions and ensure that C++ objects are cleaned up properly.
+//
+#define ICE_RUBY_TRY \
+ volatile VALUE __ice_ex = Qnil; \
+ \
+ goto __ice_start; \
+ \
+ __ice_handle_exception: \
+ rb_exc_raise(__ice_ex); \
+ \
+ __ice_start: \
+ try
+
+#define ICE_RUBY_RETHROW(ex) \
+ __ice_ex = ex; \
+ goto __ice_handle_exception;
+
+#define ICE_RUBY_CATCH \
+ catch(const ::IceRuby::RubyException& ex) \
+ { \
+ ICE_RUBY_RETHROW(ex.ex); \
+ } \
+ catch(const ::Ice::LocalException& ex) \
+ { \
+ ICE_RUBY_RETHROW(convertLocalException(ex)); \
+ } \
+ catch(const ::Ice::Exception& ex) \
+ { \
+ string __ice_msg = "unknown Ice exception: " + ex.ice_name(); \
+ ICE_RUBY_RETHROW(rb_exc_new2(rb_eRuntimeError, __ice_msg.c_str())); \
+ } \
+ catch(const std::bad_alloc& ex) \
+ { \
+ ICE_RUBY_RETHROW(rb_exc_new2(rb_eNoMemError, ex.what())); \
+ } \
+ catch(const std::exception& ex) \
+ { \
+ ICE_RUBY_RETHROW(rb_exc_new2(rb_eRuntimeError, ex.what())); \
+ } \
+ catch(...) \
+ { \
+ ICE_RUBY_RETHROW(rb_exc_new2(rb_eRuntimeError, "caught unknown C++ exception")); \
+ }
+
+#endif
diff --git a/ruby/src/Makefile b/ruby/src/Makefile
new file mode 100644
index 00000000000..e46841bcaaa
--- /dev/null
+++ b/ruby/src/Makefile
@@ -0,0 +1,24 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2015 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 = IceRuby
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ if test -d $$subdir ; \
+ then \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ fi; \
+ done