diff options
author | Mark Spruiell <mes@zeroc.com> | 2014-07-29 17:22:45 -0700 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2014-07-29 17:22:45 -0700 |
commit | 1ae29aa042323c6ea5b776eda3d14003e17bdbb1 (patch) | |
tree | 64d76ec048ece9271753d026f1607f867ffdcab6 /cpp/src | |
parent | adding -n option for PHP tests to eliminate warnings (diff) | |
download | ice-1ae29aa042323c6ea5b776eda3d14003e17bdbb1.tar.bz2 ice-1ae29aa042323c6ea5b776eda3d14003e17bdbb1.tar.xz ice-1ae29aa042323c6ea5b776eda3d14003e17bdbb1.zip |
ICE-2600 - serialization support for C# exceptions
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/CsUtil.cpp | 271 | ||||
-rw-r--r-- | cpp/src/slice2cs/Gen.cpp | 87 |
2 files changed, 330 insertions, 28 deletions
diff --git a/cpp/src/Slice/CsUtil.cpp b/cpp/src/Slice/CsUtil.cpp index 6c064e5a6c0..3a330819f57 100644 --- a/cpp/src/Slice/CsUtil.cpp +++ b/cpp/src/Slice/CsUtil.cpp @@ -404,6 +404,34 @@ Slice::CsGenerator::isValueType(const TypePtr& type) return false; } +bool +Slice::CsGenerator::isSerializable(const TypePtr& type) +{ + // + // A proxy cannot be serialized because a communicator is required during deserialization. + // + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + ProxyPtr proxy = ProxyPtr::dynamicCast(type); + if((builtin && builtin->kind() == Builtin::KindObjectProxy) || proxy) + { + return false; + } + + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + return isSerializable(seq->type()); + } + + DictionaryPtr d = DictionaryPtr::dynamicCast(type); + if(d) + { + return isSerializable(d->keyType()) && isSerializable(d->valueType()); + } + + return true; +} + void Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out, const TypePtr& type, @@ -2063,6 +2091,249 @@ Slice::CsGenerator::writeOptionalSequenceMarshalUnmarshalCode(Output& out, } } +void +Slice::CsGenerator::writeSerializeDeserializeCode(Output &out, + const TypePtr& type, + const string& param, + bool optional, + int tag, + bool serialize) +{ + if(!isSerializable(type)) + { + return; + } + + if(optional) + { + const string typeName = typeToString(type, true); + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ", typeof(" << typeName << "));"; + } + else + { + out << nl << param << " = (" << typeName << ")info__.GetValue(\"" << param << "\", typeof(" << typeName + << "));"; + } + return; + } + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) + { + switch(builtin->kind()) + { + case Builtin::KindByte: + { + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ");"; + } + else + { + out << nl << param << " = " << "info__.GetByte(\"" << param << "\");"; + } + break; + } + case Builtin::KindBool: + { + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ");"; + } + else + { + out << nl << param << " = " << "info__.GetBoolean(\"" << param << "\");"; + } + break; + } + case Builtin::KindShort: + { + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ");"; + } + else + { + out << nl << param << " = " << "info__.GetInt16(\"" << param << "\");"; + } + break; + } + case Builtin::KindInt: + { + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ");"; + } + else + { + out << nl << param << " = " << "info__.GetInt32(\"" << param << "\");"; + } + break; + } + case Builtin::KindLong: + { + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ");"; + } + else + { + out << nl << param << " = " << "info__.GetInt64(\"" << param << "\");"; + } + break; + } + case Builtin::KindFloat: + { + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ");"; + } + else + { + out << nl << param << " = " << "info__.GetSingle(\"" << param << "\");"; + } + break; + } + case Builtin::KindDouble: + { + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ");"; + } + else + { + out << nl << param << " = " << "info__.GetDouble(\"" << param << "\");"; + } + break; + } + case Builtin::KindString: + { + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << " == null ? \"\" : " << param + << ");"; + } + else + { + out << nl << param << " = " << "info__.GetString(\"" << param << "\");"; + } + break; + } + case Builtin::KindObject: + case Builtin::KindLocalObject: + { + const string typeName = typeToString(type, false); + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ", typeof(" << typeName << "));"; + } + else + { + out << nl << param << " = (" << typeName << ")info__.GetValue(\"" << param << "\", typeof(" + << typeName << "));"; + } + break; + } + case Builtin::KindObjectProxy: + { + // + // Proxies cannot be serialized. + // + break; + } + } + return; + } + + ProxyPtr prx = ProxyPtr::dynamicCast(type); + if(prx) + { + // + // Proxies cannot be serialized. + // + return; + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + if(cl) + { + const string typeName = typeToString(type, false); + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ", typeof(" << typeName << "));"; + } + else + { + out << nl << param << " = (" << typeName << ")info__.GetValue(\"" << param << "\", typeof(" << typeName + << "));"; + } + return; + } + + StructPtr st = StructPtr::dynamicCast(type); + if(st) + { + const string typeName = typeToString(type, false); + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ", typeof(" << typeName << "));"; + } + else + { + out << nl << param << " = (" << typeName << ")info__.GetValue(\"" << param << "\", typeof(" << typeName + << "));"; + } + return; + } + + EnumPtr en = EnumPtr::dynamicCast(type); + if(en) + { + const string typeName = typeToString(type, false); + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ", typeof(" << typeName << "));"; + } + else + { + out << nl << param << " = (" << typeName << ")info__.GetValue(\"" << param << "\", typeof(" << typeName + << "));"; + } + return; + } + + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + const string typeName = typeToString(type, false); + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ", typeof(" << typeName << "));"; + } + else + { + out << nl << param << " = (" << typeName << ")info__.GetValue(\"" << param << "\", typeof(" << typeName + << "));"; + } + return; + } + + DictionaryPtr d = DictionaryPtr::dynamicCast(type); + assert(d); + const string typeName = typeToString(type, false); + if(serialize) + { + out << nl << "info__.AddValue(\"" << param << "\", " << param << ", typeof(" << typeName << "));"; + } + else + { + out << nl << param << " = (" << typeName << ")info__.GetValue(\"" << param << "\", typeof(" << typeName + << "));"; + } +} + string Slice::CsGenerator::toArrayAlloc(const string& decl, const string& sz) { diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp index adaeb38b502..dd1020042f7 100644 --- a/cpp/src/slice2cs/Gen.cpp +++ b/cpp/src/slice2cs/Gen.cpp @@ -3018,6 +3018,7 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) { emitComVisibleAttribute(); emitPartialTypeAttributes(); + _out << nl << "[_System.Serializable]"; if(p->allOperations().size() > 0) // See bug 4747 { _out << nl << "[_System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1012\")]"; @@ -3029,56 +3030,43 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) } _out << "partial class " << fixId(name); - bool baseWritten = false; - + StringList baseNames; if(!hasBaseClass) { if(!p->isLocal()) { - _out << " : Ice.Object"; - baseWritten = true; + baseNames.push_back("Ice.Object"); } } else { - _out << " : " << fixId(bases.front()->scoped()); - baseWritten = true; + baseNames.push_back(fixId(bases.front()->scoped())); bases.pop_front(); } if(p->isAbstract() && !p->isLocal()) { - if(baseWritten) - { - _out << ", "; - } - else - { - _out << " : "; - baseWritten = true; - } + baseNames.push_back(name + "Operations_"); + baseNames.push_back(name + "OperationsNC_"); + } - if(!p->isLocal()) + for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) + { + if((*q)->isAbstract()) { - _out << name << "Operations_, "; - _out << name << "OperationsNC_"; + baseNames.push_back(fixId((*q)->scoped())); } } - for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) + if(!baseNames.empty()) { - if((*q)->isAbstract()) + _out << " : "; + for(StringList::iterator q = baseNames.begin(); q != baseNames.end(); ++q) { - if(baseWritten) + if(q != baseNames.begin()) { _out << ", "; } - else - { - _out << " : "; - baseWritten = true; - } - - _out << fixId((*q)->scoped()); + _out << *q; } } } @@ -3381,6 +3369,10 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) emitAttributes(p); emitComVisibleAttribute(); emitGeneratedCodeAttribute(); + if(isSerializable(p->type())) + { + _out << nl << "[_System.Serializable]"; + } _out << nl << "public class " << name << " : Ice.CollectionBase<" << s << ">, _System.ICloneable"; _out << sb; @@ -3462,6 +3454,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) // Suppress FxCop diagnostic about a missing constructor MyException(String). // _out << nl << "[_System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1032\")]"; + _out << nl << "[_System.Serializable]"; emitPartialTypeAttributes(); _out << nl << "public partial class " << name << " : "; if(base) @@ -3561,6 +3554,18 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) } _out << eb; + _out << sp; + emitGeneratedCodeAttribute(); + _out << nl << "public " << name << "(_System.Runtime.Serialization.SerializationInfo info__, " + << "_System.Runtime.Serialization.StreamingContext context__) : base(info__, context__)"; + _out << sb; + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string name = fixId((*q)->name(), DotNet::Exception, false); + writeSerializeDeserializeCode(_out, (*q)->type(), name, (*q)->optional(), (*q)->tag(), false); + } + _out << eb; + if(!allDataMembers.empty()) { if(!dataMembers.empty()) @@ -3665,6 +3670,22 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << nl << "return true;"; _out << eb; + if(!dataMembers.empty()) + { + _out << sp; + emitGeneratedCodeAttribute(); + _out << nl << "public override void GetObjectData(_System.Runtime.Serialization.SerializationInfo info__, " + << "_System.Runtime.Serialization.StreamingContext context__)"; + _out << sb; + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string name = fixId((*q)->name(), DotNet::Exception, false); + writeSerializeDeserializeCode(_out, (*q)->type(), name, (*q)->optional(), (*q)->tag(), true); + } + _out << sp << nl << "base.GetObjectData(info__, context__);"; + _out << eb; + } + _out << sp << nl << "#endregion"; // Object members _out << sp << nl << "#region Comparison members"; @@ -3962,6 +3983,7 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p) emitAttributes(p); emitPartialTypeAttributes(); + _out << nl << "[_System.Serializable]"; if(isValueType(p)) { _out << nl << "public partial struct " << name; @@ -4268,6 +4290,10 @@ Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) emitAttributes(p); emitComVisibleAttribute(); emitGeneratedCodeAttribute(); + if(isSerializable(p->keyType()) && isSerializable(p->valueType())) + { + _out << nl << "[_System.Serializable]"; + } _out << nl << "public class " << name << " : Ice.DictionaryBase<" << ks << ", " << vs << ">, _System.ICloneable"; _out << sb; @@ -4433,6 +4459,11 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) dataMemberName = propertyName; } + if(!isSerializable(p->type())) + { + _out << nl << "[_System.NonSerialized]"; + } + if(isProperty) { _out << nl << "private"; |