diff options
Diffstat (limited to 'ruby/src')
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 |