summaryrefslogtreecommitdiff
path: root/cpp/src/slice2matlab/Main.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2017-09-20 16:39:17 -0700
committerMark Spruiell <mes@zeroc.com>2017-09-20 16:39:17 -0700
commite1faa79247984c40326c90a3089011134080c2c6 (patch)
treef60085249f78efbb4c59ba214133deee0013d006 /cpp/src/slice2matlab/Main.cpp
parentAdding slicing/objects test; Adding automated test support (diff)
downloadice-e1faa79247984c40326c90a3089011134080c2c6.tar.bz2
ice-e1faa79247984c40326c90a3089011134080c2c6.tar.xz
ice-e1faa79247984c40326c90a3089011134080c2c6.zip
Simplifying mapping for struct and sequence
Diffstat (limited to 'cpp/src/slice2matlab/Main.cpp')
-rw-r--r--cpp/src/slice2matlab/Main.cpp563
1 files changed, 327 insertions, 236 deletions
diff --git a/cpp/src/slice2matlab/Main.cpp b/cpp/src/slice2matlab/Main.cpp
index 7ebe12e29ab..0f85509bd5b 100644
--- a/cpp/src/slice2matlab/Main.cpp
+++ b/cpp/src/slice2matlab/Main.cpp
@@ -504,6 +504,75 @@ isClass(const TypePtr& type)
return (b && (b->kind() == Builtin::KindObject || b->kind() == Builtin::KindValue)) || cl;
}
+bool
+needsConversion(const TypePtr& type)
+{
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ return isClass(seq->type()) || needsConversion(seq->type());
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ const DataMemberList members = st->dataMembers();
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ if(needsConversion((*q)->type()) || isClass((*q)->type()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ return needsConversion(d->valueType()) || isClass(d->valueType());
+ }
+
+ return false;
+}
+
+void
+convertValueType(IceUtilInternal::Output& out, const string& dest, const string& src, const TypePtr& type,
+ bool optional)
+{
+ assert(needsConversion(type));
+
+ if(optional)
+ {
+ out << nl << "if " << src << " ~= Ice.Unset";
+ out.inc();
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ out << nl << dest << " = " << getAbsolute(seq) << ".convert(" << src << ");";
+ }
+
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ out << nl << dest << " = " << getAbsolute(d) << ".convert(" << src << ");";
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ out << nl << dest << " = " << src << ".ice_convert();";
+ }
+
+ if(optional)
+ {
+ out.dec();
+ out << nl << "end";
+ }
+}
+
}
//
@@ -750,6 +819,31 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
out << nl << "r = obj.iceSlicedData_;";
out.dec();
out << nl << "end";
+ }
+ }
+
+ out.dec();
+ out << nl << "end";
+ }
+
+ if(!p->isLocal())
+ {
+ DataMemberList convertMembers;
+ for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d)
+ {
+ if(needsConversion((*d)->type()))
+ {
+ convertMembers.push_back(*d);
+ }
+ }
+
+ if((preserved && !basePreserved) || !convertMembers.empty())
+ {
+ out << nl << "methods(Hidden=true)";
+ out.inc();
+
+ if(preserved && !basePreserved)
+ {
out << nl << "function iceWrite_(obj, os)";
out.inc();
out << nl << "os.startValue(obj.iceSlicedData_);";
@@ -765,14 +859,33 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
out.dec();
out << nl << "end";
}
- }
- out.dec();
- out << nl << "end";
- }
+ if(!convertMembers.empty())
+ {
+ out << nl << "function r = iceDelayPostUnmarshal_(obj)";
+ out.inc();
+ out << nl << "r = true;";
+ out.dec();
+ out << nl << "end";
+ out << nl << "function icePostUnmarshal_(obj)";
+ out.inc();
+ for(DataMemberList::const_iterator d = convertMembers.begin(); d != convertMembers.end(); ++d)
+ {
+ string m = "obj." + fixIdent((*d)->name());
+ convertValueType(out, m, m, (*d)->type(), (*d)->optional());
+ }
+ if(base)
+ {
+ out << nl << "icePostUnmarshal_@" << getAbsolute(base) << "(obj);";
+ }
+ out.dec();
+ out << nl << "end";
+ }
+
+ out.dec();
+ out << nl << "end";
+ }
- if(!p->isLocal())
- {
out << nl << "methods(Access=protected)";
out.inc();
@@ -809,7 +922,8 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
{
if(isClass((*d)->type()))
{
- unmarshal(out, "is", "@obj.set_" + fixIdent((*d)->name()) + "_", (*d)->type(), false, 0);
+ unmarshal(out, "is", "@obj.iceSetMember_" + fixIdent((*d)->name()) + "_", (*d)->type(), false,
+ 0);
}
else
{
@@ -821,7 +935,8 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
{
if(isClass((*d)->type()))
{
- unmarshal(out, "is", "@obj.set_" + fixIdent((*d)->name()) + "_", (*d)->type(), true, (*d)->tag());
+ unmarshal(out, "is", "@obj.iceSetMember_" + fixIdent((*d)->name()) + "_", (*d)->type(), true,
+ (*d)->tag());
}
else
{
@@ -845,10 +960,10 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
//
for(DataMemberList::const_iterator d = classMembers.begin(); d != classMembers.end(); ++d)
{
- string name = fixIdent((*d)->name());
- out << nl << "function set_" << name << "_(obj, v)";
+ string m = fixIdent((*d)->name());
+ out << nl << "function iceSetMember_" << m << "_(obj, v)";
out.inc();
- out << nl << "obj." << name << " = v;";
+ out << nl << "obj." << m << " = v;";
out.dec();
out << nl << "end";
}
@@ -1074,6 +1189,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
// * unmarshal all optional out parameters (this includes an optional return value)
//
ParamInfoList classParams;
+ ParamInfoList convertParams;
for(ParamInfoList::const_iterator r = requiredOutParams.begin(); r != requiredOutParams.end(); ++r)
{
if(r->param)
@@ -1082,7 +1198,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
if(isClass(r->type))
{
out << nl << r->fixedName << "_h_ = Ice.ValueHolder();";
- name = "@" + r->fixedName + "_h_.set";
+ name = "@(v) " + r->fixedName + "_h_.set(v)";
classParams.push_back(*r);
}
else
@@ -1090,6 +1206,11 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
name = r->fixedName;
}
unmarshal(out, "is_", name, r->type, false, -1);
+
+ if(needsConversion(r->type))
+ {
+ convertParams.push_back(*r);
+ }
}
}
//
@@ -1102,7 +1223,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
if(isClass(r->type))
{
out << nl << r->fixedName << "_h_ = Ice.ValueHolder();";
- name = "@" + r->fixedName + "_h_.set";
+ name = "@(v) " + r->fixedName + "_h_.set(v)";
classParams.push_back(*r);
}
else
@@ -1110,6 +1231,11 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
name = r->fixedName;
}
unmarshal(out, "is_", name, r->type, false, -1);
+
+ if(needsConversion(r->type))
+ {
+ convertParams.push_back(*r);
+ }
}
//
// Now unmarshal all optional out parameters. They are already sorted by tag.
@@ -1120,7 +1246,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
if(isClass(r->type))
{
out << nl << r->fixedName << "_h_ = Ice.ValueHolder();";
- name = "@" + r->fixedName + "_h_.set";
+ name = "@(v) " + r->fixedName + "_h_.set(v)";
classParams.push_back(*r);
}
else
@@ -1128,6 +1254,11 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
name = r->fixedName;
}
unmarshal(out, "is_", name, r->type, r->optional, r->tag);
+
+ if(needsConversion(r->type))
+ {
+ convertParams.push_back(*r);
+ }
}
if(op->returnsClasses(false))
{
@@ -1142,6 +1273,11 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
{
out << nl << r->fixedName << " = " << r->fixedName << "_h_.value;";
}
+
+ for(ParamInfoList::const_iterator r = convertParams.begin(); r != convertParams.end(); ++r)
+ {
+ convertValueType(out, r->fixedName, r->fixedName, r->type, r->optional);
+ }
}
out.dec();
out << nl << "else";
@@ -1225,7 +1361,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
if(isClass(r->type))
{
out << nl << r->fixedName << " = Ice.ValueHolder();";
- name = "@" + r->fixedName + ".set";
+ name = "@(v) " + r->fixedName + ".set(v)";
}
else
{
@@ -1244,7 +1380,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
if(isClass(r->type))
{
out << nl << r->fixedName << " = Ice.ValueHolder();";
- name = "@" + r->fixedName + ".set";
+ name = "@(v) " + r->fixedName + ".set(v)";
}
else
{
@@ -1261,7 +1397,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
if(isClass(r->type))
{
out << nl << r->fixedName << " = Ice.ValueHolder();";
- name = "@" + r->fixedName + ".set";
+ name = "@(v) " + r->fixedName + ".set(v)";
}
else
{
@@ -1280,6 +1416,12 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
{
out << nl << "varargout{" << r->pos << "} = " << r->fixedName << ".value;";
}
+ else if(needsConversion(r->type))
+ {
+ ostringstream dest;
+ dest << "varargout{" << r->pos << "}";
+ convertValueType(out, dest.str(), r->fixedName, r->type, r->optional);
+ }
else
{
out << nl << "varargout{" << r->pos << "} = " << r->fixedName << ';';
@@ -1291,6 +1433,12 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
{
out << nl << "varargout{" << r->pos << "} = " << r->fixedName << ".value;";
}
+ else if(needsConversion(r->type))
+ {
+ ostringstream dest;
+ dest << "varargout{" << r->pos << "}";
+ convertValueType(out, dest.str(), r->fixedName, r->type, r->optional);
+ }
else
{
out << nl << "varargout{" << r->pos << "} = " << r->fixedName << ';';
@@ -1522,9 +1670,15 @@ CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
collectExceptionMembers(p, allMembers, false);
vector<string> allNames;
+ MemberInfoList convertMembers;
for(MemberInfoList::const_iterator q = allMembers.begin(); q != allMembers.end(); ++q)
{
allNames.push_back(q->fixedName);
+
+ if(!q->inherited && needsConversion(q->dataMember->type()))
+ {
+ convertMembers.push_back(*q);
+ }
}
out << nl << "methods";
out.inc();
@@ -1621,7 +1775,7 @@ CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
if(!p->isLocal())
{
const DataMemberList classMembers = p->classDataMembers();
- if(!classMembers.empty() || (preserved && !basePreserved))
+ if(!classMembers.empty() || !convertMembers.empty() || (preserved && !basePreserved))
{
out << nl << "methods(Hidden=true)";
out.inc();
@@ -1640,34 +1794,19 @@ CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
out << nl << "end";
}
- if(!classMembers.empty())
+ if(!classMembers.empty() || !convertMembers.empty())
{
- //
- // Only define preUnmarshal_ for the first exception in the hierarchy that defines a class members.
- //
- if(!base || (base && !base->usesClasses(true)))
- {
- //
- // Exceptions are value types. If it has class members, we use a shared map (which is a handle
- // type) to keep track of class instances as they are unmarshaled.
- //
- out << nl << "function obj = preUnmarshal_(obj)";
- out.inc();
- out << nl << "obj.iceValueTable_ = containers.Map('KeyType', 'char', 'ValueType', 'any');";
- out.dec();
- out << nl << "end";
- }
-
out << nl << "function obj = postUnmarshal_(obj)";
out.inc();
for(DataMemberList::const_iterator q = classMembers.begin(); q != classMembers.end(); ++q)
{
string m = fixExceptionMemberIdent((*q)->name());
- out << nl << "if obj.iceValueTable_.isKey('" << m << "')";
- out.inc();
- out << nl << "obj." << m << " = obj.iceValueTable_('" << m << "');";
- out.dec();
- out << nl << "end";
+ out << nl << "obj." << m << " = obj." << m << ".value;";
+ }
+ for(MemberInfoList::const_iterator q = convertMembers.begin(); q != convertMembers.end(); ++q)
+ {
+ string m = "obj." + q->fixedName;
+ convertValueType(out, m, m, q->dataMember->type(), q->dataMember->optional());
}
if(base && base->usesClasses(true))
{
@@ -1694,8 +1833,8 @@ CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
{
if(isClass((*q)->type()))
{
- string func = "@(v) obj.setValueMember_('" + m + "', v)";
- unmarshal(out, "is", func, (*q)->type(), false, 0);
+ out << nl << "obj." << m << " = Ice.ValueHolder();";
+ unmarshal(out, "is", "@(v) obj." + m + ".set(v)", (*q)->type(), false, 0);
}
else
{
@@ -1709,8 +1848,8 @@ CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
string m = fixExceptionMemberIdent((*q)->name());
if(isClass((*q)->type()))
{
- string func = "@(v) obj.setValueMember_('" + m + "', v)";
- unmarshal(out, "is", func, (*q)->type(), true, (*q)->tag());
+ out << nl << "obj." << m << " = Ice.ValueHolder();";
+ unmarshal(out, "is", "@(v) obj." + m + ".set(v)", (*q)->type(), true, (*q)->tag());
}
else
{
@@ -1725,30 +1864,14 @@ CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
out.dec();
out << nl << "end";
- if(p->usesClasses(true) && (!base || (base && !base->usesClasses(true))))
- {
- out << nl << "function setValueMember_(obj, k, v)";
- out.inc();
- out << nl << "obj.iceValueTable_(k) = v;";
- out.dec();
- out << nl << "end";
- }
-
out.dec();
out << nl << "end";
- if((p->usesClasses(true) && (!base || (base && !base->usesClasses(true)))) || (preserved && !basePreserved))
+ if(preserved && !basePreserved)
{
out << nl << "properties(Access=protected)";
out.inc();
- if(p->usesClasses(true) && (!base || (base && !base->usesClasses(true))))
- {
- out << nl << "iceValueTable_";
- }
- if(preserved && !basePreserved)
- {
- out << nl << "iceSlicedData_";
- }
+ out << nl << "iceSlicedData_";
out.dec();
out << nl << "end";
}
@@ -1777,18 +1900,12 @@ CodeVisitor::visitStructStart(const StructPtr& p)
const DataMemberList classMembers = p->classDataMembers();
out << nl << "classdef " << name;
- if(!classMembers.empty())
- {
- //
- // A struct becomes a "handle" type when it has at least one class data member.
- //
- out << " < matlab.mixin.Copyable";
- }
out.inc();
out << nl << "properties";
out.inc();
vector<string> memberNames;
+ DataMemberList convertMembers;
for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
{
const string m = fixIdent((*q)->name());
@@ -1798,6 +1915,11 @@ CodeVisitor::visitStructStart(const StructPtr& p)
{
out << " " << typeToString((*q)->type());
}
+
+ if(needsConversion((*q)->type()))
+ {
+ convertMembers.push_back(*q);
+ }
}
out.dec();
out << nl << "end";
@@ -1835,6 +1957,24 @@ CodeVisitor::visitStructStart(const StructPtr& p)
out.dec();
out << nl << "end";
+ if(!convertMembers.empty() || !classMembers.empty())
+ {
+ out << nl << "function obj = ice_convert(obj)";
+ out.inc();
+ for(DataMemberList::const_iterator q = convertMembers.begin(); q != convertMembers.end(); ++q)
+ {
+ string m = "obj." + fixIdent((*q)->name());
+ convertValueType(out, m, m, (*q)->type(), (*q)->optional());
+ }
+ for(DataMemberList::const_iterator q = classMembers.begin(); q != classMembers.end(); ++q)
+ {
+ string m = "obj." + fixIdent((*q)->name());
+ out << nl << m << " = " << m << ".value;";
+ }
+ out.dec();
+ out << nl << "end";
+ }
+
out.dec();
out << nl << "end";
@@ -1849,7 +1989,9 @@ CodeVisitor::visitStructStart(const StructPtr& p)
{
if(isClass((*q)->type()))
{
- unmarshal(out, "is", "@r.set_" + fixIdent((*q)->name()) + "_", (*q)->type(), false, 0);
+ string m = fixIdent((*q)->name());
+ out << nl << "r." << m << " = Ice.ValueHolder();";
+ unmarshal(out, "is", "@(v) r." + m + ".set(v)", (*q)->type(), false, 0);
}
else
{
@@ -1916,27 +2058,6 @@ CodeVisitor::visitStructStart(const StructPtr& p)
out << nl << "end";
out.dec();
out << nl << "end";
-
- if(!classMembers.empty())
- {
- out << nl << "methods(Access=protected)";
- out.inc();
- //
- // For each class data member, we generate a "set_<name>_" method that is called when the instance
- // is eventually unmarshaled.
- //
- for(DataMemberList::const_iterator d = classMembers.begin(); d != classMembers.end(); ++d)
- {
- string name = fixIdent((*d)->name());
- out << nl << "function set_" << name << "_(obj, v)";
- out.inc();
- out << nl << "obj." << name << " = v;";
- out.dec();
- out << nl << "end";
- }
- out.dec();
- out << nl << "end";
- }
}
out.dec();
@@ -1990,12 +2111,8 @@ CodeVisitor::visitSequence(const SequencePtr& p)
const string name = fixIdent(p->name());
const string scoped = p->scoped();
const string abs = getAbsolute(p);
-
- //
- // We map a sequence of values to a containers.Map because it's a handle class and therefore we can
- // update it as the values are unmarshaled.
- //
const bool cls = isClass(content);
+ const bool convert = needsConversion(content);
IceUtilInternal::Output out;
openClass(abs, out);
@@ -2005,49 +2122,15 @@ CodeVisitor::visitSequence(const SequencePtr& p)
out << nl << "methods(Static)";
out.inc();
- if(cls)
- {
- out << nl << "function r = new()";
- out.inc();
- out << nl << "r = containers.Map('KeyType', 'int32', 'ValueType', 'any');";
- out.dec();
- out << nl << "end";
- }
-
out << nl << "function write(os, seq)";
out.inc();
- if(cls)
- {
- //
- // Map for class elements
- //
- out << nl << "if ~isempty(seq) && ~isa(seq, 'containers.Map')";
- out.inc();
- out << nl << "throw(MException('Ice:ArgumentException', 'expecting a containers.Map'));";
- out.dec();
- out << nl << "end";
- out << nl << "keys = seq.keys();";
- out << nl << "sz = length(keys);";
- out << nl << "os.writeSize(sz);";
- out << nl << "for i = 1:sz";
- out.inc();
- marshal(out, "os", "seq(keys{i})", content, false, 0);
- out.dec();
- out << nl << "end";
- }
- else
- {
- //
- // Cell array
- //
- out << nl << "sz = length(seq);";
- out << nl << "os.writeSize(sz);";
- out << nl << "for i = 1:sz";
- out.inc();
- marshal(out, "os", "seq{i}", content, false, 0);
- out.dec();
- out << nl << "end";
- }
+ out << nl << "sz = length(seq);";
+ out << nl << "os.writeSize(sz);";
+ out << nl << "for i = 1:sz";
+ out.inc();
+ marshal(out, "os", "seq{i}", content, false, 0);
+ out.dec();
+ out << nl << "end";
out.dec();
out << nl << "end";
@@ -2092,22 +2175,25 @@ CodeVisitor::visitSequence(const SequencePtr& p)
out << nl << "sz = is.readSize();";
if(cls)
{
- out << nl << "r = " << abs << ".new();";
+ //
+ // For a sequence<class>, read() returns an instance of Ice.CellArrayHandle that we later replace with
+ // the cell array. See convert().
+ //
+ out << nl << "r = Ice.CellArrayHandle();";
+ out << nl << "r.array = cell(1, sz);";
}
else
{
- out << nl << "r = {};";
+ out << nl << "r = cell(1, sz);";
}
out << nl << "for i = 1:sz";
out.inc();
if(cls)
{
//
- // It would be nice if we could use the anonymous function "@(v) r(i) = v", but MATLAB doesn't
- // allow assignment expressions as anonymous functions. So we have to call a static method
- // that adds the value to the map.
+ // Ice.CellArrayHandle defines a set() method that we call from the lambda.
//
- unmarshal(out, "is", "@(v) " + abs + ".setValue_(r, i, v)", content, false, 0);
+ unmarshal(out, "is", "@(v) r.set(i, v)", content, false, 0);
}
else
{
@@ -2139,21 +2225,31 @@ CodeVisitor::visitSequence(const SequencePtr& p)
out << nl << "end";
out.dec();
out << nl << "end";
- out.dec();
- out << nl << "end";
- if(cls)
+ if(cls || convert)
{
- out << nl << "methods(Static,Hidden=true)";
+ out << nl << "function r = convert(seq)";
out.inc();
- out << nl << "function setValue_(map, i, v)";
- out.inc();
- out << nl << "map(i) = v;";
- out.dec();
- out << nl << "end";
+ if(cls)
+ {
+ out << nl << "r = seq.array;";
+ }
+ else
+ {
+ out << nl << "r = cell(1, length(seq));";
+ out << nl << "for i = 1:length(seq)";
+ out.inc();
+ convertValueType(out, "r{i}", "seq{i}", content, false);
+ out.dec();
+ out << nl << "end";
+ }
out.dec();
out << nl << "end";
}
+
+ out.dec();
+ out << nl << "end";
+
out.dec();
out << nl << "end";
out << nl;
@@ -2167,6 +2263,7 @@ CodeVisitor::visitDictionary(const DictionaryPtr& p)
const TypePtr key = p->keyType();
const TypePtr value = p->valueType();
const bool cls = isClass(value);
+ const bool convert = needsConversion(value);
const StructPtr st = StructPtr::dynamicCast(key);
@@ -2199,19 +2296,9 @@ CodeVisitor::visitDictionary(const DictionaryPtr& p)
if(st)
{
//
- // We can't use containers.Map for a structure key.
- //
- // If the value type is a Value, we map to an instance of StructArrayHandle so that we can correctly
- // handle the staged nature of value unmarshaling. Otherwise we map to a struct array.
+ // We use a struct array when the key is a structure type because we can't use containers.Map.
//
- if(cls)
- {
- out << nl << "r = Ice.StructArrayHandle();";
- }
- else
- {
- out << nl << "r = [];";
- }
+ out << nl << "r = [];";
}
else
{
@@ -2233,28 +2320,14 @@ CodeVisitor::visitDictionary(const DictionaryPtr& p)
out.inc();
if(st)
{
- if(cls)
- {
- out << nl << "sz = length(d.array);";
- out << nl << "os.writeSize(sz);";
- out << nl << "for i = 1:sz";
- out.inc();
- marshal(out, "os", "d.array(i).key", key, false, 0);
- marshal(out, "os", "d.array(i).value", value, false, 0);
- out.dec();
- out << nl << "end";
- }
- else
- {
- out << nl << "sz = length(d);";
- out << nl << "os.writeSize(sz);";
- out << nl << "for i = 1:sz";
- out.inc();
- marshal(out, "os", "d(i).key", key, false, 0);
- marshal(out, "os", "d(i).value", value, false, 0);
- out.dec();
- out << nl << "end";
- }
+ out << nl << "sz = length(d);";
+ out << nl << "os.writeSize(sz);";
+ out << nl << "for i = 1:sz";
+ out.inc();
+ marshal(out, "os", "d(i).key", key, false, 0);
+ marshal(out, "os", "d(i).value", value, false, 0);
+ out.dec();
+ out << nl << "end";
}
else
{
@@ -2317,65 +2390,35 @@ CodeVisitor::visitDictionary(const DictionaryPtr& p)
out.inc();
out << nl << "sz = is.readSize();";
out << nl << "r = " << abs << ".new();";
- if(cls)
- {
- if(st)
- {
- out << nl << "function setValue(ah_, i_, k_, v_)";
- out.inc();
- out << nl << "ah_.array(i_).key = k_;";
- out << nl << "ah_.array(i_).value = v_;";
- out.dec();
- out << nl << "end";
- }
- else if(EnumPtr::dynamicCast(key))
- {
- out << nl << "function setValue(m_, k_, v_)";
- out.inc();
- out << nl << "m_(int32(k_)) = v_;";
- out.dec();
- out << nl << "end";
- }
- else
- {
- out << nl << "function setValue(m_, k_, v_)";
- out.inc();
- out << nl << "m_(k_) = v_;";
- out.dec();
- out << nl << "end";
- }
- }
out << nl << "for i = 1:sz";
out.inc();
+
unmarshal(out, "is", "k", key, false, 0);
+
if(cls)
{
- if(st)
- {
- unmarshal(out, "is", "@(v) setValue(r, i, k, v)", value, false, 0);
- }
- else
- {
- unmarshal(out, "is", "@(v) setValue(r, k, v)", value, false, 0);
- }
+ out << nl << "v = Ice.ValueHolder();";
+ unmarshal(out, "is", "@(v_) v.set(v_)", value, false, 0);
}
else
{
unmarshal(out, "is", "v", value, false, 0);
- if(st)
- {
- out << nl << "r(i).key = k;";
- out << nl << "r(i).value = v;";
- }
- else if(EnumPtr::dynamicCast(key))
- {
- out << nl << "r(int32(k)) = v;";
- }
- else
- {
- out << nl << "r(k) = v;";
- }
}
+
+ if(st)
+ {
+ out << nl << "r(i).key = k;";
+ out << nl << "r(i).value = v;";
+ }
+ else if(EnumPtr::dynamicCast(key))
+ {
+ out << nl << "r(int32(k)) = v;";
+ }
+ else
+ {
+ out << nl << "r(k) = v;";
+ }
+
out.dec();
out << nl << "end";
out.dec();
@@ -2402,6 +2445,55 @@ CodeVisitor::visitDictionary(const DictionaryPtr& p)
out << nl << "end";
out.dec();
out << nl << "end";
+
+ if(cls || convert)
+ {
+ out << nl << "function r = convert(d, obj)";
+ out.inc();
+ if(st)
+ {
+ out << nl << "for i = 1:length(d)";
+ out.inc();
+ if(cls)
+ {
+ //
+ // Each entry has a temporary Ice.ValueHolder that we need to replace with the actual value.
+ //
+ out << nl << "d(i).value = d(i).value.value;";
+ }
+ else
+ {
+ convertValueType(out, "d(i).value", "d(i).value", value, false);
+ }
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << "keys = d.keys();";
+ out << nl << "values = d.values();";
+ out << nl << "for i = 1:d.Count";
+ out.inc();
+ out << nl << "k = keys{i};";
+ out << nl << "v = values{i};";
+ if(cls)
+ {
+ //
+ // Each entry has a temporary Ice.ValueHolder that we need to replace with the actual value.
+ //
+ out << nl << "d(k) = v.value;";
+ }
+ else
+ {
+ convertValueType(out, "d(k)", "v", value, false);
+ }
+ out.dec();
+ out << nl << "end";
+ }
+ out << nl << "r = d;";
+ out.dec();
+ out << nl << "end";
+ }
}
out.dec();
@@ -3135,7 +3227,6 @@ CodeVisitor::marshal(IceUtilInternal::Output& out, const string& stream, const s
assert(false);
}
-
void
CodeVisitor::unmarshal(IceUtilInternal::Output& out, const string& stream, const string& v, const TypePtr& type,
bool optional, int tag)