summaryrefslogtreecommitdiff
path: root/ruby/src
diff options
context:
space:
mode:
Diffstat (limited to 'ruby/src')
-rw-r--r--ruby/src/IceRuby/Communicator.cpp54
-rw-r--r--ruby/src/IceRuby/Init.cpp2
-rw-r--r--ruby/src/IceRuby/Makefile4
-rw-r--r--ruby/src/IceRuby/ObjectFactory.cpp140
-rw-r--r--ruby/src/IceRuby/ObjectFactory.h50
-rw-r--r--ruby/src/IceRuby/Operation.cpp73
-rw-r--r--ruby/src/IceRuby/Types.cpp184
-rw-r--r--ruby/src/IceRuby/Types.h163
-rw-r--r--ruby/src/IceRuby/Util.cpp8
-rw-r--r--ruby/src/IceRuby/Util.h2
-rw-r--r--ruby/src/IceRuby/ValueFactoryManager.cpp432
-rw-r--r--ruby/src/IceRuby/ValueFactoryManager.h100
12 files changed, 825 insertions, 387 deletions
diff --git a/ruby/src/IceRuby/Communicator.cpp b/ruby/src/IceRuby/Communicator.cpp
index 7a7635c1dbf..3d90f420464 100644
--- a/ruby/src/IceRuby/Communicator.cpp
+++ b/ruby/src/IceRuby/Communicator.cpp
@@ -10,11 +10,12 @@
#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 <ValueFactoryManager.h>
+#include <IceUtil/DisableWarnings.h>
#include <Ice/Communicator.h>
#include <Ice/Initialize.h>
#include <Ice/Locator.h>
@@ -37,9 +38,9 @@ IceRuby_Communicator_mark(Ice::CommunicatorPtr* p)
assert(p);
try
{
- ObjectFactoryPtr pof = ObjectFactoryPtr::dynamicCast((*p)->findObjectFactory(""));
- assert(pof);
- pof->mark();
+ ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast((*p)->getValueFactoryManager());
+ assert(vfm);
+ vfm->markSelf();
}
catch(const Ice::CommunicatorDestroyedException&)
{
@@ -128,6 +129,7 @@ IceRuby_initialize(int argc, VALUE* argv, VALUE self)
seq.insert(seq.begin(), getString(progName));
data.compactIdResolver = new IdResolver;
+ data.valueFactoryManager = new ValueFactoryManager;
if(hasArgs)
{
@@ -181,7 +183,7 @@ IceRuby_initialize(int argc, VALUE* argv, VALUE self)
throw;
}
-
+
//
// Replace the contents of the given argument list with the filtered arguments.
//
@@ -205,9 +207,6 @@ IceRuby_initialize(int argc, VALUE* argv, VALUE self)
}
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));
@@ -256,12 +255,19 @@ extern "C"
VALUE
IceRuby_Communicator_destroy(VALUE self)
{
+ Ice::CommunicatorPtr p = getCommunicator(self);
+
+ ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast(p->getValueFactoryManager());
+ assert(vfm);
+
ICE_RUBY_TRY
{
- Ice::CommunicatorPtr p = getCommunicator(self);
p->destroy();
}
ICE_RUBY_CATCH
+
+ vfm->destroy();
+
return Qnil;
}
@@ -371,7 +377,7 @@ IceRuby_Communicator_proxyToProperty(VALUE self, VALUE obj, VALUE str)
volatile VALUE value = createString(q->second);
callRuby(rb_hash_aset, result, key, value);
}
- return result;
+ return result;
}
ICE_RUBY_CATCH
return Qnil;
@@ -414,10 +420,10 @@ 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);
+ ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast(p->getValueFactoryManager());
+ assert(vfm);
string idstr = getString(id);
- pof->add(factory, idstr);
+ vfm->addObjectFactory(factory, idstr);
}
ICE_RUBY_CATCH
return Qnil;
@@ -430,10 +436,25 @@ IceRuby_Communicator_findObjectFactory(VALUE self, VALUE id)
ICE_RUBY_TRY
{
Ice::CommunicatorPtr p = getCommunicator(self);
- ObjectFactoryPtr pof = ObjectFactoryPtr::dynamicCast(p->findObjectFactory(""));
- assert(pof);
+ ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast(p->getValueFactoryManager());
+ assert(vfm);
string idstr = getString(id);
- return pof->find(idstr);
+ return vfm->findObjectFactory(idstr);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_Communicator_getValueFactoryManager(VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ Ice::CommunicatorPtr p = getCommunicator(self);
+ ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast(p->getValueFactoryManager());
+ assert(vfm);
+ return vfm->getObject();
}
ICE_RUBY_CATCH
return Qnil;
@@ -596,6 +617,7 @@ IceRuby::initCommunicator(VALUE iceModule)
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, "getValueFactoryManager", CAST_METHOD(IceRuby_Communicator_getValueFactoryManager), 0);
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);
diff --git a/ruby/src/IceRuby/Init.cpp b/ruby/src/IceRuby/Init.cpp
index 26f915275fb..5520de7d9fe 100644
--- a/ruby/src/IceRuby/Init.cpp
+++ b/ruby/src/IceRuby/Init.cpp
@@ -17,6 +17,7 @@
#include <Types.h>
#include <Connection.h>
#include <Endpoint.h>
+#include <ValueFactoryManager.h>
using namespace std;
using namespace IceRuby;
@@ -54,6 +55,7 @@ ICE_DECLSPEC_EXPORT Init_IceRuby()
initUtil(iceModule);
initConnection(iceModule);
initEndpoint(iceModule);
+ initValueFactoryManager(iceModule);
}
}
diff --git a/ruby/src/IceRuby/Makefile b/ruby/src/IceRuby/Makefile
index 2cb6e3a8c30..ccbdc362991 100644
--- a/ruby/src/IceRuby/Makefile
+++ b/ruby/src/IceRuby/Makefile
@@ -20,13 +20,13 @@ OBJS = Communicator.o \
ImplicitContext.o \
Init.o \
Logger.o \
- ObjectFactory.o \
Operation.o \
Properties.o \
Proxy.o \
Slice.o \
Types.o \
- Util.o
+ Util.o \
+ ValueFactoryManager.o
include $(top_srcdir)/config/Make.rules
diff --git a/ruby/src/IceRuby/ObjectFactory.cpp b/ruby/src/IceRuby/ObjectFactory.cpp
deleted file mode 100644
index 2c2282b7fe2..00000000000
--- a/ruby/src/IceRuby/ObjectFactory.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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
deleted file mode 100644
index a677ad51833..00000000000
--- a/ruby/src/IceRuby/ObjectFactory.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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
index 2f4d34210ca..55de1f69c0e 100644
--- a/ruby/src/IceRuby/Operation.cpp
+++ b/ruby/src/IceRuby/Operation.cpp
@@ -71,7 +71,7 @@ private:
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*>&);
+ void prepareRequest(const Ice::ObjectPrx&, VALUE, Ice::OutputStream*, 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;
@@ -79,27 +79,18 @@ private:
};
typedef IceUtil::Handle<OperationI> OperationIPtr;
-class UserExceptionReaderFactoryI : public Ice::UserExceptionReaderFactory
+class UserExceptionFactory : public Ice::UserExceptionFactory
{
public:
- UserExceptionReaderFactoryI(const Ice::CommunicatorPtr& communicator) :
- _communicator(communicator)
- {
- }
-
- virtual void createAndThrow(const string& id) const
+ virtual void createAndThrow(const string& id)
{
ExceptionInfoPtr info = lookupExceptionInfo(id);
if(info)
{
- throw ExceptionReader(_communicator, info);
+ throw ExceptionReader(info);
}
}
-
-private:
-
- const Ice::CommunicatorPtr _communicator;
};
}
@@ -299,9 +290,9 @@ IceRuby::OperationI::invoke(const Ice::ObjectPrx& proxy, VALUE args, VALUE hctx)
//
// Marshal the input parameters to a byte sequence.
//
- Ice::OutputStreamPtr os;
+ Ice::OutputStream os(communicator);
pair<const Ice::Byte*, const Ice::Byte*> params;
- prepareRequest(proxy, args, os, params);
+ prepareRequest(proxy, args, &os, params);
if(!_deprecateMessage.empty())
{
@@ -409,7 +400,7 @@ IceRuby::OperationI::convertParam(VALUE v, int pos)
}
void
-IceRuby::OperationI::prepareRequest(const Ice::ObjectPrx& proxy, VALUE args, Ice::OutputStreamPtr& os,
+IceRuby::OperationI::prepareRequest(const Ice::ObjectPrx& proxy, VALUE args, Ice::OutputStream* os,
pair<const Ice::Byte*, const Ice::Byte*>& params)
{
params.first = params.second = static_cast<const Ice::Byte*>(0);
@@ -430,7 +421,6 @@ IceRuby::OperationI::prepareRequest(const Ice::ObjectPrx& proxy, VALUE args, Ice
//
// Marshal the in parameters.
//
- os = Ice::createOutputStream(proxy->ice_getCommunicator());
os->startEncapsulation(proxy->ice_getEncodingVersion(), _format);
ObjectMap objectMap;
@@ -503,17 +493,17 @@ IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice:
// 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);
+ Ice::InputStream is(communicator, bytes);
//
- // Store a pointer to a local SlicedDataUtil object as the stream's closure.
+ // Store a pointer to a local StreamUtil object as the stream's closure.
// This is necessary to support object unmarshaling (see ObjectReader).
//
- SlicedDataUtil util;
- assert(!is->closure());
- is->closure(&util);
+ StreamUtil util;
+ assert(!is.getClosure());
+ is.setClosure(&util);
- is->startEncapsulation();
+ is.startEncapsulation();
ParamInfoList::iterator p;
@@ -526,7 +516,7 @@ IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice:
if(!info->optional)
{
void* closure = reinterpret_cast<void*>(info->pos);
- info->type->unmarshal(is, info, results, closure, false);
+ info->type->unmarshal(&is, info, results, closure, false);
}
}
@@ -537,7 +527,7 @@ IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice:
{
assert(_returnType->pos == 0);
void* closure = reinterpret_cast<void*>(_returnType->pos);
- _returnType->type->unmarshal(is, _returnType, results, closure, false);
+ _returnType->type->unmarshal(&is, _returnType, results, closure, false);
}
//
@@ -546,10 +536,10 @@ IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice:
for(p = _optionalOutParams.begin(); p != _optionalOutParams.end(); ++p)
{
ParamInfoPtr info = *p;
- if(is->readOptional(info->tag, info->type->optionalFormat()))
+ if(is.readOptional(info->tag, info->type->optionalFormat()))
{
void* closure = reinterpret_cast<void*>(info->pos);
- info->type->unmarshal(is, info, results, closure, true);
+ info->type->unmarshal(&is, info, results, closure, true);
}
else
{
@@ -559,12 +549,12 @@ IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice:
if(_returnsClasses)
{
- is->readPendingObjects();
+ is.readPendingObjects();
}
- is->endEncapsulation();
+ is.endEncapsulation();
- util.update();
+ util.updateSlicedData();
return results;
}
@@ -572,37 +562,37 @@ IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice:
VALUE
IceRuby::OperationI::unmarshalException(const vector<Ice::Byte>& bytes, const Ice::CommunicatorPtr& communicator)
{
- Ice::InputStreamPtr is = Ice::wrapInputStream(communicator, bytes);
+ Ice::InputStream is(communicator, bytes);
//
- // Store a pointer to a local SlicedDataUtil object as the stream's closure.
+ // Store a pointer to a local StreamUtil object as the stream's closure.
// This is necessary to support object unmarshaling (see ObjectReader).
//
- SlicedDataUtil util;
- assert(!is->closure());
- is->closure(&util);
+ StreamUtil util;
+ assert(!is.getClosure());
+ is.setClosure(&util);
- is->startEncapsulation();
+ is.startEncapsulation();
try
{
- Ice::UserExceptionReaderFactoryPtr factory = new UserExceptionReaderFactoryI(communicator);
- is->throwException(factory);
+ Ice::UserExceptionFactoryPtr factory = new UserExceptionFactory;
+ is.throwException(factory);
}
catch(const ExceptionReader& r)
{
- is->endEncapsulation();
+ is.endEncapsulation();
volatile VALUE ex = r.getException();
if(validateException(ex))
{
- util.update();
+ util.updateSlicedData();
Ice::SlicedDataPtr slicedData = r.getSlicedData();
if(slicedData)
{
- SlicedDataUtil::setMember(ex, slicedData);
+ StreamUtil::setSlicedDataMember(ex, slicedData);
}
return ex;
@@ -622,7 +612,6 @@ IceRuby::OperationI::unmarshalException(const vector<Ice::Byte>& bytes, const Ic
#ifdef __SUNPRO_CC
return 0;
#endif
-
}
bool
diff --git a/ruby/src/IceRuby/Types.cpp b/ruby/src/IceRuby/Types.cpp
index 8ca6e29cffa..228154401d6 100644
--- a/ruby/src/IceRuby/Types.cpp
+++ b/ruby/src/IceRuby/Types.cpp
@@ -13,7 +13,9 @@
#include <IceUtil/InputUtil.h>
#include <IceUtil/OutputUtil.h>
#include <IceUtil/ScopedArray.h>
+#include <Ice/InputStream.h>
#include <Ice/LocalException.h>
+#include <Ice/OutputStream.h>
#include <Ice/SlicedData.h>
#include <list>
#include <limits>
@@ -63,22 +65,6 @@ public:
};
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)
{
@@ -184,16 +170,16 @@ addExceptionInfo(const string& id, const ExceptionInfoPtr& info)
}
//
-// SlicedDataUtil implementation
+// StreamUtil implementation
//
-VALUE IceRuby::SlicedDataUtil::_slicedDataType = Qnil;
-VALUE IceRuby::SlicedDataUtil::_sliceInfoType = Qnil;
+VALUE IceRuby::StreamUtil::_slicedDataType = Qnil;
+VALUE IceRuby::StreamUtil::_sliceInfoType = Qnil;
-IceRuby::SlicedDataUtil::SlicedDataUtil()
+IceRuby::StreamUtil::StreamUtil()
{
}
-IceRuby::SlicedDataUtil::~SlicedDataUtil()
+IceRuby::StreamUtil::~StreamUtil()
{
//
// Make sure we break any cycles among the ObjectReaders in preserved slices.
@@ -216,23 +202,29 @@ IceRuby::SlicedDataUtil::~SlicedDataUtil()
}
void
-IceRuby::SlicedDataUtil::add(const ObjectReaderPtr& reader)
+IceRuby::StreamUtil::add(const ReadObjectCallbackPtr& callback)
+{
+ _callbacks.push_back(callback);
+}
+
+void
+IceRuby::StreamUtil::add(const ObjectReaderPtr& reader)
{
assert(reader->getSlicedData());
_readers.insert(reader);
}
void
-IceRuby::SlicedDataUtil::update()
+IceRuby::StreamUtil::updateSlicedData()
{
for(set<ObjectReaderPtr>::iterator p = _readers.begin(); p != _readers.end(); ++p)
{
- setMember((*p)->getObject(), (*p)->getSlicedData());
+ setSlicedDataMember((*p)->getObject(), (*p)->getSlicedData());
}
}
void
-IceRuby::SlicedDataUtil::setMember(VALUE obj, const Ice::SlicedDataPtr& slicedData)
+IceRuby::StreamUtil::setSlicedDataMember(VALUE obj, const Ice::SlicedDataPtr& slicedData)
{
//
// Create a Ruby equivalent of the SlicedData object.
@@ -325,7 +317,7 @@ IceRuby::SlicedDataUtil::setMember(VALUE obj, const Ice::SlicedDataPtr& slicedDa
// named _ice_slicedData which is an instance of the Ruby class Ice::SlicedData.
//
Ice::SlicedDataPtr
-IceRuby::SlicedDataUtil::getMember(VALUE obj, ObjectMap* objectMap)
+IceRuby::StreamUtil::getSlicedDataMember(VALUE obj, ObjectMap* objectMap)
{
Ice::SlicedDataPtr slicedData;
@@ -544,7 +536,7 @@ IceRuby::PrimitiveInfo::optionalFormat() const
}
void
-IceRuby::PrimitiveInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*, bool)
+IceRuby::PrimitiveInfo::marshal(VALUE p, Ice::OutputStream* os, ObjectMap*, bool)
{
switch(kind)
{
@@ -625,7 +617,7 @@ IceRuby::PrimitiveInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectM
}
void
-IceRuby::PrimitiveInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+IceRuby::PrimitiveInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb, VALUE target,
void* closure, bool)
{
volatile VALUE val = Qnil;
@@ -814,7 +806,7 @@ IceRuby::EnumInfo::optionalFormat() const
}
void
-IceRuby::EnumInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*, bool)
+IceRuby::EnumInfo::marshal(VALUE p, Ice::OutputStream* os, ObjectMap*, bool)
{
assert(callRuby(rb_obj_is_instance_of, p, rubyClass) == Qtrue); // validate() should have caught this.
@@ -832,7 +824,7 @@ IceRuby::EnumInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*,
}
void
-IceRuby::EnumInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target, void* closure,
+IceRuby::EnumInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb, VALUE target, void* closure,
bool)
{
Ice::Int val = is->readEnum(maxValue);
@@ -995,7 +987,7 @@ IceRuby::StructInfo::usesClasses() const
}
void
-IceRuby::StructInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
+IceRuby::StructInfo::marshal(VALUE p, Ice::OutputStream* os, ObjectMap* objectMap, bool optional)
{
assert(NIL_P(p) || callRuby(rb_obj_is_kind_of, p, rubyClass) == Qtrue); // validate() should have caught this.
@@ -1041,7 +1033,7 @@ IceRuby::StructInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*
}
void
-IceRuby::StructInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+IceRuby::StructInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb, VALUE target,
void* closure, bool optional)
{
volatile VALUE obj = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), rubyClass);
@@ -1178,7 +1170,7 @@ IceRuby::SequenceInfo::usesClasses() const
}
void
-IceRuby::SequenceInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
+IceRuby::SequenceInfo::marshal(VALUE p, Ice::OutputStream* os, ObjectMap* objectMap, bool optional)
{
PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
@@ -1256,7 +1248,7 @@ IceRuby::SequenceInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMa
}
void
-IceRuby::SequenceInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+IceRuby::SequenceInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb, VALUE target,
void* closure, bool optional)
{
if(optional)
@@ -1355,7 +1347,7 @@ IceRuby::SequenceInfo::destroy()
}
void
-IceRuby::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, VALUE p, const Ice::OutputStreamPtr& os)
+IceRuby::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, VALUE p, Ice::OutputStream* os)
{
volatile VALUE arr = Qnil;
volatile VALUE str = Qnil;
@@ -1517,14 +1509,14 @@ IceRuby::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, VALU
{
seq[i] = getString(RARRAY_PTR(arr)[i]);
}
- os->write(seq, true);
+ os->write(&seq[0], &seq[0] + seq.size());
break;
}
}
}
void
-IceRuby::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, const Ice::InputStreamPtr& is,
+IceRuby::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice::InputStream* is,
const UnmarshalCallbackPtr& cb, VALUE target, void* closure)
{
volatile VALUE result = Qnil;
@@ -1721,7 +1713,7 @@ namespace
{
struct DictionaryMarshalIterator : public IceRuby::HashIterator
{
- DictionaryMarshalIterator(const IceRuby::DictionaryInfoPtr& d, const Ice::OutputStreamPtr o, IceRuby::ObjectMap* m)
+ DictionaryMarshalIterator(const IceRuby::DictionaryInfoPtr& d, Ice::OutputStream* o, IceRuby::ObjectMap* m)
: dict(d), os(o), objectMap(m)
{
}
@@ -1732,13 +1724,13 @@ struct DictionaryMarshalIterator : public IceRuby::HashIterator
}
IceRuby::DictionaryInfoPtr dict;
- Ice::OutputStreamPtr os;
+ Ice::OutputStream* os;
IceRuby::ObjectMap* objectMap;
};
}
void
-IceRuby::DictionaryInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
+IceRuby::DictionaryInfo::marshal(VALUE p, Ice::OutputStream* os, ObjectMap* objectMap, bool optional)
{
volatile VALUE hash = Qnil;
@@ -1791,7 +1783,7 @@ IceRuby::DictionaryInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, Object
}
void
-IceRuby::DictionaryInfo::marshalElement(VALUE key, VALUE value, const Ice::OutputStreamPtr& os, ObjectMap* objectMap)
+IceRuby::DictionaryInfo::marshalElement(VALUE key, VALUE value, Ice::OutputStream* os, ObjectMap* objectMap)
{
if(!keyType->validate(key))
{
@@ -1808,7 +1800,7 @@ IceRuby::DictionaryInfo::marshalElement(VALUE key, VALUE value, const Ice::Outpu
}
void
-IceRuby::DictionaryInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+IceRuby::DictionaryInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb, VALUE target,
void* closure, bool optional)
{
if(optional)
@@ -2062,7 +2054,7 @@ IceRuby::ClassInfo::usesClasses() const
}
void
-IceRuby::ClassInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool)
+IceRuby::ClassInfo::marshal(VALUE p, Ice::OutputStream* os, ObjectMap* objectMap, bool)
{
if(!defined)
{
@@ -2071,7 +2063,8 @@ IceRuby::ClassInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*
if(NIL_P(p))
{
- os->writeObject(0);
+ Ice::ObjectPtr nil;
+ os->write(nil);
return;
}
@@ -2097,19 +2090,40 @@ IceRuby::ClassInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*
//
// Give the writer to the stream. The stream will eventually call write() on it.
//
- os->writeObject(writer);
+ os->write(writer);
+}
+
+namespace
+{
+
+void
+patchObject(void* addr, const Ice::ObjectPtr& v)
+{
+ ReadObjectCallback* cb = static_cast<ReadObjectCallback*>(addr);
+ assert(cb);
+ cb->invoke(v);
+}
+
}
void
-IceRuby::ClassInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
- void* closure, bool)
+IceRuby::ClassInfo::unmarshal(Ice::InputStream* 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));
+ //
+ // This callback is notified when the Slice value is actually read. The StreamUtil object
+ // attached to the stream keeps a reference to the callback object to ensure it lives
+ // long enough.
+ //
+ ReadObjectCallbackPtr rocb = new ReadObjectCallback(this, cb, target, closure);
+ StreamUtil* util = reinterpret_cast<StreamUtil*>(is->getClosure());
+ assert(util);
+ util->add(rocb);
+ is->read(patchObject, rocb.get());
}
void
@@ -2336,7 +2350,7 @@ IceRuby::ProxyInfo::optionalFormat() const
}
void
-IceRuby::ProxyInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*, bool optional)
+IceRuby::ProxyInfo::marshal(VALUE p, Ice::OutputStream* os, ObjectMap*, bool optional)
{
Ice::OutputStream::size_type sizePos = -1;
if(optional)
@@ -2361,7 +2375,7 @@ IceRuby::ProxyInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*,
}
void
-IceRuby::ProxyInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, VALUE target,
+IceRuby::ProxyInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb, VALUE target,
void* closure, bool optional)
{
if(optional)
@@ -2446,7 +2460,7 @@ IceRuby::ObjectWriter::ice_preMarshal()
}
void
-IceRuby::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
+IceRuby::ObjectWriter::__write(Ice::OutputStream* os) const
{
Ice::SlicedDataPtr slicedData;
@@ -2455,7 +2469,7 @@ IceRuby::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
//
// Retrieve the SlicedData object that we stored as a hidden member of the Ruby object.
//
- slicedData = SlicedDataUtil::getMember(_object, const_cast<ObjectMap*>(_map));
+ slicedData = StreamUtil::getSlicedDataMember(_object, const_cast<ObjectMap*>(_map));
}
os->startObject(slicedData);
@@ -2480,7 +2494,13 @@ IceRuby::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
}
void
-IceRuby::ObjectWriter::writeMembers(const Ice::OutputStreamPtr& os, const DataMemberList& members) const
+IceRuby::ObjectWriter::__read(Ice::InputStream*)
+{
+ assert(false);
+}
+
+void
+IceRuby::ObjectWriter::writeMembers(Ice::OutputStream* os, const DataMemberList& members) const
{
for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
{
@@ -2531,7 +2551,13 @@ IceRuby::ObjectReader::ice_postUnmarshal()
}
void
-IceRuby::ObjectReader::read(const Ice::InputStreamPtr& is)
+IceRuby::ObjectReader::__write(Ice::OutputStream*) const
+{
+ assert(false);
+}
+
+void
+IceRuby::ObjectReader::__read(Ice::InputStream* is)
{
is->startObject();
@@ -2581,7 +2607,7 @@ IceRuby::ObjectReader::read(const Ice::InputStreamPtr& is)
if(_slicedData)
{
- SlicedDataUtil* util = reinterpret_cast<SlicedDataUtil*>(is->closure());
+ StreamUtil* util = reinterpret_cast<StreamUtil*>(is->getClosure());
assert(util);
util->add(this);
@@ -2679,7 +2705,7 @@ IceRuby::ReadObjectCallback::invoke(const Ice::ObjectPtr& p)
// ExceptionInfo implementation.
//
VALUE
-IceRuby::ExceptionInfo::unmarshal(const Ice::InputStreamPtr& is)
+IceRuby::ExceptionInfo::unmarshal(Ice::InputStream* is)
{
volatile VALUE obj = callRuby(rb_class_new_instance, 0, static_cast<VALUE*>(0), rubyClass);
@@ -2789,8 +2815,8 @@ IceRuby::ExceptionInfo::printMembers(VALUE value, IceUtilInternal::Output& out,
//
// ExceptionReader implementation.
//
-IceRuby::ExceptionReader::ExceptionReader(const Ice::CommunicatorPtr& communicator, const ExceptionInfoPtr& info) :
- Ice::UserExceptionReader(communicator), _info(info)
+IceRuby::ExceptionReader::ExceptionReader(const ExceptionInfoPtr& info) :
+ _info(info)
{
}
@@ -2799,34 +2825,20 @@ IceRuby::ExceptionReader::~ExceptionReader()
{
}
-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
+IceRuby::ExceptionReader::ice_id() const
{
return _info->id;
}
+#ifndef ICE_CPP11_MAPPING
Ice::UserException*
IceRuby::ExceptionReader::ice_clone() const
{
assert(false);
return 0;
}
+#endif
void
IceRuby::ExceptionReader::ice_throw() const
@@ -2834,6 +2846,28 @@ IceRuby::ExceptionReader::ice_throw() const
throw *this;
}
+void
+IceRuby::ExceptionReader::__write(Ice::OutputStream*) const
+{
+ assert(false);
+}
+
+void
+IceRuby::ExceptionReader::__read(Ice::InputStream* is)
+{
+ 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;
+}
+
VALUE
IceRuby::ExceptionReader::getException() const
{
diff --git a/ruby/src/IceRuby/Types.h b/ruby/src/IceRuby/Types.h
index d93ec58e7d9..809b34aed0c 100644
--- a/ruby/src/IceRuby/Types.h
+++ b/ruby/src/IceRuby/Types.h
@@ -12,7 +12,9 @@
#include <Config.h>
#include <Util.h>
-#include <Ice/Stream.h>
+#include <Ice/FactoryTable.h>
+#include <Ice/Object.h>
+#include <Ice/SlicedData.h>
#include <IceUtil/OutputUtil.h>
namespace IceRuby
@@ -40,31 +42,6 @@ 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;
@@ -95,6 +72,64 @@ public:
typedef IceUtil::Handle<UnmarshalCallback> UnmarshalCallbackPtr;
//
+// ReadObjectCallback retains all of the information necessary to store an unmarshaled
+// Slice value as a Ruby object.
+//
+class ReadObjectCallback : public IceUtil::Shared
+{
+public:
+
+ ReadObjectCallback(const ClassInfoPtr&, const UnmarshalCallbackPtr&, VALUE, void*);
+
+ void invoke(const ::Ice::ObjectPtr&);
+
+private:
+
+ ClassInfoPtr _info;
+ UnmarshalCallbackPtr _cb;
+ VALUE _target;
+ void* _closure;
+};
+typedef IceUtil::Handle<ReadObjectCallback> ReadObjectCallbackPtr;
+
+//
+// This class assists during unmarshaling of Slice classes and exceptions.
+// We attach an instance to a stream.
+//
+class StreamUtil
+{
+public:
+
+ StreamUtil();
+ ~StreamUtil();
+
+ //
+ // Keep a reference to a ReadObjectCallback for patching purposes.
+ //
+ void add(const ReadObjectCallbackPtr&);
+
+ //
+ // Keep track of object instances that have preserved slices.
+ //
+ void add(const ObjectReaderPtr&);
+
+ //
+ // Updated the sliced data information for all stored object instances.
+ //
+ void updateSlicedData();
+
+ static void setSlicedDataMember(VALUE, const Ice::SlicedDataPtr&);
+ static Ice::SlicedDataPtr getSlicedDataMember(VALUE, ObjectMap*);
+
+private:
+
+ std::vector<ReadObjectCallbackPtr> _callbacks;
+ std::set<ObjectReaderPtr> _readers;
+ static VALUE _slicedDataType;
+ static VALUE _sliceInfoType;
+};
+
+//
// Base class for type information.
//
class TypeInfo : public UnmarshalCallback
@@ -125,8 +160,8 @@ 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 marshal(VALUE, Ice::OutputStream*, ObjectMap*, bool) = 0;
+ virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, VALUE, void*, bool) = 0;
virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*) = 0;
};
@@ -162,8 +197,8 @@ public:
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 marshal(VALUE, Ice::OutputStream*, ObjectMap*, bool);
+ virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, VALUE, void*, bool);
virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
@@ -192,8 +227,8 @@ public:
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 marshal(VALUE, Ice::OutputStream*, ObjectMap*, bool);
+ virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, VALUE, void*, bool);
virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
@@ -238,8 +273,8 @@ public:
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 marshal(VALUE, Ice::OutputStream*, ObjectMap*, bool);
+ virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, VALUE, void*, bool);
virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
@@ -276,8 +311,8 @@ public:
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 marshal(VALUE, Ice::OutputStream*, ObjectMap*, bool);
+ virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, VALUE, void*, bool);
virtual void unmarshaled(VALUE, VALUE, void*);
virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
@@ -289,8 +324,8 @@ public:
private:
- void marshalPrimitiveSequence(const PrimitiveInfoPtr&, VALUE, const Ice::OutputStreamPtr&);
- void unmarshalPrimitiveSequence(const PrimitiveInfoPtr&, const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&,
+ void marshalPrimitiveSequence(const PrimitiveInfoPtr&, VALUE, Ice::OutputStream*);
+ void unmarshalPrimitiveSequence(const PrimitiveInfoPtr&, Ice::InputStream*, const UnmarshalCallbackPtr&,
VALUE, void*);
};
typedef IceUtil::Handle<SequenceInfo> SequenceInfoPtr;
@@ -314,9 +349,9 @@ public:
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 marshal(VALUE, Ice::OutputStream*, ObjectMap*, bool);
+ virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, VALUE, void*, bool);
+ void marshalElement(VALUE, VALUE, Ice::OutputStream*, ObjectMap*);
virtual void unmarshaled(VALUE, VALUE, void*);
virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
@@ -365,8 +400,8 @@ public:
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 marshal(VALUE, Ice::OutputStream*, ObjectMap*, bool);
+ virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, VALUE, void*, bool);
virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
@@ -410,8 +445,8 @@ public:
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 marshal(VALUE, Ice::OutputStream*, ObjectMap*, bool);
+ virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, VALUE, void*, bool);
virtual void print(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
@@ -431,7 +466,7 @@ class ExceptionInfo : public IceUtil::Shared
{
public:
- VALUE unmarshal(const Ice::InputStreamPtr&);
+ VALUE unmarshal(Ice::InputStream*);
void print(VALUE, IceUtilInternal::Output&);
void printMembers(VALUE, IceUtilInternal::Output&, PrintObjectHistory*);
@@ -448,7 +483,7 @@ public:
//
// ObjectWriter wraps a Ruby object for marshaling.
//
-class ObjectWriter : public Ice::ObjectWriter
+class ObjectWriter : public Ice::Object
{
public:
@@ -457,11 +492,12 @@ public:
virtual void ice_preMarshal();
- virtual void write(const Ice::OutputStreamPtr&) const;
+ virtual void __write(Ice::OutputStream*) const;
+ virtual void __read(Ice::InputStream*);
private:
- void writeMembers(const Ice::OutputStreamPtr&, const DataMemberList&) const;
+ void writeMembers(Ice::OutputStream*, const DataMemberList&) const;
VALUE _object;
ObjectMap* _map;
@@ -471,7 +507,7 @@ private:
//
// ObjectReader unmarshals the state of an Ice object.
//
-class ObjectReader : public Ice::ObjectReader
+class ObjectReader : public Ice::Object
{
public:
@@ -480,7 +516,8 @@ public:
virtual void ice_postUnmarshal();
- virtual void read(const Ice::InputStreamPtr&);
+ virtual void __write(Ice::OutputStream*) const;
+ virtual void __read(Ice::InputStream*);
virtual ClassInfoPtr getInfo() const;
@@ -498,24 +535,36 @@ private:
//
// ExceptionReader creates a Ruby user exception and unmarshals it.
//
-class ExceptionReader : public Ice::UserExceptionReader
+class ExceptionReader : public Ice::UserException
{
public:
- ExceptionReader(const Ice::CommunicatorPtr&, const ExceptionInfoPtr&);
+ ExceptionReader(const ExceptionInfoPtr&);
~ExceptionReader() throw();
- virtual void read(const Ice::InputStreamPtr&) const;
- virtual bool usesClasses() const;
-
- virtual std::string ice_name() const;
+ virtual std::string ice_id() const;
+#ifndef ICE_CPP11_MAPPING
virtual Ice::UserException* ice_clone() const;
+#endif
virtual void ice_throw() const;
+ virtual void __write(Ice::OutputStream*) const;
+ virtual void __read(Ice::InputStream*);
+
+ virtual bool __usesClasses() const;
+
VALUE getException() const;
Ice::SlicedDataPtr getSlicedData() const;
+ using Ice::UserException::__read;
+ using Ice::UserException::__write;
+
+protected:
+
+ virtual void __writeImpl(Ice::OutputStream*) const {}
+ virtual void __readImpl(Ice::InputStream*) {}
+
private:
ExceptionInfoPtr _info;
diff --git a/ruby/src/IceRuby/Util.cpp b/ruby/src/IceRuby/Util.cpp
index 6b9ba1314d7..e297c258c03 100644
--- a/ruby/src/IceRuby/Util.cpp
+++ b/ruby/src/IceRuby/Util.cpp
@@ -311,7 +311,7 @@ IceRuby::createString(const string& str)
namespace
{
-template <typename T>
+template <typename T>
struct RubyCallArgs
{
volatile VALUE val;
@@ -699,7 +699,7 @@ setExceptionMembers(const Ice::LocalException& ex, VALUE p)
m = createEncodingVersion(e.supported);
callRuby(rb_iv_set, p, "@supported", m);
}
- catch(const Ice::NoObjectFactoryException& e)
+ catch(const Ice::NoValueFactoryException& e)
{
volatile VALUE v;
v = createString(e.reason);
@@ -761,7 +761,7 @@ IceRuby::convertLocalException(const Ice::LocalException& ex)
//
try
{
- string name = ex.ice_name();
+ string name = ex.ice_id().substr(2);
volatile VALUE cls = callRuby(rb_path2class, name.c_str());
if(NIL_P(cls))
{
@@ -777,7 +777,7 @@ IceRuby::convertLocalException(const Ice::LocalException& ex)
}
catch(...)
{
- string msg = "failure occurred while converting exception " + ex.ice_name();
+ string msg = "failure occurred while converting exception " + ex.ice_id();
return rb_exc_new2(rb_eRuntimeError, msg.c_str());
}
}
diff --git a/ruby/src/IceRuby/Util.h b/ruby/src/IceRuby/Util.h
index 40054f909d5..1cd6ea08c34 100644
--- a/ruby/src/IceRuby/Util.h
+++ b/ruby/src/IceRuby/Util.h
@@ -492,7 +492,7 @@ VALUE convertLocalException(const Ice::LocalException&);
} \
catch(const ::Ice::Exception& ex) \
{ \
- string __ice_msg = "unknown Ice exception: " + ex.ice_name(); \
+ string __ice_msg = "unknown Ice exception: " + ex.ice_id(); \
ICE_RUBY_RETHROW(rb_exc_new2(rb_eRuntimeError, __ice_msg.c_str())); \
} \
catch(const std::bad_alloc& ex) \
diff --git a/ruby/src/IceRuby/ValueFactoryManager.cpp b/ruby/src/IceRuby/ValueFactoryManager.cpp
new file mode 100644
index 00000000000..ee235bb9272
--- /dev/null
+++ b/ruby/src/IceRuby/ValueFactoryManager.cpp
@@ -0,0 +1,432 @@
+// **********************************************************************
+//
+// 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 <ValueFactoryManager.h>
+#include <Types.h>
+#include <Util.h>
+#include <Ice/LocalException.h>
+
+using namespace std;
+using namespace IceRuby;
+
+static VALUE _valueFactoryManagerClass;
+
+namespace
+{
+
+ClassInfoPtr
+getClassInfo(const string& id)
+{
+ 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);
+ }
+
+ return info;
+}
+
+}
+
+extern "C"
+void
+IceRuby_ValueFactoryManager_mark(ValueFactoryManagerPtr* p)
+{
+ assert(p);
+ (*p)->mark();
+}
+
+extern "C"
+void
+IceRuby_ValueFactoryManager_free(ValueFactoryManagerPtr* p)
+{
+ assert(p);
+ delete p;
+}
+
+IceRuby::ValueFactoryManager::ValueFactoryManager()
+{
+ //
+ // Create a Ruby wrapper around this object. Note that this is a cyclic reference.
+ //
+ _self = Data_Wrap_Struct(_valueFactoryManagerClass, IceRuby_ValueFactoryManager_mark,
+ IceRuby_ValueFactoryManager_free, new ValueFactoryManagerPtr(this));
+
+ _defaultFactory = new DefaultValueFactory;
+}
+
+IceRuby::ValueFactoryManager::~ValueFactoryManager()
+{
+ assert(_factories.empty());
+}
+
+void
+IceRuby::ValueFactoryManager::add(const Ice::ValueFactoryPtr& f, const string& id)
+{
+ Lock lock(*this);
+
+ if(id.empty())
+ {
+ if(_defaultFactory->getDelegate())
+ {
+ throw Ice::AlreadyRegisteredException(__FILE__, __LINE__, "value factory", id);
+ }
+
+ _defaultFactory->setDelegate(f);
+ }
+ else
+ {
+ FactoryMap::iterator p = _factories.find(id);
+ if(p != _factories.end())
+ {
+ throw Ice::AlreadyRegisteredException(__FILE__, __LINE__, "value factory", id);
+ }
+
+ _factories.insert(FactoryMap::value_type(id, f));
+ }
+}
+
+Ice::ValueFactoryPtr
+IceRuby::ValueFactoryManager::find(const string& id) const
+{
+ Lock lock(*this);
+
+ if(id.empty())
+ {
+ return _defaultFactory;
+ }
+
+ FactoryMap::const_iterator p = _factories.find(id);
+ if(p != _factories.end())
+ {
+ return p->second;
+ }
+
+ return 0;
+}
+
+void
+IceRuby::ValueFactoryManager::addValueFactory(VALUE f, const string& id)
+{
+ ICE_RUBY_TRY
+ {
+ add(new FactoryWrapper(f, false), id);
+ }
+ ICE_RUBY_CATCH
+}
+
+VALUE
+IceRuby::ValueFactoryManager::findValueFactory(const string& id) const
+{
+ Ice::ValueFactoryPtr f = find(id);
+ if(f)
+ {
+ FactoryWrapperPtr w = FactoryWrapperPtr::dynamicCast(f);
+ if(w)
+ {
+ return w->getObject();
+ }
+ }
+
+ return Qnil;
+}
+
+void
+IceRuby::ValueFactoryManager::addObjectFactory(VALUE f, const string& id)
+{
+ ICE_RUBY_TRY
+ {
+ add(new FactoryWrapper(f, true), id);
+ }
+ ICE_RUBY_CATCH
+}
+
+VALUE
+IceRuby::ValueFactoryManager::findObjectFactory(const string& id) const
+{
+ Ice::ValueFactoryPtr f = find(id);
+ if(f)
+ {
+ FactoryWrapperPtr w = FactoryWrapperPtr::dynamicCast(f);
+ if(w && w->isObjectFactory())
+ {
+ return w->getObject();
+ }
+ }
+
+ return Qnil;
+}
+
+void
+IceRuby::ValueFactoryManager::mark()
+{
+ Lock lock(*this);
+
+ for(FactoryMap::iterator p = _factories.begin(); p != _factories.end(); ++p)
+ {
+ FactoryWrapperPtr w = FactoryWrapperPtr::dynamicCast(p->second);
+ if(w)
+ {
+ w->mark();
+ }
+ }
+
+ _defaultFactory->mark();
+}
+
+void
+IceRuby::ValueFactoryManager::markSelf()
+{
+ Lock lock(*this);
+
+ if(!NIL_P(_self))
+ {
+ rb_gc_mark(_self);
+ }
+}
+
+VALUE
+IceRuby::ValueFactoryManager::getObject() const
+{
+ return _self;
+}
+
+void
+IceRuby::ValueFactoryManager::destroy()
+{
+ FactoryMap factories;
+
+ {
+ Lock lock(*this);
+
+ factories.swap(_factories);
+
+ _self = Qnil;
+ }
+
+ for(FactoryMap::iterator p = factories.begin(); p != factories.end(); ++p)
+ {
+ FactoryWrapperPtr w = FactoryWrapperPtr::dynamicCast(p->second);
+ if(w)
+ {
+ w->destroy();
+ }
+ }
+
+ _defaultFactory->destroy();
+}
+
+IceRuby::FactoryWrapper::FactoryWrapper(VALUE factory, bool isObjectFactory) :
+ _factory(factory),
+ _isObjectFactory(isObjectFactory)
+{
+}
+
+Ice::ValuePtr
+IceRuby::FactoryWrapper::create(const string& id)
+{
+ //
+ // Get the type information.
+ //
+ ClassInfoPtr info = getClassInfo(id);
+
+ if(!info)
+ {
+ return 0;
+ }
+
+ //
+ // Invoke the create method on the Ruby factory object.
+ //
+ volatile VALUE str = createString(id);
+ volatile VALUE obj = callRuby(rb_funcall, _factory, rb_intern("create"), 1, str);
+ if(NIL_P(obj))
+ {
+ return 0;
+ }
+
+ return new ObjectReader(obj, info);
+}
+
+VALUE
+IceRuby::FactoryWrapper::getObject() const
+{
+ return _factory;
+}
+
+bool
+IceRuby::FactoryWrapper::isObjectFactory() const
+{
+ return _isObjectFactory;
+}
+
+void
+IceRuby::FactoryWrapper::mark()
+{
+ rb_gc_mark(_factory);
+}
+
+void
+IceRuby::FactoryWrapper::destroy()
+{
+ if(_isObjectFactory)
+ {
+ callRuby(rb_funcall, _factory, rb_intern("destroy"), 0);
+ }
+}
+
+Ice::ValuePtr
+IceRuby::DefaultValueFactory::create(const string& id)
+{
+ Ice::ValuePtr v;
+
+ //
+ // Give the application-provided default factory a chance to create the object first.
+ //
+ if(_delegate)
+ {
+ v = _delegate->create(id);
+ if(v)
+ {
+ return v;
+ }
+ }
+
+ //
+ // Get the type information.
+ //
+ ClassInfoPtr info = getClassInfo(id);
+
+ if(!info)
+ {
+ return 0;
+ }
+
+ //
+ // NOTE: We don't do this in Ruby because a generated class can be re-opened to define operations.
+ //
+ ////
+ //// If the requested type is an abstract class, then we give up.
+ ////
+ //if(info->isAbstract)
+ //{
+ // return 0;
+ //}
+
+ //
+ // 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::DefaultValueFactory::setDelegate(const Ice::ValueFactoryPtr& d)
+{
+ _delegate = d;
+}
+
+VALUE
+IceRuby::DefaultValueFactory::getObject() const
+{
+ if(_delegate)
+ {
+ FactoryWrapperPtr w = FactoryWrapperPtr::dynamicCast(_delegate);
+ if(w)
+ {
+ return w->getObject();
+ }
+ }
+
+ return Qnil;
+}
+
+void
+IceRuby::DefaultValueFactory::mark()
+{
+ if(_delegate)
+ {
+ FactoryWrapperPtr w = FactoryWrapperPtr::dynamicCast(_delegate);
+ if(w)
+ {
+ w->mark();
+ }
+ }
+}
+
+void
+IceRuby::DefaultValueFactory::destroy()
+{
+ if(_delegate)
+ {
+ FactoryWrapperPtr w = FactoryWrapperPtr::dynamicCast(_delegate);
+ if(w)
+ {
+ w->destroy();
+ }
+ }
+
+ _delegate = 0;
+}
+
+extern "C"
+VALUE
+IceRuby_ValueFactoryManager_add(VALUE self, VALUE factory, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ ValueFactoryManagerPtr* p = reinterpret_cast<ValueFactoryManagerPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string type = getString(id);
+ (*p)->addValueFactory(factory, type);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_ValueFactoryManager_find(VALUE self, VALUE id)
+{
+ ICE_RUBY_TRY
+ {
+ ValueFactoryManagerPtr* p = reinterpret_cast<ValueFactoryManagerPtr*>(DATA_PTR(self));
+ assert(p);
+
+ string type = getString(id);
+ return (*p)->findValueFactory(type);
+ }
+ ICE_RUBY_CATCH
+ return Qnil;
+}
+
+bool
+IceRuby::initValueFactoryManager(VALUE iceModule)
+{
+ _valueFactoryManagerClass = rb_define_class_under(iceModule, "ValueFactoryManagerI", rb_cObject);
+
+ //
+ // Instance methods.
+ //
+ rb_define_method(_valueFactoryManagerClass, "add", CAST_METHOD(IceRuby_ValueFactoryManager_add), 2);
+ rb_define_method(_valueFactoryManagerClass, "find", CAST_METHOD(IceRuby_ValueFactoryManager_find), 1);
+
+ return true;
+}
diff --git a/ruby/src/IceRuby/ValueFactoryManager.h b/ruby/src/IceRuby/ValueFactoryManager.h
new file mode 100644
index 00000000000..d0b79d23528
--- /dev/null
+++ b/ruby/src/IceRuby/ValueFactoryManager.h
@@ -0,0 +1,100 @@
+// **********************************************************************
+//
+// 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/ValueFactory.h>
+#include <IceUtil/Mutex.h>
+
+namespace IceRuby
+{
+
+bool initValueFactoryManager(VALUE);
+
+class FactoryWrapper : public Ice::ValueFactory
+{
+public:
+
+ FactoryWrapper(VALUE, bool);
+
+ virtual Ice::ValuePtr create(const std::string&);
+
+ VALUE getObject() const;
+
+ bool isObjectFactory() const;
+
+ void mark();
+
+ void destroy();
+
+protected:
+
+ VALUE _factory;
+ bool _isObjectFactory;
+};
+typedef IceUtil::Handle<FactoryWrapper> FactoryWrapperPtr;
+
+class DefaultValueFactory : public Ice::ValueFactory
+{
+public:
+
+ virtual Ice::ValuePtr create(const std::string&);
+
+ void setDelegate(const Ice::ValueFactoryPtr&);
+ Ice::ValueFactoryPtr getDelegate() const { return _delegate; }
+
+ VALUE getObject() const;
+
+ void mark();
+
+ void destroy();
+
+private:
+
+ Ice::ValueFactoryPtr _delegate;
+};
+typedef IceUtil::Handle<DefaultValueFactory> DefaultValueFactoryPtr;
+
+class ValueFactoryManager : public Ice::ValueFactoryManager, public IceUtil::Mutex
+{
+public:
+
+ ValueFactoryManager();
+ ~ValueFactoryManager();
+
+ virtual void add(const Ice::ValueFactoryPtr&, const std::string&);
+ virtual Ice::ValueFactoryPtr find(const std::string&) const;
+
+ void addValueFactory(VALUE, const std::string&);
+ VALUE findValueFactory(const std::string&) const;
+ void addObjectFactory(VALUE, const std::string&);
+ VALUE findObjectFactory(const std::string&) const;
+
+ void mark();
+ void markSelf();
+
+ VALUE getObject() const;
+
+ void destroy();
+
+private:
+
+ typedef std::map<std::string, Ice::ValueFactoryPtr> FactoryMap;
+
+ VALUE _self;
+ FactoryMap _factories;
+ DefaultValueFactoryPtr _defaultFactory;
+};
+typedef IceUtil::Handle<ValueFactoryManager> ValueFactoryManagerPtr;
+
+}
+
+#endif