1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #include <Communicator.h>
6 #include <ImplicitContext.h>
7 #include <Logger.h>
8 #include <Properties.h>
9 #include <Proxy.h>
10 #include <Types.h>
11 #include <Util.h>
12 #include <ValueFactoryManager.h>
13 #include <IceUtil/DisableWarnings.h>
14 #include <Ice/Communicator.h>
15 #include <Ice/Initialize.h>
16 #include <Ice/Locator.h>
17 #include <Ice/ObjectFactory.h>
18 #include <Ice/Properties.h>
19 #include <Ice/Router.h>
20 
21 using namespace std;
22 using namespace IceRuby;
23 
24 static VALUE _communicatorClass;
25 
26 typedef map<Ice::CommunicatorPtr, VALUE> CommunicatorMap;
27 static CommunicatorMap _communicatorMap;
28 
29 extern "C"
30 void
IceRuby_Communicator_mark(Ice::CommunicatorPtr * p)31 IceRuby_Communicator_mark(Ice::CommunicatorPtr* p)
32 {
33     assert(p);
34     try
35     {
36         ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast((*p)->getValueFactoryManager());
37         assert(vfm);
38         vfm->markSelf();
39     }
40     catch(const Ice::CommunicatorDestroyedException&)
41     {
42         // Ignore. This is expected.
43     }
44 }
45 
46 extern "C"
47 void
IceRuby_Communicator_free(Ice::CommunicatorPtr * p)48 IceRuby_Communicator_free(Ice::CommunicatorPtr* p)
49 {
50     assert(p);
51     delete p;
52 }
53 
54 namespace
55 {
56 
57 class CommunicatorDestroyer
58 {
59 public:
60 
CommunicatorDestroyer(const Ice::CommunicatorPtr & c)61     CommunicatorDestroyer(const Ice::CommunicatorPtr& c) : _communicator(c) {}
62 
~CommunicatorDestroyer()63     ~CommunicatorDestroyer()
64     {
65         _communicator->destroy();
66     }
67 
68 private:
69 
70     Ice::CommunicatorPtr _communicator;
71 };
72 
73 }
74 
75 extern "C"
76 VALUE
IceRuby_initialize(int argc,VALUE * argv,VALUE)77 IceRuby_initialize(int argc, VALUE* argv, VALUE /*self*/)
78 {
79     ICE_RUBY_TRY
80     {
81         //
82         // The argument options are:
83         //
84         // Ice::initialize()
85         // Ice::initialize(args)
86         // Ice::initialize(initData)
87         // Ice::initialize(configFile)
88         // Ice::initialize(args, initData)
89         // Ice::initialize(args, configFile)
90         //
91         // An implicit block is optional.
92         //
93 
94         if(argc > 2)
95         {
96             throw RubyException(rb_eArgError, "invalid number of arguments to Ice::initialize");
97         }
98 
99         volatile VALUE initDataCls = callRuby(rb_path2class, "Ice::InitializationData");
100         volatile VALUE args = Qnil, initData = Qnil, configFile = Qnil;
101 
102         if(argc >= 1)
103         {
104             if(isArray(argv[0]))
105             {
106                 args = argv[0];
107             }
108             else if(callRuby(rb_obj_is_instance_of, argv[0], initDataCls) == Qtrue)
109             {
110                 initData = argv[0];
111             }
112             else if(TYPE(argv[0]) == T_STRING)
113             {
114                 configFile = argv[0];
115             }
116             else
117             {
118                 throw RubyException(rb_eTypeError,
119                     "initialize expects an argument list, InitializationData or a configuration filename");
120             }
121         }
122 
123         if(argc >= 2)
124         {
125             if(isArray(argv[1]))
126             {
127                 if(!NIL_P(args))
128                 {
129                     throw RubyException(rb_eTypeError, "unexpected array argument to initialize");
130                 }
131                 args = argv[1];
132             }
133             else if(callRuby(rb_obj_is_instance_of, argv[1], initDataCls) == Qtrue)
134             {
135                 if(!NIL_P(initData))
136                 {
137                     throw RubyException(rb_eTypeError, "unexpected InitializationData argument to initialize");
138                 }
139                 initData = argv[1];
140             }
141             else if(TYPE(argv[1]) == T_STRING)
142             {
143                 if(!NIL_P(configFile))
144                 {
145                     throw RubyException(rb_eTypeError, "unexpected string argument to initialize");
146                 }
147                 configFile = argv[1];
148             }
149             else
150             {
151                 throw RubyException(rb_eTypeError,
152                     "initialize expects an argument list, InitializationData or a configuration filename");
153             }
154         }
155 
156         if(!NIL_P(initData) && !NIL_P(configFile))
157         {
158             throw RubyException(rb_eTypeError,
159                 "initialize accepts either Ice.InitializationData or a configuration filename");
160         }
161 
162         Ice::StringSeq seq;
163         if(!NIL_P(args) && !arrayToStringSeq(args, seq))
164         {
165             throw RubyException(rb_eTypeError, "invalid array argument to Ice::initialize");
166         }
167 
168         Ice::InitializationData data;
169         if(!NIL_P(initData))
170         {
171             volatile VALUE properties = callRuby(rb_iv_get, initData, "@properties");
172             volatile VALUE logger = callRuby(rb_iv_get, initData, "@logger");
173 
174             if(!NIL_P(properties))
175             {
176                 data.properties = getProperties(properties);
177             }
178 
179             if(!NIL_P(logger))
180             {
181                 throw RubyException(rb_eArgError, "custom logger is not supported");
182             }
183         }
184 
185         //
186         // Insert the program name (stored in the Ruby global variable $0) as the first
187         // element of the sequence.
188         //
189         volatile VALUE progName = callRuby(rb_gv_get, "$0");
190         seq.insert(seq.begin(), getString(progName));
191 
192         data.compactIdResolver = new IdResolver;
193         data.valueFactoryManager = new ValueFactoryManager;
194 
195         if(!data.properties)
196         {
197             data.properties = Ice::createProperties();
198         }
199 
200         if(!NIL_P(configFile))
201         {
202             data.properties->load(getString(configFile));
203         }
204 
205         if(!NIL_P(args))
206         {
207             data.properties = Ice::createProperties(seq, data.properties);
208         }
209 
210         //
211         // Remaining command line options are passed to the communicator
212         // as an argument vector in case they contain plugin properties.
213         //
214         int ac = static_cast<int>(seq.size());
215         char** av = new char*[ac + 1];
216         int i = 0;
217         for(Ice::StringSeq::const_iterator s = seq.begin(); s != seq.end(); ++s, ++i)
218         {
219             av[i] = strdup(s->c_str());
220         }
221         av[ac] = 0;
222 
223         Ice::CommunicatorPtr communicator;
224         try
225         {
226             if(!NIL_P(args))
227             {
228                 communicator = Ice::initialize(ac, av, data);
229             }
230             else
231             {
232                 communicator = Ice::initialize(data);
233             }
234         }
235         catch(const Ice::LocalException& ex)
236         {
237             cerr << ex << endl;
238             for(i = 0; i < ac + 1; ++i)
239             {
240                 free(av[i]);
241             }
242             delete[] av;
243 
244             throw;
245         }
246         catch(...)
247         {
248             for(i = 0; i < ac + 1; ++i)
249             {
250                 free(av[i]);
251             }
252             delete[] av;
253 
254             throw;
255         }
256 
257         //
258         // Replace the contents of the given argument list with the filtered arguments.
259         //
260         if(!NIL_P(args))
261         {
262             callRuby(rb_ary_clear, args);
263 
264             //
265             // We start at index 1 in order to skip the element that we inserted earlier.
266             //
267             for(i = 1; i < ac; ++i)
268             {
269                 volatile VALUE str = createString(av[i]);
270                 callRuby(rb_ary_push, args, str);
271             }
272         }
273 
274         for(i = 0; i < ac + 1; ++i)
275         {
276             free(av[i]);
277         }
278         delete[] av;
279 
280         VALUE result = Data_Wrap_Struct(_communicatorClass, IceRuby_Communicator_mark,
281                                         IceRuby_Communicator_free, new Ice::CommunicatorPtr(communicator));
282 
283         CommunicatorMap::iterator p = _communicatorMap.find(communicator);
284         if(p != _communicatorMap.end())
285         {
286             _communicatorMap.erase(p);
287         }
288         _communicatorMap.insert(CommunicatorMap::value_type(communicator, reinterpret_cast<const VALUE&>(result)));
289 
290         //
291         // If an implicit block was provided, yield to the block and pass it the communicator instance.
292         // We destroy the communicator after the block is finished, and return the result of the block.
293         //
294         if(rb_block_given_p())
295         {
296             CommunicatorDestroyer destroyer(communicator);
297             //
298             // Examine the arity of the block procedure. If it accepts one argument, pass it the
299             // communicator. If it accepts two arguments, pass it the communicator and the
300             // argument vector.
301             //
302             VALUE proc = callRuby(rb_block_proc);
303             int arity = rb_proc_arity(proc);
304             if(arity == 1)
305             {
306                 return callRuby(rb_yield, result);
307             }
308             else if(arity == 2)
309             {
310                 VALUE blockArgs = createArray(2);
311                 RARRAY_ASET(blockArgs, 0, result);
312                 RARRAY_ASET(blockArgs, 1, args);
313                 return callRuby(rb_yield, blockArgs);
314             }
315             else
316             {
317                 throw RubyException(rb_eArgError, "block must accept one or two arguments");
318             }
319         }
320         else
321         {
322             return result;
323         }
324     }
325     ICE_RUBY_CATCH
326     return Qnil;
327 }
328 
329 extern "C"
330 VALUE
IceRuby_stringToIdentity(VALUE,VALUE str)331 IceRuby_stringToIdentity(VALUE /*self*/, VALUE str)
332 {
333     ICE_RUBY_TRY
334     {
335         string s = getString(str);
336         Ice::Identity ident = Ice::stringToIdentity(s);
337         return createIdentity(ident);
338     }
339     ICE_RUBY_CATCH
340     return Qnil;
341 }
342 
343 extern "C"
344 VALUE
IceRuby_identityToString(int argc,VALUE * argv,VALUE)345 IceRuby_identityToString(int argc, VALUE* argv, VALUE /*self*/)
346 {
347     ICE_RUBY_TRY
348     {
349         if(argc < 1 || argc > 2)
350         {
351             throw RubyException(rb_eArgError, "wrong number of arguments");
352         }
353 
354         Ice::Identity ident = getIdentity(argv[0]);
355 
356         Ice::ToStringMode toStringMode = Ice::Unicode;
357         if(argc == 2)
358         {
359             volatile VALUE modeValue = callRuby(rb_funcall, argv[1], rb_intern("to_i"), 0);
360             assert(TYPE(modeValue) == T_FIXNUM);
361             toStringMode = static_cast<Ice::ToStringMode>(FIX2LONG(modeValue));
362         }
363 
364         string str = Ice::identityToString(ident, toStringMode);
365         return createString(str);
366     }
367     ICE_RUBY_CATCH
368     return Qnil;
369 }
370 
371 extern "C"
372 VALUE
IceRuby_Communicator_destroy(VALUE self)373 IceRuby_Communicator_destroy(VALUE self)
374 {
375     Ice::CommunicatorPtr p = getCommunicator(self);
376 
377     ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast(p->getValueFactoryManager());
378     assert(vfm);
379 
380     ICE_RUBY_TRY
381     {
382         p->destroy();
383     }
384     ICE_RUBY_CATCH
385 
386     vfm->destroy();
387 
388     return Qnil;
389 }
390 
391 extern "C"
392 VALUE
IceRuby_Communicator_shutdown(VALUE self)393 IceRuby_Communicator_shutdown(VALUE self)
394 {
395     ICE_RUBY_TRY
396     {
397         Ice::CommunicatorPtr p = getCommunicator(self);
398         p->shutdown();
399     }
400     ICE_RUBY_CATCH
401     return Qnil;
402 }
403 
404 extern "C"
405 VALUE
IceRuby_Communicator_isShutdown(VALUE self)406 IceRuby_Communicator_isShutdown(VALUE self)
407 {
408     ICE_RUBY_TRY
409     {
410         Ice::CommunicatorPtr p = getCommunicator(self);
411         return p->isShutdown() ? Qtrue : Qfalse;
412     }
413     ICE_RUBY_CATCH
414     return Qnil;
415 }
416 
417 extern "C"
418 VALUE
IceRuby_Communicator_waitForShutdown(VALUE self)419 IceRuby_Communicator_waitForShutdown(VALUE self)
420 {
421     ICE_RUBY_TRY
422     {
423         Ice::CommunicatorPtr p = getCommunicator(self);
424         p->waitForShutdown();
425     }
426     ICE_RUBY_CATCH
427     return Qnil;
428 }
429 
430 extern "C"
431 VALUE
IceRuby_Communicator_stringToProxy(VALUE self,VALUE str)432 IceRuby_Communicator_stringToProxy(VALUE self, VALUE str)
433 {
434     ICE_RUBY_TRY
435     {
436         Ice::CommunicatorPtr p = getCommunicator(self);
437         string s = getString(str);
438         Ice::ObjectPrx proxy = p->stringToProxy(s);
439         if(proxy)
440         {
441             return createProxy(proxy);
442         }
443     }
444     ICE_RUBY_CATCH
445     return Qnil;
446 }
447 
448 extern "C"
449 VALUE
IceRuby_Communicator_proxyToString(VALUE self,VALUE proxy)450 IceRuby_Communicator_proxyToString(VALUE self, VALUE proxy)
451 {
452     ICE_RUBY_TRY
453     {
454         Ice::CommunicatorPtr p = getCommunicator(self);
455         Ice::ObjectPrx prx;
456         if(!NIL_P(proxy))
457         {
458             if(!checkProxy(proxy))
459             {
460                 throw RubyException(rb_eTypeError, "argument must be a proxy");
461             }
462             prx = getProxy(proxy);
463         }
464         string str = p->proxyToString(prx);
465         return createString(str);
466     }
467     ICE_RUBY_CATCH
468     return Qnil;
469 }
470 
471 extern "C"
472 VALUE
IceRuby_Communicator_propertyToProxy(VALUE self,VALUE str)473 IceRuby_Communicator_propertyToProxy(VALUE self, VALUE str)
474 {
475     ICE_RUBY_TRY
476     {
477         Ice::CommunicatorPtr p = getCommunicator(self);
478         string s = getString(str);
479         Ice::ObjectPrx proxy = p->propertyToProxy(s);
480         if(proxy)
481         {
482             return createProxy(proxy);
483         }
484     }
485     ICE_RUBY_CATCH
486     return Qnil;
487 }
488 
489 extern "C"
490 VALUE
IceRuby_Communicator_proxyToProperty(VALUE self,VALUE obj,VALUE str)491 IceRuby_Communicator_proxyToProperty(VALUE self, VALUE obj, VALUE str)
492 {
493     ICE_RUBY_TRY
494     {
495         if(!checkProxy(obj))
496         {
497             throw RubyException(rb_eTypeError, "argument must be a proxy");
498         }
499         Ice::CommunicatorPtr p = getCommunicator(self);
500         Ice::ObjectPrx o = getProxy(obj);
501         string s = getString(str);
502         Ice::PropertyDict dict = p->proxyToProperty(o, s);
503         volatile VALUE result = callRuby(rb_hash_new);
504         for(Ice::PropertyDict::const_iterator q = dict.begin(); q != dict.end(); ++q)
505         {
506             volatile VALUE key = createString(q->first);
507             volatile VALUE value = createString(q->second);
508             callRuby(rb_hash_aset, result, key, value);
509         }
510         return result;
511     }
512     ICE_RUBY_CATCH
513     return Qnil;
514 }
515 
516 extern "C"
517 VALUE
IceRuby_Communicator_stringToIdentity(VALUE self,VALUE str)518 IceRuby_Communicator_stringToIdentity(VALUE self, VALUE str)
519 {
520     ICE_RUBY_TRY
521     {
522         Ice::CommunicatorPtr p = getCommunicator(self);
523         string s = getString(str);
524         Ice::Identity ident = p->stringToIdentity(s);
525         return createIdentity(ident);
526     }
527     ICE_RUBY_CATCH
528     return Qnil;
529 }
530 
531 extern "C"
532 VALUE
IceRuby_Communicator_identityToString(VALUE self,VALUE id)533 IceRuby_Communicator_identityToString(VALUE self, VALUE id)
534 {
535     ICE_RUBY_TRY
536     {
537         Ice::CommunicatorPtr p = getCommunicator(self);
538         Ice::Identity ident = getIdentity(id);
539         string str = p->identityToString(ident);
540         return createString(str);
541     }
542     ICE_RUBY_CATCH
543     return Qnil;
544 }
545 
546 extern "C"
547 VALUE
IceRuby_Communicator_addObjectFactory(VALUE self,VALUE factory,VALUE id)548 IceRuby_Communicator_addObjectFactory(VALUE self, VALUE factory, VALUE id)
549 {
550     ICE_RUBY_TRY
551     {
552         Ice::CommunicatorPtr p = getCommunicator(self);
553         ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast(p->getValueFactoryManager());
554         assert(vfm);
555         string idstr = getString(id);
556         vfm->addObjectFactory(factory, idstr);
557     }
558     ICE_RUBY_CATCH
559     return Qnil;
560 }
561 
562 extern "C"
563 VALUE
IceRuby_Communicator_findObjectFactory(VALUE self,VALUE id)564 IceRuby_Communicator_findObjectFactory(VALUE self, VALUE id)
565 {
566     ICE_RUBY_TRY
567     {
568         Ice::CommunicatorPtr p = getCommunicator(self);
569         ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast(p->getValueFactoryManager());
570         assert(vfm);
571         string idstr = getString(id);
572         return vfm->findObjectFactory(idstr);
573     }
574     ICE_RUBY_CATCH
575     return Qnil;
576 }
577 
578 extern "C"
579 VALUE
IceRuby_Communicator_getValueFactoryManager(VALUE self)580 IceRuby_Communicator_getValueFactoryManager(VALUE self)
581 {
582     ICE_RUBY_TRY
583     {
584         Ice::CommunicatorPtr p = getCommunicator(self);
585         ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast(p->getValueFactoryManager());
586         assert(vfm);
587         return vfm->getObject();
588     }
589     ICE_RUBY_CATCH
590     return Qnil;
591 }
592 
593 extern "C"
594 VALUE
IceRuby_Communicator_getImplicitContext(VALUE self)595 IceRuby_Communicator_getImplicitContext(VALUE self)
596 {
597     ICE_RUBY_TRY
598     {
599         Ice::CommunicatorPtr p = getCommunicator(self);
600         Ice::ImplicitContextPtr implicitContext = p->getImplicitContext();
601         return createImplicitContext(implicitContext);
602     }
603     ICE_RUBY_CATCH
604     return Qnil;
605 }
606 
607 extern "C"
608 VALUE
IceRuby_Communicator_getProperties(VALUE self)609 IceRuby_Communicator_getProperties(VALUE self)
610 {
611     ICE_RUBY_TRY
612     {
613         Ice::CommunicatorPtr p = getCommunicator(self);
614         Ice::PropertiesPtr props = p->getProperties();
615         return createProperties(props);
616     }
617     ICE_RUBY_CATCH
618     return Qnil;
619 }
620 
621 extern "C"
622 VALUE
IceRuby_Communicator_getLogger(VALUE self)623 IceRuby_Communicator_getLogger(VALUE self)
624 {
625     ICE_RUBY_TRY
626     {
627         Ice::CommunicatorPtr p = getCommunicator(self);
628         Ice::LoggerPtr logger = p->getLogger();
629         return createLogger(logger);
630     }
631     ICE_RUBY_CATCH
632     return Qnil;
633 }
634 
635 extern "C"
636 VALUE
IceRuby_Communicator_getDefaultRouter(VALUE self)637 IceRuby_Communicator_getDefaultRouter(VALUE self)
638 {
639     ICE_RUBY_TRY
640     {
641         Ice::CommunicatorPtr p = getCommunicator(self);
642         Ice::RouterPrx router = p->getDefaultRouter();
643         if(router)
644         {
645             volatile VALUE cls = callRuby(rb_path2class, "Ice::RouterPrx");
646             assert(!NIL_P(cls));
647             return createProxy(router, cls);
648         }
649     }
650     ICE_RUBY_CATCH
651     return Qnil;
652 }
653 
654 extern "C"
655 VALUE
IceRuby_Communicator_setDefaultRouter(VALUE self,VALUE router)656 IceRuby_Communicator_setDefaultRouter(VALUE self, VALUE router)
657 {
658     ICE_RUBY_TRY
659     {
660         Ice::CommunicatorPtr p = getCommunicator(self);
661         Ice::RouterPrx proxy;
662         if(!NIL_P(router))
663         {
664             if(!checkProxy(router))
665             {
666                 throw RubyException(rb_eTypeError, "argument must be a proxy");
667             }
668             proxy = Ice::RouterPrx::uncheckedCast(getProxy(router));
669         }
670         p->setDefaultRouter(proxy);
671     }
672     ICE_RUBY_CATCH
673     return Qnil;
674 }
675 
676 extern "C"
677 VALUE
IceRuby_Communicator_getDefaultLocator(VALUE self)678 IceRuby_Communicator_getDefaultLocator(VALUE self)
679 {
680     ICE_RUBY_TRY
681     {
682         Ice::CommunicatorPtr p = getCommunicator(self);
683         Ice::LocatorPrx locator = p->getDefaultLocator();
684         if(locator)
685         {
686             volatile VALUE cls = callRuby(rb_path2class, "Ice::LocatorPrx");
687             assert(!NIL_P(cls));
688             return createProxy(locator, cls);
689         }
690     }
691     ICE_RUBY_CATCH
692     return Qnil;
693 }
694 
695 extern "C"
696 VALUE
IceRuby_Communicator_setDefaultLocator(VALUE self,VALUE locator)697 IceRuby_Communicator_setDefaultLocator(VALUE self, VALUE locator)
698 {
699     ICE_RUBY_TRY
700     {
701         Ice::CommunicatorPtr p = getCommunicator(self);
702         Ice::LocatorPrx proxy;
703         if(!NIL_P(locator))
704         {
705             if(!checkProxy(locator))
706             {
707                 throw RubyException(rb_eTypeError, "argument must be a proxy");
708             }
709             proxy = Ice::LocatorPrx::uncheckedCast(getProxy(locator));
710         }
711         p->setDefaultLocator(proxy);
712     }
713     ICE_RUBY_CATCH
714     return Qnil;
715 }
716 
717 extern "C"
718 VALUE
IceRuby_Communicator_flushBatchRequests(VALUE self,VALUE compress)719 IceRuby_Communicator_flushBatchRequests(VALUE self, VALUE compress)
720 {
721     ICE_RUBY_TRY
722     {
723         Ice::CommunicatorPtr p = getCommunicator(self);
724 
725         volatile VALUE type = callRuby(rb_path2class, "Ice::CompressBatch");
726         if(callRuby(rb_obj_is_instance_of, compress, type) != Qtrue)
727         {
728             throw RubyException(rb_eTypeError,
729                 "value for 'compress' argument must be an enumerator of Ice::CompressBatch");
730         }
731         volatile VALUE compressValue = callRuby(rb_funcall, compress, rb_intern("to_i"), 0);
732         assert(TYPE(compressValue) == T_FIXNUM);
733         Ice::CompressBatch cb = static_cast<Ice::CompressBatch>(FIX2LONG(compressValue));
734         p->flushBatchRequests(cb);
735     }
736     ICE_RUBY_CATCH
737     return Qnil;
738 }
739 
740 void
initCommunicator(VALUE iceModule)741 IceRuby::initCommunicator(VALUE iceModule)
742 {
743     rb_define_module_function(iceModule, "initialize", CAST_METHOD(IceRuby_initialize), -1);
744     rb_define_module_function(iceModule, "identityToString", CAST_METHOD(IceRuby_identityToString), -1);
745     rb_define_module_function(iceModule, "stringToIdentity", CAST_METHOD(IceRuby_stringToIdentity), 1);
746 
747     _communicatorClass = rb_define_class_under(iceModule, "CommunicatorI", rb_cObject);
748     rb_define_method(_communicatorClass, "destroy", CAST_METHOD(IceRuby_Communicator_destroy), 0);
749     rb_define_method(_communicatorClass, "shutdown", CAST_METHOD(IceRuby_Communicator_shutdown), 0);
750     rb_define_method(_communicatorClass, "isShutdown", CAST_METHOD(IceRuby_Communicator_isShutdown), 0);
751     rb_define_method(_communicatorClass, "waitForShutdown", CAST_METHOD(IceRuby_Communicator_waitForShutdown), 0);
752     rb_define_method(_communicatorClass, "stringToProxy", CAST_METHOD(IceRuby_Communicator_stringToProxy), 1);
753     rb_define_method(_communicatorClass, "proxyToString", CAST_METHOD(IceRuby_Communicator_proxyToString), 1);
754     rb_define_method(_communicatorClass, "propertyToProxy", CAST_METHOD(IceRuby_Communicator_propertyToProxy), 1);
755     rb_define_method(_communicatorClass, "proxyToProperty", CAST_METHOD(IceRuby_Communicator_proxyToProperty), 2);
756     rb_define_method(_communicatorClass, "stringToIdentity", CAST_METHOD(IceRuby_Communicator_stringToIdentity), 1);
757     rb_define_method(_communicatorClass, "identityToString", CAST_METHOD(IceRuby_Communicator_identityToString), 1);
758     rb_define_method(_communicatorClass, "addObjectFactory", CAST_METHOD(IceRuby_Communicator_addObjectFactory), 2);
759     rb_define_method(_communicatorClass, "findObjectFactory", CAST_METHOD(IceRuby_Communicator_findObjectFactory), 1);
760     rb_define_method(_communicatorClass, "getValueFactoryManager", CAST_METHOD(IceRuby_Communicator_getValueFactoryManager), 0);
761     rb_define_method(_communicatorClass, "getImplicitContext", CAST_METHOD(IceRuby_Communicator_getImplicitContext), 0);
762     rb_define_method(_communicatorClass, "getProperties", CAST_METHOD(IceRuby_Communicator_getProperties), 0);
763     rb_define_method(_communicatorClass, "getLogger", CAST_METHOD(IceRuby_Communicator_getLogger), 0);
764     rb_define_method(_communicatorClass, "getDefaultRouter", CAST_METHOD(IceRuby_Communicator_getDefaultRouter), 0);
765     rb_define_method(_communicatorClass, "setDefaultRouter", CAST_METHOD(IceRuby_Communicator_setDefaultRouter), 1);
766     rb_define_method(_communicatorClass, "getDefaultLocator", CAST_METHOD(IceRuby_Communicator_getDefaultLocator), 0);
767     rb_define_method(_communicatorClass, "setDefaultLocator", CAST_METHOD(IceRuby_Communicator_setDefaultLocator), 1);
768     rb_define_method(_communicatorClass, "flushBatchRequests", CAST_METHOD(IceRuby_Communicator_flushBatchRequests), 1);
769 }
770 
771 Ice::CommunicatorPtr
getCommunicator(VALUE v)772 IceRuby::getCommunicator(VALUE v)
773 {
774     Ice::CommunicatorPtr* p = reinterpret_cast<Ice::CommunicatorPtr*>(DATA_PTR(v));
775     assert(p);
776     return *p;
777 }
778 
779 VALUE
lookupCommunicator(const Ice::CommunicatorPtr & p)780 IceRuby::lookupCommunicator(const Ice::CommunicatorPtr& p)
781 {
782     CommunicatorMap::iterator q = _communicatorMap.find(p.get());
783     if(q != _communicatorMap.end())
784     {
785         return q->second;
786     }
787     return Qnil;
788 }
789