summaryrefslogtreecommitdiff
path: root/ruby/src
diff options
context:
space:
mode:
Diffstat (limited to 'ruby/src')
-rw-r--r--ruby/src/IceRuby/Proxy.cpp63
-rw-r--r--ruby/src/IceRuby/Types.cpp191
-rw-r--r--ruby/src/IceRuby/Types.h22
-rw-r--r--ruby/src/IceRuby/ValueFactoryManager.cpp2
4 files changed, 144 insertions, 134 deletions
diff --git a/ruby/src/IceRuby/Proxy.cpp b/ruby/src/IceRuby/Proxy.cpp
index fee9df5c85d..2f59a6a9ee9 100644
--- a/ruby/src/IceRuby/Proxy.cpp
+++ b/ruby/src/IceRuby/Proxy.cpp
@@ -49,9 +49,9 @@ IceRuby_ObjectPrx_free(Ice::ObjectPrx* p)
}
//
-// Returns true if a context was provided.
+// If a context was provided set it to ::Ice::noExplicitContext.
//
-static bool
+static void
checkArgs(const char* name, int numArgs, int argc, VALUE* argv, Ice::Context& ctx)
{
if(argc < numArgs || argc > numArgs + 1)
@@ -65,9 +65,11 @@ checkArgs(const char* name, int numArgs, int argc, VALUE* argv, Ice::Context& ct
{
throw RubyException(rb_eArgError, "%s: invalid context hash", name);
}
- return true;
}
- return false;
+ else
+ {
+ ctx = ::Ice::noExplicitContext;
+ }
}
extern "C"
@@ -120,20 +122,10 @@ IceRuby_ObjectPrx_ice_isA(int argc, VALUE* argv, VALUE self)
Ice::ObjectPrx p = getProxy(self);
Ice::Context ctx;
- bool haveContext = checkArgs("ice_isA", 1, argc, argv, ctx);
-
+ checkArgs("ice_isA", 1, argc, argv, ctx);
string id = getString(argv[0]);
- bool result;
- if(haveContext)
- {
- result = p->ice_isA(id, ctx);
- }
- else
- {
- result = p->ice_isA(id);
- }
- return result ? Qtrue : Qfalse;
+ return p->ice_isA(id, ctx) ? Qtrue : Qfalse;
}
ICE_RUBY_CATCH
return Qnil;
@@ -148,16 +140,8 @@ IceRuby_ObjectPrx_ice_ping(int argc, VALUE* argv, VALUE self)
Ice::ObjectPrx p = getProxy(self);
Ice::Context ctx;
- bool haveContext = checkArgs("ice_ping", 0, argc, argv, ctx);
-
- if(haveContext)
- {
- p->ice_ping(ctx);
- }
- else
- {
- p->ice_ping();
- }
+ checkArgs("ice_ping", 0, argc, argv, ctx);
+ p->ice_ping(ctx);
}
ICE_RUBY_CATCH
return Qnil;
@@ -172,18 +156,9 @@ IceRuby_ObjectPrx_ice_ids(int argc, VALUE* argv, VALUE self)
Ice::ObjectPrx p = getProxy(self);
Ice::Context ctx;
- bool haveContext = checkArgs("ice_ids", 0, argc, argv, ctx);
-
- vector<string> ids;
- if(haveContext)
- {
- ids = p->ice_ids(ctx);
- }
- else
- {
- ids = p->ice_ids();
- }
+ checkArgs("ice_ids", 0, argc, argv, ctx);
+ vector<string> ids = p->ice_ids(ctx);
volatile VALUE result = createArray(ids.size());
long i = 0;
for(vector<string>::iterator q = ids.begin(); q != ids.end(); ++q, ++i)
@@ -206,18 +181,8 @@ IceRuby_ObjectPrx_ice_id(int argc, VALUE* argv, VALUE self)
Ice::ObjectPrx p = getProxy(self);
Ice::Context ctx;
- bool haveContext = checkArgs("ice_id", 0, argc, argv, ctx);
-
- string id;
- if(haveContext)
- {
- id = p->ice_id(ctx);
- }
- else
- {
- id = p->ice_id();
- }
-
+ checkArgs("ice_id", 0, argc, argv, ctx);
+ string id = p->ice_id(ctx);
return createString(id);
}
ICE_RUBY_CATCH
diff --git a/ruby/src/IceRuby/Types.cpp b/ruby/src/IceRuby/Types.cpp
index 3561d1f3952..43326e728b6 100644
--- a/ruby/src/IceRuby/Types.cpp
+++ b/ruby/src/IceRuby/Types.cpp
@@ -373,7 +373,7 @@ IceRuby::StreamUtil::getSlicedDataMember(VALUE obj, ObjectMap* objectMap)
ObjectMap::iterator i = objectMap->find(o);
if(i == objectMap->end())
{
- writer = new ObjectWriter(o, objectMap);
+ writer = new ObjectWriter(o, objectMap, 0);
objectMap->insert(ObjectMap::value_type(o, writer));
}
else
@@ -1944,7 +1944,7 @@ IceRuby::DictionaryInfo::destroy()
// ClassInfo implementation.
//
IceRuby::ClassInfo::ClassInfo(VALUE ident, bool loc) :
- compactId(-1), isBase(false), isLocal(loc), isAbstract(false), preserve(false), rubyClass(Qnil), typeObj(Qnil),
+ compactId(-1), isBase(false), isLocal(loc), preserve(false), interface(false), rubyClass(Qnil), typeObj(Qnil),
defined(false)
{
const_cast<string&>(id) = getString(ident);
@@ -1960,7 +1960,7 @@ IceRuby::ClassInfo::ClassInfo(VALUE ident, bool loc) :
}
void
-IceRuby::ClassInfo::define(VALUE t, VALUE compact, VALUE abstr, VALUE pres, VALUE b, VALUE i, VALUE m)
+IceRuby::ClassInfo::define(VALUE t, VALUE compact, VALUE pres, VALUE intf, VALUE b, VALUE m)
{
if(!NIL_P(b))
{
@@ -1969,23 +1969,9 @@ IceRuby::ClassInfo::define(VALUE t, VALUE compact, VALUE abstr, VALUE pres, VALU
}
const_cast<Ice::Int&>(compactId) = static_cast<Ice::Int>(getInteger(compact));
- const_cast<bool&>(isAbstract) = RTEST(abstr);
const_cast<bool&>(preserve) = RTEST(pres);
-
- long n;
- volatile VALUE arr;
-
- arr = callRuby(rb_check_array_type, i);
- assert(!NIL_P(arr));
- for(n = 0; n < RARRAY_LEN(arr); ++n)
- {
- ClassInfoPtr iface = ClassInfoPtr::dynamicCast(getType(RARRAY_AREF(arr, n)));
- assert(iface);
- const_cast<ClassInfoList&>(interfaces).push_back(iface);
- }
-
+ const_cast<bool&>(interface) = RTEST(intf);
convertDataMembers(m, const_cast<DataMemberList&>(members), const_cast<DataMemberList&>(optionalMembers), true);
-
const_cast<VALUE&>(rubyClass) = t;
const_cast<bool&>(defined) = true;
}
@@ -2034,7 +2020,7 @@ IceRuby::ClassInfo::validate(VALUE val)
assert(!NIL_P(type));
ClassInfoPtr info = ClassInfoPtr::dynamicCast(getType(type));
assert(info);
- return info->isA(this);
+ return this->interface || info->isA(this);
}
bool
@@ -2087,7 +2073,7 @@ IceRuby::ClassInfo::marshal(VALUE p, Ice::OutputStream* os, ObjectMap* objectMap
ObjectMap::iterator q = objectMap->find(p);
if(q == objectMap->end())
{
- writer = new ObjectWriter(p, objectMap);
+ writer = new ObjectWriter(p, objectMap, this);
objectMap->insert(ObjectMap::value_type(p, writer));
}
else
@@ -2204,7 +2190,6 @@ void
IceRuby::ClassInfo::destroy()
{
const_cast<ClassInfoPtr&>(base) = 0;
- const_cast<ClassInfoList&>(interfaces).clear();
if(!members.empty())
{
DataMemberList ml = members;
@@ -2278,40 +2263,40 @@ IceRuby::ClassInfo::isA(const ClassInfoPtr& info)
{
return true;
}
- else if(base && base->isA(info))
- {
- return true;
- }
- else if(!interfaces.empty())
- {
- for(ClassInfoList::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
- {
- if((*p)->isA(info))
- {
- return true;
- }
- }
- }
-
- return false;
+
+ return base && base->isA(info);
}
//
// ProxyInfo implementation.
//
IceRuby::ProxyInfo::ProxyInfo(VALUE ident) :
- rubyClass(Qnil), typeObj(Qnil)
+ isBase(false), rubyClass(Qnil), typeObj(Qnil)
{
const_cast<string&>(id) = getString(ident);
+ const_cast<bool&>(isBase) = id == "::Ice::Object";
const_cast<VALUE&>(typeObj) = createType(this);
}
void
-IceRuby::ProxyInfo::define(VALUE t, VALUE i)
+IceRuby::ProxyInfo::define(VALUE t, VALUE b, VALUE i)
{
+ if(!NIL_P(b))
+ {
+ const_cast<ProxyInfoPtr&>(base) = ProxyInfoPtr::dynamicCast(getType(b));
+ assert(base);
+ }
+
+ volatile VALUE arr = callRuby(rb_check_array_type, i);
+ assert(!NIL_P(arr));
+ for(int n = 0; n < RARRAY_LEN(arr); ++n)
+ {
+ ProxyInfoPtr iface = ProxyInfoPtr::dynamicCast(getType(RARRAY_AREF(arr, n)));
+ assert(iface);
+ const_cast<ProxyInfoList&>(interfaces).push_back(iface);
+ }
+
const_cast<VALUE&>(rubyClass) = t;
- const_cast<ClassInfoPtr&>(classInfo) = ClassInfoPtr::dynamicCast(getType(i));
- assert(classInfo);
}
string
@@ -2334,7 +2319,7 @@ IceRuby::ProxyInfo::validate(VALUE val)
assert(!NIL_P(type));
ProxyInfoPtr info = ProxyInfoPtr::dynamicCast(getType(type));
assert(info);
- return info->classInfo->isA(classInfo);
+ return info->isA(this);
}
return true;
}
@@ -2428,28 +2413,63 @@ IceRuby::ProxyInfo::print(VALUE value, IceUtilInternal::Output& out, PrintObject
}
}
+bool
+IceRuby::ProxyInfo::isA(const ProxyInfoPtr& info)
+{
+ //
+ // Return true if this class has an is-a relationship with info.
+ //
+ if(info->isBase)
+ {
+ return true;
+ }
+ else if(this == info.get())
+ {
+ return true;
+ }
+ else if(base && base->isA(info))
+ {
+ return true;
+ }
+ else if(!interfaces.empty())
+ {
+ for(ProxyInfoList::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
+ {
+ if((*p)->isA(info))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
void
IceRuby::ProxyInfo::destroy()
{
- const_cast<ClassInfoPtr&>(classInfo) = 0;
+ const_cast<ProxyInfoPtr&>(base) = 0;
+ const_cast<ProxyInfoList&>(interfaces).clear();
}
//
// ObjectWriter implementation.
//
-IceRuby::ObjectWriter::ObjectWriter(VALUE object, ObjectMap* objectMap) :
- _object(object), _map(objectMap)
+IceRuby::ObjectWriter::ObjectWriter(VALUE object, ObjectMap* objectMap, const ClassInfoPtr& formal) :
+ _object(object), _map(objectMap), _formal(formal)
{
//
// Mark the object as in use for the lifetime of this wrapper.
//
rb_gc_register_address(&_object);
-
- volatile VALUE cls = CLASS_OF(object);
- volatile VALUE type = callRuby(rb_const_get, cls, rb_intern("ICE_TYPE"));
- assert(!NIL_P(type));
- _info = ClassInfoPtr::dynamicCast(getType(type));
- assert(_info);
+ if(!_formal || !_formal->interface)
+ {
+ volatile VALUE cls = CLASS_OF(object);
+ volatile VALUE type = callRuby(rb_const_get, cls, rb_intern("ICE_TYPE"));
+ assert(!NIL_P(type));
+ _info = ClassInfoPtr::dynamicCast(getType(type));
+ assert(_info);
+ }
}
IceRuby::ObjectWriter::~ObjectWriter()
@@ -2472,7 +2492,7 @@ IceRuby::ObjectWriter::_iceWrite(Ice::OutputStream* os) const
{
Ice::SlicedDataPtr slicedData;
- if(_info->preserve)
+ if(_info && _info->preserve)
{
//
// Retrieve the SlicedData object that we stored as a hidden member of the Ruby object.
@@ -2481,23 +2501,31 @@ IceRuby::ObjectWriter::_iceWrite(Ice::OutputStream* os) const
}
os->startValue(slicedData);
-
- if(_info->id != "::Ice::UnknownSlicedObject")
+ if(_formal && _formal->interface)
{
- ClassInfoPtr info = _info;
- while(info)
+ ID op = rb_intern("ice_id");
+ string id = getString(callRuby(rb_funcall, _object, op, 0));
+ os->startSlice(id, -1, true);
+ os->endSlice();
+ }
+ else
+ {
+ if(_info->id != "::Ice::UnknownSlicedValue")
{
- os->startSlice(info->id, info->compactId, !info->base);
+ ClassInfoPtr info = _info;
+ while(info)
+ {
+ os->startSlice(info->id, info->compactId, !info->base);
- writeMembers(os, info->members);
- writeMembers(os, info->optionalMembers); // The optional members have already been sorted by tag.
+ writeMembers(os, info->members);
+ writeMembers(os, info->optionalMembers); // The optional members have already been sorted by tag.
- os->endSlice();
+ os->endSlice();
- info = info->base;
+ info = info->base;
+ }
}
}
-
os->endValue();
}
@@ -2569,7 +2597,7 @@ IceRuby::ObjectReader::_iceRead(Ice::InputStream* is)
{
is->startValue();
- const bool unknown = _info->id == "::Ice::UnknownSlicedObject";
+ const bool unknown = _info->id == "::Ice::UnknownSlicedValue";
//
// Unmarshal the slices of a user-defined class.
@@ -2620,7 +2648,7 @@ IceRuby::ObjectReader::_iceRead(Ice::InputStream* is)
util->add(this);
//
- // Define the "unknownTypeId" member for an instance of UnknownSlicedObject.
+ // Define the "unknownTypeId" member for an instance of UnknownSlicedValue.
//
if(unknown)
{
@@ -2692,7 +2720,7 @@ IceRuby::ReadObjectCallback::invoke(const Ice::ObjectPtr& p)
// Verify that the unmarshaled object is compatible with the formal type.
//
volatile VALUE obj = reader->getObject();
- if(!_info->validate(obj))
+ if(!_info->interface && !_info->validate(obj))
{
Ice::UnexpectedObjectException ex(__FILE__, __LINE__);
ex.reason = "unmarshaled object is not an instance of " + _info->id;
@@ -3060,14 +3088,16 @@ IceRuby_defineException(VALUE /*self*/, VALUE id, VALUE type, VALUE preserve, VA
extern "C"
VALUE
-IceRuby_TypeInfo_defineProxy(VALUE self, VALUE type, VALUE classInfo)
+IceRuby_TypeInfo_defineProxy(VALUE self, VALUE type, VALUE base, VALUE interfaces)
{
ICE_RUBY_TRY
{
ProxyInfoPtr info = ProxyInfoPtr::dynamicCast(getType(self));
assert(info);
- info->define(type, classInfo);
+ info->define(type, base, interfaces);
+ rb_define_const(type, "ICE_TYPE", self);
+ rb_define_const(type, "ICE_ID", createString(info->id));
}
ICE_RUBY_CATCH
return Qnil;
@@ -3075,22 +3105,31 @@ IceRuby_TypeInfo_defineProxy(VALUE self, VALUE type, VALUE classInfo)
extern "C"
VALUE
-IceRuby_TypeInfo_defineClass(VALUE self, VALUE type, VALUE compactId, VALUE isAbstract, VALUE preserve, VALUE base,
- VALUE interfaces, VALUE members)
+IceRuby_TypeInfo_defineClass(VALUE self, VALUE type, VALUE compactId, VALUE preserve, VALUE interface, VALUE base,
+ VALUE members)
{
ICE_RUBY_TRY
{
ClassInfoPtr info = ClassInfoPtr::dynamicCast(getType(self));
assert(info);
- info->define(type, compactId, isAbstract, preserve, base, interfaces, members);
+ info->define(type, compactId, preserve, interface, base, members);
- CompactIdMap::iterator q = _compactIdMap.find(info->compactId);
- if(q != _compactIdMap.end())
+ if(info->compactId != -1)
+ {
+ CompactIdMap::iterator q = _compactIdMap.find(info->compactId);
+ if(q != _compactIdMap.end())
+ {
+ _compactIdMap.erase(q);
+ }
+ _compactIdMap.insert(CompactIdMap::value_type(info->compactId, info));
+ }
+
+ if(type != Qnil && !info->interface)
{
- _compactIdMap.erase(q);
+ rb_define_const(type, "ICE_TYPE", self);
+ rb_define_const(type, "ICE_ID", createString(info->id));
}
- _compactIdMap.insert(CompactIdMap::value_type(info->compactId, info));
}
ICE_RUBY_CATCH
return Qnil;
@@ -3193,8 +3232,8 @@ IceRuby::initTypes(VALUE iceModule)
rb_define_module_function(iceModule, "__declareLocalClass", CAST_METHOD(IceRuby_declareLocalClass), 1);
rb_define_module_function(iceModule, "__defineException", CAST_METHOD(IceRuby_defineException), 5);
- rb_define_method(_typeInfoClass, "defineClass", CAST_METHOD(IceRuby_TypeInfo_defineClass), 7);
- rb_define_method(_typeInfoClass, "defineProxy", CAST_METHOD(IceRuby_TypeInfo_defineProxy), 2);
+ rb_define_method(_typeInfoClass, "defineClass", CAST_METHOD(IceRuby_TypeInfo_defineClass), 6);
+ rb_define_method(_typeInfoClass, "defineProxy", CAST_METHOD(IceRuby_TypeInfo_defineProxy), 3);
rb_define_module_function(iceModule, "__stringify", CAST_METHOD(IceRuby_stringify), 2);
rb_define_module_function(iceModule, "__stringifyException", CAST_METHOD(IceRuby_stringifyException), 1);
diff --git a/ruby/src/IceRuby/Types.h b/ruby/src/IceRuby/Types.h
index 8e59edc056f..9d2ae37ee95 100644
--- a/ruby/src/IceRuby/Types.h
+++ b/ruby/src/IceRuby/Types.h
@@ -26,7 +26,10 @@ typedef std::vector<ExceptionInfoPtr> ExceptionInfoList;
class ClassInfo;
typedef IceUtil::Handle<ClassInfo> ClassInfoPtr;
-typedef std::vector<ClassInfoPtr> ClassInfoList;
+
+class ProxyInfo;
+typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr;
+typedef std::vector<ProxyInfoPtr> ProxyInfoList;
//
// This class is raised as an exception when object marshaling needs to be aborted.
@@ -388,7 +391,7 @@ public:
ClassInfo(VALUE, bool);
- void define(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
+ void define(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
virtual std::string getId() const;
@@ -415,10 +418,9 @@ public:
const Ice::Int compactId;
const bool isBase; // Is this the ClassInfo for Ice::Object or Ice::LocalObject?
const bool isLocal;
- const bool isAbstract;
const bool preserve;
+ const bool interface;
const ClassInfoPtr base;
- const ClassInfoList interfaces;
const DataMemberList members;
const DataMemberList optionalMembers;
const VALUE rubyClass;
@@ -435,7 +437,7 @@ public:
ProxyInfo(VALUE);
- void define(VALUE, VALUE);
+ void define(VALUE, VALUE, VALUE);
virtual std::string getId() const;
@@ -452,12 +454,15 @@ public:
virtual void destroy();
+ bool isA(const ProxyInfoPtr&);
+
const std::string id;
+ const bool isBase; // Is this the ClassInfo for Ice::ObjectPrx?
+ const ProxyInfoPtr base;
+ const ProxyInfoList interfaces;
const VALUE rubyClass;
- const ClassInfoPtr classInfo;
const VALUE typeObj;
};
-typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr;
//
// Exception information.
@@ -487,7 +492,7 @@ class ObjectWriter : public Ice::Object
{
public:
- ObjectWriter(VALUE, ObjectMap*);
+ ObjectWriter(VALUE, ObjectMap*, const ClassInfoPtr&);
virtual ~ObjectWriter();
virtual void ice_preMarshal();
@@ -502,6 +507,7 @@ private:
VALUE _object;
ObjectMap* _map;
ClassInfoPtr _info;
+ ClassInfoPtr _formal;
};
//
diff --git a/ruby/src/IceRuby/ValueFactoryManager.cpp b/ruby/src/IceRuby/ValueFactoryManager.cpp
index 562526c0003..e125328afdf 100644
--- a/ruby/src/IceRuby/ValueFactoryManager.cpp
+++ b/ruby/src/IceRuby/ValueFactoryManager.cpp
@@ -31,7 +31,7 @@ getClassInfo(const string& id)
// 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");
+ info = lookupClassInfo("::Ice::UnknownSlicedValue");
}
else
{