diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/include/Slice/CsUtil.h | 12 | ||||
-rw-r--r-- | cpp/src/Slice/CsUtil.cpp | 684 | ||||
-rw-r--r-- | cpp/src/slice2cs/Gen.cpp | 1732 | ||||
-rw-r--r-- | cpp/src/slice2cs/Gen.h | 1 |
4 files changed, 1866 insertions, 563 deletions
diff --git a/cpp/include/Slice/CsUtil.h b/cpp/include/Slice/CsUtil.h index 39b8ac9bbae..9cc8360cb38 100644 --- a/cpp/include/Slice/CsUtil.h +++ b/cpp/include/Slice/CsUtil.h @@ -34,16 +34,22 @@ public: protected: static std::string fixId(const std::string&, int = 0, bool = false); static std::string fixId(const ContainedPtr&, int = 0, bool = false); - static std::string typeToString(const TypePtr&); + static std::string getOptionalType(const TypePtr&); + static std::string getStaticId(const TypePtr&); + static std::string typeToString(const TypePtr&, bool = false); static bool isValueType(const TypePtr&); // // Generate code to marshal or unmarshal a type // void writeMarshalUnmarshalCode(::IceUtilInternal::Output&, const TypePtr&, const std::string&, bool, bool, - bool, const std::string& = "", bool = false); + const std::string& = ""); + void writeOptionalMarshalUnmarshalCode(::IceUtilInternal::Output&, const TypePtr&, const std::string&, int, bool, + bool, const std::string& = ""); void writeSequenceMarshalUnmarshalCode(::IceUtilInternal::Output&, const SequencePtr&, const std::string&, - bool, bool); + bool, bool, bool); + void writeOptionalSequenceMarshalUnmarshalCode(::IceUtilInternal::Output&, const SequencePtr&, const std::string&, + int, bool, bool); private: diff --git a/cpp/src/Slice/CsUtil.cpp b/cpp/src/Slice/CsUtil.cpp index 482ee8a11b1..05e50fc201c 100644 --- a/cpp/src/Slice/CsUtil.cpp +++ b/cpp/src/Slice/CsUtil.cpp @@ -138,7 +138,7 @@ Slice::CsGenerator::fixId(const ContainedPtr& cont, int baseTypes, bool mangleCa ContainedPtr contained = ContainedPtr::dynamicCast(container); if(contained && contained->hasMetaData("clr:property")) { - return cont->name() + "_prop"; + return cont->name() + "__prop"; } else { @@ -147,13 +147,123 @@ Slice::CsGenerator::fixId(const ContainedPtr& cont, int baseTypes, bool mangleCa } string -Slice::CsGenerator::typeToString(const TypePtr& type) +Slice::CsGenerator::getOptionalType(const TypePtr& type) +{ + BuiltinPtr bp = BuiltinPtr::dynamicCast(type); + if(bp) + { + switch(bp->kind()) + { + case Builtin::KindByte: + case Builtin::KindBool: + { + return "Ice.OptionalType.F1"; + } + case Builtin::KindShort: + { + return "Ice.OptionalType.F2"; + } + case Builtin::KindInt: + case Builtin::KindFloat: + { + return "Ice.OptionalType.F4"; + } + case Builtin::KindLong: + case Builtin::KindDouble: + { + return "Ice.OptionalType.F8"; + } + case Builtin::KindString: + { + return "Ice.OptionalType.VSize"; + } + case Builtin::KindObject: + { + return "Ice.OptionalType.Size"; + } + case Builtin::KindObjectProxy: + { + return "Ice.OptionalType.FSize"; + } + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + } + + if(EnumPtr::dynamicCast(type)) + { + return "Ice.OptionalType.Size"; + } + + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + return seq->type()->isVariableLength() ? "Ice.OptionalType.FSize" : "Ice.OptionalType.VSize"; + } + + DictionaryPtr d = DictionaryPtr::dynamicCast(type); + if(d) + { + return (d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) ? + "Ice.OptionalType.FSize" : "Ice.OptionalType.VSize"; + } + + StructPtr st = StructPtr::dynamicCast(type); + if(st) + { + return st->isVariableLength() ? "Ice.OptionalType.FSize" : "Ice.OptionalType.VSize"; + } + + if(ProxyPtr::dynamicCast(type)) + { + return "Ice.OptionalType.FSize"; + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + assert(cl); + return "Ice.OptionalType.Size"; +} + +string +Slice::CsGenerator::getStaticId(const TypePtr& type) +{ + BuiltinPtr b = BuiltinPtr::dynamicCast(type); + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + + assert((b && b->kind() == Builtin::KindObject) || cl); + + if(b) + { + return "Ice.ObjectImpl.ice_staticId()"; + } + else if(cl->isInterface()) + { + ContainedPtr cont = ContainedPtr::dynamicCast(cl->container()); + assert(cont); + return fixId(cont->scoped(), DotNet::ICloneable) + "." + cl->name() + "Disp_.ice_staticId()"; + } + else + { + return fixId(cl->scoped(), DotNet::ICloneable) + ".ice_staticId()"; + } +} + +string +Slice::CsGenerator::typeToString(const TypePtr& type, bool optional) { if(!type) { return "void"; } + if(optional) + { + return "Ice.Optional<" + typeToString(type, false) + ">"; + } + static const char* builtinTable[] = { "byte", @@ -299,9 +409,7 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out, const string& param, bool marshal, bool streamingAPI, - bool isOutParam, - const string& patchParams, - bool newAMI) + const string& patchParams) { string stream; @@ -423,26 +531,7 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out, } else { - if(isOutParam) - { - out << nl << "IceInternal.ParamPatcher<Ice.Object> " << param - << "_PP = new IceInternal.ParamPatcher<Ice.Object>(\"::Ice::Object\");"; - out << nl << stream << ".readObject("; - if(streamingAPI) - { - out << "(Ice.ReadObjectCallback)"; - } - out << param << "_PP);"; - } - else - { - out << nl << stream << ".readObject("; - if(streamingAPI) - { - out << "(Ice.ReadObjectCallback)"; - } - out << "new Patcher__(\"::Ice::Object\", " << patchParams << "));"; - } + out << nl << stream << ".readObject(" << patchParams << ");"; } break; } @@ -502,27 +591,7 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out, } else { - if(isOutParam) - { - out << nl << "IceInternal.ParamPatcher<" << typeToString(type) << ">" << param - << "_PP = new IceInternal.ParamPatcher<" << typeToString(type) << ">(\"" - << cl->scoped() << "\");"; - out << nl << stream << ".readObject("; - if(streamingAPI) - { - out << "(Ice.ReadObjectCallback)"; - } - out << param << "_PP);"; - } - else - { - out << nl << stream << ".readObject("; - if(streamingAPI) - { - out << "(Ice.ReadObjectCallback)"; - } - out << "new Patcher__(\"" << cl->scoped() << "\", " << patchParams << "));"; - } + out << nl << stream << ".readObject(" << patchParams << ");"; } return; } @@ -611,7 +680,7 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out, SequencePtr seq = SequencePtr::dynamicCast(type); if(seq) { - writeSequenceMarshalUnmarshalCode(out, seq, param, marshal, streamingAPI); + writeSequenceMarshalUnmarshalCode(out, seq, param, marshal, streamingAPI, true); return; } @@ -637,11 +706,324 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out, } void +Slice::CsGenerator::writeOptionalMarshalUnmarshalCode(Output &out, + const TypePtr& type, + const string& param, + int tag, + bool marshal, + bool streamingAPI, + const string& patchParams) +{ + string stream; + + if(marshal) + { + stream = streamingAPI ? "outS__" : "os__"; + } + else + { + stream = streamingAPI ? "inS__" : "is__"; + } + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) + { + switch(builtin->kind()) + { + case Builtin::KindByte: + { + if(marshal) + { + out << nl << stream << ".writeByte(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = " << stream << ".readByte(" << tag << ");"; + } + break; + } + case Builtin::KindBool: + { + if(marshal) + { + out << nl << stream << ".writeBool(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = " << stream << ".readBool(" << tag << ");"; + } + break; + } + case Builtin::KindShort: + { + if(marshal) + { + out << nl << stream << ".writeShort(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = " << stream << ".readShort(" << tag << ");"; + } + break; + } + case Builtin::KindInt: + { + if(marshal) + { + out << nl << stream << ".writeInt(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = " << stream << ".readInt(" << tag << ");"; + } + break; + } + case Builtin::KindLong: + { + if(marshal) + { + out << nl << stream << ".writeLong(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = " << stream << ".readLong(" << tag << ");"; + } + break; + } + case Builtin::KindFloat: + { + if(marshal) + { + out << nl << stream << ".writeFloat(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = " << stream << ".readFloat(" << tag << ");"; + } + break; + } + case Builtin::KindDouble: + { + if(marshal) + { + out << nl << stream << ".writeDouble(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = " << stream << ".readDouble(" << tag << ");"; + } + break; + } + case Builtin::KindString: + { + if(marshal) + { + out << nl << stream << ".writeString(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = " << stream << ".readString(" << tag << ");"; + } + break; + } + case Builtin::KindObject: + { + if(marshal) + { + out << nl << stream << ".writeObject(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = new Ice.Optional<Ice.Object>();"; + out << nl << stream << ".readObject(" << tag << ", " << param + << ", Ice.ObjectImpl.ice_staticId());"; + } + break; + } + case Builtin::KindObjectProxy: + { + string typeS = typeToString(type); + if(marshal) + { + out << nl << stream << ".writeProxy(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = " << stream << ".readProxy(" << tag << ");"; + } + break; + } + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + return; + } + + ProxyPtr prx = ProxyPtr::dynamicCast(type); + if(prx) + { + if(marshal) + { + out << nl << "if(" << param << " != null && " << param << ".HasValue && " << stream << ".writeOpt(" << tag + << ", Ice.OptionalType.FSize))"; + out << sb; + out << nl << stream << ".startSize();"; + writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams); + out << nl << stream << ".endSize();"; + out << eb; + } + else + { + out << nl << "if(" << stream << ".readOpt(" << tag << ", Ice.OptionalType.FSize))"; + out << sb; + out << nl << stream << ".skip(4);"; + writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams); + out << eb; + } + return; + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + if(cl) + { + if(marshal) + { + out << nl << stream << ".writeObject(" << tag << ", " << param << ");"; + } + else + { + out << nl << param << " = new Ice.Optional<" << typeToString(type) << ">();"; + out << nl << stream << ".readObject(" << tag << ", " << param << ", " << getStaticId(cl) << ");"; + } + return; + } + + StructPtr st = StructPtr::dynamicCast(type); + if(st) + { + if(marshal) + { + out << nl << "if(" << param << " != null && " << param << ".HasValue && " << stream << ".writeOpt(" << tag + << ", " << getOptionalType(st) << "))"; + out << sb; + if(st->isVariableLength()) + { + out << nl << stream << ".startSize();"; + } + else + { + out << nl << stream << ".writeSize(" << st->minWireSize() << ");"; + } + writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams); + if(st->isVariableLength()) + { + out << nl << stream << ".endSize();"; + } + out << eb; + } + else + { + out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(st) << "))"; + out << sb; + if(st->isVariableLength()) + { + out << nl << stream << ".skip(4);"; + } + else + { + out << nl << stream << ".skipSize();"; + } + string typeS = typeToString(type); + string tmp = "tmp__" + param; + out << nl << typeS << ' ' << tmp << " = new " << typeS << "();"; + writeMarshalUnmarshalCode(out, type, tmp, marshal, streamingAPI, patchParams); + out << nl << param << " = " << tmp << ';'; + out << eb; + } + return; + } + + EnumPtr en = EnumPtr::dynamicCast(type); + if(en) + { + size_t sz = en->getEnumerators().size(); + if(marshal) + { + out << nl << "if(" << param << " != null && " << param << ".HasValue)"; + out << sb; + out << nl << stream << ".writeEnum(" << tag << ", (int)" << param << ".Value, " << sz << ");"; + out << eb; + } + else + { + out << nl << "if(" << stream << ".readOpt(" << tag << ", Ice.OptionalType.Size))"; + out << sb; + writeMarshalUnmarshalCode(out, type, param, marshal, streamingAPI, patchParams); + out << eb; + } + return; + } + + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + writeOptionalSequenceMarshalUnmarshalCode(out, seq, param, tag, marshal, streamingAPI); + return; + } + + DictionaryPtr d = DictionaryPtr::dynamicCast(type); + assert(d); + TypePtr keyType = d->keyType(); + TypePtr valueType = d->valueType(); + if(marshal) + { + out << nl << "if(" << param << " != null && " << param << ".HasValue && " << stream << ".writeOpt(" << tag + << ", " << getOptionalType(d) << "))"; + out << sb; + if(keyType->isVariableLength() || valueType->isVariableLength()) + { + out << nl << stream << ".startSize();"; + } + else + { + out << nl << stream << ".writeSize(" << param << ".Value == null ? 1 : " << param << ".Value.Count * " + << (keyType->minWireSize() + valueType->minWireSize()) << " + (" << param + << ".Value.Count > 254 ? 5 : 1));"; + } + writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams); + if(keyType->isVariableLength() || valueType->isVariableLength()) + { + out << nl << stream << ".endSize();"; + } + out << eb; + } + else + { + out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(d) << "))"; + out << sb; + if(keyType->isVariableLength() || valueType->isVariableLength()) + { + out << nl << stream << ".skip(4);"; + } + else + { + out << nl << stream << ".skipSize();"; + } + writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams); + out << eb; + } +} + +void Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out, const SequencePtr& seq, const string& param, bool marshal, - bool streamingAPI) + bool streamingAPI, + bool useHelper) { string stream; if(marshal) @@ -653,13 +1035,29 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out, stream = streamingAPI ? "inS__" : "is__"; } + if(useHelper) + { + ContainedPtr cont = ContainedPtr::dynamicCast(seq->container()); + assert(cont); + string helperName = fixId(cont->scoped(), DotNet::ICloneable) + "." + seq->name() + "Helper"; + if(marshal) + { + out << nl << helperName << ".write(" << stream << ", " << param << ");"; + } + else + { + out << nl << param << " = " << helperName << ".read(" << stream << ");"; + } + return; + } + TypePtr type = seq->type(); string typeS = typeToString(type); - string genericPrefix = "clr:generic:"; + const string genericPrefix = "clr:generic:"; string genericType; string addMethod = "Add"; - bool isGeneric = seq->findMetaData(genericPrefix, genericType); + const bool isGeneric = seq->findMetaData(genericPrefix, genericType); bool isStack = false; bool isList = false; bool isLinkedList = false; @@ -690,9 +1088,9 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out, isCustom = true; } } - bool isCollection = seq->hasMetaData("clr:collection"); - bool isArray = !isGeneric && !isCollection; - string limitID = isArray ? "Length" : "Count"; + const bool isCollection = seq->hasMetaData("clr:collection"); + const bool isArray = !isGeneric && !isCollection; + const string limitID = isArray ? "Length" : "Count"; BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); if(builtin) @@ -1404,6 +1802,186 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out, return; } +void +Slice::CsGenerator::writeOptionalSequenceMarshalUnmarshalCode(Output& out, + const SequencePtr& seq, + const string& param, + int tag, + bool marshal, + bool streamingAPI) +{ + string stream; + if(marshal) + { + stream = streamingAPI ? "outS__" : "os__"; + } + else + { + stream = streamingAPI ? "inS__" : "is__"; + } + + const TypePtr type = seq->type(); + const string typeS = typeToString(type); + + string meta; + const bool isArray = !seq->findMetaData("clr:generic:", meta) && !seq->hasMetaData("clr:collection"); + const string length = isArray ? param + ".Value.Length" : param + ".Value.Count"; + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) + { + switch(builtin->kind()) + { + case Builtin::KindByte: + case Builtin::KindBool: + case Builtin::KindShort: + case Builtin::KindInt: + case Builtin::KindFloat: + case Builtin::KindLong: + case Builtin::KindDouble: + case Builtin::KindString: + { + string func = typeS; + func[0] = toupper(static_cast<unsigned char>(typeS[0])); + const bool isSerializable = seq->findMetaData("clr:serializable:", meta); + + if(marshal) + { + if(isSerializable) + { + out << nl << "if(" << param << " != null && " << param << ".HasValue && " << stream << ".writeOpt(" + << tag << ", Ice.OptionalType.VSize))"; + out << sb; + out << nl << stream << ".writeSerializable(" << param << ".Value);"; + out << eb; + } + else if(isArray) + { + out << nl << stream << ".write" << func << "Seq(" << tag << ", " << param << ");"; + } + else + { + out << nl << "if(" << param << " != null && " << param << ".HasValue)"; + out << sb; + out << nl << stream << ".write" << func << "Seq(" << tag << ", " << param + << ".Value == null ? 0 : " << param << ".Value.Count, " << param << ".Value);"; + out << eb; + } + } + else + { + out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(seq) << "))"; + out << sb; + if(builtin->isVariableLength()) + { + out << nl << stream << ".skip(4);"; + } + else if(builtin->kind() != Builtin::KindByte && builtin->kind() != Builtin::KindBool) + { + out << nl << stream << ".skipSize();"; + } + writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true); + out << eb; + } + break; + } + + case Builtin::KindObject: + case Builtin::KindObjectProxy: + { + if(marshal) + { + out << nl << "if(" << param << " != null && " << param << ".HasValue && " + << stream << ".writeOpt(" << tag << ", " << getOptionalType(seq) << "))"; + out << sb; + out << nl << stream << ".startSize();"; + writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true); + out << nl << stream << ".endSize();"; + out << eb; + } + else + { + out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(seq) << "))"; + out << sb; + out << nl << stream << ".skip(4);"; + writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true); + out << eb; + } + break; + } + + case Builtin::KindLocalObject: + assert(false); + } + + return; + } + + StructPtr st = StructPtr::dynamicCast(type); + if(st) + { + if(marshal) + { + out << nl << "if(" << param << " != null && " << param << ".HasValue && " + << stream << ".writeOpt(" << tag << ", " << getOptionalType(seq) << "))"; + out << sb; + if(st->isVariableLength()) + { + out << nl << stream << ".startSize();"; + } + else + { + out << nl << stream << ".writeSize(" << param << ".Value == null ? 1 : " << length << " * " + << st->minWireSize() << " + (" << length << " > 254 ? 5 : 1));"; + } + writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true); + if(st->isVariableLength()) + { + out << nl << stream << ".endSize();"; + } + out << eb; + } + else + { + out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(seq) << "))"; + out << sb; + if(st->isVariableLength()) + { + out << nl << stream << ".skip(4);"; + } + else + { + out << nl << stream << ".skipSize();"; + } + writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true); + out << eb; + } + return; + } + + // + // At this point, all remaining element types have variable size. + // + if(marshal) + { + out << nl << "if(" << param << " != null && " << param << ".HasValue && " + << stream << ".writeOpt(" << tag << ", " << getOptionalType(seq) << "))"; + out << sb; + out << nl << stream << ".startSize();"; + writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true); + out << nl << stream << ".endSize();"; + out << eb; + } + else + { + out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(seq) << "))"; + out << sb; + out << nl << stream << ".skip(4);"; + writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true); + out << eb; + } +} + 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 a79ea86851e..cca005f3c81 100644 --- a/cpp/src/slice2cs/Gen.cpp +++ b/cpp/src/slice2cs/Gen.cpp @@ -79,6 +79,13 @@ opFormatTypeToString(const OperationPtr& op) return "???"; } +static bool +isClassType(const TypePtr type) +{ + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + return (builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(type); +} + static string getDeprecateReason(const ContainedPtr& p1, const ContainedPtr& p2, const string& type) { @@ -115,130 +122,824 @@ Slice::CsVisitor::~CsVisitor() } void -Slice::CsVisitor::writeMarshalDataMember(const DataMemberPtr& member, const string& name) +Slice::CsVisitor::writeMarshalUnmarshalParams(const ParamDeclList& params, const OperationPtr& op, bool marshal) { - writeMarshalUnmarshalCode(_out, member->type(), name, true, false, false); + ParamDeclList optionals; + ParamDeclList::const_iterator pli; -#if 0 + for(pli = params.begin(); pli != params.end(); ++pli) + { + if((*pli)->optional()) + { + optionals.push_back(*pli); + } + else + { + string param = fixId((*pli)->name()); + TypePtr type = (*pli)->type(); + string patchParams; + if(!marshal && isClassType(type)) + { + param += "__PP"; + string typeS = typeToString(type); + _out << nl << "IceInternal.ParamPatcher<" << typeS << "> " << param + << " = new IceInternal.ParamPatcher<" << typeS << ">(" + << getStaticId(type) << ");"; + patchParams = param; + } + writeMarshalUnmarshalCode(_out, type, param, marshal, false, patchParams); + } + } + + TypePtr ret; + + if(op && op->returnType()) + { + ret = op->returnType(); + + if(!op->returnIsOptional()) + { + string patchParams; + string param = "ret__"; + + if(!marshal && isClassType(ret)) + { + param = "ret__PP"; + string typeS = typeToString(ret); + _out << nl << "IceInternal.ParamPatcher<" << typeS << "> " << param + << " = new IceInternal.ParamPatcher<" << typeS << ">(" + << getStaticId(ret) << ");"; + patchParams = param; + } + + writeMarshalUnmarshalCode(_out, ret, param, marshal, false, patchParams); + } + } + + // + // Sort optional parameters by tag. + // + class SortFn + { + public: + static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs) + { + return lhs->tag() < rhs->tag(); + } + }; + optionals.sort(SortFn::compare); + + // + // Handle optional parameters. + // + bool checkReturnType = op && op->returnIsOptional(); + + string returnPatchParams; + if(!marshal && checkReturnType && isClassType(ret)) + { + returnPatchParams = "new Ice.OptionalObject<" + typeToString(ret) + ">(ret__, " + getStaticId(ret) + ")"; + } + + for(pli = optionals.begin(); pli != optionals.end(); ++pli) + { + if(checkReturnType && op->returnTag() < (*pli)->tag()) + { + writeOptionalMarshalUnmarshalCode(_out, ret, "ret__", op->returnTag(), marshal, false, returnPatchParams); + checkReturnType = false; + } + + string param = fixId((*pli)->name()); + TypePtr type = (*pli)->type(); + + string patchParams; + if(!marshal && isClassType(type)) + { + patchParams = "new Ice.OptionalObject<" + typeToString(type) + ">(" + param + ", " + getStaticId(type) + + ")"; + } + + writeOptionalMarshalUnmarshalCode(_out, type, param, (*pli)->tag(), marshal, false, patchParams); + } + + if(checkReturnType) + { + writeOptionalMarshalUnmarshalCode(_out, ret, "ret__", op->returnTag(), marshal, false, returnPatchParams); + } +} + +void +Slice::CsVisitor::writeMarshalDataMember(const DataMemberPtr& member, const string& name) +{ if(!member->optional()) { - writeMarshalUnmarshalCode(out, package, member->type(), OptionalNone, false, 0, fixKwd(member->name()), - true, iter, false, member->getMetaData()); + writeMarshalUnmarshalCode(_out, member->type(), name, true, false); + return; } - else + + const string flag = member->name() + "__isset"; + const string prop = member->name() + "__prop"; + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); + if(builtin) { - out << nl << "if(__has_" << member->name() << " && __os.writeOpt(" << member->tag() << ", " - << getOptionalType(member->type()) << "))"; - out << sb; - writeMarshalUnmarshalCode(out, package, member->type(), OptionalMember, false, 0, fixKwd(member->name()), true, - iter, false, member->getMetaData()); - out << eb; + switch(builtin->kind()) + { + case Builtin::KindByte: + case Builtin::KindBool: + case Builtin::KindShort: + case Builtin::KindInt: + case Builtin::KindFloat: + case Builtin::KindLong: + case Builtin::KindDouble: + case Builtin::KindString: + { + string func = typeToString(builtin); + func[0] = toupper(static_cast<unsigned char>(func[0])); + + _out << nl << "if(" << flag << ')'; + _out << sb; + _out << nl << "os__.write" << func << '(' << member->tag() << ", " << prop << ");"; + _out << eb; + break; + } + case Builtin::KindObject: + { + _out << nl << "if(" << flag << ')'; + _out << sb; + _out << nl << "os__.writeObject(" << member->tag() << ", " << prop << ");"; + _out << eb; + break; + } + case Builtin::KindObjectProxy: + { + _out << nl << "if(" << flag << ')'; + _out << sb; + _out << nl << "os__.writeProxy(" << member->tag() << ", " << prop << ");"; + _out << eb; + break; + } + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + return; } -#endif + + SequencePtr seq = SequencePtr::dynamicCast(member->type()); + if(seq) + { + string meta; + const bool serializable = seq->findMetaData("clr:serializable:", meta); + const bool isArray = !seq->findMetaData("clr:generic:", meta) && !seq->hasMetaData("clr:collection"); + const string length = isArray ? prop + ".Length" : prop + ".Count"; + + BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type()); + if(b && !serializable) + { + switch(b->kind()) + { + case Builtin::KindByte: + case Builtin::KindBool: + case Builtin::KindShort: + case Builtin::KindInt: + case Builtin::KindFloat: + case Builtin::KindLong: + case Builtin::KindDouble: + case Builtin::KindString: + { + string func = typeToString(b); + func[0] = toupper(static_cast<unsigned char>(func[0])); + + _out << nl << "if(" << flag << ')'; + _out << sb; + _out << nl << "os__.write" << func << "Seq(" << member->tag() << ", " << prop << ");"; + _out << eb; + break; + } + case Builtin::KindObject: + case Builtin::KindObjectProxy: + { + _out << nl << "if(" << flag << " && os__.writeOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + _out << nl << "os__.startSize();"; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, false); + _out << nl << "os__.endSize();"; + _out << eb; + break; + } + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + return; + } + else + { + _out << nl << "if(" << flag << " && os__.writeOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + StructPtr st = StructPtr::dynamicCast(seq->type()); + if(st && !st->isVariableLength()) + { + _out << nl << "os__.writeSize(" << prop << " == null ? 1 : " << length << " * " << st->minWireSize() + << " + (" << length << " > 254 ? 5 : 1));"; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, false); + } + else if(serializable) + { + writeMarshalUnmarshalCode(_out, member->type(), prop, true, false); + } + else + { + _out << nl << "os__.startSize();"; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, false); + _out << nl << "os__.endSize();"; + } + + _out << eb; + } + return; + } + + DictionaryPtr d = DictionaryPtr::dynamicCast(member->type()); + if(d) + { + _out << nl << "if(" << flag << " && os__.writeOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + if(d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) + { + _out << nl << "os__.startSize();"; + } + else + { + _out << nl << "os__.writeSize(" << prop << " == null ? 1 : " << prop << ".Count * " + << (d->keyType()->minWireSize() + d->valueType()->minWireSize()) << " + (" << prop + << ".Count > 254 ? 5 : 1));"; + } + + writeMarshalUnmarshalCode(_out, member->type(), prop, true, false); + if(d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) + { + _out << nl << "os__.endSize();"; + } + _out << eb; + return; + } + + StructPtr st = StructPtr::dynamicCast(member->type()); + if(st) + { + _out << nl << "if(" << flag << " && os__.writeOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + if(st->isVariableLength()) + { + _out << nl << "os__.startSize();"; + } + else + { + _out << nl << "os__.writeSize(" << st->minWireSize() << ");"; + } + + writeMarshalUnmarshalCode(_out, member->type(), prop, true, false); + if(st->isVariableLength()) + { + _out << nl << "os__.endSize();"; + } + _out << eb; + return; + } + + EnumPtr en = EnumPtr::dynamicCast(member->type()); + if(en) + { + size_t sz = en->getEnumerators().size(); + _out << nl << "if(" << flag << ')'; + _out << sb; + _out << nl << "os__.writeEnum(" << member->tag() << ", (int)" << prop << ", " << sz << ");"; + _out << eb; + return; + } + + ProxyPtr pr = ProxyPtr::dynamicCast(member->type()); + if(pr) + { + _out << nl << "if(" << flag << " && os__.writeOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + _out << nl << "os__.startSize();"; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, false); + _out << nl << "os__.endSize();"; + _out << eb; + return; + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(member->type()); + assert(cl); + _out << nl << "if(" << flag << ')'; + _out << sb; + _out << nl << "os__.writeObject(" << member->tag() << ", " << prop << ");"; + _out << eb; } void Slice::CsVisitor::writeUnmarshalDataMember(const DataMemberPtr& member, const string& name, bool needPatcher, int& patchIter) { - string patchParams = "this"; - if(needPatcher) + string patchParams; + if(isClassType(member->type())) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + patchParams = "new Patcher__(" + getStaticId(member->type()) + ", this"; + if(needPatcher) { ostringstream ostr; ostr << ", " << patchIter++; patchParams += ostr.str(); } + patchParams += ")"; } - writeMarshalUnmarshalCode(_out, member->type(), name, false, false, false, patchParams); -#if 0 if(!member->optional()) { - writeMarshalUnmarshalCode(out, package, member->type(), OptionalNone, false, 0, fixKwd(member->name()), false, - iter, false, member->getMetaData(), patchParams); + writeMarshalUnmarshalCode(_out, member->type(), name, false, false, patchParams); + return; } - else + + const string flag = member->name() + "__isset"; + const string prop = member->name() + "__prop"; + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); + if(builtin) { - out << nl << "if(__has_" << member->name() << " = __is.readOpt(" << member->tag() << ", " - << getOptionalType(member->type()) << "))"; - out << sb; - writeMarshalUnmarshalCode(out, package, member->type(), OptionalMember, false, 0, fixKwd(member->name()), false, - iter, false, member->getMetaData(), patchParams); - out << eb; + string func = typeToString(builtin); + func[0] = toupper(static_cast<unsigned char>(func[0])); + + switch(builtin->kind()) + { + case Builtin::KindByte: + case Builtin::KindBool: + case Builtin::KindShort: + case Builtin::KindInt: + case Builtin::KindFloat: + case Builtin::KindLong: + case Builtin::KindDouble: + case Builtin::KindString: + { + _out << nl << "is__.read" << func << '(' << member->tag() << ", out " << flag << ", out " << prop << ");"; + break; + } + case Builtin::KindObject: + { + _out << nl << "if(" << flag << " = is__.readOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + writeMarshalUnmarshalCode(_out, member->type(), prop, false, false, patchParams); + _out << eb; + break; + } + case Builtin::KindObjectProxy: + { + _out << nl << "is__.readProxy(" << member->tag() << ", out " << flag << ", out " << prop << ");"; + break; + } + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + return; } -#endif + + SequencePtr seq = SequencePtr::dynamicCast(member->type()); + if(seq) + { + string meta; + const bool serializable = seq->findMetaData("clr:serializable:", meta); + const bool isArray = !seq->findMetaData("clr:generic:", meta) && !seq->hasMetaData("clr:collection"); + const string length = isArray ? prop + ".Length" : prop + ".Count"; + + BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type()); + if(b && !serializable) + { + string func = typeToString(b); + func[0] = toupper(static_cast<unsigned char>(func[0])); + + switch(b->kind()) + { + case Builtin::KindByte: + case Builtin::KindBool: + case Builtin::KindShort: + case Builtin::KindInt: + case Builtin::KindFloat: + case Builtin::KindLong: + case Builtin::KindDouble: + case Builtin::KindString: + { + _out << nl << "is__.read" << func << "Seq(" << member->tag() << ", out " << flag << ", out " << prop + << ");"; + break; + } + case Builtin::KindObject: + case Builtin::KindObjectProxy: + { + _out << nl << "if(" << flag << " = is__.readOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + _out << nl << "is__.skip(4);"; + writeMarshalUnmarshalCode(_out, member->type(), prop, false, false, patchParams); + _out << eb; + break; + } + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + } + else + { + _out << nl << "if(" << flag << " = is__.readOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + if(!serializable) + { + if(seq->type()->isVariableLength()) + { + _out << nl << "is__.skip(4);"; + } + else + { + _out << nl << "is__.skipSize();"; + } + } + writeMarshalUnmarshalCode(_out, member->type(), prop, false, false, patchParams); + _out << eb; + } + return; + } + + DictionaryPtr d = DictionaryPtr::dynamicCast(member->type()); + if(d) + { + _out << nl << "if(" << flag << " = is__.readOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + if(d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) + { + _out << nl << "is__.skip(4);"; + } + else + { + _out << nl << "is__.skipSize();"; + } + + writeMarshalUnmarshalCode(_out, member->type(), prop, false, false, patchParams); + _out << eb; + return; + } + + StructPtr st = StructPtr::dynamicCast(member->type()); + if(st) + { + _out << nl << "if(" << flag << " = is__.readOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + if(st->isVariableLength()) + { + _out << nl << "is__.skip(4);"; + } + else + { + _out << nl << "is__.skipSize();"; + } + + writeMarshalUnmarshalCode(_out, member->type(), prop, false, false, patchParams); + _out << eb; + return; + } + + EnumPtr en = EnumPtr::dynamicCast(member->type()); + if(en) + { + _out << nl << "if(" << flag << " = is__.readOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + writeMarshalUnmarshalCode(_out, member->type(), prop, false, false, patchParams); + _out << eb; + return; + } + + ProxyPtr pr = ProxyPtr::dynamicCast(member->type()); + if(pr) + { + _out << nl << "if(" << flag << " = is__.readOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + _out << nl << "is__.skip(4);"; + writeMarshalUnmarshalCode(_out, member->type(), prop, false, false, patchParams); + _out << eb; + return; + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(member->type()); + assert(cl); + _out << nl << "if(" << flag << " = is__.readOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + writeMarshalUnmarshalCode(_out, member->type(), prop, false, false, patchParams); + _out << eb; } void Slice::CsVisitor::writeStreamMarshalDataMember(const DataMemberPtr& member, const string& name) { - writeMarshalUnmarshalCode(_out, member->type(), name, true, true, false); -#if 0 if(!member->optional()) { - writeStreamMarshalUnmarshalCode(out, package, member->type(), false, 0, fixKwd(member->name()), true, - iter, false, member->getMetaData()); + writeMarshalUnmarshalCode(_out, member->type(), name, true, true); + return; } - else + + const string flag = member->name() + "__isset"; + const string prop = member->name() + "__prop"; + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); + if(builtin) { - out << nl << "if(__has_" << member->name() << " && __outS.writeOptional(" << member->tag() << ", " - << getOptionalType(member->type()) << "))"; - out << sb; - writeStreamMarshalUnmarshalCode(out, package, member->type(), true, member->tag(), fixKwd(member->name()), - true, iter, false, member->getMetaData()); - out << eb; + _out << nl << "if(" << flag << " && outS__.writeOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + if(builtin->kind() == Builtin::KindObjectProxy) + { + _out << nl << "outS__.startSize();"; + } + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + if(builtin->kind() == Builtin::KindObjectProxy) + { + _out << nl << "outS__.endSize();"; + } + _out << eb; + return; } -#endif + + SequencePtr seq = SequencePtr::dynamicCast(member->type()); + if(seq) + { + string meta; + const bool serializable = seq->findMetaData("clr:serializable:", meta); + const bool isArray = !seq->findMetaData("clr:generic:", meta) && !seq->hasMetaData("clr:collection"); + const string length = isArray ? prop + ".Length" : prop + ".Count"; + + _out << nl << "if(" << flag << " && outS__.writeOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type()); + + if(serializable) + { + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + } + else if(b) + { + switch(b->kind()) + { + case Builtin::KindByte: + case Builtin::KindBool: + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + break; + case Builtin::KindShort: + case Builtin::KindInt: + case Builtin::KindFloat: + case Builtin::KindLong: + case Builtin::KindDouble: + _out << nl << "outS__.writeSize(" << prop << " == null ? 1 : " << length << " * " << b->minWireSize() + << " + (" << length << " > 254 ? 5 : 1));"; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + break; + case Builtin::KindString: + case Builtin::KindObject: + case Builtin::KindObjectProxy: + { + _out << nl << "outS__.startSize();"; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + _out << nl << "outS__.endSize();"; + break; + } + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + } + else + { + StructPtr st = StructPtr::dynamicCast(seq->type()); + if(st && !st->isVariableLength()) + { + _out << nl << "outS__.writeSize(" << prop << " == null ? 1 : " << length << " * " << st->minWireSize() + << " + (" << length << " > 254 ? 5 : 1));"; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + } + else + { + _out << nl << "outS__.startSize();"; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + _out << nl << "outS__.endSize();"; + } + } + + _out << eb; + return; + } + + DictionaryPtr d = DictionaryPtr::dynamicCast(member->type()); + if(d) + { + _out << nl << "if(" << flag << " && outS__.writeOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + if(d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) + { + _out << nl << "outS__.startSize();"; + } + else + { + _out << nl << "outS__.writeSize(" << prop << " == null ? 1 : " << prop << ".Count * " + << (d->keyType()->minWireSize() + d->valueType()->minWireSize()) << " + (" << prop + << ".Count > 254 ? 5 : 1));"; + } + + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + if(d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) + { + _out << nl << "outS__.endSize();"; + } + _out << eb; + return; + } + + StructPtr st = StructPtr::dynamicCast(member->type()); + if(st) + { + _out << nl << "if(" << flag << " && outS__.writeOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + if(st->isVariableLength()) + { + _out << nl << "outS__.startSize();"; + } + else + { + _out << nl << "outS__.writeSize(" << st->minWireSize() << ");"; + } + + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + if(st->isVariableLength()) + { + _out << nl << "outS__.endSize();"; + } + _out << eb; + return; + } + + EnumPtr en = EnumPtr::dynamicCast(member->type()); + if(en) + { + _out << nl << "if(" << flag << " && outS__.writeOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + _out << eb; + return; + } + + ProxyPtr pr = ProxyPtr::dynamicCast(member->type()); + if(pr) + { + _out << nl << "if(" << flag << " && outS__.writeOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + _out << nl << "outS__.startSize();"; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + _out << nl << "outS__.endSize();"; + _out << eb; + return; + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(member->type()); + assert(cl); + _out << nl << "if(" << flag << " && outS__.writeOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + writeMarshalUnmarshalCode(_out, member->type(), prop, true, true); + _out << eb; } void Slice::CsVisitor::writeStreamUnmarshalDataMember(const DataMemberPtr& member, const string& name, bool needPatcher, int& patchIter) { - string patchParams = "this"; - if(needPatcher) + string patchParams; + if(isClassType(member->type())) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + patchParams = "new Patcher__(" + getStaticId(member->type()) + ", this"; + if(needPatcher) { ostringstream ostr; ostr << ", " << patchIter++; patchParams += ostr.str(); } + patchParams += ")"; } - writeMarshalUnmarshalCode(_out, member->type(), name, false, true, false, patchParams); -#if 0 - string patchParams; - if(needPatcher) + if(!member->optional()) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + writeMarshalUnmarshalCode(_out, member->type(), name, false, true, patchParams); + return; + } + + const string flag = member->name() + "__isset"; + const string prop = member->name() + "__prop"; + + _out << nl << "if(" << flag << " = inS__.readOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + _out << sb; + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); + if(builtin && builtin->kind() == Builtin::KindObjectProxy) + { + _out << nl << "inS__.skip(4);"; + } + + SequencePtr seq = SequencePtr::dynamicCast(member->type()); + if(seq) + { + BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type()); + if(!b || (b->kind() != Builtin::KindByte && b->kind() != Builtin::KindBool)) { - ostringstream ostr; - ostr << "new Patcher(" << patchIter++ << ')'; - patchParams = ostr.str(); + if(seq->type()->isVariableLength()) + { + _out << nl << "inS__.skip(4);"; + } + else + { + _out << nl << "inS__.skipSize();"; + } } } - if(!member->optional()) + DictionaryPtr d = DictionaryPtr::dynamicCast(member->type()); + if(d) { - writeStreamMarshalUnmarshalCode(out, package, member->type(), false, 0, fixKwd(member->name()), false, - iter, false, member->getMetaData(), patchParams); + if(d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) + { + _out << nl << "inS__.skip(4);"; + } + else + { + _out << nl << "inS__.skipSize();"; + } } - else + + StructPtr st = StructPtr::dynamicCast(member->type()); + if(st) { - out << nl << "if(__has_" << member->name() << " = __inS.readOptional(" << member->tag() << ", " - << getOptionalType(member->type()) << "))"; - out << sb; - writeStreamMarshalUnmarshalCode(out, package, member->type(), true, member->tag(), fixKwd(member->name()), - false, iter, false, member->getMetaData(), patchParams); - out << eb; + if(st->isVariableLength()) + { + _out << nl << "inS__.skip(4);"; + } + else + { + _out << nl << "inS__.skipSize();"; + } } -#endif + + ProxyPtr pr = ProxyPtr::dynamicCast(member->type()); + if(pr) + { + _out << nl << "inS__.skip(4);"; + } + + writeMarshalUnmarshalCode(_out, member->type(), prop, false, true, patchParams); + _out << eb; } void @@ -459,26 +1160,78 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) << " obj__, IceInternal.Incoming inS__, Ice.Current current__)"; _out << sb; - bool amd = p->hasMetaData("amd") || op->hasMetaData("amd"); - if(!amd) + TypePtr ret = op->returnType(); + + ParamDeclList paramList = op->parameters(); + ParamDeclList::const_iterator pli; + ParamDeclList inParams; + ParamDeclList outParams; + + for(pli = paramList.begin(); pli != paramList.end(); ++pli) { - TypePtr ret = op->returnType(); + if((*pli)->isOutParam()) + { + outParams.push_back(*pli); + } + else + { + inParams.push_back(*pli); + } + } - TypeStringList inParams; - TypeStringList outParams; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) + _out << nl << "checkMode__(" << sliceModeToIceMode(op->mode()) << ", current__.mode);"; + if(!inParams.empty()) + { + // + // Unmarshal 'in' parameters. + // + _out << nl << "IceInternal.BasicStream is__ = inS__.startReadParams();"; + for(pli = inParams.begin(); pli != inParams.end(); ++pli) { - if((*pli)->isOutParam()) + string param = fixId((*pli)->name()); + string typeS = typeToString((*pli)->type(), (*pli)->optional()); + const bool isClass = isClassType((*pli)->type()); + + if((*pli)->optional()) { - outParams.push_back(make_pair((*pli)->type(), (*pli)->name())); + BuiltinPtr b = BuiltinPtr::dynamicCast((*pli)->type()); + if(!b || isClass) + { + _out << nl << typeS << ' ' << param << " = new " << typeS << "();"; + } + else + { + _out << nl << typeS << ' ' << param << ';'; + } } - else + else if(!isClass) { - inParams.push_back(make_pair((*pli)->type(), (*pli)->name())); + _out << nl << typeS << ' ' << param << ';'; + StructPtr st = StructPtr::dynamicCast((*pli)->type()); + if(st) + { + if(isValueType((*pli)->type())) + { + _out << nl << param << " = new " << typeS << "();"; + } + else + { + _out << nl << param << " = null;"; + } + } } } + writeMarshalUnmarshalParams(inParams, 0, false); + _out << nl << "inS__.endReadParams();"; + } + else + { + _out << nl << "inS__.readEmptyParams();"; + } + const bool amd = p->hasMetaData("amd") || op->hasMetaData("amd"); + if(!amd) + { ExceptionList throws = op->throws(); throws.sort(); throws.unique(); @@ -495,55 +1248,10 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) throws.sort(Slice::DerivedToBaseCompare()); #endif - TypeStringList::const_iterator q; - - _out << nl << "checkMode__(" << sliceModeToIceMode(op->mode()) << ", current__.mode);"; - if(!inParams.empty()) - { - // - // Unmarshal 'in' parameters. - // - _out << nl << "IceInternal.BasicStream is__ = inS__.startReadParams();"; - for(q = inParams.begin(); q != inParams.end(); ++q) - { - string param = fixId(q->second); - string typeS = typeToString(q->first); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(q->first); - bool isClass = (builtin && builtin->kind() == Builtin::KindObject) - || ClassDeclPtr::dynamicCast(q->first); - if(!isClass) - { - _out << nl << typeS << ' ' << param << ';'; - StructPtr st = StructPtr::dynamicCast(q->first); - if(st) - { - if(isValueType(q->first)) - { - _out << nl << param << " = new " << typeS << "();"; - } - else - { - _out << nl << param << " = null;"; - } - } - } - writeMarshalUnmarshalCode(_out, q->first, param, false, false, true); - } - if(op->sendsClasses()) - { - _out << nl << "is__.readPendingObjects();"; - } - _out << nl << "inS__.endReadParams();"; - } - else - { - _out << nl << "inS__.readEmptyParams();"; - } - - for(q = outParams.begin(); q != outParams.end(); ++q) + for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - string typeS = typeToString(q->first); - _out << nl << typeS << ' ' << fixId(q->second) << ";"; + string typeS = typeToString((*pli)->type(), (*pli)->optional()); + _out << nl << typeS << ' ' << fixId((*pli)->name()) << ";"; } // @@ -557,31 +1265,22 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) _out << nl; if(ret) { - string retS = typeToString(ret); + string retS = typeToString(ret, op->returnIsOptional()); _out << retS << " ret__ = "; } _out << "obj__." << fixId(opName, DotNet::ICloneable, true) << spar; - for(q = inParams.begin(); q != inParams.end(); ++q) + for(pli = inParams.begin(); pli != inParams.end(); ++pli) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(q->first); - bool isClass = (builtin && builtin->kind() == Builtin::KindObject) - || ClassDeclPtr::dynamicCast(q->first); - - string arg; - if(isClass) - { - arg += "(" + typeToString(q->first) + ")"; - } - arg += fixId(q->second); - if(isClass) + string arg = fixId((*pli)->name()); + if(!(*pli)->optional() && isClassType((*pli)->type())) { - arg += "_PP.value"; + arg += "__PP.value"; } _out << arg; } - for(q = outParams.begin(); q != outParams.end(); ++q) + for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - _out << "out " + fixId(q->second); + _out << "out " + fixId((*pli)->name()); } _out << "current__" << epar << ';'; @@ -592,18 +1291,7 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) { _out << nl << "IceInternal.BasicStream os__ = inS__.startWriteParams__(" << opFormatTypeToString(op) << ");"; - for(q = outParams.begin(); q != outParams.end(); ++q) - { - writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), true, false, true, ""); - } - if(ret) - { - writeMarshalUnmarshalCode(_out, ret, "ret__", true, false, true, ""); - } - if(op->returnsClasses()) - { - _out << nl << "os__.writePendingObjects();"; - } + writeMarshalUnmarshalParams(outParams, op, true); _out << nl << "inS__.endWriteParams__(true);"; } else @@ -634,61 +1322,6 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) } else { - TypeStringList inParams; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) - { - if(!(*pli)->isOutParam()) - { - inParams.push_back(make_pair((*pli)->type(), (*pli)->name())); - } - } - - TypeStringList::const_iterator q; - _out << nl << "checkMode__(" << sliceModeToIceMode(op->mode()) << ", current__.mode);"; - - if(!inParams.empty()) - { - // - // Unmarshal 'in' parameters. - // - _out << nl << "IceInternal.BasicStream is__ = inS__.startReadParams();"; - for(q = inParams.begin(); q != inParams.end(); ++q) - { - string param = fixId(q->second); - string typeS = typeToString(q->first); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(q->first); - bool isClass = (builtin && builtin->kind() == Builtin::KindObject) - || ClassDeclPtr::dynamicCast(q->first); - if(!isClass) - { - _out << nl << typeS << ' ' << param << ';'; - StructPtr st = StructPtr::dynamicCast(q->first); - if(st) - { - if(isValueType(q->first)) - { - _out << nl << param << " = new " << typeS << "();"; - } - else - { - _out << nl << param << " = null;"; - } - } - } - writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), false, false, true); - } - if(op->sendsClasses()) - { - _out << nl << "is__.readPendingObjects();"; - } - _out << nl << "inS__.endReadParams();"; - } - else - { - _out << nl << "inS__.readEmptyParams();"; - } - // // Call on the servant. // @@ -711,20 +1344,12 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) { _out << "cb__"; } - for(q = inParams.begin(); q != inParams.end(); ++q) + for(pli = inParams.begin(); pli != inParams.end(); ++pli) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(q->first); - bool isClass = (builtin && builtin->kind() == Builtin::KindObject) - || ClassDeclPtr::dynamicCast(q->first); - string arg; - if(isClass) + string arg = fixId((*pli)->name()); + if(!(*pli)->optional() && isClassType((*pli)->type())) { - arg += "(" + typeToString(q->first) + ")"; - } - arg += fixId(q->second); - if(isClass) - { - arg += "_PP.value"; + arg += "__PP.value"; } _out << arg; } @@ -860,6 +1485,7 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) DataMemberList allClassMembers = p->allClassDataMembers(); DataMemberList::const_iterator d; DataMemberList members = p->dataMembers(); + DataMemberList optionalMembers = p->orderedOptionalDataMembers(); DataMemberList classMembers = p->classDataMembers(); const bool basePreserved = p->inheritsMetaData("preserve-slice"); const bool preserved = basePreserved || p->hasMetaData("preserve-slice"); @@ -902,6 +1528,13 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) _out << nl << "os__.startWriteSlice(ice_staticId(), " << (!base ? "true" : "false") << ");"; for(d = members.begin(); d != members.end(); ++d) { + if(!(*d)->optional()) + { + writeMarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true)); + } + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { writeMarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true)); } _out << nl << "os__.endWriteSlice();"; @@ -923,7 +1556,7 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) { _out << "new "; } - _out << "class Patcher__ : IceInternal.Patcher<" << name << ">"; + _out << "class Patcher__ : IceInternal.Patcher"; _out << sb; _out << sp << nl << "internal Patcher__(string type, Ice.ObjectImpl instance"; if(allClassMembers.size() > 1) @@ -959,10 +1592,14 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) } string memberName = fixId((*d)->name(), DotNet::ICloneable, true); string memberType = typeToString((*d)->type()); - _out << nl << "_instance." << memberName << " = (" << memberType << ")v;"; - ContainedPtr contained = ContainedPtr::dynamicCast((*d)->type()); - string sliceId = contained ? contained->scoped() : string("::Ice::Object"); - _out << nl << "_typeId = \"" << sliceId << "\";"; + if(ClassDeclPtr::dynamicCast((*d)->type())) + { + _out << nl << "_instance." << memberName << " = (" << memberType << ")v;"; + } + else + { + _out << nl << "_instance." << memberName << " = v;"; + } if(allClassMembers.size() > 1) { _out << nl << "break;"; @@ -976,7 +1613,7 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) _out << eb; _out << nl << "catch(_System.InvalidCastException)"; _out << sb; - _out << nl << "IceInternal.Ex.throwUOE(_typeId, v.ice_id());"; + _out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());"; _out << eb; _out << eb; @@ -985,7 +1622,6 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) { _out << nl << "private int _member;"; } - _out << nl << "private string _typeId;"; _out << eb; } @@ -1020,6 +1656,13 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) const bool needCustomPatcher = classMembers.size() > 1 || allClassMembers.size() > 1; for(d = members.begin(); d != members.end(); ++d) { + if(!(*d)->optional()) + { + writeUnmarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true), needCustomPatcher, classMemberCount); + } + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { writeUnmarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true), needCustomPatcher, classMemberCount); } _out << nl << "is__.endReadSlice();"; @@ -1063,6 +1706,13 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) _out << nl << "outS__.startSlice(ice_staticId(), " << (!base ? "true" : "false") << ");"; for(d = members.begin(); d != members.end(); ++d) { + if(!(*d)->optional()) + { + writeStreamMarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true)); + } + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { writeStreamMarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true)); } _out << nl << "outS__.endSlice();"; @@ -1102,6 +1752,14 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size()); for(d = members.begin(); d != members.end(); ++d) { + if(!(*d)->optional()) + { + writeStreamUnmarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true), needCustomPatcher, + classMemberCount); + } + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { writeStreamUnmarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true), needCustomPatcher, classMemberCount); } @@ -1180,7 +1838,7 @@ Slice::CsVisitor::getParams(const OperationPtr& op) { param += "out "; } - param += typeToString((*q)->type()) + " " + fixId((*q)->name()); + param += typeToString((*q)->type(), (*q)->optional()) + " " + fixId((*q)->name()); params.push_back(param); } return params; @@ -1205,7 +1863,8 @@ Slice::CsVisitor::getParamsAsync(const OperationPtr& op, bool amd, bool newAMI) { if(!(*q)->isOutParam()) { - params.push_back(getParamAttributes(*q) + typeToString((*q)->type()) + " " + fixId((*q)->name())); + params.push_back(getParamAttributes(*q) + typeToString((*q)->type(), (*q)->optional()) + " " + + fixId((*q)->name())); } } return params; @@ -1221,7 +1880,7 @@ Slice::CsVisitor::getParamsAsyncCB(const OperationPtr& op, bool newAMI, bool out TypePtr ret = op->returnType(); if(ret) { - params.push_back(typeToString(ret) + " ret__"); + params.push_back(typeToString(ret, op->returnIsOptional()) + " ret__"); } } @@ -1232,7 +1891,8 @@ Slice::CsVisitor::getParamsAsyncCB(const OperationPtr& op, bool newAMI, bool out { if(!newAMI) { - params.push_back(getParamAttributes(*q) + typeToString((*q)->type()) + ' ' + fixId((*q)->name())); + params.push_back(getParamAttributes(*q) + typeToString((*q)->type(), (*q)->optional()) + ' ' + + fixId((*q)->name())); } else { @@ -1241,7 +1901,7 @@ Slice::CsVisitor::getParamsAsyncCB(const OperationPtr& op, bool newAMI, bool out { s += "out "; } - s += typeToString((*q)->type()) + ' ' + fixId((*q)->name()); + s += typeToString((*q)->type(), (*q)->optional()) + ' ' + fixId((*q)->name()); params.push_back(s); } } @@ -1515,11 +2175,14 @@ Slice::CsVisitor::writeDataMemberInitializers(const DataMemberList& members, int { if((*p)->defaultValueType()) { - string memberName = fixId((*p)->name(), baseTypes); - _out << nl << "this." << memberName; - if(propertyMapping) + _out << nl << "this."; + if(propertyMapping && !(*p)->optional()) + { + _out << (*p)->name() << "__prop"; + } + else { - _out << "_prop"; + _out << fixId((*p)->name(), baseTypes); } _out << " = "; writeConstantValue((*p)->type(), (*p)->defaultValueType(), (*p)->defaultValue()); @@ -2565,7 +3228,7 @@ Slice::Gen::TypesVisitor::visitClassDefEnd(const ClassDefPtr& p) if(!allDataMembers.empty()) { - bool propertyMapping = p->hasMetaData("clr:property"); + const bool propertyMapping = p->hasMetaData("clr:property"); _out << sp << nl << "#region Constructors"; _out << sp; @@ -2602,19 +3265,19 @@ Slice::Gen::TypesVisitor::visitClassDefEnd(const ClassDefPtr& p) _out << baseParamNames << epar; } _out << sb; - vector<string> paramNames; for(d = dataMembers.begin(); d != dataMembers.end(); ++d) { - paramNames.push_back(fixId((*d)->name())); - } - for(vector<string>::const_iterator i = paramNames.begin(); i != paramNames.end(); ++i) - { - _out << nl << "this." << *i; - if(propertyMapping) + _out << nl << "this."; + const string paramName = fixId((*d)->name()); + if(propertyMapping && !(*d)->optional()) + { + _out << (*d)->name() << "__prop"; + } + else { - _out << "_prop"; + _out << paramName; } - _out << " = " << *i << ';'; + _out << " = " << paramName << ';'; } _out << eb; @@ -2668,7 +3331,7 @@ Slice::Gen::TypesVisitor::visitOperation(const OperationPtr& p) params = getParams(p); args = getArgs(p); name = fixId(name, DotNet::ICloneable, true); - retS = typeToString(p->returnType()); + retS = typeToString(p->returnType(), p->returnIsOptional()); } else { @@ -2759,8 +3422,8 @@ Slice::Gen::TypesVisitor::visitOperation(const OperationPtr& p) { _out << "public abstract "; } - _out << typeToString(p->returnType()) << " end_" << name << spar << getParamsAsyncCB(p, true) - << "Ice.AsyncResult r__" << epar << ';'; + _out << typeToString(p->returnType(), p->returnIsOptional()) << " end_" << name << spar + << getParamsAsyncCB(p, true) << "Ice.AsyncResult r__" << epar << ';'; } } @@ -3161,7 +3824,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) { _out << "new "; } - _out << "class Patcher__ : IceInternal.Patcher<" << name << ">"; + _out << "class Patcher__ : IceInternal.Patcher"; _out << sb; _out << sp << nl << "internal Patcher__(string type, Ice.Exception instance"; if(allClassMembers.size() > 1) @@ -3197,10 +3860,14 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) } string memberName = fixId((*q)->name(), DotNet::Exception); string memberType = typeToString((*q)->type()); - _out << nl << "_instance." << memberName << " = (" << memberType << ")v;"; - ContainedPtr contained = ContainedPtr::dynamicCast((*q)->type()); - string sliceId = contained ? contained->scoped() : string("::Ice::Object"); - _out << nl << "_typeId = \"" << sliceId << "\";"; + if(ClassDeclPtr::dynamicCast((*q)->type())) + { + _out << nl << "_instance." << memberName << " = (" << memberType << ")v;"; + } + else + { + _out << nl << "_instance." << memberName << " = v;"; + } if(allClassMembers.size() > 1) { _out << nl << "break;"; @@ -3214,7 +3881,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << eb; _out << nl << "catch(_System.InvalidCastException)"; _out << sb; - _out << nl << "IceInternal.Ex.throwUOE(_typeId, v.ice_id());"; + _out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());"; _out << eb; _out << eb; @@ -3223,7 +3890,6 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) { _out << nl << "private int _member;"; } - _out << nl << "private string _typeId;"; _out << eb; } @@ -3422,11 +4088,11 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) DataMemberList dataMembers = p->dataMembers(); DataMemberList::const_iterator q; - bool propertyMapping = p->hasMetaData("clr:property"); + const bool propertyMapping = p->hasMetaData("clr:property"); _out << sp << nl << "#endregion"; // Slice data members - bool isClass = !isValueType(p) || p->hasDefaultValues(); + const bool isClass = !isValueType(p) || p->hasDefaultValues(); _out << sp << nl << "#region Constructor"; if(isClass) @@ -3450,24 +4116,27 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) emitGeneratedCodeAttribute(); _out << nl << "public " << name << spar; vector<string> paramDecl; - vector<string> paramNames; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0); string memberType = typeToString((*q)->type()); paramDecl.push_back(memberType + " " + memberName); - paramNames.push_back(memberName); } _out << paramDecl << epar; _out << sb; - for(vector<string>::const_iterator i = paramNames.begin(); i != paramNames.end(); ++i) + for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - _out << nl << "this." << *i; + string paramName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0); + _out << nl << "this."; if(propertyMapping) { - _out << "_prop"; + _out << (*q)->name() << "__prop"; } - _out << " = " << *i << ';'; + else + { + _out << paramName; + } + _out << " = " << paramName << ';'; } _out << eb; @@ -3563,17 +4232,15 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) _out << sb; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, isClass ? DotNet::ICloneable : 0), - true, false, false); + writeMarshalDataMember(*q, fixId(*q, isClass ? DotNet::ICloneable : 0)); } _out << eb; - if(isClass && classMembers.size() != 0) { _out << sp; emitGeneratedCodeAttribute(); - _out << nl << "public sealed class Patcher__ : IceInternal.Patcher<" << name << ">"; + _out << nl << "public sealed class Patcher__ : IceInternal.Patcher"; _out << sb; _out << sp << nl << "internal Patcher__(string type, " << name << " instance"; if(classMembers.size() > 1) @@ -3609,10 +4276,14 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) } string memberType = typeToString((*q)->type()); string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0); - _out << nl << "_instance." << memberName << " = (" << memberType << ")v;"; - ContainedPtr contained = ContainedPtr::dynamicCast((*q)->type()); - string sliceId = contained ? contained->scoped() : string("::Ice::Object"); - _out << nl << "_typeId = \"" << sliceId << "\";"; + if(ClassDeclPtr::dynamicCast((*q)->type())) + { + _out << nl << "_instance." << memberName << " = (" << memberType << ")v;"; + } + else + { + _out << nl << "_instance." << memberName << " = v;"; + } if(classMembers.size() > 1) { _out << nl << "break;"; @@ -3626,7 +4297,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) _out << eb; _out << nl << "catch(_System.InvalidCastException)"; _out << sb; - _out << nl << "IceInternal.Ex.throwUOE(_typeId, v.ice_id());"; + _out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());"; _out << eb; _out << eb; @@ -3636,7 +4307,6 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) { _out << nl << "private int _member;"; } - _out << nl << "private string _typeId;"; _out << eb; } @@ -3645,20 +4315,11 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) _out << nl << "public void read__(IceInternal.BasicStream is__)"; _out << sb; int classMemberCount = 0; + const bool needCustomPatcher = classMembers.size() > 1; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - ostringstream patchParams; - patchParams << "this"; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*q)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*q)->type())) - { - if(classMembers.size() > 1) - { - patchParams << ", " << classMemberCount++; - } - } - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, isClass ? DotNet::ICloneable : 0 ), - false, false, false, patchParams.str()); + writeUnmarshalDataMember(*q, fixId(*q, isClass ? DotNet::ICloneable : 0), needCustomPatcher, + classMemberCount); } _out << eb; @@ -3670,8 +4331,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) _out << sb; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, isClass ? DotNet::ICloneable : 0), - true, true, false); + writeStreamMarshalDataMember(*q, fixId(*q, isClass ? DotNet::ICloneable : 0)); } _out << eb; @@ -3682,18 +4342,8 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) classMemberCount = 0; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - ostringstream patchParams; - patchParams << "this"; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*q)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*q)->type())) - { - if(classMembers.size() > 1) - { - patchParams << ", " << classMemberCount++; - } - } - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, isClass ? DotNet::ICloneable : 0 ), - false, true, false, patchParams.str()); + writeStreamUnmarshalDataMember(*q, fixId(*q, isClass ? DotNet::ICloneable : 0), needCustomPatcher, + classMemberCount); } _out << eb; } @@ -3794,13 +4444,13 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) _out << sp << nl << "public static void write(Ice.OutputStream outS__, " << scoped << " v__)"; _out << sb; - writeMarshalUnmarshalCode(_out, p, "v__", true, true, false); + writeMarshalUnmarshalCode(_out, p, "v__", true, true); _out << eb; _out << sp << nl << "public static " << scoped << " read(Ice.InputStream inS__)"; _out << sb; _out << nl << scoped << " v__;"; - writeMarshalUnmarshalCode(_out, p, "v__", false, true, false); + writeMarshalUnmarshalCode(_out, p, "v__", false, true); _out << nl << "return v__;"; _out << eb; @@ -3828,9 +4478,10 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) { int baseTypes = 0; bool isClass = false; - bool propertyMapping = false; + bool isProperty = false; bool isValue = false; bool isProtected = false; + const bool isOptional = p->optional(); ContainedPtr cont = ContainedPtr::dynamicCast(p->container()); assert(cont); if(StructPtr::dynamicCast(cont)) @@ -3842,7 +4493,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) } if(cont->hasMetaData("clr:property")) { - propertyMapping = true; + isProperty = true; } } else if(ExceptionPtr::dynamicCast(cont)) @@ -3855,7 +4506,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) isClass = true; if(cont->hasMetaData("clr:property")) { - propertyMapping = true; + isProperty = true; } isProtected = cont->hasMetaData("protected") || p->hasMetaData("protected"); } @@ -3866,13 +4517,17 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) string type = typeToString(p->type()); string propertyName = fixId(p->name(), baseTypes, isClass); - string dataMemberName = propertyName; - if(propertyMapping) + string dataMemberName; + if(isProperty || isOptional) + { + dataMemberName = p->name() + "__prop"; + } + else { - dataMemberName += "_prop"; + dataMemberName = propertyName; } - if(propertyMapping) + if(isProperty || isOptional) { _out << nl << "private"; } @@ -3888,31 +4543,80 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) emitGeneratedCodeAttribute(); _out << nl << "public"; } + _out << ' ' << type << ' ' << dataMemberName << ';'; - if(!propertyMapping) + if(isOptional) { - return; - } + const string flagName = propertyName + "__isset"; + _out << nl << "private bool " << flagName << ';'; - emitAttributes(p); - emitGeneratedCodeAttribute(); - _out << nl << (isProtected ? "protected" : "public"); - if(!isValue) + _out << sp; + emitAttributes(p); + emitGeneratedCodeAttribute(); + _out << nl << (isProtected ? "protected" : "public") << " virtual " << type << ' ' << propertyName; + _out << sb; + _out << nl << "get"; + _out << sb; + _out << nl << "if(" << flagName << ')'; + _out << sb; + _out << nl << "return " << dataMemberName << ';'; + _out << eb; + _out << nl << "else"; + _out << sb; + _out << nl << "throw new _System.InvalidOperationException();"; + _out << eb; + _out << eb; + _out << nl << "set"; + _out << sb; + _out << nl << dataMemberName << " = value;"; + _out << nl << flagName << " = true;"; + _out << eb; + _out << eb; + + string capName = p->name(); + capName[0] = toupper(static_cast<unsigned char>(capName[0])); + + _out << sp; + emitAttributes(p); + emitGeneratedCodeAttribute(); + _out << nl << (isProtected ? "protected" : "public") << " virtual bool has" << capName; + _out << sb; + _out << nl << "get"; + _out << sb; + _out << nl << "return " << flagName << ';'; + _out << eb; + _out << eb; + + _out << sp; + emitAttributes(p); + emitGeneratedCodeAttribute(); + _out << nl << (isProtected ? "protected" : "public") << " virtual void clear" << capName << "()"; + _out << sb; + _out << nl << flagName << " = false;"; + _out << eb; + } + else if(isProperty) { - _out << " virtual"; + emitAttributes(p); + emitGeneratedCodeAttribute(); + _out << nl << (isProtected ? "protected" : "public"); + if(!isValue) + { + _out << " virtual"; + } + _out << ' ' << type << ' ' << propertyName; + _out << sb; + _out << nl << "get"; + _out << sb; + _out << nl << "return " << dataMemberName << ';'; + _out << eb; + _out << nl << "set"; + _out << sb; + _out << nl << dataMemberName << " = value;"; + _out << eb; + _out << eb; } - _out << ' ' << type << ' ' << propertyName; - _out << sb; - _out << nl << "get"; - _out << sb; - _out << nl << "return " << dataMemberName << ';'; - _out << eb; - _out << nl << "set"; - _out << sb; - _out << nl << dataMemberName << " = value;"; - _out << eb; - _out << eb; } void @@ -4086,7 +4790,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) string name = fixId(p->name(), DotNet::ICloneable, true); vector<string> params = getParams(p); ParamDeclList paramList = p->parameters(); - + string retS = typeToString(p->returnType(), p->returnIsOptional()); _out << sp; @@ -4110,14 +4814,14 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) { _out << nl << "[_System.Obsolete(\"" << deprecateReason << "\")]"; } - _out << nl << typeToString(p->returnType()) << " " << name << spar << params << epar << ';'; + _out << nl << retS << " " << name << spar << params << epar << ';'; if(!deprecateReason.empty()) { _out << nl << "[_System.Obsolete(\"" << deprecateReason << "\")]"; } - _out << nl << typeToString(p->returnType()) << " " << name - << spar << params << "_System.Collections.Generic.Dictionary<string, string> context__" << epar << ';'; + _out << nl << retS << " " << name << spar << params + << "_System.Collections.Generic.Dictionary<string, string> context__" << epar << ';'; // // Write the operations for the new async mapping. @@ -4163,8 +4867,8 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) // end_ method. // _out << sp; - _out << nl << typeToString(p->returnType()) << " end_" << p->name() << spar - << getParamsAsyncCB(p, true) << "Ice.AsyncResult r__" << epar << ';'; + _out << nl << retS << " end_" << p->name() << spar << getParamsAsyncCB(p, true) << "Ice.AsyncResult r__" << epar + << ';'; if(cl->hasMetaData("ami") || p->hasMetaData("ami")) { @@ -4233,7 +4937,7 @@ Slice::Gen::AsyncDelegateVisitor::visitOperation(const OperationPtr& p) } vector<string> paramDeclAMI = getParamsAsyncCB(p, true, false); - string retS = typeToString(p->returnType()); + string retS = typeToString(p->returnType(), p->returnIsOptional()); string delName = "Callback_" + cl->name() + "_" + p->name(); _out << sp; @@ -4382,7 +5086,7 @@ Slice::Gen::OpsVisitor::writeOperations(const ClassDefPtr& p, bool noCurrent) emitDeprecate(op, p, _out, "operation"); emitAttributes(op); - string retS = typeToString(ret); + string retS = typeToString(ret, op->returnIsOptional()); _out << nl << retS << ' ' << opname << spar << params; if(!noCurrent && !p->isLocal()) { @@ -4449,7 +5153,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) OperationPtr op = *r; string opName = fixId(op->name(), DotNet::ICloneable, true); TypePtr ret = op->returnType(); - string retS = typeToString(ret); + string retS = typeToString(ret, op->returnIsOptional()); vector<string> params = getParams(op); vector<string> args = getArgs(op); @@ -4553,20 +5257,20 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) string opName = op->name(); - TypeStringList inParams; - TypeStringList outParams; - TypeStringList::const_iterator q; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) + ParamDeclList::const_iterator pli; + ParamDeclList inParams; + ParamDeclList outParams; + + for(pli = paramList.begin(); pli != paramList.end(); ++pli) { if((*pli)->isOutParam()) { - outParams.push_back(make_pair((*pli)->type(), (*pli)->name())); + outParams.push_back(*pli); } else { - inParams.push_back(make_pair((*pli)->type(), (*pli)->name())); + inParams.push_back(*pli); } } @@ -4619,7 +5323,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) _out << sp << nl << "private const string " << flatName << " = \"" << op->name() << "\";"; TypePtr ret = op->returnType(); - string retS = typeToString(ret); + string retS = typeToString(ret, op->returnIsOptional()); _out << sp << nl << "public " << retS << " end_" << opName << spar << getParamsAsyncCB(op, true) << "Ice.AsyncResult r__" << epar; _out << sb; @@ -4662,6 +5366,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) _out << nl << "throw new Ice.UnknownUserException(ex__.ice_name(), ex__);"; _out << eb; _out << eb; + if(ret || !outParams.empty()) { if(ret) @@ -4669,65 +5374,81 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) _out << nl << retS << " ret__;"; } _out << nl << "IceInternal.BasicStream is__ = outAsync__.startReadParams__();"; - for(q = outParams.begin(); q != outParams.end(); ++q) + for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - string param = fixId(q->second); - StructPtr st = StructPtr::dynamicCast(q->first); - if(st) + string param = fixId((*pli)->name()); + string typeS = typeToString((*pli)->type(), (*pli)->optional()); + const bool isClass = isClassType((*pli)->type()); + + if((*pli)->optional()) { - if(isValueType(st)) + BuiltinPtr b = BuiltinPtr::dynamicCast((*pli)->type()); + if(!b || isClass) { - _out << nl << param << " = new " << typeToString(q->first) << "();"; + _out << nl << param << " = new " << typeS << "();"; } - else + } + else if(!isClass) + { + StructPtr st = StructPtr::dynamicCast((*pli)->type()); + if(st) { - _out << nl << param << " = null;"; + if(isValueType((*pli)->type())) + { + _out << nl << param << " = new " << typeS << "();"; + } + else + { + _out << nl << param << " = null;"; + } } } - writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), false, false, true); } if(ret) { - StructPtr st = StructPtr::dynamicCast(ret); - if(st) + string typeS = typeToString(ret, op->returnIsOptional()); + const bool isClass = isClassType(ret); + + if(op->returnIsOptional()) { - if(isValueType(ret)) + BuiltinPtr b = BuiltinPtr::dynamicCast(ret); + if(!b || isClass) { - _out << nl << "ret__ = new " << retS << "();"; + _out << nl << "ret__ = new " << typeS << "();"; } - else + } + else if(!isClass) + { + StructPtr st = StructPtr::dynamicCast(ret); + if(st) { - _out << nl << "ret__ = null;"; + if(isValueType(ret)) + { + _out << nl << "ret__ = new " << typeS << "();"; + } + else + { + _out << nl << "ret__ = null;"; + } } } - writeMarshalUnmarshalCode(_out, ret, "ret__", false, false, true); - } - if(op->returnsClasses()) - { - _out << nl << "is__.readPendingObjects();"; } + writeMarshalUnmarshalParams(outParams, op, false); _out << nl << "outAsync__.endReadParams__();"; - for(q = outParams.begin(); q != outParams.end(); ++q) + for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - string param = fixId(q->second); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(q->first); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(q->first)) + string param = fixId((*pli)->name()); + if(!(*pli)->optional() && isClassType((*pli)->type())) { - string type = typeToString(q->first); - _out << nl << param << " = (" << type << ")" << param << "_PP.value;"; + _out << nl << param << " = " << param << "__PP.value;"; } } if(ret) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret)) + if(!op->returnIsOptional() && isClassType(ret)) { - string type = typeToString(ret); - _out << nl << "ret__ = (" << retS << ")ret___PP.value;"; + _out << nl << "ret__ = ret__PP.value;"; } - } - if(ret) - { _out << nl << "return ret__;"; } } @@ -4776,15 +5497,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) { _out << nl << "IceInternal.BasicStream os__ = result__.startWriteParams__(" << opFormatTypeToString(op) << ");"; - for(q = inParams.begin(); q != inParams.end(); ++q) - { - string typeS = typeToString(q->first); - writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), true, false, false, "", true); - } - if(op->sendsClasses()) - { - _out << nl << "os__.writePendingObjects();"; - } + writeMarshalUnmarshalParams(inParams, 0, true); _out << nl << "result__.endWriteParams__();"; } else @@ -4808,10 +5521,9 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) _out << sp << nl << "private void " << op->name() << "_completed__(Ice.AsyncResult r__, " << delType << " cb__, Ice.ExceptionCallback excb__)"; _out << sb; - TypeStringList::const_iterator tsli; - for(tsli = outParams.begin(); tsli != outParams.end(); ++tsli) + for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - _out << nl << typeToString(tsli->first) << ' ' << fixId(tsli->second) << ';'; + _out << nl << typeToString((*pli)->type(), (*pli)->optional()) << ' ' << fixId((*pli)->name()) << ';'; } if(ret) { @@ -4825,9 +5537,9 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) _out << "ret__ = "; } _out << "end_" << op->name() << spar; - for(tsli = outParams.begin(); tsli != outParams.end(); ++tsli) + for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - _out << "out " + fixId(tsli->second); + _out << "out " + fixId((*pli)->name()); } _out << "r__" << epar << ';'; _out << eb; @@ -4846,9 +5558,9 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) { _out << "ret__"; } - for(tsli = outParams.begin(); tsli != outParams.end(); ++tsli) + for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - _out << fixId(tsli->second); + _out << fixId((*pli)->name()); } _out << epar << ';'; _out << eb; @@ -5188,13 +5900,13 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p) _out << sp << nl << "public static void write(IceInternal.BasicStream os__, " << typeS << " v__)"; _out << sb; - writeSequenceMarshalUnmarshalCode(_out, p, "v__", true, false); + writeSequenceMarshalUnmarshalCode(_out, p, "v__", true, false, false); _out << eb; _out << sp << nl << "public static " << typeS << " read(IceInternal.BasicStream is__)"; _out << sb; _out << nl << typeS << " v__;"; - writeSequenceMarshalUnmarshalCode(_out, p, "v__", false, false); + writeSequenceMarshalUnmarshalCode(_out, p, "v__", false, false, false); _out << nl << "return v__;"; _out << eb; @@ -5202,13 +5914,13 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p) { _out << sp << nl << "public static void write(Ice.OutputStream outS__, " << typeS << " v__)"; _out << sb; - writeSequenceMarshalUnmarshalCode(_out, p, "v__", true, true); + writeSequenceMarshalUnmarshalCode(_out, p, "v__", true, true, false); _out << eb; _out << sp << nl << "public static " << typeS << " read(Ice.InputStream inS__)"; _out << sb; _out << nl << typeS << " v__;"; - writeSequenceMarshalUnmarshalCode(_out, p, "v__", false, true); + writeSequenceMarshalUnmarshalCode(_out, p, "v__", false, true, false); _out << nl << "return v__;"; _out << eb; } @@ -5315,18 +6027,18 @@ Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p) _out << " e__ in v__)"; _out << sb; string keyArg = isNewMapping ? string("e__.Key") : "((" + keyS + ")e__.Key)"; - writeMarshalUnmarshalCode(_out, key, keyArg, true, false, false); + writeMarshalUnmarshalCode(_out, key, keyArg, true, false); string valueArg = isNewMapping ? string("e__.Value") : "((" + valueS + ")e__.Value)"; - writeMarshalUnmarshalCode(_out, value, valueArg, true, false, false); + writeMarshalUnmarshalCode(_out, value, valueArg, true, false); _out << eb; _out << eb; _out << eb; - BuiltinPtr builtin = BuiltinPtr::dynamicCast(value); - bool hasClassValue = (builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(value); + const bool hasClassValue = isClassType(value); + if(hasClassValue) { - _out << sp << nl << "public sealed class Patcher__ : IceInternal.Patcher<" << valueS << ">"; + _out << sp << nl << "public sealed class Patcher__ : IceInternal.Patcher"; _out << sb; _out << sp << nl << "internal Patcher__(string type, " << name << " m, " << keyS << " key) : base(type)"; _out << sb; @@ -5334,16 +6046,23 @@ Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p) _out << nl << "_key = key;"; _out << eb; - _out << sp << nl << "public override void" << nl << "patch(Ice.Object v)"; - _out << sb; - _out << nl << "try"; - _out << sb; - _out << nl << "_m[_key] = (" << valueS << ")v;"; - _out << eb; - _out << nl << "catch(_System.InvalidCastException)"; + _out << sp << nl << "public override void patch(Ice.Object v)"; _out << sb; - _out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());"; - _out << eb; + if(ClassDeclPtr::dynamicCast(value)) + { + _out << nl << "try"; + _out << sb; + _out << nl << "_m[_key] = (" << valueS << ")v;"; + _out << eb; + _out << nl << "catch(_System.InvalidCastException)"; + _out << sb; + _out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());"; + _out << eb; + } + else + { + _out << nl << "_m[_key] = v;"; + } _out << eb; _out << sp << nl << "private " << name << " _m;"; @@ -5370,8 +6089,14 @@ Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p) _out << nl << "k__ = null;"; } } - writeMarshalUnmarshalCode(_out, key, "k__", false, false, false); - if(!hasClassValue) + writeMarshalUnmarshalCode(_out, key, "k__", false, false); + + string patchParams; + if(hasClassValue) + { + patchParams = "new Patcher__(" + getStaticId(value) + ", r__, k__)"; + } + else { _out << nl << valueS << " v__;"; @@ -5388,7 +6113,7 @@ Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p) } } } - writeMarshalUnmarshalCode(_out, value, "v__", false, false, false, "r__, k__"); + writeMarshalUnmarshalCode(_out, value, "v__", false, false, patchParams); if(!hasClassValue) { _out << nl << "r__[k__] = v__;"; @@ -5419,8 +6144,8 @@ Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p) } _out << " e__ in v__)"; _out << sb; - writeMarshalUnmarshalCode(_out, key, keyArg, true, true, false); - writeMarshalUnmarshalCode(_out, value, valueArg, true, true, false); + writeMarshalUnmarshalCode(_out, key, keyArg, true, true); + writeMarshalUnmarshalCode(_out, value, valueArg, true, true); _out << eb; _out << eb; _out << eb; @@ -5444,7 +6169,7 @@ Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p) _out << nl << "k__ = null;"; } } - writeMarshalUnmarshalCode(_out, key, "k__", false, true, false); + writeMarshalUnmarshalCode(_out, key, "k__", false, true); if(!hasClassValue) { _out << nl << valueS << " v__;"; @@ -5461,7 +6186,7 @@ Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p) } } } - writeMarshalUnmarshalCode(_out, value, "v__", false, true, false, "r__, k__"); + writeMarshalUnmarshalCode(_out, value, "v__", false, true, patchParams); if(!hasClassValue) { _out << nl << "r__[k__] = v__;"; @@ -5541,7 +6266,7 @@ Slice::Gen::DelegateVisitor::visitClassDefStart(const ClassDefPtr& p) OperationPtr op = *r; string opName = fixId(op->name(), DotNet::ICloneable, true); TypePtr ret = op->returnType(); - string retS = typeToString(ret); + string retS = typeToString(ret, op->returnIsOptional()); vector<string> params = getParams(op); _out << sp << nl << retS << ' ' << opName << spar << params @@ -5606,25 +6331,25 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) OperationPtr op = *r; string opName = fixId(op->name(), DotNet::ICloneable, true); TypePtr ret = op->returnType(); - string retS = typeToString(ret); + string retS = typeToString(ret, op->returnIsOptional()); - TypeStringList inParams; - TypeStringList outParams; ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) + ParamDeclList::const_iterator pli; + ParamDeclList inParams; + ParamDeclList outParams; + + for(pli = paramList.begin(); pli != paramList.end(); ++pli) { if((*pli)->isOutParam()) { - outParams.push_back(make_pair((*pli)->type(), (*pli)->name())); + outParams.push_back(*pli); } else { - inParams.push_back(make_pair((*pli)->type(), (*pli)->name())); + inParams.push_back(*pli); } } - TypeStringList::const_iterator q; - ExceptionList throws = op->throws(); throws.sort(); throws.unique(); @@ -5656,14 +6381,7 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) _out << nl << "try"; _out << sb; _out << nl << "IceInternal.BasicStream os__ = og__.startWriteParams(" << opFormatTypeToString(op) << ");"; - for(q = inParams.begin(); q != inParams.end(); ++q) - { - writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), true, false, false); - } - if(op->sendsClasses()) - { - _out << nl << "os__.writePendingObjects();"; - } + writeMarshalUnmarshalParams(inParams, 0, true); _out << nl << "og__.endWriteParams();"; _out << eb; _out << nl << "catch(Ice.LocalException ex__)"; @@ -5708,73 +6426,76 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) if(ret || !outParams.empty()) { _out << nl << "IceInternal.BasicStream is__ = og__.startReadParams();"; - for(q = outParams.begin(); q != outParams.end(); ++q) + for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - string param = fixId(q->second); - StructPtr st = StructPtr::dynamicCast(q->first); - if(st) + string param = fixId((*pli)->name()); + string typeS = typeToString((*pli)->type(), (*pli)->optional()); + const bool isClass = isClassType((*pli)->type()); + + if((*pli)->optional()) { - if(isValueType(q->first)) + BuiltinPtr b = BuiltinPtr::dynamicCast((*pli)->type()); + if(!b || isClass) { - _out << nl << param << " = new " << typeToString(q->first) << "();"; + _out << nl << param << " = new " << typeS << "();"; } - else + } + else if(!isClass) + { + StructPtr st = StructPtr::dynamicCast((*pli)->type()); + if(st) { - _out << nl << param << " = null;"; + if(isValueType((*pli)->type())) + { + _out << nl << param << " = new " << typeS << "();"; + } + else + { + _out << nl << param << " = null;"; + } } } - writeMarshalUnmarshalCode(_out, q->first, param, false, false, true, ""); } if(ret) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret)) + string typeS = typeToString(ret, op->returnIsOptional()); + const bool isClass = isClassType(ret); + + _out << nl << typeS << " ret__;"; + + if(op->returnIsOptional()) { - _out << nl << retS << " ret__;"; - ContainedPtr contained = ContainedPtr::dynamicCast(ret); - string sliceId = contained ? contained->scoped() : string("::Ice::Object"); - _out << nl << "IceInternal.ParamPatcher<" << retS << "> ret___PP = new IceInternal.ParamPatcher<" - << retS << ">(\"" << sliceId << "\");"; - _out << nl << "is__.readObject(ret___PP);"; + BuiltinPtr b = BuiltinPtr::dynamicCast(ret); + if(!b || isClass) + { + _out << nl << "ret__ = new " << typeS << "();"; + } } - else + else if(!isClass) { - _out << nl << retS << " ret__;"; StructPtr st = StructPtr::dynamicCast(ret); if(st) { - if(isValueType(st)) + if(isValueType(ret)) { - _out << nl << "ret__ = new " << retS << "();"; + _out << nl << "ret__ = new " << typeS << "();"; } else { _out << nl << "ret__ = null;"; } } - writeMarshalUnmarshalCode(_out, ret, "ret__", false, false, true, ""); } } + writeMarshalUnmarshalParams(outParams, op, false); if(op->returnsClasses()) { - _out << nl << "is__.readPendingObjects();"; - for(q = outParams.begin(); q != outParams.end(); ++q) + for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - string param = fixId(q->second); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(q->first); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(q->first)) + string param = fixId((*pli)->name()); + if(!(*pli)->optional() && isClassType((*pli)->type())) { - string type = typeToString(q->first); - _out << nl << "try"; - _out << sb; - _out << nl << param << " = (" << type << ")" << param << "_PP.value;"; - _out << eb; - _out << nl << "catch(_System.InvalidCastException)"; - _out << sb; - _out << nl << param << " = null;"; - _out << nl << "IceInternal.Ex.throwUOE(" << param << "_PP.type(), " - << param << "_PP.value.ice_id());"; - _out << eb; + _out << nl << param << " = " << param << "__PP.value;"; } } } @@ -5787,18 +6508,9 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) if(ret) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret)) + if(!op->returnIsOptional() && isClassType(ret)) { - _out << nl << "try"; - _out << sb; - _out << nl << "ret__ = (" << retS << ")ret___PP.value;"; - _out << eb; - _out << nl << "catch(_System.InvalidCastException)"; - _out << sb; - _out << nl << "ret__ = null;"; - _out << nl << "IceInternal.Ex.throwUOE(ret___PP.type(), ret___PP.value.ice_id());"; - _out << eb; + _out << nl << "ret__ = ret__PP.value;"; } _out << nl << "return ret__;"; } @@ -5877,7 +6589,7 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) OperationPtr op = *r; string opName = fixId(op->name(), DotNet::ICloneable, true); TypePtr ret = op->returnType(); - string retS = typeToString(ret); + string retS = typeToString(ret, op->returnIsOptional()); ClassDefPtr containingClass = ClassDefPtr::dynamicCast(op->container()); ExceptionList throws = op->throws(); @@ -5914,7 +6626,6 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) << sliceModeToIceMode(op->sendMode()) << ", context__);"; - // // Create out holders and delArgs // @@ -5927,7 +6638,16 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) string arg = fixId((*q)->name()); if((*q)->isOutParam()) { - _out << nl << typeToString((*q)->type()) << " " << arg << "Holder__ = " << writeValue((*q)->type()) << ";"; + _out << nl << typeToString((*q)->type(), (*q)->optional()) << " " << arg << "Holder__ = "; + if((*q)->optional()) + { + _out << "null"; + } + else + { + _out << writeValue((*q)->type()); + } + _out << ';'; outHolders.push_back(arg); arg = "out " + arg + "Holder__"; } @@ -5936,7 +6656,16 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) if(ret) { - _out << nl << retS << " result__ = " << writeValue(ret) << ";"; + _out << nl << retS << " result__ = "; + if(op->returnIsOptional()) + { + _out << "null"; + } + else + { + _out << writeValue(ret); + } + _out << ';'; } if(!throws.empty()) @@ -5953,7 +6682,8 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) _out << eb; _out << nl << "catch(_System.InvalidCastException)"; _out << sb; - _out << nl << "throw new Ice.OperationNotExistException(current__.id, current__.facet, current__.operation);"; + _out << nl + << "throw new Ice.OperationNotExistException(current__.id, current__.facet, current__.operation);"; _out << eb; if(!throws.empty()) @@ -6242,13 +6972,15 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) TypePtr ret = p->returnType(); - TypeStringList outParams; ParamDeclList paramList = p->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) + ParamDeclList::const_iterator pli; + ParamDeclList outParams; + + for(pli = paramList.begin(); pli != paramList.end(); ++pli) { if((*pli)->isOutParam()) { - outParams.push_back(make_pair((*pli)->type(), (*pli)->name())); + outParams.push_back(*pli); } } @@ -6268,7 +7000,6 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) throws.sort(Slice::DerivedToBaseCompare()); #endif - TypeStringList::const_iterator q; _out << sp; emitGeneratedCodeAttribute(); _out << nl << "class " << classNameAMDI << '_' << name @@ -6288,20 +7019,7 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) _out << nl << "try"; _out << sb; _out << nl << "IceInternal.BasicStream os__ = startWriteParams__(" << opFormatTypeToString(p) << ");"; - for(q = outParams.begin(); q != outParams.end(); ++q) - { - string typeS = typeToString(q->first); - writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), true, false, false); - } - if(ret) - { - string retS = typeToString(ret); - writeMarshalUnmarshalCode(_out, ret, "ret__", true, false, false); - } - if(p->returnsClasses()) - { - _out << nl << "os__.writePendingObjects();"; - } + writeMarshalUnmarshalParams(outParams, p, true); _out << nl << "endWriteParams__(true);"; _out << eb; _out << nl << "catch(Ice.LocalException ex__)"; diff --git a/cpp/src/slice2cs/Gen.h b/cpp/src/slice2cs/Gen.h index 2c171a71e25..22d6cac7930 100644 --- a/cpp/src/slice2cs/Gen.h +++ b/cpp/src/slice2cs/Gen.h @@ -24,6 +24,7 @@ public: protected: + void writeMarshalUnmarshalParams(const ParamDeclList&, const OperationPtr&, bool); void writeMarshalDataMember(const DataMemberPtr&, const std::string&); void writeUnmarshalDataMember(const DataMemberPtr&, const std::string&, bool, int&); void writeStreamMarshalDataMember(const DataMemberPtr&, const std::string&); |