diff options
author | Matthew Newhook <matthew@zeroc.com> | 2015-03-21 15:35:40 -0230 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2015-03-21 15:35:40 -0230 |
commit | 630a37d2fe66f24518299e705f958b571803c522 (patch) | |
tree | 969723791bdc4d73bb099c19d45554d0ca241ad9 /ruby/src/IceRuby/Communicator.cpp | |
parent | Fix some README.md markdown formatting (diff) | |
download | ice-630a37d2fe66f24518299e705f958b571803c522.tar.bz2 ice-630a37d2fe66f24518299e705f958b571803c522.tar.xz ice-630a37d2fe66f24518299e705f958b571803c522.zip |
py -> python
rb -> ruby
objc -> objective-c
cs -> csharp
Diffstat (limited to 'ruby/src/IceRuby/Communicator.cpp')
-rw-r--r-- | ruby/src/IceRuby/Communicator.cpp | 596 |
1 files changed, 596 insertions, 0 deletions
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; +} |