diff options
42 files changed, 5048 insertions, 1134 deletions
diff --git a/cpp/src/Slice/CsUtil.cpp b/cpp/src/Slice/CsUtil.cpp index 1cd5e3dcec3..5a8c7968b7f 100644 --- a/cpp/src/Slice/CsUtil.cpp +++ b/cpp/src/Slice/CsUtil.cpp @@ -609,21 +609,11 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out, out << nl << "throw new Ice.MarshalException(\"enumerator out of range\");"; out << eb; } - out << nl << stream << '.' << func << '(' << cast << param; - if(!streamingAPI) - { - out << ", " << sz; - } - out << ");"; + out << nl << stream << ".writeEnum((int)" << param << ", " << sz << ");"; } else { - out << nl << param << " = " << cast << stream << '.' << func << "("; - if(!streamingAPI) - { - out << sz; - } - out << ")" << ';'; + out << nl << param << " = (" << fixId(en->scoped()) << ')' << stream << ".readEnum(" << sz << ");"; if(streamingAPI) { out << nl << "if((int)" << param << " < 0 || (int)" << param << " >= " << sz << ")"; diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp index f76877a2065..8a9b4efbac5 100644 --- a/cpp/src/slice2cs/Gen.cpp +++ b/cpp/src/slice2cs/Gen.cpp @@ -62,6 +62,24 @@ sliceModeToIceMode(Operation::Mode opMode) } static string +opFormatTypeToString(const OperationPtr& op) +{ + switch(op->format()) + { + case DefaultFormat: + return "Ice.FormatType.DefaultFormat"; + case CompactFormat: + return "Ice.FormatType.CompactFormat"; + case SlicedFormat: + return "Ice.FormatType.SlicedFormat"; + default: + assert(false); + } + + return "???"; +} + +static string getDeprecateReason(const ContainedPtr& p1, const ContainedPtr& p2, const string& type) { string deprecateMetadata, deprecateReason; @@ -97,6 +115,133 @@ Slice::CsVisitor::~CsVisitor() } void +Slice::CsVisitor::writeMarshalDataMember(const DataMemberPtr& member, const string& name) +{ + writeMarshalUnmarshalCode(_out, member->type(), name, true, false, false); + +#if 0 + if(!member->optional()) + { + writeMarshalUnmarshalCode(out, package, member->type(), OptionalNone, false, 0, fixKwd(member->name()), + true, iter, false, member->getMetaData()); + } + else + { + 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; + } +#endif +} + +void +Slice::CsVisitor::writeUnmarshalDataMember(const DataMemberPtr& member, const string& name, bool needPatcher, + int& patchIter) +{ + string patchParams = "this"; + if(needPatcher) + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + { + ostringstream ostr; + ostr << ", " << patchIter++; + patchParams += ostr.str(); + } + } + + 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); + } + else + { + 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; + } +#endif +} + +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()); + } + else + { + 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; + } +#endif +} + +void +Slice::CsVisitor::writeStreamUnmarshalDataMember(const DataMemberPtr& member, const string& name, bool needPatcher, + int& patchIter) +{ + string patchParams = "this"; + if(needPatcher) + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + { + ostringstream ostr; + ostr << ", " << patchIter++; + patchParams += ostr.str(); + } + } + + writeMarshalUnmarshalCode(_out, member->type(), name, false, true, false, patchParams); +#if 0 + string patchParams; + if(needPatcher) + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + { + ostringstream ostr; + ostr << "new Patcher(" << patchIter++ << ')'; + patchParams = ostr.str(); + } + } + + if(!member->optional()) + { + writeStreamMarshalUnmarshalCode(out, package, member->type(), false, 0, fixKwd(member->name()), false, + iter, false, member->getMetaData(), patchParams); + } + else + { + 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; + } +#endif +} + +void Slice::CsVisitor::writeInheritedOperations(const ClassDefPtr& p) { ClassList bases = p->bases(); @@ -445,7 +590,8 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) // if(!outParams.empty() || ret) { - _out << nl << "IceInternal.BasicStream os__ = inS__.startWriteParams__();"; + _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, ""); @@ -478,8 +624,7 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) string exS = fixId((*t)->scoped()); _out << nl << "catch(" << exS << " ex__)"; _out << sb; - _out << nl << "inS__.startWriteParams__().writeUserException(ex__);"; - _out << nl << "inS__.endWriteParams__(false);"; + _out << nl << "inS__.writeUserException__(ex__, " << opFormatTypeToString(op) << ");"; _out << nl << "return Ice.DispatchStatus.DispatchUserException;"; _out << eb; } @@ -716,6 +861,9 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) DataMemberList::const_iterator d; DataMemberList members = p->dataMembers(); DataMemberList classMembers = p->classDataMembers(); + const bool basePreserved = p->inheritsMetaData("preserve-slice"); + const bool preserved = basePreserved || p->hasMetaData("preserve-slice"); + ClassList bases = p->bases(); ClassDefPtr base; if(!bases.empty() && !bases.front()->isInterface()) @@ -732,15 +880,35 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) } _out << nl << "public override void write__(IceInternal.BasicStream os__)"; _out << sb; - _out << nl << "os__.writeTypeId(ice_staticId());"; - _out << nl << "os__.startWriteSlice();"; + if(preserved) + { + _out << nl << "os__.startWriteObject(slicedData__);"; + } + else + { + _out << nl << "os__.startWriteObject(null);"; + } + _out << nl << "writeImpl__(os__);"; + _out << nl << "os__.endWriteObject();"; + _out << eb; + + _out << sp; + if(!p->isInterface()) + { + emitGeneratedCodeAttribute(); + } + _out << nl << "public override void writeImpl__(IceInternal.BasicStream os__)"; + _out << sb; + _out << nl << "os__.startWriteSlice(ice_staticId(), " << (!base ? "true" : "false") << ");"; for(d = members.begin(); d != members.end(); ++d) { - writeMarshalUnmarshalCode(_out, (*d)->type(), fixId(*d, DotNet::ICloneable, true), - true, false, false); + writeMarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true)); } _out << nl << "os__.endWriteSlice();"; - _out << nl << "base.write__(os__);"; + if(base) + { + _out << nl << "base.writeImpl__(os__);"; + } _out << eb; if(allClassMembers.size() != 0) @@ -826,31 +994,39 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) { emitGeneratedCodeAttribute(); } - _out << nl << "public override void read__(IceInternal.BasicStream is__, bool rid__)"; - _out << sb; - _out << nl << "if(rid__)"; + _out << nl << "public override void read__(IceInternal.BasicStream is__)"; _out << sb; - _out << nl << "/* string myId = */ is__.readTypeId();"; + _out << nl << "is__.startReadObject();"; + _out << nl << "readImpl__(is__);"; + if(preserved) + { + _out << nl << "slicedData__ = is__.endReadObject(true);"; + } + else + { + _out << nl << "is__.endReadObject(false);"; + } _out << eb; + + _out << sp; + if(!p->isInterface()) + { + emitGeneratedCodeAttribute(); + } + _out << nl << "public override void readImpl__(IceInternal.BasicStream is__)"; + _out << sb; _out << nl << "is__.startReadSlice();"; int classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size()); + const bool needCustomPatcher = classMembers.size() > 1 || allClassMembers.size() > 1; for(d = members.begin(); d != members.end(); ++d) { - ostringstream patchParams; - patchParams << "this"; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type())) - { - if(classMembers.size() > 1 || allClassMembers.size() > 1) - { - patchParams << ", " << classMemberCount++; - } - } - writeMarshalUnmarshalCode(_out, (*d)->type(), fixId(*d, DotNet::ICloneable, true), - false, false, false, patchParams.str()); + writeUnmarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true), needCustomPatcher, classMemberCount); } _out << nl << "is__.endReadSlice();"; - _out << nl << "base.read__(is__, true);"; + if(base) + { + _out << nl << "base.readImpl__(is__);"; + } _out << eb; // @@ -865,15 +1041,35 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) } _out << nl << "public override void write__(Ice.OutputStream outS__)"; _out << sb; - _out << nl << "outS__.writeTypeId(ice_staticId());"; - _out << nl << "outS__.startSlice();"; + if(preserved) + { + _out << nl << "outS__.startObject(slicedData__);"; + } + else + { + _out << nl << "outS__.startObject(null);"; + } + _out << nl << "writeImpl__(outS__);"; + _out << nl << "outS__.endObject();"; + _out << eb; + + _out << sp; + if(!p->isInterface()) + { + emitGeneratedCodeAttribute(); + } + _out << nl << "public override void writeImpl__(Ice.OutputStream outS__)"; + _out << sb; + _out << nl << "outS__.startSlice(ice_staticId(), " << (!base ? "true" : "false") << ");"; for(d = members.begin(); d != members.end(); ++d) { - writeMarshalUnmarshalCode(_out, (*d)->type(), fixId(*d, DotNet::ICloneable, true), - true, true, false); + writeStreamMarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true)); } _out << nl << "outS__.endSlice();"; - _out << nl << "base.write__(outS__);"; + if(base) + { + _out << nl << "base.writeImpl__(outS__);"; + } _out << eb; _out << sp; @@ -881,30 +1077,39 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) { emitGeneratedCodeAttribute(); } - _out << nl << "public override void read__(Ice.InputStream inS__, bool rid__)"; - _out << sb; - _out << nl << "if(rid__)"; + _out << nl << "public override void read__(Ice.InputStream inS__)"; _out << sb; - _out << nl << "/* string myId = */ inS__.readTypeId();"; + _out << nl << "inS__.startObject();"; + _out << nl << "readImpl__(inS__);"; + if(preserved) + { + _out << nl << "slicedData__ = inS__.endObject(true);"; + } + else + { + _out << nl << "inS__.endObject(false);"; + } _out << eb; + + _out << sp; + if(!p->isInterface()) + { + emitGeneratedCodeAttribute(); + } + _out << nl << "public override void readImpl__(Ice.InputStream inS__)"; + _out << sb; _out << nl << "inS__.startSlice();"; + classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size()); for(d = members.begin(); d != members.end(); ++d) { - ostringstream patchParams; - patchParams << "this"; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type())) - { - if(classMembers.size() > 1 || allClassMembers.size() > 1) - { - patchParams << ", " << classMemberCount++; - } - } - writeMarshalUnmarshalCode(_out, (*d)->type(), fixId(*d, DotNet::ICloneable, true), - false, true, false, patchParams.str()); + writeStreamUnmarshalDataMember(*d, fixId(*d, DotNet::ICloneable, true), needCustomPatcher, + classMemberCount); } _out << nl << "inS__.endSlice();"; - _out << nl << "base.read__(inS__, true);"; + if(base) + { + _out << nl << "base.readImpl__(inS__);"; + } _out << eb; } else @@ -930,7 +1135,7 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) { emitGeneratedCodeAttribute(); } - _out << nl << "public override void read__(Ice.InputStream inS__, bool rid__)"; + _out << nl << "public override void read__(Ice.InputStream inS__)"; _out << sb; _out << nl << "Ice.MarshalException ex = new Ice.MarshalException();"; _out << nl << "ex.reason = \"type " << scoped.substr(2) << " was not generated with stream support\";"; @@ -938,6 +1143,11 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream) _out << eb; } + if(preserved && !basePreserved) + { + _out << sp << nl << "protected Ice.SlicedData slicedData__;"; + } + _out << sp << nl << "#endregion"; // Marshalling support } @@ -2906,21 +3116,38 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) string scoped = p->scoped(); ExceptionPtr base = p->base(); + const bool basePreserved = p->inheritsMetaData("preserve-slice"); + const bool preserved = basePreserved || p->hasMetaData("preserve-slice"); + _out << sp; emitGeneratedCodeAttribute(); _out << nl << "public override void write__(IceInternal.BasicStream os__)"; _out << sb; - _out << nl << "os__.writeString(\"" << scoped << "\");"; - _out << nl << "os__.startWriteSlice();"; + if(preserved) + { + _out << nl << "os__.startWriteException(slicedData__);"; + } + else + { + _out << nl << "os__.startWriteException(null);"; + } + _out << nl << "writeImpl__(os__);"; + _out << nl << "os__.endWriteException();"; + _out << eb; + + _out << sp; + emitGeneratedCodeAttribute(); + _out << nl << "public override void writeImpl__(IceInternal.BasicStream os__)"; + _out << sb; + _out << nl << "os__.startWriteSlice(\"" << scoped << "\", " << (!base ? "true" : "false") << ");"; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::Exception), - true, false, false); + writeMarshalDataMember(*q, fixId((*q)->name(), DotNet::Exception)); } _out << nl << "os__.endWriteSlice();"; if(base) { - _out << nl << "base.write__(os__);"; + _out << nl << "base.writeImpl__(os__);"; } _out << eb; @@ -3002,34 +3229,36 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << sp; emitGeneratedCodeAttribute(); - _out << nl << "public override void read__(IceInternal.BasicStream is__, bool rid__)"; + _out << nl << "public override void read__(IceInternal.BasicStream is__)"; _out << sb; - _out << nl << "if(rid__)"; - _out << sb; - _out << nl << "/* string myId = */ is__.readString();"; + _out << nl << "is__.startReadException();"; + _out << nl << "readImpl__(is__);"; + if(preserved) + { + _out << nl << "slicedData__ = is__.endReadException(true);"; + } + else + { + _out << nl << "is__.endReadException(false);"; + } _out << eb; + + _out << sp; + emitGeneratedCodeAttribute(); + _out << nl << "public override void readImpl__(IceInternal.BasicStream is__)"; + _out << sb; _out << nl << "is__.startReadSlice();"; DataMemberList classMembers = p->classDataMembers(); int classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size()); + const bool needCustomPatcher = classMembers.size() > 1 || allClassMembers.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 || allClassMembers.size() > 1) - { - patchParams << ", " << classMemberCount++; - } - } - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::Exception), - false, false, false, patchParams.str()); + writeUnmarshalDataMember(*q, fixId((*q)->name(), DotNet::Exception), needCustomPatcher, classMemberCount); } _out << nl << "is__.endReadSlice();"; if(base) { - _out << nl << "base.read__(is__, true);"; + _out << nl << "base.readImpl__(is__);"; } _out << eb; @@ -3039,49 +3268,65 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) emitGeneratedCodeAttribute(); _out << nl << "public override void write__(Ice.OutputStream outS__)"; _out << sb; - _out << nl << "outS__.writeString(\"" << scoped << "\");"; - _out << nl << "outS__.startSlice();"; + if(preserved) + { + _out << nl << "outS__.startException(slicedData__);"; + } + else + { + _out << nl << "outS__.startException(null);"; + } + _out << nl << "writeImpl__(outS__);"; + _out << nl << "outS__.endException();"; + _out << eb; + + _out << sp; + emitGeneratedCodeAttribute(); + _out << nl << "public override void writeImpl__(Ice.OutputStream outS__)"; + _out << sb; + _out << nl << "outS__.startSlice(\"" << scoped << "\", " << (!base ? "true" : "false") << ");"; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::Exception), - true, true, false); + writeStreamMarshalDataMember(*q, fixId((*q)->name(), DotNet::Exception)); } _out << nl << "outS__.endSlice();"; if(base) { - _out << nl << "base.write__(outS__);"; + _out << nl << "base.writeImpl__(outS__);"; } _out << eb; _out << sp; emitGeneratedCodeAttribute(); - _out << nl << "public override void read__(Ice.InputStream inS__, bool rid__)"; + _out << nl << "public override void read__(Ice.InputStream inS__)"; _out << sb; - _out << nl << "if(rid__)"; - _out << sb; - _out << nl << "/* string myId = */ inS__.readString();"; + _out << nl << "inS__.startException();"; + _out << nl << "readImpl__(inS__);"; + if(preserved) + { + _out << nl << "slicedData__ = inS__.endException(true);"; + } + else + { + _out << nl << "inS__.endException(false);"; + } _out << eb; + + _out << sp; + emitGeneratedCodeAttribute(); + _out << nl << "public override void readImpl__(Ice.InputStream inS__)"; + _out << sb; _out << nl << "inS__.startSlice();"; classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size()); 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 || allClassMembers.size() > 1) - { - patchParams << ", " << classMemberCount++; - } - } - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::Exception), - false, true, false, patchParams.str()); + writeStreamUnmarshalDataMember(*q, fixId((*q)->name(), DotNet::Exception), needCustomPatcher, + classMemberCount); } _out << nl << "inS__.endSlice();"; if(base) { - _out << nl << "base.read__(inS__, true);"; + _out << nl << "base.readImpl__(inS__);"; } _out << eb; } @@ -3101,7 +3346,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << sp; emitGeneratedCodeAttribute(); - _out << nl << "public override void read__(Ice.InputStream inS__, bool rid__)"; + _out << nl << "public override void read__(Ice.InputStream inS__)"; _out << sb; _out << nl << "Ice.MarshalException ex = new Ice.MarshalException();"; _out << nl << "ex.reason = \"exception " << scoped.substr(2) << " was not generated with stream support\";"; @@ -3109,14 +3354,9 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << eb; } - if((!base || (base && !base->usesClasses())) && p->usesClasses()) + if(preserved && !basePreserved) { - _out << sp; - emitGeneratedCodeAttribute(); - _out << nl << "public override bool usesClasses__()"; - _out << sb; - _out << nl << "return true;"; - _out << eb; + _out << sp << nl << "protected Ice.SlicedData slicedData__;"; } _out << sp << nl << "#endregion"; // Marshalling support @@ -4534,7 +4774,8 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) << sliceModeToIceMode(op->sendMode()) << ", ctx__, explicitContext__);"; if(!inParams.empty()) { - _out << nl << "IceInternal.BasicStream os__ = result__.startWriteParams__();"; + _out << nl << "IceInternal.BasicStream os__ = result__.startWriteParams__(" + << opFormatTypeToString(op) << ");"; for(q = inParams.begin(); q != inParams.end(); ++q) { string typeS = typeToString(q->first); @@ -5414,7 +5655,7 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) { _out << nl << "try"; _out << sb; - _out << nl << "IceInternal.BasicStream os__ = og__.startWriteParams();"; + _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); @@ -6046,7 +6287,7 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) { _out << nl << "try"; _out << sb; - _out << nl << "IceInternal.BasicStream os__ = startWriteParams__();"; + _out << nl << "IceInternal.BasicStream os__ = startWriteParams__(" << opFormatTypeToString(p) << ");"; for(q = outParams.begin(); q != outParams.end(); ++q) { string typeS = typeToString(q->first); @@ -6092,8 +6333,7 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) _out << sb; _out << nl << "if(validateResponse__(false))"; _out << sb; - _out << nl << "startWriteParams__().writeUserException(ex__);"; - _out << nl << "endWriteParams__(false);"; + _out << nl << "writeUserException__(ex__, " << opFormatTypeToString(p) << ");"; _out << nl << "response__();"; _out << eb; _out << eb; diff --git a/cpp/src/slice2cs/Gen.h b/cpp/src/slice2cs/Gen.h index bec13760eaf..2c171a71e25 100644 --- a/cpp/src/slice2cs/Gen.h +++ b/cpp/src/slice2cs/Gen.h @@ -24,6 +24,11 @@ public: protected: + void writeMarshalDataMember(const DataMemberPtr&, const std::string&); + void writeUnmarshalDataMember(const DataMemberPtr&, const std::string&, bool, int&); + void writeStreamMarshalDataMember(const DataMemberPtr&, const std::string&); + void writeStreamUnmarshalDataMember(const DataMemberPtr&, const std::string&, bool, int&); + virtual void writeInheritedOperations(const ClassDefPtr&); virtual void writeDispatchAndMarshalling(const ClassDefPtr&, bool); virtual std::vector<std::string> getParams(const OperationPtr&); diff --git a/cs/src/Ice/BasicStream.cs b/cs/src/Ice/BasicStream.cs index 240149502c5..af409ff9b55 100644 --- a/cs/src/Ice/BasicStream.cs +++ b/cs/src/Ice/BasicStream.cs @@ -114,24 +114,22 @@ namespace IceInternal private void initialize(Instance instance, Ice.EncodingVersion encoding, bool unlimited) { instance_ = instance; - _encoding = encoding; _buf = new Buffer(instance_.messageSizeMax()); _closure = null; - _unlimited = unlimited; + _encoding = encoding; _readEncapsStack = null; _writeEncapsStack = null; _readEncapsCache = null; _writeEncapsCache = null; - _traceSlicing = -1; - _sliceObjects = true; _messageSizeMax = instance_.messageSizeMax(); // Cached for efficiency. + _unlimited = unlimited; _startSeq = -1; - _objectList = null; + _sizePos = -1; } // @@ -166,11 +164,6 @@ namespace IceInternal _startSeq = -1; - if(_objectList != null) - { - _objectList.Clear(); - } - _sliceObjects = true; } @@ -194,38 +187,26 @@ namespace IceInternal public void swap(BasicStream other) { Debug.Assert(instance_ == other.instance_); - - object tmpClosure = other._closure; - other._closure = _closure; - _closure = tmpClosure; Buffer tmpBuf = other._buf; other._buf = _buf; _buf = tmpBuf; - ReadEncaps tmpRead = other._readEncapsStack; - other._readEncapsStack = _readEncapsStack; - _readEncapsStack = tmpRead; - - tmpRead = other._readEncapsCache; - other._readEncapsCache = _readEncapsCache; - _readEncapsCache = tmpRead; - - WriteEncaps tmpWrite = other._writeEncapsStack; - other._writeEncapsStack = _writeEncapsStack; - _writeEncapsStack = tmpWrite; - - tmpWrite = other._writeEncapsCache; - other._writeEncapsCache = _writeEncapsCache; - _writeEncapsCache = tmpWrite; + object tmpClosure = other._closure; + other._closure = _closure; + _closure = tmpClosure; - int tmpReadSlice = other._readSlice; - other._readSlice = _readSlice; - _readSlice = tmpReadSlice; + // + // Swap is never called for BasicStreams that have encapsulations being read/write. However, + // encapsulations might still be set in case marshalling or un-marshalling failed. We just + // reset the encapsulations if there are still some set. + // + resetEncaps(); + other.resetEncaps(); - int tmpWriteSlice = other._writeSlice; - other._writeSlice = _writeSlice; - _writeSlice = tmpWriteSlice; + bool tmpUnlimited = other._unlimited; + other._unlimited = _unlimited; + _unlimited = tmpUnlimited; int tmpStartSeq = other._startSeq; other._startSeq = _startSeq; @@ -235,13 +216,15 @@ namespace IceInternal other._minSeqSize = _minSeqSize; _minSeqSize = tmpMinSeqSize; - List<Ice.Object> tmpObjectList = other._objectList; - other._objectList = _objectList; - _objectList = tmpObjectList; + int tmpSizePos = other._sizePos; + other._sizePos = _sizePos; + _sizePos = tmpSizePos; + } - bool tmpUnlimited = other._unlimited; - other._unlimited = _unlimited; - _unlimited = tmpUnlimited; + public void resetEncaps() + { + _readEncapsStack = null; + _writeEncapsStack = null; } public void resize(int sz, bool reading) @@ -270,6 +253,54 @@ namespace IceInternal return _buf; } + public void startWriteObject(Ice.SlicedData data) + { + Debug.Assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null); + _writeEncapsStack.encoder.startObject(data); + } + + public void endWriteObject() + { + Debug.Assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null); + _writeEncapsStack.encoder.endObject(); + } + + public void startReadObject() + { + Debug.Assert(_readEncapsStack != null && _readEncapsStack.decoder != null); + _readEncapsStack.decoder.startObject(); + } + + public Ice.SlicedData endReadObject(bool preserve) + { + Debug.Assert(_readEncapsStack != null && _readEncapsStack.decoder != null); + return _readEncapsStack.decoder.endObject(preserve); + } + + public void startWriteException(Ice.SlicedData data) + { + Debug.Assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null); + _writeEncapsStack.encoder.startException(data); + } + + public void endWriteException() + { + Debug.Assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null); + _writeEncapsStack.encoder.endException(); + } + + public void startReadException() + { + Debug.Assert(_readEncapsStack != null && _readEncapsStack.decoder != null); + _readEncapsStack.decoder.startException(); + } + + public Ice.SlicedData endReadException(bool preserve) + { + Debug.Assert(_readEncapsStack != null && _readEncapsStack.decoder != null); + return _readEncapsStack.decoder.endException(preserve); + } + public void startWriteEncaps() { // @@ -280,33 +311,33 @@ namespace IceInternal if(_writeEncapsStack != null) { - startWriteEncaps(_writeEncapsStack.encoding); + startWriteEncaps(_writeEncapsStack.encoding, _writeEncapsStack.format); } else { - startWriteEncaps(_encoding); + startWriteEncaps(_encoding, Ice.FormatType.DefaultFormat); } } - public void startWriteEncaps(Ice.EncodingVersion encoding) - { + public void startWriteEncaps(Ice.EncodingVersion encoding, Ice.FormatType format) + { Protocol.checkSupportedEncoding(encoding); + WriteEncaps curr = _writeEncapsCache; + if(curr != null) { - WriteEncaps curr = _writeEncapsCache; - if(curr != null) - { - curr.reset(); - _writeEncapsCache = _writeEncapsCache.next; - } - else - { - curr = new WriteEncaps(); - } - curr.next = _writeEncapsStack; - _writeEncapsStack = curr; + curr.reset(); + _writeEncapsCache = _writeEncapsCache.next; } - _writeEncapsStack.encoding = encoding; + else + { + curr = new WriteEncaps(); + } + curr.next = _writeEncapsStack; + _writeEncapsStack = curr; + + _writeEncapsStack.format = format; + _writeEncapsStack.setEncoding(encoding); _writeEncapsStack.start = _buf.b.position(); writeInt(0); // Placeholder for the encapsulation length. @@ -316,8 +347,15 @@ namespace IceInternal public void endWriteEncaps() { Debug.Assert(_writeEncapsStack != null); + + if(_writeEncapsStack.encoder != null) + { + _writeEncapsStack.encoder.writePendingObjects(); + } + + // Size includes size and version. int start = _writeEncapsStack.start; - int sz = _buf.size() - start; // Size includes size and version. + int sz = _buf.size() - start; _buf.b.putInt(start, sz); WriteEncaps curr = _writeEncapsStack; @@ -333,20 +371,17 @@ namespace IceInternal { throw new Ice.EncapsulationException("not in an encapsulation"); } - endWriteEncaps(); } - - public void - writeEmptyEncaps(Ice.EncodingVersion encoding) + + public void writeEmptyEncaps(Ice.EncodingVersion encoding) { Protocol.checkSupportedEncoding(encoding); writeInt(6); // Size encoding.write__(this); } - - public void - writeEncaps(byte[] v) + + public void writeEncaps(byte[] v) { if(v.Length < 6) { @@ -356,38 +391,33 @@ namespace IceInternal _buf.b.put(v); } - public Ice.EncodingVersion - getWriteEncoding() + public Ice.EncodingVersion getWriteEncoding() { return _writeEncapsStack != null ? _writeEncapsStack.encoding : _encoding; } - public Ice.EncodingVersion - startReadEncaps() + public Ice.EncodingVersion startReadEncaps() { + ReadEncaps curr = _readEncapsCache; + if(curr != null) { - ReadEncaps curr = _readEncapsCache; - if(curr != null) - { - curr.reset(); - _readEncapsCache = _readEncapsCache.next; - } - else - { - curr = new ReadEncaps(); - } - curr.next = _readEncapsStack; - _readEncapsStack = curr; + curr.reset(); + _readEncapsCache = _readEncapsCache.next; + } + else + { + curr = new ReadEncaps(); } + curr.next = _readEncapsStack; + _readEncapsStack = curr; _readEncapsStack.start = _buf.b.position(); // - // I don't use readSize() and writeSize() for - // encapsulations, because when creating an encapsulation, - // I must know in advance how many bytes the size - // information will require in the data stream. If I use - // an Int, it is always 4 bytes. For + // I don't use readSize() and writeSize() for encapsulations, + // because when creating an encapsulation, I must know in advance + // how many bytes the size information will require in the data + // stream. If I use an Int, it is always 4 bytes. For // readSize()/writeSize(), it could be 1 or 5 bytes. // int sz = readInt(); @@ -395,22 +425,44 @@ namespace IceInternal { throw new Ice.UnmarshalOutOfBoundsException(); } - if(sz - 4 > _buf.b.remaining()) { throw new Ice.UnmarshalOutOfBoundsException(); } _readEncapsStack.sz = sz; - _readEncapsStack.encoding.read__(this); - Protocol.checkSupportedEncoding(_readEncapsStack.encoding); // Make sure the encoding is supported. + Ice.EncodingVersion encoding = new Ice.EncodingVersion(); + encoding.read__(this); + Protocol.checkSupportedEncoding(encoding); // Make sure the encoding is supported. + _readEncapsStack.setEncoding(encoding); - return _readEncapsStack.encoding; + return encoding; } public void endReadEncaps() { Debug.Assert(_readEncapsStack != null); + + if(_readEncapsStack.decoder != null) + { + _readEncapsStack.decoder.readPendingObjects(); + } + else if(_buf.b.position() < _readEncapsStack.start + _readEncapsStack.sz && !_readEncapsStack.encoding_1_0) + { + // + // Read remaining encapsulation optionals. This returns + // true if the optionals end with the end marker. The end + // marker indicates that there are more to read from the + // encapsulation: object instances. In this case, don't + // bother reading the objects, just skip to the end of the + // encapsulation. + // + if(skipOpts()) + { + _buf.b.position(_readEncapsStack.start + _readEncapsStack.sz); + } + } + if(_buf.b.position() != _readEncapsStack.start + _readEncapsStack.sz) { if(_buf.b.position() + 1 != _readEncapsStack.start + _readEncapsStack.sz) @@ -454,34 +506,32 @@ namespace IceInternal return encoding; } - public void endReadEncapsChecked() + public void endReadEncapsChecked() // Used by public stream API. { if(_readEncapsStack == null) { throw new Ice.EncapsulationException("not in an encapsulation"); } - endReadEncaps(); } - public byte[] - readEncaps(out Ice.EncodingVersion encoding) + public byte[] readEncaps(out Ice.EncodingVersion encoding) { int sz = readInt(); if(sz < 6) { throw new Ice.UnmarshalOutOfBoundsException(); } - + if(sz - 4 > _buf.b.remaining()) { throw new Ice.UnmarshalOutOfBoundsException(); } - + encoding = new Ice.EncodingVersion(); encoding.read__(this); _buf.b.position(_buf.b.position() - 6); - + byte[] v = new byte[sz]; try { @@ -493,13 +543,12 @@ namespace IceInternal throw new Ice.UnmarshalOutOfBoundsException(ex); } } - - public Ice.EncodingVersion - getReadEncoding() + + public Ice.EncodingVersion getReadEncoding() { return _readEncapsStack != null ? _readEncapsStack.encoding : _encoding; } - + public int getReadEncapsSize() { Debug.Assert(_readEncapsStack != null); @@ -526,96 +575,50 @@ namespace IceInternal return encoding; } - public void startWriteSlice() + public void startWriteSlice(string typeId, bool last) { - writeInt(0); // Placeholder for the slice length. - _writeSlice = _buf.size(); + Debug.Assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null); + _writeEncapsStack.encoder.startSlice(typeId, last); } public void endWriteSlice() { - int sz = _buf.size() - _writeSlice + 4; - _buf.b.putInt(_writeSlice - 4, sz); + Debug.Assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null); + _writeEncapsStack.encoder.endSlice(); } - public void startReadSlice() + public string startReadSlice() // Returns type ID of next slice { - int sz = readInt(); - if(sz < 4) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - _readSlice = _buf.b.position(); + Debug.Assert(_readEncapsStack != null && _readEncapsStack.decoder != null); + return _readEncapsStack.decoder.startSlice(); } public void endReadSlice() { + Debug.Assert(_readEncapsStack != null && _readEncapsStack.decoder != null); + _readEncapsStack.decoder.endSlice(); } public void skipSlice() { - int sz = readInt(); - if(sz < 4) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - try - { - _buf.b.position(_buf.b.position() + sz - 4); - } - catch(ArgumentOutOfRangeException ex) - { - throw new Ice.UnmarshalOutOfBoundsException(ex); - } + Debug.Assert(_readEncapsStack != null && _readEncapsStack.decoder != null); + _readEncapsStack.decoder.skipSlice(); } - public int readAndCheckSeqSize(int minSize) + public void readPendingObjects() { - int sz = readSize(); - - if(sz == 0) + if(_readEncapsStack != null && _readEncapsStack.decoder != null) { - return 0; - } - - // - // The _startSeq variable points to the start of the sequence for which - // we expect to read at least _minSeqSize bytes from the stream. - // - // If not initialized or if we already read more data than _minSeqSize, - // we reset _startSeq and _minSeqSize for this sequence (possibly a - // top-level sequence or enclosed sequence it doesn't really matter). - // - // Otherwise, we are reading an enclosed sequence and we have to bump - // _minSeqSize by the minimum size that this sequence will require on - // the stream. - // - // The goal of this check is to ensure that when we start un-marshalling - // a new sequence, we check the minimal size of this new sequence against - // the estimated remaining buffer size. This estimatation is based on - // the minimum size of the enclosing sequences, it's _minSeqSize. - // - if(_startSeq == -1 || _buf.b.position() > (_startSeq + _minSeqSize)) - { - _startSeq = _buf.b.position(); - _minSeqSize = sz * minSize; - } - else - { - _minSeqSize += sz * minSize; + _readEncapsStack.decoder.readPendingObjects(); } + } - // - // If there isn't enough data to read on the stream for the sequence (and - // possibly enclosed sequences), something is wrong with the marshalled - // data: it's claiming having more data that what is possible to read. - // - if(_startSeq + _minSeqSize > _buf.size()) + public void writePendingObjects() + { + if(_writeEncapsStack != null && _writeEncapsStack.encoder != null) { - throw new Ice.UnmarshalOutOfBoundsException(); + _writeEncapsStack.encoder.writePendingObjects(); } - - return sz; } public void writeSize(int v) @@ -633,6 +636,15 @@ namespace IceInternal } } + public void writeSizeSeq(ICollection<int> v) + { + writeSize(v.Count); + foreach(int n in v) + { + writeSize(n); + } + } + public int readSize() { try @@ -653,7 +665,7 @@ namespace IceInternal } else { - return (int) (b < 0 ? b + 256 : b); + return b; // byte is unsigned } } catch(InvalidOperationException ex) @@ -662,53 +674,82 @@ namespace IceInternal } } - public void writeTypeId(string id) + public int[] readSizeSeq() { - if(_writeEncapsStack == null || _writeEncapsStack.typeIdMap == null) - { - throw new Ice.MarshalException("type ids require an encapsulation"); - } + int sz = readSize(); + int[] v = new int[sz]; - int index; - if(_writeEncapsStack.typeIdMap.TryGetValue(id, out index)) - { - writeBool(true); - writeSize(index); - } - else + if(sz > 0) { - index = ++_writeEncapsStack.typeIdIndex; - _writeEncapsStack.typeIdMap[id] = index; - writeBool(false); - writeString(id); + for(int n = 0; n < sz; ++n) + { + v[n] = readSize(); + } } + + return v; } - public string readTypeId() + public int readAndCheckSeqSize(int minSize) { - if(_readEncapsStack == null || _readEncapsStack.typeIdMap == null) + int sz = readSize(); + + if(sz == 0) { - throw new Ice.MarshalException("type ids require an encapsulation"); + return 0; } - string id; - int index; - bool isIndex = readBool(); - if(isIndex) + // + // The _startSeq variable points to the start of the sequence for which + // we expect to read at least _minSeqSize bytes from the stream. + // + // If not initialized or if we already read more data than _minSeqSize, + // we reset _startSeq and _minSeqSize for this sequence (possibly a + // top-level sequence or enclosed sequence it doesn't really matter). + // + // Otherwise, we are reading an enclosed sequence and we have to bump + // _minSeqSize by the minimum size that this sequence will require on + // the stream. + // + // The goal of this check is to ensure that when we start un-marshalling + // a new sequence, we check the minimal size of this new sequence against + // the estimated remaining buffer size. This estimatation is based on + // the minimum size of the enclosing sequences, it's _minSeqSize. + // + if(_startSeq == -1 || _buf.b.position() > (_startSeq + _minSeqSize)) { - index = readSize(); - if(!_readEncapsStack.typeIdMap.TryGetValue(index, out id)) - { - throw new Ice.UnmarshalOutOfBoundsException("Missing type ID"); - } + _startSeq = _buf.b.position(); + _minSeqSize = sz * minSize; } else { - id = readString(); - index = ++_readEncapsStack.typeIdIndex; - _readEncapsStack.typeIdMap[index] = id; + _minSeqSize += sz * minSize; } - return id; + + // + // If there isn't enough data to read on the stream for the sequence (and + // possibly enclosed sequences), something is wrong with the marshalled + // data: it's claiming having more data that what is possible to read. + // + if(_startSeq + _minSeqSize > _buf.size()) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } + + return sz; + } + + public void startSize() + { + _sizePos = _buf.b.position(); + writeInt(0); // Placeholder for 32-bit size + } + + public void endSize() + { + Debug.Assert(_sizePos >= 0); + rewriteInt(_buf.b.position() - _sizePos - 4, _sizePos); + _sizePos = -1; } public void writeBlob(byte[] v) @@ -751,19 +792,60 @@ namespace IceInternal } } + // Read/write type and tag for optionals + public bool writeOpt(int tag, Ice.OptionalType type) + { + Debug.Assert(_writeEncapsStack != null); + if(_writeEncapsStack.encoder != null) + { + return _writeEncapsStack.encoder.writeOpt(tag, type); + } + else + { + return writeOptImpl(tag, type); + } + } + + public bool readOpt(int tag, Ice.OptionalType expectedType) + { + Debug.Assert(_readEncapsStack != null); + if(_readEncapsStack.decoder != null) + { + return _readEncapsStack.decoder.readOpt(tag, expectedType); + } + else + { + return readOptImpl(tag, expectedType); + } + } + public void writeByte(byte v) { expand(1); _buf.b.put(v); } - public void writeByte(byte v, int end) + /* + public void writeByte(int tag, Ice.ByteOptional v) + { + if(v != null && v.isSet()) + { + writeByte(tag, v.get()); + } + } + */ + + public void writeByte(int tag, byte v) { - if(v < 0 || v >= end) + if(writeOpt(tag, Ice.OptionalType.F1)) { - throw new Ice.MarshalException("enumerator out of range"); + writeByte(v); } - writeByte(v); + } + + public void rewriteByte(byte v, int dest) + { + _buf.b.put(dest, v); } public void writeByteSeq(byte[] v) @@ -838,6 +920,24 @@ namespace IceInternal } } + /* + public void writeByteSeq(int tag, Ice.Optional<byte[]> v) + { + if(v != null && v.isSet()) + { + writeByteSeq(tag, v.get()); + } + } + */ + + public void writeByteSeq(int tag, byte[] v) + { + if(writeOpt(tag, Ice.OptionalType.VSize)) + { + writeByteSeq(v); + } + } + public void writeSerializable(object o) { #if !COMPACT && !SILVERLIGHT @@ -874,16 +974,20 @@ namespace IceInternal } } - public byte readByte(int end) + /* + public void readByte(int tag, Ice.ByteOptional v) { - byte v = readByte(); - if(v < 0 || v >= end) + if(readOpt(tag, Ice.OptionalType.F1)) { - throw new Ice.MarshalException("enumerator out of range"); + v.set(readByte()); + } + else + { + v.clear(); } - return v; } - + */ + public byte[] readByteSeq() { try @@ -943,6 +1047,20 @@ namespace IceInternal } } + /* + public void readByteSeq(int tag, Ice.Optional<byte[]> v) + { + if(readOpt(tag, Ice.OptionalType.VSize)) + { + v.set(readByteSeq()); + } + else + { + v.clear(); + } + } + */ + public object readSerializable() { #if !COMPACT && !SILVERLIGHT @@ -972,6 +1090,29 @@ namespace IceInternal _buf.b.put(v ? (byte)1 : (byte)0); } + /* + public void writeBool(int tag, Ice.BooleanOptional v) + { + if(v != null && v.isSet()) + { + writeBool(tag, v.get()); + } + } + */ + + public void writeBool(int tag, bool v) + { + if(writeOpt(tag, Ice.OptionalType.F1)) + { + writeBool(v); + } + } + + public void rewriteBool(bool v, int dest) + { + _buf.b.put(dest, v ? (byte)1 : (byte)0); + } + public void writeBoolSeq(bool[] v) { if(v == null) @@ -1044,6 +1185,24 @@ namespace IceInternal } } + /* + public void writeBoolSeq(int tag, Ice.Optional<bool[]> v) + { + if(v != null && v.isSet()) + { + writeBoolSeq(tag, v.get()); + } + } + */ + + public void writeBoolSeq(int tag, bool[] v) + { + if(writeOpt(tag, Ice.OptionalType.VSize)) + { + writeBoolSeq(v); + } + } + public bool readBool() { try @@ -1056,6 +1215,20 @@ namespace IceInternal } } + /* + public void readBool(int tag, Ice.BooleanOptional v) + { + if(readOpt(tag, Ice.OptionalType.F1)) + { + v.set(readBool()); + } + else + { + v.clear(); + } + } + */ + public bool[] readBoolSeq() { try @@ -1115,12 +1288,44 @@ namespace IceInternal } } + /* + public void readBoolSeq(int tag, Ice.Optional<bool[]> v) + { + if(readOpt(tag, Ice.OptionalType.VSize)) + { + v.set(readBoolSeq()); + } + else + { + v.clear(); + } + } + */ + public void writeShort(short v) { expand(2); _buf.b.putShort(v); } + /* + public void writeShort(int tag, Ice.ShortOptional v) + { + if(v != null && v.isSet()) + { + writeShort(tag, v.get()); + } + } + */ + + public void writeShort(int tag, short v) + { + if(writeOpt(tag, Ice.OptionalType.F2)) + { + writeShort(v); + } + } + public void writeShortSeq(short[] v) { if(v == null) @@ -1142,7 +1347,7 @@ namespace IceInternal writeSize(0); return; } - + { List<short> value = v as List<short>; if(value != null) @@ -1193,6 +1398,25 @@ namespace IceInternal } } + /* + public void writeShortSeq(int tag, Ice.Optional<short[]> v) + { + if(v != null && v.isSet()) + { + writeShortSeq(tag, v.get()); + } + } + */ + + public void writeShortSeq(int tag, short[] v) + { + if(writeOpt(tag, Ice.OptionalType.VSize)) + { + writeSize(v == null || v.Length == 0 ? 1 : v.Length * 2 + (v.Length > 254 ? 5 : 1)); + writeShortSeq(v); + } + } + public short readShort() { try @@ -1205,6 +1429,20 @@ namespace IceInternal } } + /* + public void readShort(int tag, Ice.ShortOptional v) + { + if(readOpt(tag, Ice.OptionalType.F2)) + { + v.set(readShort()); + } + else + { + v.clear(); + } + } + */ + public short[] readShortSeq() { try @@ -1264,12 +1502,50 @@ namespace IceInternal } } + /* + public void readShortSeq(int tag, Ice.Optional<short[]> v) + { + if(readOpt(tag, Ice.OptionalType.VSize)) + { + skipSize(); + v.set(readShortSeq()); + } + else + { + v.clear(); + } + } + */ + public void writeInt(int v) { expand(4); _buf.b.putInt(v); } + /* + public void writeInt(int tag, Ice.IntOptional v) + { + if(v != null && v.isSet()) + { + writeInt(tag, v.get()); + } + } + */ + + public void writeInt(int tag, int v) + { + if(writeOpt(tag, Ice.OptionalType.F4)) + { + writeInt(v); + } + } + + public void rewriteInt(int v, int dest) + { + _buf.b.putInt(dest, v); + } + public void writeIntSeq(int[] v) { if(v == null) @@ -1324,7 +1600,7 @@ namespace IceInternal return; } } - + { Stack<int> value = v as Stack<int>; if(value != null) @@ -1342,6 +1618,25 @@ namespace IceInternal } } + /* + public void writeIntSeq(int tag, Ice.Optional<int[]> v) + { + if(v != null && v.isSet()) + { + writeIntSeq(tag, v.get()); + } + } + */ + + public void writeIntSeq(int tag, int[] v) + { + if(writeOpt(tag, Ice.OptionalType.VSize)) + { + writeSize(v == null || v.Length == 0 ? 1 : v.Length * 4 + (v.Length > 254 ? 5 : 1)); + writeIntSeq(v); + } + } + public int readInt() { try @@ -1354,6 +1649,20 @@ namespace IceInternal } } + /* + public void readInt(int tag, Ice.IntOptional v) + { + if(readOpt(tag, Ice.OptionalType.F4)) + { + v.set(readInt()); + } + else + { + v.clear(); + } + } + */ + public int[] readIntSeq() { try @@ -1433,12 +1742,45 @@ namespace IceInternal } } + /* + public void readIntSeq(int tag, Ice.Optional<int[]> v) + { + if(readOpt(tag, Ice.OptionalType.VSize)) + { + skipSize(); + v.set(readIntSeq()); + } + else + { + v.clear(); + } + } + */ + public void writeLong(long v) { expand(8); _buf.b.putLong(v); } + /* + public void writeLong(int tag, Ice.LongOptional v) + { + if(v != null && v.isSet()) + { + writeLong(tag, v.get()); + } + } + */ + + public void writeLong(int tag, long v) + { + if(writeOpt(tag, Ice.OptionalType.F8)) + { + writeLong(v); + } + } + public void writeLongSeq(long[] v) { if(v == null) @@ -1511,6 +1853,25 @@ namespace IceInternal } } + /* + public void writeLongSeq(int tag, Ice.Optional<long[]> v) + { + if(v != null && v.isSet()) + { + writeLongSeq(tag, v.get()); + } + } + */ + + public void writeLongSeq(int tag, long[] v) + { + if(writeOpt(tag, Ice.OptionalType.VSize)) + { + writeSize(v == null || v.Length == 0 ? 1 : v.Length * 8 + (v.Length > 254 ? 5 : 1)); + writeLongSeq(v); + } + } + public long readLong() { try @@ -1523,6 +1884,20 @@ namespace IceInternal } } + /* + public void readLong(int tag, Ice.LongOptional v) + { + if(readOpt(tag, Ice.OptionalType.F8)) + { + v.set(readLong()); + } + else + { + v.clear(); + } + } + */ + public long[] readLongSeq() { try @@ -1602,12 +1977,45 @@ namespace IceInternal } } + /* + public void readLongSeq(int tag, Ice.Optional<long[]> v) + { + if(readOpt(tag, Ice.OptionalType.VSize)) + { + skipSize(); + v.set(readLongSeq()); + } + else + { + v.clear(); + } + } + */ + public void writeFloat(float v) { expand(4); _buf.b.putFloat(v); } + /* + public void writeFloat(int tag, Ice.FloatOptional v) + { + if(v != null && v.isSet()) + { + writeFloat(tag, v.get()); + } + } + */ + + public void writeFloat(int tag, float v) + { + if(writeOpt(tag, Ice.OptionalType.F4)) + { + writeFloat(v); + } + } + public void writeFloatSeq(float[] v) { if(v == null) @@ -1662,7 +2070,7 @@ namespace IceInternal return; } } - + { Stack<float> value = v as Stack<float>; if(value != null) @@ -1680,6 +2088,25 @@ namespace IceInternal } } + /* + public void writeFloatSeq(int tag, Ice.Optional<float[]> v) + { + if(v != null && v.isSet()) + { + writeFloatSeq(tag, v.get()); + } + } + */ + + public void writeFloatSeq(int tag, float[] v) + { + if(writeOpt(tag, Ice.OptionalType.VSize)) + { + writeSize(v == null || v.Length == 0 ? 1 : v.Length * 4 + (v.Length > 254 ? 5 : 1)); + writeFloatSeq(v); + } + } + public float readFloat() { try @@ -1692,6 +2119,20 @@ namespace IceInternal } } + /* + public void readFloat(int tag, Ice.FloatOptional v) + { + if(readOpt(tag, Ice.OptionalType.F4)) + { + v.set(readFloat()); + } + else + { + v.clear(); + } + } + */ + public float[] readFloatSeq() { try @@ -1771,12 +2212,45 @@ namespace IceInternal } } + /* + public void readFloatSeq(int tag, Ice.Optional<float[]> v) + { + if(readOpt(tag, Ice.OptionalType.VSize)) + { + skipSize(); + v.set(readFloatSeq()); + } + else + { + v.clear(); + } + } + */ + public void writeDouble(double v) { expand(8); _buf.b.putDouble(v); } + /* + public void writeDouble(int tag, Ice.DoubleOptional v) + { + if(v != null && v.isSet()) + { + writeDouble(tag, v.get()); + } + } + */ + + public void writeDouble(int tag, double v) + { + if(writeOpt(tag, Ice.OptionalType.F8)) + { + writeDouble(v); + } + } + public void writeDoubleSeq(double[] v) { if(v == null) @@ -1831,7 +2305,7 @@ namespace IceInternal return; } } - + { Stack<double> value = v as Stack<double>; if (value != null) @@ -1849,6 +2323,25 @@ namespace IceInternal } } + /* + public void writeDoubleSeq(int tag, Ice.Optional<double[]> v) + { + if(v != null && v.isSet()) + { + writeDoubleSeq(tag, v.get()); + } + } + */ + + public void writeDoubleSeq(int tag, double[] v) + { + if(writeOpt(tag, Ice.OptionalType.VSize)) + { + writeSize(v == null || v.Length == 0 ? 1 : v.Length * 8 + (v.Length > 254 ? 5 : 1)); + writeDoubleSeq(v); + } + } + public double readDouble() { try @@ -1861,6 +2354,20 @@ namespace IceInternal } } + /* + public void readDouble(int tag, Ice.DoubleOptional v) + { + if(readOpt(tag, Ice.OptionalType.F8)) + { + v.set(readDouble()); + } + else + { + v.clear(); + } + } + */ + public double[] readDoubleSeq() { try @@ -1940,6 +2447,21 @@ namespace IceInternal } } + /* + public void readDoubleSeq(int tag, Ice.Optional<double[]> v) + { + if(readOpt(tag, Ice.OptionalType.VSize)) + { + skipSize(); + v.set(readDoubleSeq()); + } + else + { + v.clear(); + } + } + */ + private static System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(false, true); public void writeString(string v) @@ -1955,6 +2477,24 @@ namespace IceInternal _buf.b.put(arr); } + /* + public void writeString(int tag, Ice.Optional<string> v) + { + if(v != null && v.isSet()) + { + writeString(tag, v.get()); + } + } + */ + + public void writeString(int tag, string v) + { + if(writeOpt(tag, Ice.OptionalType.VSize)) + { + writeString(v); + } + } + public void writeStringSeq(string[] v) { if(v == null) @@ -1983,6 +2523,26 @@ namespace IceInternal } } + /* + public void writeStringSeq(int tag, Ice.Optional<String[]> v) + { + if(v != null && v.isSet()) + { + writeStringSeq(tag, v.get()); + } + } + */ + + public void writeStringSeq(int tag, string[] v) + { + if(writeOpt(tag, Ice.OptionalType.FSize)) + { + startSize(); + writeStringSeq(v); + endSize(); + } + } + public string readString() { int len = readSize(); @@ -2012,7 +2572,7 @@ namespace IceInternal } _buf.b.get(_stringBytes, 0, len); return utf8.GetString(_stringBytes, 0, len); - } + } catch(InvalidOperationException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); @@ -2023,6 +2583,20 @@ namespace IceInternal } } + /* + public void readString(int tag, Ice.Optional<string> v) + { + if(readOpt(tag, Ice.OptionalType.VSize)) + { + v.set(readString()); + } + else + { + v.clear(); + } + } + */ + public string[] readStringSeq() { int sz = readAndCheckSeqSize(1); @@ -2093,498 +2667,354 @@ namespace IceInternal } } - public void writeProxy(Ice.ObjectPrx v) + /* + public void readStringSeq(int tag, Ice.Optional<string[]> v) { - instance_.proxyFactory().proxyToStream(v, this); + if(readOpt(tag, Ice.OptionalType.FSize)) + { + skip(4); + v.set(readStringSeq()); + } + else + { + v.clear(); + } } + */ - public Ice.ObjectPrx readProxy() + public void writeProxy(Ice.ObjectPrx v) { - return instance_.proxyFactory().streamToProxy(this); + instance_.proxyFactory().proxyToStream(v, this); } - public void writeObject(Ice.Object v) + /* + public void writeProxy(int tag, Ice.Optional<Ice.ObjectPrx> v) { - if(_writeEncapsStack == null) // Lazy initialization + if(v != null && v.isSet()) { - _writeEncapsStack = _writeEncapsCache; - if(_writeEncapsStack != null) - { - _writeEncapsCache = _writeEncapsCache.next; - } - else - { - _writeEncapsStack = new WriteEncaps(); - } + writeProxy(tag, v.get()); } + } + */ - if(_writeEncapsStack.toBeMarshaledMap == null) // Lazy initialization + public void writeProxy(int tag, Ice.ObjectPrx v) + { + if(writeOpt(tag, Ice.OptionalType.FSize)) { - _writeEncapsStack.toBeMarshaledMap = new Dictionary<Ice.Object, int>(); - _writeEncapsStack.marshaledMap = new Dictionary<Ice.Object, int>(); - _writeEncapsStack.typeIdMap = new Dictionary<string, int>(); + startSize(); + writeProxy(v); + endSize(); } - if(v != null) + } + + public Ice.ObjectPrx readProxy() + { + return instance_.proxyFactory().streamToProxy(this); + } + + /* + public void readProxy(int tag, Ice.Optional<Ice.ObjectPrx> v) + { + if(readOpt(tag, Ice.OptionalType.FSize)) { - // - // Look for this instance in the to-be-marshaled map. - // - int p; - if(!_writeEncapsStack.toBeMarshaledMap.TryGetValue(v, out p)) - { - // - // Didn't find it, try the marshaled map next. - // - if(!_writeEncapsStack.marshaledMap.TryGetValue(v, out p)) - { - // - // We haven't seen this instance previously, - // create a new index, and insert it into the - // to-be-marshaled map. - // - p = ++_writeEncapsStack.writeIndex; - _writeEncapsStack.toBeMarshaledMap[v] = p; - } - } - writeInt(-p); + skip(4); + v.set(readProxy()); } else { - writeInt(0); // Write null reference + v.clear(); } } + */ - public void readObject(IPatcher patcher) + public void writeEnum(int v, int limit) { - Ice.Object v = null; - - if(_readEncapsStack == null) // Lazy initialization + if(isWriteEncoding_1_0()) { - _readEncapsStack = _readEncapsCache; - if(_readEncapsStack != null) + if(limit <= 127) { - _readEncapsCache = _readEncapsCache.next; + writeByte((byte)v); + } + else if(limit <= 32767) + { + writeShort((short)v); } else { - _readEncapsStack = new ReadEncaps(); + writeInt(v); } } - - if(_readEncapsStack.patchMap == null) // Lazy initialization + else { - _readEncapsStack.patchMap = new Dictionary<int, List<IceInternal.IPatcher> >(); - _readEncapsStack.unmarshaledMap = new Dictionary<int, Ice.Object>(); - _readEncapsStack.typeIdMap = new Dictionary<int, string>(); + writeSize(v); } + } - int index = readInt(); - - if(patcher != null) + public int readEnum(int limit) + { + if(getReadEncoding().Equals(Ice.Util.Encoding_1_0)) { - if(index == 0) + if(limit <= 127) { - patcher.patch(null); - return; + return readByte(); } - - if(index < 0) + else if(limit <= 32767) { - int i = -index; - List<IceInternal.IPatcher> patchlist; - if(!_readEncapsStack.patchMap.TryGetValue(i, out patchlist)) - { - // - // We have no outstanding instances to be patched - // for this index, so make a new entry in the - // patch map. - // - patchlist = new List<IceInternal.IPatcher>(); - _readEncapsStack.patchMap[i] = patchlist; - } - // - // Append a patcher for this instance and see if we - // can patch the instance. (The instance may have been - // unmarshaled previously.) - // - patchlist.Add(patcher); - patchReferences(null, i); - return; + return readShort(); + } + else + { + return readInt(); } } - if(index < 0) + else { - throw new Ice.MarshalException("Invalid class instance index"); + return readSize(); } + } - string mostDerivedId = readTypeId(); - string id = mostDerivedId; + public void writeObject(Ice.Object v) + { + initWriteEncaps(); + _writeEncapsStack.encoder.writeObject(v); + } - while(true) + /* + public <T extends Ice.Object> void writeObject(int tag, Ice.Optional<T> v) + { + if(v != null && v.isSet()) { - // - // If we slice all the way down to Ice::Object, we throw - // because Ice::Object is abstract. - // - if(id == Ice.ObjectImpl.ice_staticId()) - { - Ice.NoObjectFactoryException ex - = new Ice.NoObjectFactoryException(); - ex.type = mostDerivedId; - throw ex; - } - - // - // Try to find a factory registered for the specific - // type. - // - Ice.ObjectFactory userFactory = instance_.servantFactoryManager().find(id); - if(userFactory != null) - { - v = userFactory.create(id); - } - - // - // If that fails, invoke the default factory if one - // has been registered. - // - if(v == null) - { - userFactory = instance_.servantFactoryManager().find(""); - if(userFactory != null) - { - v = userFactory.create(id); - } - } - - // - // Last chance: check whether the class is - // non-abstract and dynamically instantiate it using - // reflection. - // - if(v == null) - { - userFactory = loadObjectFactory(id); - if(userFactory != null) - { - v = userFactory.create(id); - } - } - - if(v == null) - { - if(_sliceObjects) - { - // - // Performance sensitive, so we use lazy - // initialization for tracing. - // - if(_traceSlicing == -1) - { - _traceSlicing = instance_.traceLevels().slicing; - _slicingCat = instance_.traceLevels().slicingCat; - } - if(_traceSlicing > 0) - { - TraceUtil.traceSlicing("class", id, _slicingCat, instance_.initializationData().logger); - } - skipSlice(); // Slice off this derived part -- we don't understand it. - id = readTypeId(); // Read next id for next iteration. - continue; - } - else - { - Ice.NoObjectFactoryException ex = new Ice.NoObjectFactoryException(); - ex.type = id; - throw ex; - } - } + writeObject(tag, v.get()); + } + } + */ - int i = index; - _readEncapsStack.unmarshaledMap[i] = v; + public void writeObject(int tag, Ice.Object v) + { + if(writeOpt(tag, Ice.OptionalType.Size)) + { + writeObject(v); + } + } - // - // Record each object instance so that - // readPendingObjects can invoke ice_postUnmarshal - // after all objects have been unmarshaled. - // - if(_objectList == null) - { - _objectList = new List<Ice.Object>(); - } - _objectList.Add(v); + public void readObject(IPatcher patcher) + { + Debug.Assert(patcher != null); + initReadEncaps(); + _readEncapsStack.decoder.readObject(patcher); + } - v.read__(this, false); - patchReferences(i, null); - return; + /* + public void readObject(int tag, Ice.Optional<Ice.Object> v) + { + if(readOpt(tag, Ice.OptionalType.Size)) + { + Ice.OptionalObject opt = new Ice.OptionalObject(v, Ice.Object.class, Ice.ObjectImpl.ice_staticId()); + readObject(opt); + } + else + { + v.clear(); } } + */ public void writeUserException(Ice.UserException v) { - writeBool(v.usesClasses__()); - v.write__(this); - if(v.usesClasses__()) - { - writePendingObjects(); - } + initWriteEncaps(); + _writeEncapsStack.encoder.writeUserException(v); } - public void throwException() + public void throwException(UserExceptionFactory factory) { - bool usesClasses = readBool(); + initReadEncaps(); + _readEncapsStack.decoder.throwException(factory); + } - string id = readString(); - string origId = id; + public void + sliceObjects(bool b) + { + _sliceObjects = b; + } - for(;;) + public bool readOptImpl(int readTag, Ice.OptionalType expectedType) + { + if(isReadEncoding_1_0()) { - // - // Look for a factory for this ID. - // - UserExceptionFactory factory = getUserExceptionFactory(id); + return false; // Optional members aren't supported with the 1.0 encoding. + } - if(factory != null) + int tag = 0; + Ice.OptionalType type; + do + { + if(_buf.b.position() >= _readEncapsStack.start + _readEncapsStack.sz) { - // - // Got factory -- get the factory to instantiate - // the exception, initialize the exception - // members, and throw the exception. - // - try - { - factory.createAndThrow(); - } - catch(Ice.UserException ex) - { - ex.read__(this, false); - if(usesClasses) - { - readPendingObjects(); - } - throw; - } + return false; // End of encapsulation also indicates end of optionals. } - else + + int v = readByte(); + type = (Ice.OptionalType)(v & 0x07); // First 3 bits. + tag = v >> 3; + if(tag == 31) { - // - // Performance sensitive, so we use lazy - // initialization for tracing. - // - if(_traceSlicing == -1) - { - _traceSlicing = instance_.traceLevels().slicing; - _slicingCat = instance_.traceLevels().slicingCat; - } - if(_traceSlicing > 0) - { - TraceUtil.traceSlicing("exception", id, _slicingCat, instance_.initializationData().logger); - } + tag = readSize(); + } + } + while(type != Ice.OptionalType.EndMarker && tag < readTag && skipOpt(type)); // Skip optional data members - skipSlice(); // Slice off what we don't understand. + if(type == Ice.OptionalType.EndMarker || tag > readTag) + { + // + // Rewind the stream to correctly read the next optional data + // member tag & type next time. + // + int offset = tag < 31 ? 1 : (tag < 255 ? 2 : 6); + _buf.b.position(_buf.b.position() - offset); + return false; // No optional data members with the requested tag. + } - try - { - id = readString(); // Read type id for next slice. - } - catch(Ice.UnmarshalOutOfBoundsException ex) - { - // - // When readString raises this exception it means we've seen the last slice, - // so we set the reason member to a more helpful message. - // - ex.reason = "unknown exception type `" + origId + "'"; - throw; - } - } + Debug.Assert(readTag == tag); + if(type != expectedType) + { + string msg = "invalid optional data member `" + tag + "': unexpected type"; + throw new Ice.MarshalException(msg); } // - // The only way out of the loop above is to find an - // exception for which the receiver has a factory. If this - // does not happen, sender and receiver disagree about the - // Slice definitions they use. In that case, the receiver - // will eventually fail to read another type ID and throw - // a MarshalException. + // We have an optional data member with the requested tag and + // type. // + return true; } - public void writePendingObjects() + public bool writeOptImpl(int tag, Ice.OptionalType type) { - if(_writeEncapsStack != null && _writeEncapsStack.toBeMarshaledMap != null) + if(isWriteEncoding_1_0()) { - while(_writeEncapsStack.toBeMarshaledMap.Count > 0) - { - Dictionary<Ice.Object, int> savedMap = - new Dictionary<Ice.Object, int>(_writeEncapsStack.toBeMarshaledMap); - writeSize(savedMap.Count); - foreach(KeyValuePair<Ice.Object, int> e in savedMap) - { - // - // Add an instance from the old - // to-be-marshaled map to the marshaled map - // and then ask the instance to marshal - // itself. Any new class instances that are - // triggered by the classes marshaled are - // added to toBeMarshaledMap. - // - _writeEncapsStack.marshaledMap[e.Key] = e.Value; - writeInstance((Ice.Object)e.Key, (int)e.Value); - } + return false; // Optional members aren't supported with the 1.0 encoding. + } - // - // We have marshaled all the instances for this - // pass, substract what we have marshaled from the - // toBeMarshaledMap. - // - foreach(KeyValuePair<Ice.Object, int> e in savedMap) - { - _writeEncapsStack.toBeMarshaledMap.Remove(e.Key); - } - } + int v = (int)type; + if(tag < 31) + { + v |= tag << 3; + writeByte((byte)v); } - writeSize(0); // Zero marker indicates end of sequence of sequences of instances. + else + { + v |= 0x0F8; // tag = 31 + writeByte((byte)v); + writeSize(tag); + } + return true; } - public void readPendingObjects() + public bool skipOpt(Ice.OptionalType type) { - int num; - do + int sz; + switch(type) { - num = readSize(); - for(int k = num; k > 0; --k) - { - readObject(null); - } + case Ice.OptionalType.F1: + { + sz = 1; + break; } - while(num > 0); - - if(_readEncapsStack != null && _readEncapsStack.patchMap != null && _readEncapsStack.patchMap.Count != 0) + case Ice.OptionalType.F2: { - // - // If any entries remain in the patch map, the sender has sent an index for an object, but failed - // to supply the object. - // - throw new Ice.MarshalException("Index for class received, but no instance"); + sz = 2; + break; } - - // - // Iterate over unmarshaledMap and invoke - // ice_postUnmarshal on each object. We must do this - // after all objects in this encapsulation have been - // unmarshaled in order to ensure that any object data - // members have been properly patched. - // - if(_objectList != null) + case Ice.OptionalType.F4: { - foreach(Ice.Object obj in _objectList) - { - try - { - obj.ice_postUnmarshal(); - } - catch(System.Exception ex) - { - instance_.initializationData().logger.warning("exception raised by ice_postUnmarshal::\n" + - ex); - } - } + sz = 4; + break; } - } - - public void - sliceObjects(bool b) - { - _sliceObjects = b; - } - - internal void writeInstance(Ice.Object v, int index) - { - writeInt(index); - try + case Ice.OptionalType.F8: { - v.ice_preMarshal(); + sz = 8; + break; } - catch(System.Exception ex) + case Ice.OptionalType.Size: + { + skipSize(); + return true; + } + case Ice.OptionalType.VSize: + { + sz = readSize(); + break; + } + case Ice.OptionalType.FSize: + { + sz = readInt(); + break; + } + default: { - instance_.initializationData().logger.warning("exception raised by ice_preMarshal::\n" + ex); + return false; + } } - v.write__(this); + skip(sz); + return true; } - internal void patchReferences(object instanceIndex, object patchIndex) + public bool skipOpts() { // - // Called whenever we have unmarshaled a new instance or - // an index. The instanceIndex is the index of the - // instance just unmarshaled and patchIndex is the index - // just unmarshaled. (Exactly one of the two parameters - // must be null.) Patch any pointers in the patch map with - // the new address. + // Skip remaining un-read optional members. // - Debug.Assert(((object)instanceIndex != null && (object)patchIndex == null) || - ((object)instanceIndex == null && (object)patchIndex != null)); - - List<IceInternal.IPatcher> patchlist; - Ice.Object v; - if((object)instanceIndex != null) + Ice.OptionalType type; + do { - // - // We have just unmarshaled an instance -- check if - // something needs patching for that instance. - // - if(!_readEncapsStack.patchMap.TryGetValue((int)instanceIndex, out patchlist)) + if(_buf.b.position() >= _readEncapsStack.start + _readEncapsStack.sz) { - return; // We don't have anything to patch for the instance just unmarshaled. + return false; // End of encapsulation also indicates end of optionals. } - v = _readEncapsStack.unmarshaledMap[(int)instanceIndex]; - patchIndex = instanceIndex; - } - else - { - // - // We have just unmarshaled an index -- check if we - // have unmarshaled the instance for that index yet. - // - if(!_readEncapsStack.unmarshaledMap.TryGetValue((int)patchIndex, out v)) + + int v = readByte(); + type = (Ice.OptionalType)(v & 0x07); // Read first 3 bits. + if((v >> 3) == 31) { - return; // We haven't unmarshaled the instance for this index yet. + skipSize(); } - patchlist = _readEncapsStack.patchMap[(int)patchIndex]; } - Debug.Assert(patchlist != null && patchlist.Count > 0); - Debug.Assert(v != null); + while(skipOpt(type)); + Debug.Assert(type == Ice.OptionalType.EndMarker); + return true; + } - // - // Patch all references that refer to the instance. - // - foreach(IPatcher patcher in patchlist) + public void skip(int size) + { + if(size > _buf.b.remaining()) { - try - { - patcher.patch(v); - } - catch(InvalidCastException ex) - { - // - // TODO: Fix this (also for C++ and Java): - // NoObjectFactoryException is misleading because - // the type sent by the sender is incompatible - // with what is expected. This really should be a - // MarshalException. - // - Ice.NoObjectFactoryException nof = new Ice.NoObjectFactoryException(ex); - nof.type = patcher.type(); - throw nof; - } + throw new Ice.UnmarshalOutOfBoundsException(); } + _buf.b.position(_buf.b.position() + size); + } - // - // Clear out the patch map for that index -- there is - // nothing left to patch for that index for the time - // being. - // - _readEncapsStack.patchMap.Remove((int)patchIndex); + public void skipSize() + { + byte b = readByte(); + if(b == 255) + { + skip(4); + } + } + + public int pos() + { + return _buf.b.position(); + } + + public void pos(int n) + { + _buf.b.position(n); + } + + public int size() + { + return _buf.size(); } #if !MANAGED && !COMPACT && !SILVERLIGHT @@ -2674,7 +3104,7 @@ namespace IceInternal int compressedLen = (int)(uncompressedLen * 1.01 + 600); byte[] compressed = new byte[compressedLen]; - int rc = NativeMethods.BZ2_bzBuffToBuffCompress(compressed, ref compressedLen, uncompressed, + int rc = NativeMethods.BZ2_bzBuffToBuffCompress(compressed, ref compressedLen, uncompressed, uncompressedLen, compressionLevel, 0, 0); if(rc == BZ_OUTBUFF_FULL) { @@ -2743,7 +3173,7 @@ namespace IceInternal byte[] compressed = _buf.b.rawBytes(headerSize + 4, compressedLen); int uncompressedLen = uncompressedSize - headerSize; byte[] uncompressed = new byte[uncompressedLen]; - int rc = NativeMethods.BZ2_bzBuffToBuffDecompress(uncompressed, ref uncompressedLen, compressed, + int rc = NativeMethods.BZ2_bzBuffToBuffDecompress(uncompressed, ref uncompressedLen, compressed, compressedLen, 0, 0); if(rc < 0) { @@ -2760,21 +3190,6 @@ namespace IceInternal #endif } - internal int pos() - { - return _buf.b.position(); - } - - internal void pos(int n) - { - _buf.b.position(n); - } - - public int size() - { - return _buf.size(); - } - public bool isEmpty() { return _buf.empty(); @@ -2783,7 +3198,7 @@ namespace IceInternal public void expand(int n) { if(!_unlimited && _buf.b != null && _buf.b.position() + n > _messageSizeMax) - { + { Ex.throwMemoryLimitException(_buf.b.position() + n, _messageSizeMax); } _buf.expand(n); @@ -2831,6 +3246,13 @@ namespace IceInternal // if(!c.IsAbstract && !c.IsInterface) { + factory = new DynamicObjectFactory(c); + /* + * TODO: See ICE-3635 regarding caching of factories. + * Perhaps we should store these dynamic factories in a + * per-communicator map and check this map prior to + * calling findClass above. + * Ice.ObjectFactory dynamicFactory = new DynamicObjectFactory(c); // // We will try to install the dynamic factory, but @@ -2857,6 +3279,7 @@ namespace IceInternal factory = instance_.servantFactoryManager().find(id); } } + */ } } catch(Exception ex) @@ -2876,7 +3299,7 @@ namespace IceInternal _class = c; } - public void createAndThrow() + public void createAndThrow(string typeId) { try { @@ -2939,62 +3362,1386 @@ namespace IceInternal return id.Substring(2).Replace("::", "."); } + // + // Optional data member type. + // + internal const int MemberTypeF1 = 0; + internal const int MemberTypeF2 = 1; + internal const int MemberTypeF4 = 2; + internal const int MemberTypeF8 = 3; + internal const int MemberTypeVSize = 4; + internal const int MemberTypeFSize = 5; + internal const int MemberTypeReserved = 6; + internal const int MemberTypeEndMarker = 7; + private Instance instance_; - private Ice.EncodingVersion _encoding; private Buffer _buf; private object _closure; private byte[] _stringBytes; // Reusable array for reading strings. - private sealed class ReadEncaps + private enum SliceType { NoSlice, ObjectSlice, ExceptionSlice } + + private sealed class EncapsDecoder { - internal int start; - internal int sz; + internal EncapsDecoder(BasicStream stream, ReadEncaps encaps, bool sliceObjects) + { + _stream = stream; + _encaps = encaps; + _sliceObjects = sliceObjects; + _traceSlicing = -1; + _sliceType = SliceType.NoSlice; + _usesClasses = false; + _typeIdIndex = 0; + _slices = new List<Ice.SliceInfo>(); + _indirectionTables = new List<int[]>(); + _indirectPatchList = new List<IndirectPatchEntry>(); + _patchMap = new Dictionary<int, LinkedList<IPatcher>>(); + _unmarshaledMap = new Dictionary<int, Ice.Object>(); + _typeIdMap = new Dictionary<int, string>(); + } - // internal byte encodingMajor; // Currently unused - // internal byte encodingMinor; // Currently unused + internal void readObject(IPatcher patcher) + { + int index = 0; + if(_encaps.encoding_1_0) + { + // + // Object references are encoded as a negative integer in 1.0. + // + index = _stream.readInt(); + _usesClasses = true; + if(index > 0) + { + throw new Ice.MarshalException("invalid object id"); + } + index = -index; + } + else + { + // + // Later versions use a size. + // + index = _stream.readSize(); + if(index < 0) + { + throw new Ice.MarshalException("invalid object id"); + } + } - internal Dictionary<int, List<IceInternal.IPatcher> > patchMap; - internal Dictionary<int, Ice.Object> unmarshaledMap; - internal int typeIdIndex; - internal Dictionary<int, string> typeIdMap; - internal Ice.EncodingVersion encoding = new Ice.EncodingVersion(); - internal ReadEncaps next; + if(index == 0) + { + patcher.patch(null); + } + else if(_sliceType != SliceType.NoSlice && (_sliceFlags & FLAG_HAS_INDIRECTION_TABLE) != 0) + { + // + // Maintain a list of indirect references. Note that the indirect index + // starts at 1, so we decrement it by one to derive an index into + // the indirection table that we'll read at the end of the slice. + // + IndirectPatchEntry e = new IndirectPatchEntry(); + e.index = index - 1; + e.patcher = patcher; + _indirectPatchList.Add(e); + } + else + { + addPatchEntry(index, patcher); + } + } - internal void reset() + internal void throwException(UserExceptionFactory factory) { - if(patchMap != null) + Debug.Assert(_sliceType == SliceType.NoSlice); + + if(_encaps.encoding_1_0) { - patchMap.Clear(); - unmarshaledMap.Clear(); - typeIdIndex = 0; - typeIdMap.Clear(); + // + // User exception with the 1.0 encoding start with a bool + // flag that indicates whether or not the exception has + // classes. This allows reading the pending objects even if + // some the exception was sliced. With encoding > 1.0, we + // don't need this, each slice indirect patch table indicates + // the presence of objects. + // + bool usesClasses = _stream.readBool(); + _usesClasses |= usesClasses; } + + _sliceType = SliceType.ExceptionSlice; + _skipFirstSlice = false; + + // + // Read the first slice header. + // + startSlice(); + string mostDerivedId = _typeId; + UserExceptionFactory exceptionFactory = factory; + while(true) + { + // + // Look for a factory for this ID. + // + if(exceptionFactory == null) + { + exceptionFactory = _stream.getUserExceptionFactory(_typeId); + } + + // + // We found a factory, we get out of this loop. + // + if(exceptionFactory != null) + { + // + // Got factory -- ask the factory to instantiate the + // exception, initialize the exception members, and throw + // the exception. + // + try + { + exceptionFactory.createAndThrow(_typeId); + } + catch(Ice.UserException ex) + { + ex.read__(_stream); + readPendingObjects(); + throw ex; + + // Never reached. + } + } + + // + // Performance sensitive, so we use lazy initialization for + // tracing. + // + if(_traceSlicing == -1) + { + _traceSlicing = _stream.instance().traceLevels().slicing; + _slicingCat = _stream.instance().traceLevels().slicingCat; + } + if(_traceSlicing > 0) + { + TraceUtil.traceSlicing("exception", _typeId, _slicingCat, + _stream.instance().initializationData().logger); + } + + // + // Slice off what we don't understand. + // + skipSlice(); + + if((_sliceFlags & FLAG_IS_LAST_SLICE) != 0) + { + if(mostDerivedId.Length > 2 && mostDerivedId[0] == ':' && mostDerivedId[1] == ':') + { + throw new Ice.UnknownUserException(mostDerivedId.Substring(2)); + } + else + { + throw new Ice.UnknownUserException(mostDerivedId); + } + } + + try + { + startSlice(); + } + catch(Ice.UnmarshalOutOfBoundsException ex) + { + // + // An oversight in the 1.0 encoding means there is no marker to indicate + // the last slice of an exception. As a result, we just try to read the + // next type ID, which raises UnmarshalOutOfBoundsException when the + // input buffer underflows. + // + if(_encaps.encoding_1_0) + { + // Set the reason member to a more helpful message. + ex.reason = "unknown exception type `" + mostDerivedId + "'"; + } + throw ex; + } + } + } + + internal void startObject() + { + Debug.Assert(_sliceType == SliceType.ObjectSlice); + _skipFirstSlice = true; + } + + internal Ice.SlicedData endObject(bool preserve) + { + if(_encaps.encoding_1_0) + { + // + // Read the Ice::Object slice. + // + startSlice(); + + // + // For compatibility with the old AFM. + // + int sz = _stream.readSize(); + if(sz != 0) + { + throw new Ice.MarshalException("invalid Object slice"); + } + + endSlice(); + } + + _sliceType = SliceType.NoSlice; + Ice.SlicedData slicedData = null; + if(preserve) + { + slicedData = readSlicedData(); + } + _slices.Clear(); + _indirectionTables.Clear(); + return slicedData; } + + internal void startException() + { + Debug.Assert(_sliceType == SliceType.ExceptionSlice); + _skipFirstSlice = true; + } + + internal Ice.SlicedData endException(bool preserve) + { + _sliceType = SliceType.NoSlice; + Ice.SlicedData slicedData = null; + if(preserve) + { + slicedData = readSlicedData(); + } + _slices.Clear(); + _indirectionTables.Clear(); + return slicedData; + } + + internal string startSlice() + { + // + // If first slice, don't read the header, it was already read in + // readInstance or throwException to find the factory. + // + if(_skipFirstSlice) + { + _skipFirstSlice = false; + return _typeId; + } + + // + // Read the slice flags. For the 1.0 encoding there's no flag but + // just a bool for object slices. The bool indicates whether + // or not the type ID is encoded as a string or as an index. + // + if(_encaps.encoding_1_0) + { + _sliceFlags = FLAG_HAS_SLICE_SIZE; + if(_sliceType == SliceType.ObjectSlice) // For exceptions, the type ID is always encoded as a string + { + bool isIndex = _stream.readBool(); + _sliceFlags |= isIndex ? FLAG_HAS_TYPE_ID_INDEX : FLAG_HAS_TYPE_ID_STRING; + } + } + else + { + _sliceFlags = _stream.readByte(); + } + + // + // Read the type ID, for object slices the type ID is encoded as a + // string or as an index, for exceptions it's always encoded as a + // string. + // + if(_sliceType == SliceType.ObjectSlice) + { + if((_sliceFlags & FLAG_HAS_TYPE_ID_INDEX) != 0) + { + int index = _stream.readSize(); + if(!_typeIdMap.TryGetValue(index, out _typeId)) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } + } + else if((_sliceFlags & FLAG_HAS_TYPE_ID_STRING) != 0) + { + _typeId = _stream.readString(); + _typeIdMap.Add(++_typeIdIndex, _typeId); + } + else + { + // Only the most derived slice encodes the type ID for the + // compact format. + _typeId = ""; + } + } + else + { + _typeId = _stream.readString(); + } + + // + // Read the slice size if necessary. + // + if((_sliceFlags & FLAG_HAS_SLICE_SIZE) != 0) + { + _sliceSize = _stream.readInt(); + if(_sliceSize < 4) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } + } + else + { + _sliceSize = 0; + } + + // + // Reset the indirect patch list for this new slice. + // + _indirectPatchList.Clear(); + return _typeId; + } + + internal void endSlice() + { + if((_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) != 0) + { + _stream.skipOpts(); + } + + // + // Read the indirection table if one is present and transform the + // indirect patch list into patch entries with direct references. + // + if((_sliceFlags & FLAG_HAS_INDIRECTION_TABLE) != 0) + { + // + // The table is written as a sequence<size> to conserve space. + // + int[] indirectionTable = _stream.readSizeSeq(); + + // + // Sanity checks. If there are optional members, it's possible + // that not all object references were read if they are from + // unknown optional data members. + // + if(indirectionTable.Length == 0 && _indirectPatchList.Count > 0) + { + throw new Ice.MarshalException("empty indirection table"); + } + else if(indirectionTable.Length > 0 && _indirectPatchList.Count == 0 && + (_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) == 0) + { + throw new Ice.MarshalException("no references to indirection table"); + } + + // + // Convert indirect references into direct references. + // + foreach(IndirectPatchEntry e in _indirectPatchList) + { + Debug.Assert(e.index >= 0); + if(e.index >= indirectionTable.Length) + { + throw new Ice.MarshalException("indirection out of range"); + } + int id = indirectionTable[e.index]; + if(id <= 0) + { + // + // Entries in the table must be positive, just like a regular object reference. + // + throw new Ice.MarshalException("invalid id in object indirection table"); + } + addPatchEntry(id, e.patcher); + } + } + } + + internal void skipSlice() + { + int start = _stream.pos(); + + if((_sliceFlags & FLAG_HAS_SLICE_SIZE) != 0) + { + Debug.Assert(_sliceSize >= 4); + _stream.skip(_sliceSize - 4); + } + else + { + throw new Ice.MarshalException( + "compact format prevents slicing (the sender should use the sliced format instead)"); + } + + if(!_encaps.encoding_1_0) + { + // + // Preserve this slice. + // + Ice.SliceInfo info = new Ice.SliceInfo(); + info.typeId = _typeId; + info.hasOptionalMembers = (_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) != 0; + info.isLastSlice = (_sliceFlags & FLAG_IS_LAST_SLICE) != 0; + ByteBuffer b = _stream.getBuffer().b; + int end = b.position(); + int dataEnd = end; + if(info.hasOptionalMembers) + { + // + // Don't include the optional member end marker. It will be re-written by + // endSlice when the sliced data is re-written. + // + --dataEnd; + } + info.bytes = new byte[dataEnd - start]; + b.position(start); + b.get(info.bytes); + b.position(end); + _slices.Add(info); + + if((_sliceFlags & FLAG_HAS_INDIRECTION_TABLE) != 0) + { + // + // Read the indirection table, which is written as a sequence<size> to conserve space. + // + _indirectionTables.Add(_stream.readSizeSeq()); + } + else + { + _indirectionTables.Add(new int[0]); + } + } + } + + internal bool readOpt(int readTag, Ice.OptionalType expectedType) + { + if(_sliceType == SliceType.NoSlice) + { + return _stream.readOptImpl(readTag, expectedType); + } + else if((_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) != 0) + { + return _stream.readOptImpl(readTag, expectedType); + } + return false; + } + + internal void readPendingObjects() + { + // + // With the 1.0 encoding, read pending objects if nil or non-nil + // references were read (_usesClasses == true). Otherwise, read + // pending objects only if some non-nil references were read. + // + if(_encaps.encoding_1_0) + { + if(!_usesClasses) + { + return; + } + _usesClasses = false; + } + else if(_patchMap.Count == 0) + { + return; + } + else + { + // + // Read unread encapsulation optionals before reading the + // pending objects. + // + _stream.skipOpts(); + } + + int num; + List<Ice.Object> objectList = new List<Ice.Object>(); + do + { + num = _stream.readSize(); + for(int k = num; k > 0; --k) + { + objectList.Add(readInstance()); + } + } + while(num > 0); + + if(_patchMap.Count > 0) + { + // + // If any entries remain in the patch map, the sender has sent an index for an object, but failed + // to supply the object. + // + throw new Ice.MarshalException("index for class received, but no instance"); + } + + // + // Iterate over the object list and invoke ice_postUnmarshal on + // each object. We must do this after all objects have been + // unmarshaled in order to ensure that any object data members + // have been properly patched. + // + foreach(Ice.Object p in objectList) + { + try + { + p.ice_postUnmarshal(); + } + catch(System.Exception ex) + { + _stream.instance().initializationData().logger.warning( + "exception raised by ice_postUnmarshal:\n" + ex); + } + } + } + + private Ice.Object readInstance() + { + int index; + if(_encaps.encoding_1_0) + { + index = _stream.readInt(); + } + else + { + index = _stream.readSize(); + } + + Ice.Object v = null; + if(index <= 0) + { + throw new Ice.MarshalException("invalid object id"); + } + + _sliceType = SliceType.ObjectSlice; + _skipFirstSlice = false; + + // + // Read the first slice header. + // + startSlice(); + string mostDerivedId = _typeId; + ObjectFactoryManager servantFactoryManager = _stream.instance().servantFactoryManager(); + while(true) + { + // + // For the 1.0 encoding, the type ID for the base Object class + // marks the last slice. + // + if(_typeId.Equals(Ice.ObjectImpl.ice_staticId())) + { + throw new Ice.NoObjectFactoryException("", mostDerivedId); + } + + // + // Try to find a factory registered for the specific type. + // + Ice.ObjectFactory userFactory = servantFactoryManager.find(_typeId); + if(userFactory != null) + { + v = userFactory.create(_typeId); + } + + // + // If that fails, invoke the default factory if one has been + // registered. + // + if(v == null) + { + userFactory = servantFactoryManager.find(""); + if(userFactory != null) + { + v = userFactory.create(_typeId); + } + } + + // + // Last chance: check the table of static factories (i.e., + // automatically generated factories for concrete classes). + // + if(v == null) + { + userFactory = _stream.loadObjectFactory(_typeId); + if(userFactory != null) + { + v = userFactory.create(_typeId); + Debug.Assert(v != null); + } + } + + // + // We found a factory, we get out of this loop. + // + if(v != null) + { + break; + } + + // + // Performance sensitive, so we use lazy initialization for tracing. + // + if(_traceSlicing == -1) + { + _traceSlicing = _stream.instance().traceLevels().slicing; + _slicingCat = _stream.instance().traceLevels().slicingCat; + } + if(_traceSlicing > 0) + { + TraceUtil.traceSlicing("class", _typeId, _slicingCat, + _stream.instance().initializationData().logger); + } + + // + // If object slicing is disabled, stop un-marshalling. + // + if(!_sliceObjects) + { + throw new Ice.NoObjectFactoryException("object slicing is disabled", _typeId); + } + + // + // Slice off what we don't understand. + // + skipSlice(); + + // + // If this is the last slice, keep the object as an opaque + // UnknownSlicedData object. + // + if((_sliceFlags & FLAG_IS_LAST_SLICE) != 0) + { + v = new Ice.UnknownSlicedObject(mostDerivedId); + break; + } + + startSlice(); // Read next Slice header for next iteration. + } + + // + // Add the object to the map of un-marshalled objects, this must + // be done before reading the objects (for circular references). + // + _unmarshaledMap.Add(index, v); + + // + // Read the object. + // + v.read__(_stream); + + // + // Patch all instances now that the object is un-marshalled. + // + LinkedList<IPatcher> l; + if(_patchMap.TryGetValue(index, out l)) + { + Debug.Assert(l.Count > 0); + + // + // Patch all pointers that refer to the instance. + // + foreach(IPatcher p in l) + { + p.patch(v); + } + + // + // Clear out the patch map for that index -- there is nothing left + // to patch for that index for the time being. + // + _patchMap.Remove(index); + } + + return v; + } + + private void addPatchEntry(int index, IPatcher patcher) + { + Debug.Assert(index > 0); + + // + // Check if already un-marshalled the object. If that's the case, + // just patch the object smart pointer and we're done. + // + Ice.Object obj; + if(_unmarshaledMap.TryGetValue(index, out obj)) + { + patcher.patch(obj); + return; + } + + // + // Add patch entry if the object isn't un-marshalled yet, the + // smart pointer will be patched when the instance is + // un-marshalled. + // + + LinkedList<IPatcher> l; + if(!_patchMap.TryGetValue(index, out l)) + { + // + // We have no outstanding instances to be patched for this + // index, so make a new entry in the patch map. + // + l = new LinkedList<IPatcher>(); + _patchMap.Add(index, l); + } + + // + // Append a patch entry for this instance. + // + l.AddLast(patcher); + } + + private Ice.SlicedData readSlicedData() + { + if(_slices.Count == 0) // No preserved slices. + { + return null; + } + + // + // The _indirectionTables member holds the indirection table for each slice + // in _slices. + // + Debug.Assert(_slices.Count == _indirectionTables.Count); + + for(int n = 0; n < _slices.Count; ++n) + { + // + // We use the "objects" list in SliceInfo to hold references to the target + // objects. Note however that we may not have actually read these objects + // yet, so they need to be treated just like we had read the object references + // directly (i.e., we add them to the patch list). + // + // Another important note: the SlicedData object that we return here must + // not be destroyed before readPendingObjects is called, otherwise the + // patch references will refer to invalid addresses. + // + int[] table = _indirectionTables[n]; + Ice.SliceInfo info = _slices[n]; + info.objects = new Ice.Object[table.Length]; + for(int j = 0; j < table.Length; ++j) + { + if(table[j] <= 0) + { + throw new Ice.MarshalException("invalid id in object indirection table"); + } + IPatcher patcher = new ArrayPatcher<Ice.Object>(Ice.ObjectImpl.ice_staticId(), info.objects, j); + addPatchEntry(table[j], patcher); + } + } + + return new Ice.SlicedData(_slices.ToArray()); + } + + private bool skipOpt(int type) + { + int sz; + switch(type) + { + case MemberTypeF1: + { + sz = 1; + break; + } + case MemberTypeF2: + { + sz = 2; + break; + } + case MemberTypeF4: + { + sz = 4; + break; + } + case MemberTypeF8: + { + sz = 8; + break; + } + case MemberTypeVSize: + { + sz = _stream.readSize(); + break; + } + case MemberTypeFSize: + { + sz = _stream.readInt(); + break; + } + default: + { + return false; + } + } + + int pos = _stream.pos(); + if(pos + sz > _stream.size()) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } + _stream.pos(pos + sz); + return true; + } + + private BasicStream _stream; + private ReadEncaps _encaps; + private bool _sliceObjects; + + private int _traceSlicing; + private String _slicingCat; + + // Object/exception attributes + private SliceType _sliceType; + private bool _skipFirstSlice; + private List<Ice.SliceInfo> _slices; // Preserved slices. + private List<int[]> _indirectionTables; + private bool _usesClasses; + + // Slice attributes + private byte _sliceFlags; + private int _sliceSize; + private string _typeId; + + private sealed class IndirectPatchEntry + { + internal int index; + internal IPatcher patcher; + } + private List<IndirectPatchEntry> _indirectPatchList; + + // Encapsulation attributes for object un-marshalling + private Dictionary<int, LinkedList<IPatcher>> _patchMap; + private Dictionary<int, Ice.Object> _unmarshaledMap; + private Dictionary<int, string> _typeIdMap; + private int _typeIdIndex; } - private sealed class WriteEncaps + private sealed class EncapsEncoder { - internal int start; + internal EncapsEncoder(BasicStream stream, WriteEncaps encaps) + { + _stream = stream; + _encaps = encaps; + _sliceType = SliceType.NoSlice; + _usesClasses = false; + _objectIdIndex = 0; + _typeIdIndex = 0; + _indirectionTable = new List<int>(); + _indirectionMap = new Dictionary<int, int>(); + _toBeMarshaledMap = new Dictionary<Ice.Object, int>(); + _marshaledMap = new Dictionary<Ice.Object, int>(); + _typeIdMap = new Dictionary<string, int>(); + } - internal int writeIndex; - internal Dictionary<Ice.Object, int> toBeMarshaledMap; - internal Dictionary<Ice.Object, int> marshaledMap; - internal int typeIdIndex; - internal Dictionary<string, int> typeIdMap; - internal Ice.EncodingVersion encoding = new Ice.EncodingVersion(); - internal WriteEncaps next; + internal void writeObject(Ice.Object v) + { + if(v != null) + { + // + // Register the object. + // + int index = registerObject(v); - internal void reset() + if(_encaps.encoding_1_0) + { + // + // Object references are encoded as a negative integer in 1.0. + // + _stream.writeInt(-index); + _usesClasses = true; + } + else if(_sliceType != SliceType.NoSlice && _encaps.format == Ice.FormatType.SlicedFormat) + { + // + // An object reference that appears inside a slice of an + // object or exception encoded as a positive non-zero + // index into a per-slice indirection table. + // + // We use _indirectionMap to keep track of the object + // references in the current slice; it maps the object + // reference to the position in the indirection list. Note + // that the position is offset by one (e.g., the first + // position = 1). + // + int p; + if(!_indirectionMap.TryGetValue(index, out p)) + { + _indirectionTable.Add(index); + int sz = _indirectionTable.Count; // Position + 1 + _indirectionMap.Add(index, sz); + _stream.writeSize(sz); + } + else + { + _stream.writeSize(p); + } + } + else + { + _stream.writeSize(index); + } + } + else + { + // + // Write nil reference. + // + if(_encaps.encoding_1_0) + { + _stream.writeInt(0); + _usesClasses = true; + } + else + { + _stream.writeSize(0); + } + } + } + + internal void writeUserException(Ice.UserException v) + { + v.write__(_stream); + writePendingObjects(); + } + + internal void startObject(Ice.SlicedData data) + { + _sliceType = SliceType.ObjectSlice; + _firstSlice = true; + if(data != null) + { + writeSlicedData(data); + } + } + + internal void endObject() + { + if(_encaps.encoding_1_0) + { + // + // Write the Object slice. + // + startSlice(Ice.ObjectImpl.ice_staticId(), true); + _stream.writeSize(0); // For compatibility with the old AFM. + endSlice(); + } + _sliceType = SliceType.NoSlice; + } + + internal void startException(Ice.SlicedData data) + { + _sliceType = SliceType.ExceptionSlice; + _firstSlice = true; + if(_encaps.encoding_1_0) + { + _usesClassesPos = _stream.pos(); + _stream.writeBool(false); // Placeholder for usesClasses bool + } + if(data != null) + { + writeSlicedData(data); + } + } + + internal void endException() + { + if(_encaps.encoding_1_0) + { + _stream.rewriteBool(_usesClasses, _usesClassesPos); + } + _sliceType = SliceType.NoSlice; + } + + internal void startSlice(string typeId, bool last) + { + Debug.Assert(_indirectionTable.Count == 0 && _indirectionMap.Count == 0); + _sliceFlags = (byte)0; + _sliceFlagsPos = _stream.pos(); + + // + // Encode the slice size for the old encoding and if using the + // sliced format. + // + if(_encaps.encoding_1_0 || _encaps.format == Ice.FormatType.SlicedFormat) + { + _sliceFlags |= FLAG_HAS_SLICE_SIZE; + } + + // + // This is the last slice. + // + if(last) + { + _sliceFlags |= FLAG_IS_LAST_SLICE; + } + + // + // For object slices, encode the flag and the type ID either as a + // string or index. For exception slices, don't encode slice flags + // for the old encoding and always encode the type ID a string. + // + if(_sliceType == SliceType.ObjectSlice) + { + _stream.writeByte((byte)0); // Placeholder for the slice flags + + // + // Encode the type ID (only in the first slice for the compact + // encoding). + // + if(_encaps.format == Ice.FormatType.SlicedFormat || _encaps.encoding_1_0 || _firstSlice) + { + // + // If the type ID has already been seen, write the index + // of the type ID, otherwise allocate a new type ID and + // write the string. + // + int p; + if(_typeIdMap.TryGetValue(typeId, out p)) + { + _sliceFlags |= FLAG_HAS_TYPE_ID_INDEX; + _stream.writeSize(p); + } + else + { + _sliceFlags |= FLAG_HAS_TYPE_ID_STRING; + _typeIdMap.Add(typeId, ++_typeIdIndex); + _stream.writeString(typeId); + } + } + } + else + { + if(!_encaps.encoding_1_0) + { + _stream.writeByte((byte)0); // Placeholder for the slice flags + } + _stream.writeString(typeId); + } + + if((_sliceFlags & FLAG_HAS_SLICE_SIZE) != 0) + { + _stream.writeInt(0); // Placeholder for the slice length. + } + + _writeSlice = _stream.pos(); + _firstSlice = false; + } + + internal void endSlice() + { + // + // Write the optional member end marker if some optional members + // were encoded. Note that the optional members are encoded before + // the indirection table and are included in the slice size. + // + if((_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) != 0) + { + Debug.Assert(!_encaps.encoding_1_0); + _stream.writeByte((byte)Ice.OptionalType.EndMarker); + } + + // + // Write the slice length if necessary. + // + if((_sliceFlags & FLAG_HAS_SLICE_SIZE) != 0) + { + int sz = _stream.pos() - _writeSlice + 4; + _stream.rewriteInt(sz, _writeSlice - 4); + } + + // + // Only write the indirection table if it contains entries. + // + if(_indirectionTable.Count > 0) + { + Debug.Assert(!_encaps.encoding_1_0); + Debug.Assert(_encaps.format == Ice.FormatType.SlicedFormat); + _sliceFlags |= FLAG_HAS_INDIRECTION_TABLE; + + // + // Write the indirection table as a sequence<size> to conserve space. + // + _stream.writeSizeSeq(_indirectionTable); + + _indirectionTable.Clear(); + _indirectionMap.Clear(); + } + + // + // Finally, update the slice flags (or the object slice has index + // type ID bool for the 1.0 encoding) + // + if(_encaps.encoding_1_0) + { + if(_sliceType == SliceType.ObjectSlice) // No flags for 1.0 exception slices. + { + _stream.rewriteBool((_sliceFlags & FLAG_HAS_TYPE_ID_INDEX) != 0, _sliceFlagsPos); + } + } + else + { + _stream.rewriteByte(_sliceFlags, _sliceFlagsPos); + } + } + + internal bool writeOpt(int tag, Ice.OptionalType type) + { + if(_sliceType == SliceType.NoSlice) + { + return _stream.writeOptImpl(tag, type); + } + else + { + if(_stream.writeOptImpl(tag, type)) + { + _sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS; + return true; + } + else + { + return false; + } + } + } + + internal void writePendingObjects() + { + // + // With the 1.0 encoding, write pending objects if nil or non-nil + // references were written (_usesClasses = true). Otherwise, write + // pending objects only if some non-nil references were written. + // + if(_encaps.encoding_1_0) + { + if(!_usesClasses) + { + return; + } + _usesClasses = false; + } + else if(_toBeMarshaledMap.Count == 0) + { + return; + } + else + { + // + // Write end marker for encapsulation optionals before encoding + // the pending objects. + // + _stream.writeByte((byte)Ice.OptionalType.EndMarker); + } + + while(_toBeMarshaledMap.Count > 0) + { + // + // Consider the to be marshalled objects as marshalled now, + // this is necessary to avoid adding again the "to be + // marshalled objects" into _toBeMarshaledMap while writing + // objects. + // + foreach(KeyValuePair<Ice.Object, int> e in _toBeMarshaledMap) + { + _marshaledMap.Add(e.Key, e.Value); + } + + Dictionary<Ice.Object, int> savedMap = _toBeMarshaledMap; + _toBeMarshaledMap = new Dictionary<Ice.Object, int>(); + _stream.writeSize(savedMap.Count); + foreach(KeyValuePair<Ice.Object, int> e in savedMap) + { + // + // Ask the instance to marshal itself. Any new class + // instances that are triggered by the classes marshaled + // are added to toBeMarshaledMap. + // + if(_encaps.encoding_1_0) + { + _stream.writeInt(e.Value); + } + else + { + _stream.writeSize(e.Value); + } + + try + { + e.Key.ice_preMarshal(); + } + catch(System.Exception ex) + { + _stream.instance().initializationData().logger.warning( + "exception raised by ice_preMarshal:\n" + ex); + } + + e.Key.write__(_stream); + } + } + _stream.writeSize(0); // Zero marker indicates end of sequence of sequences of instances. + } + + private void writeSlicedData(Ice.SlicedData slicedData) + { + Debug.Assert(slicedData != null); + + // + // We only remarshal preserved slices if the target encoding is > 1.0 and we are + // using the sliced format. Otherwise, we ignore the preserved slices, which + // essentially "slices" the object into the most-derived type known by the sender. + // + if(_encaps.encoding_1_0 || _encaps.format != Ice.FormatType.SlicedFormat) + { + return; + } + + for(int n = 0; n < slicedData.slices.Length; ++n) + { + Ice.SliceInfo info = slicedData.slices[n]; + startSlice(info.typeId, info.isLastSlice); + + // + // Write the bytes associated with this slice. + // + _stream.writeBlob(info.bytes); + + if(info.hasOptionalMembers) + { + _sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS; + } + + // + // Assemble and write the indirection table. The table must have the same order + // as the list of objects. + // + for(int j = 0; j < info.objects.Length; ++j) + { + _indirectionTable.Add(registerObject(info.objects[j])); + } + + endSlice(); + } + } + + private int registerObject(Ice.Object v) { - if(toBeMarshaledMap != null) + // + // Look for this instance in the to-be-marshaled map. + // + int p; + if(_toBeMarshaledMap.TryGetValue(v, out p)) { - writeIndex = 0; - toBeMarshaledMap.Clear(); - marshaledMap.Clear(); - typeIdIndex = 0; - typeIdMap.Clear(); + return p; } + + // + // Didn't find it, try the marshaled map next. + // + if(_marshaledMap.TryGetValue(v, out p)) + { + return p; + } + + // + // We haven't seen this instance previously, create a new + // index, and insert it into the to-be-marshaled map. + // + _toBeMarshaledMap.Add(v, ++_objectIdIndex); + return _objectIdIndex; + } + + private BasicStream _stream; + private WriteEncaps _encaps; + + // Object/exception attributes + private SliceType _sliceType; + private bool _firstSlice; + private bool _usesClasses; + private int _usesClassesPos; + + // Slice attributes + private byte _sliceFlags; + private int _writeSlice; // Position of the slice data members + private int _sliceFlagsPos; // Position of the slice flags + private List<int> _indirectionTable; + private Dictionary<int, int> _indirectionMap; + + // Encapsulation attributes for object marshalling. + private int _objectIdIndex; + private Dictionary<Ice.Object, int> _toBeMarshaledMap; + private Dictionary<Ice.Object, int> _marshaledMap; + private Dictionary<string, int> _typeIdMap; + private int _typeIdIndex; + } + + private sealed class ReadEncaps + { + internal void reset() + { + decoder = null; } + + internal void setEncoding(Ice.EncodingVersion encoding) + { + this.encoding = encoding; + encoding_1_0 = encoding.Equals(Ice.Util.Encoding_1_0); + } + + internal int start; + internal int sz; + internal Ice.EncodingVersion encoding; + internal bool encoding_1_0; + + internal EncapsDecoder decoder; + + internal ReadEncaps next; + } + + private sealed class WriteEncaps + { + internal void reset() + { + encoder = null; + } + + internal void setEncoding(Ice.EncodingVersion encoding) + { + this.encoding = encoding; + encoding_1_0 = encoding.Equals(Ice.Util.Encoding_1_0); + } + + internal int start; + internal Ice.EncodingVersion encoding; + internal bool encoding_1_0; + internal Ice.FormatType format; + + internal EncapsEncoder encoder; + + internal WriteEncaps next; + } + + // + // The encoding version to use when there's no encapsulation to + // read from or write to. This is for example used to read message + // headers or when the user is using the streaming API with no + // encapsulation. + // + private Ice.EncodingVersion _encoding; + + private bool isReadEncoding_1_0() + { + return _readEncapsStack != null ? _readEncapsStack.encoding_1_0 : _encoding.Equals(Ice.Util.Encoding_1_0); + } + + private bool isWriteEncoding_1_0() + { + return _writeEncapsStack != null ? _writeEncapsStack.encoding_1_0 : _encoding.Equals(Ice.Util.Encoding_1_0); } private ReadEncaps _readEncapsStack; @@ -3002,23 +4749,74 @@ namespace IceInternal private ReadEncaps _readEncapsCache; private WriteEncaps _writeEncapsCache; - private int _readSlice; - private int _writeSlice; + private void initReadEncaps() + { + if(_readEncapsStack == null) // Lazy initialization + { + _readEncapsStack = _readEncapsCache; + if(_readEncapsStack != null) + { + _readEncapsCache = _readEncapsCache.next; + } + else + { + _readEncapsStack = new ReadEncaps(); + } + _readEncapsStack.setEncoding(_encoding); + _readEncapsStack.sz = _buf.b.limit(); + } + + if(_readEncapsStack.decoder == null) // Lazy initialization. + { + _readEncapsStack.decoder = new EncapsDecoder(this, _readEncapsStack, _sliceObjects); + } + } + + private void initWriteEncaps() + { + if(_writeEncapsStack == null) // Lazy initialization + { + _writeEncapsStack = _writeEncapsCache; + if(_writeEncapsStack != null) + { + _writeEncapsCache = _writeEncapsCache.next; + } + else + { + _writeEncapsStack = new WriteEncaps(); + } + _writeEncapsStack.setEncoding(_encoding); + } + + if(_writeEncapsStack.format == Ice.FormatType.DefaultFormat) + { + _writeEncapsStack.format = instance_.defaultsAndOverrides().defaultFormat; + } - private int _traceSlicing; - private string _slicingCat; + if(_writeEncapsStack.encoder == null) // Lazy initialization. + { + _writeEncapsStack.encoder = new EncapsEncoder(this, _writeEncapsStack); + } + } private bool _sliceObjects; private int _messageSizeMax; private bool _unlimited; - int _startSeq; - int _minSeqSize; + private int _startSeq; + private int _minSeqSize; + + private int _sizePos; - private List<Ice.Object> _objectList; + private const byte FLAG_HAS_TYPE_ID_STRING = (byte)(1<<0); + private const byte FLAG_HAS_TYPE_ID_INDEX = (byte)(1<<1); + private const byte FLAG_HAS_OPTIONAL_MEMBERS = (byte)(1<<2); + private const byte FLAG_HAS_INDIRECTION_TABLE = (byte)(1<<3); + private const byte FLAG_HAS_SLICE_SIZE = (byte)(1<<4); + private const byte FLAG_IS_LAST_SLICE = (byte)(1<<5); - private static Dictionary<string, UserExceptionFactory> _exceptionFactories = + private static Dictionary<string, UserExceptionFactory> _exceptionFactories = new Dictionary<string, UserExceptionFactory>(); // <type name, factory> pairs. private static bool _bzlibInstalled; diff --git a/cs/src/Ice/ByteBuffer.cs b/cs/src/Ice/ByteBuffer.cs index 38dfef99b6e..c7c1127ea36 100644 --- a/cs/src/Ice/ByteBuffer.cs +++ b/cs/src/Ice/ByteBuffer.cs @@ -186,6 +186,12 @@ namespace IceInternal return this; } + public ByteBuffer put(int pos, byte b) + { + System.Buffer.SetByte(_bytes, pos, b); + return this; + } + public ByteBuffer put(byte[] b) { return put(b, 0, System.Buffer.ByteLength(b)); diff --git a/cs/src/Ice/DefaultsAndOverrides.cs b/cs/src/Ice/DefaultsAndOverrides.cs index 5ef89e42fe3..7a8f10c85c6 100644 --- a/cs/src/Ice/DefaultsAndOverrides.cs +++ b/cs/src/Ice/DefaultsAndOverrides.cs @@ -17,9 +17,9 @@ namespace IceInternal internal DefaultsAndOverrides(Ice.Properties properties) { string val; - + defaultProtocol = properties.getPropertyWithDefault("Ice.Default.Protocol", "tcp"); - + val = properties.getProperty("Ice.Default.Host"); if(val.Length != 0) { @@ -29,7 +29,7 @@ namespace IceInternal { defaultHost = null; } - + val = properties.getProperty("Ice.Override.Timeout"); if(val.Length > 0) { @@ -41,7 +41,7 @@ namespace IceInternal overrideTimeout = false; overrideTimeoutValue = -1; } - + val = properties.getProperty("Ice.Override.ConnectTimeout"); if(val.Length > 0) { @@ -124,12 +124,15 @@ namespace IceInternal defaultPreferSecure = properties.getPropertyAsIntWithDefault("Ice.Default.PreferSecure", 0) > 0; - val = properties.getPropertyWithDefault("Ice.Default.EncodingVersion", + val = properties.getPropertyWithDefault("Ice.Default.EncodingVersion", Ice.Util.encodingVersionToString(Ice.Util.currentEncoding)); defaultEncoding = Ice.Util.stringToEncodingVersion(val); - Protocol.checkSupportedEncoding(defaultEncoding); + Protocol.checkSupportedEncoding(defaultEncoding); + + bool slicedFormat = properties.getPropertyAsIntWithDefault("Ice.Default.SlicedFormat", 0) > 0; + defaultFormat = slicedFormat ? Ice.FormatType.SlicedFormat : Ice.FormatType.CompactFormat; } - + public string defaultHost; public string defaultProtocol; public bool defaultCollocationOptimization; @@ -137,7 +140,8 @@ namespace IceInternal public int defaultLocatorCacheTimeout; public bool defaultPreferSecure; public Ice.EncodingVersion defaultEncoding; - + public Ice.FormatType defaultFormat; + public bool overrideTimeout; public int overrideTimeoutValue; public bool overrideConnectTimeout; diff --git a/cs/src/Ice/Exception.cs b/cs/src/Ice/Exception.cs index 995d3d3406d..477298b61de 100644 --- a/cs/src/Ice/Exception.cs +++ b/cs/src/Ice/Exception.cs @@ -159,22 +159,19 @@ namespace Ice public UserException(System.Exception ex) : base(ex) {} public abstract void write__(IceInternal.BasicStream os__); - public abstract void read__(IceInternal.BasicStream is__, bool rid__); + public abstract void writeImpl__(IceInternal.BasicStream os__); + public abstract void read__(IceInternal.BasicStream is__); + public abstract void readImpl__(IceInternal.BasicStream is__); public virtual void write__(Ice.OutputStream outS__) { Debug.Assert(false); } - public virtual void read__(Ice.InputStream inS__, bool rid__) + public virtual void read__(Ice.InputStream inS__) { Debug.Assert(false); } - - public virtual bool usesClasses__() - { - return false; - } } } diff --git a/cs/src/Ice/FormatType.cs b/cs/src/Ice/FormatType.cs new file mode 100644 index 00000000000..48b71c56180 --- /dev/null +++ b/cs/src/Ice/FormatType.cs @@ -0,0 +1,21 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2012 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +namespace Ice +{ + /// <summary> + /// This enumeration describes the possible formats for classes and exceptions. + /// </summary> + public enum FormatType + { + DefaultFormat, + CompactFormat, + SlicedFormat + } +} diff --git a/cs/src/Ice/Incoming.cs b/cs/src/Ice/Incoming.cs index 89a02adcf2b..0f6d2044a5b 100644 --- a/cs/src/Ice/Incoming.cs +++ b/cs/src/Ice/Incoming.cs @@ -91,13 +91,13 @@ namespace IceInternal inc.connection_ = null; } - public BasicStream startWriteParams__() + public BasicStream startWriteParams__(Ice.FormatType format) { if(response_) { Debug.Assert(os_.size() == Protocol.headerSize + 4); // Reply status position. os_.writeByte((byte)0); - os_.startWriteEncaps(current_.encoding); + os_.startWriteEncaps(current_.encoding, format); } // @@ -148,6 +148,13 @@ namespace IceInternal } } } + + public void writeUserException__(Ice.UserException ex, Ice.FormatType format) + { + BasicStream os__ = startWriteParams__(format); + os__.writeUserException(ex); + endWriteParams__(false); + } // // These functions allow this object to be reused, rather than reallocated. @@ -612,7 +619,7 @@ namespace IceInternal if(response_) { os_.writeByte(ReplyStatus.replyUserException); - os_.startWriteEncaps(encoding); + os_.startWriteEncaps(encoding, Ice.FormatType.DefaultFormat); os_.writeUserException(ex); os_.endWriteEncaps(); connection_.sendResponse(os_, compress_); diff --git a/cs/src/Ice/Makefile b/cs/src/Ice/Makefile index cd874a9db79..c81f56fe38c 100644 --- a/cs/src/Ice/Makefile +++ b/cs/src/Ice/Makefile @@ -46,6 +46,7 @@ SRCS = Acceptor.cs \ EndpointHostResolver.cs \ EventHandler.cs \ Exception.cs \ + FormatType.cs \ ImplicitContextI.cs \ IncomingAsync.cs \ Incoming.cs \ @@ -60,6 +61,7 @@ SRCS = Acceptor.cs \ Object.cs \ ObjectFactoryManager.cs \ OpaqueEndpointI.cs \ + OptionalType.cs \ Options.cs \ OutgoingAsync.cs \ Outgoing.cs \ @@ -84,6 +86,7 @@ SRCS = Acceptor.cs \ RouterInfo.cs \ ServantManager.cs \ SliceChecksums.cs \ + SlicedData.cs \ SocketOperation.cs \ Stream.cs \ StreamI.cs \ @@ -105,6 +108,7 @@ SRCS = Acceptor.cs \ UdpEndpointI.cs \ UdpConnector.cs \ UdpTransceiver.cs \ + UnknownSlicedObject.cs \ UserExceptionFactory.cs \ Util.cs \ ValueWriter.cs diff --git a/cs/src/Ice/Makefile.mak b/cs/src/Ice/Makefile.mak index 99d8d9bae34..e22953964c0 100644 --- a/cs/src/Ice/Makefile.mak +++ b/cs/src/Ice/Makefile.mak @@ -46,6 +46,7 @@ SRCS = Acceptor.cs \ EndpointHostResolver.cs \
EventHandler.cs \
Exception.cs \
+ FormatType.cs \
HashSet.cs \
ImplicitContextI.cs \
IncomingAsync.cs \
@@ -61,6 +62,7 @@ SRCS = Acceptor.cs \ Object.cs \
ObjectFactoryManager.cs \
OPaqueEndpointI.cs \
+ OptionalType.cs \
Options.cs \
OutgoingAsync.cs \
Outgoing.cs \
@@ -86,6 +88,7 @@ SRCS = Acceptor.cs \ ServantManager.cs \
SocketOperation.cs \
SliceChecksums.cs \
+ SlicedData.cs \
Stream.cs \
StreamI.cs \
StreamWrapper.cs \
@@ -106,6 +109,7 @@ SRCS = Acceptor.cs \ UdpConnector.cs \
UdpEndpointI.cs \
UdpTransceiver.cs \
+ UnknownSlicedObject.cs \
UserExceptionFactory.cs \
Util.cs \
ValueWriter.cs
diff --git a/cs/src/Ice/Object.cs b/cs/src/Ice/Object.cs index dcd6dcc53df..ebb9786585a 100644 --- a/cs/src/Ice/Object.cs +++ b/cs/src/Ice/Object.cs @@ -16,7 +16,7 @@ namespace Ice /// <summary> /// Indicates the status of operation dispatch. /// </summary> - public enum DispatchStatus + public enum DispatchStatus { /// <summary> /// Indicates that an operation was dispatched synchronously and successfully. @@ -157,10 +157,12 @@ namespace Ice DispatchStatus collocDispatch__(IceInternal.Direct request); void write__(IceInternal.BasicStream os__); - void read__(IceInternal.BasicStream is__, bool rid__); + void writeImpl__(IceInternal.BasicStream os__); + void read__(IceInternal.BasicStream is__); + void readImpl__(IceInternal.BasicStream is__); void write__(OutputStream outS__); - void read__(InputStream inS__, bool rid__); + void read__(InputStream inS__); } /// <summary> @@ -189,7 +191,7 @@ namespace Ice { "::Ice::Object" }; - + /// <summary> /// Tests whether this object supports a specific Slice interface. /// </summary> @@ -210,19 +212,19 @@ namespace Ice { return s.Equals(ids__[0]); } - + public static DispatchStatus ice_isA___(Ice.Object __obj, IceInternal.Incoming inS__, Current __current) { IceInternal.BasicStream is__ = inS__.startReadParams(); string __id = is__.readString(); inS__.endReadParams(); bool __ret = __obj.ice_isA(__id, __current); - IceInternal.BasicStream os__ = inS__.startWriteParams__(); + IceInternal.BasicStream os__ = inS__.startWriteParams__(FormatType.DefaultFormat); os__.writeBool(__ret); inS__.endWriteParams__(true); return DispatchStatus.DispatchOK; } - + /// <summary> /// Tests whether this object can be reached. /// </summary> @@ -239,7 +241,7 @@ namespace Ice { // Nothing to do. } - + public static DispatchStatus ice_ping___(Ice.Object __obj, IceInternal.Incoming inS__, Current __current) { inS__.readEmptyParams(); @@ -247,7 +249,7 @@ namespace Ice inS__.writeEmptyParams__(); return DispatchStatus.DispatchOK; } - + /// <summary> /// Returns the Slice type IDs of the interfaces supported by this object. /// </summary> @@ -266,17 +268,17 @@ namespace Ice { return ids__; } - + public static DispatchStatus ice_ids___(Ice.Object __obj, IceInternal.Incoming inS__, Current __current) { inS__.readEmptyParams(); string[] ret__ = __obj.ice_ids(__current); - IceInternal.BasicStream os__ = inS__.startWriteParams__(); + IceInternal.BasicStream os__ = inS__.startWriteParams__(FormatType.DefaultFormat); os__.writeStringSeq(ret__); inS__.endWriteParams__(true); return DispatchStatus.DispatchOK; } - + /// <summary> /// Returns the Slice type ID of the most-derived interface supported by this object. /// </summary> @@ -295,17 +297,17 @@ namespace Ice { return ids__[0]; } - + public static DispatchStatus ice_id___(Ice.Object __obj, IceInternal.Incoming inS__, Current __current) { inS__.readEmptyParams(); string __ret = __obj.ice_id(__current); - IceInternal.BasicStream os__ = inS__.startWriteParams__(); + IceInternal.BasicStream os__ = inS__.startWriteParams__(FormatType.DefaultFormat); os__.writeString(__ret); inS__.endWriteParams__(true); return DispatchStatus.DispatchOK; } - + /// <summary> /// Returns the Slice type ID of the interface supported by this object. /// </summary> @@ -314,7 +316,7 @@ namespace Ice { return ids__[0]; } - + /// <summary> /// The Ice run time invokes this method prior to marshaling an object's data members. This allows a subclass /// to override this method in order to validate its data members. @@ -335,7 +337,7 @@ namespace Ice { "ice_id", "ice_ids", "ice_isA", "ice_ping" }; - + /// <summary> /// Dispatches an invocation to a servant. This method is used by dispatch interceptors to forward an invocation /// to a servant (or to another interceptor). @@ -390,27 +392,27 @@ namespace Ice { throw new Ice.OperationNotExistException(current.id, current.facet, current.operation); } - + switch(pos) { - case 0: + case 0: { return ice_id___(this, inc, current); } - case 1: + case 1: { return ice_ids___(this, inc, current); } - case 2: + case 2: { return ice_isA___(this, inc, current); } - case 3: + case 3: { return ice_ping___(this, inc, current); } } - + Debug.Assert(false); throw new Ice.OperationNotExistException(current.id, current.facet, current.operation); } @@ -422,61 +424,29 @@ namespace Ice public virtual void write__(IceInternal.BasicStream os__) { - os__.writeTypeId(ice_staticId()); - os__.startWriteSlice(); - os__.writeSize(0); // For compatibility with the old AFM. - os__.endWriteSlice(); } - - public virtual void read__(IceInternal.BasicStream is__, bool rid__) - { - if(rid__) - { - /* string myId = */ is__.readTypeId(); - } - - is__.startReadSlice(); - - // For compatibility with the old AFM. - int sz = is__.readSize(); - if(sz != 0) - { - throw new MarshalException(); - } - - is__.endReadSlice(); + public virtual void writeImpl__(IceInternal.BasicStream os__) + { } - public virtual void write__(OutputStream outS__) + public virtual void read__(IceInternal.BasicStream is__) { - outS__.writeTypeId(ice_staticId()); - outS__.startSlice(); - outS__.writeSize(0); // For compatibility with the old AFM. - outS__.endSlice(); } - public virtual void read__(InputStream inS__, bool rid__) + public virtual void readImpl__(IceInternal.BasicStream is__) { - if(rid__) - { - /* string myId = */ inS__.readTypeId(); - } - - inS__.startSlice(); + } - // For compatibility with the old AFM. - int sz = inS__.readSize(); - if(sz != 0) - { - throw new MarshalException(); - } + public virtual void write__(OutputStream outS__) + { + } - inS__.endSlice(); + public virtual void read__(InputStream inS__) + { } - private static string - operationModeToString(OperationMode mode) + private static string operationModeToString(OperationMode mode) { if(mode == Ice.OperationMode.Normal) { @@ -495,29 +465,27 @@ namespace Ice return "???"; } - protected static void - checkMode__(OperationMode expected, OperationMode received) + protected static void checkMode__(OperationMode expected, OperationMode received) { if(expected != received) { - if(expected == OperationMode.Idempotent - && received == OperationMode.Nonmutating) + if(expected == OperationMode.Idempotent && received == OperationMode.Nonmutating) { // - // Fine: typically an old client still using the + // Fine: typically an old client still using the // deprecated nonmutating keyword // } else { Ice.MarshalException ex = new Ice.MarshalException(); - ex.reason = "unexpected operation mode. expected = " - + operationModeToString(expected) + " received = " - + operationModeToString(received); + ex.reason = "unexpected operation mode. expected = " + operationModeToString(expected) + + " received = " + operationModeToString(received); throw ex; } } } + public static Ice.Current defaultCurrent = new Ice.Current(); } @@ -541,7 +509,7 @@ namespace Ice /// must contain the encoded user exception. If the operation raises an /// Ice run-time exception, it must throw it directly.</returns> public abstract bool ice_invoke(byte[] inParams, out byte[] outParams, Current current); - + public override DispatchStatus dispatch__(IceInternal.Incoming inS__, Current current) { byte[] inEncaps = inS__.readParamEncaps(); @@ -562,7 +530,7 @@ namespace Ice public abstract class BlobjectAsync : Ice.ObjectImpl { public abstract void ice_invoke_async(AMD_Object_ice_invoke cb, byte[] inEncaps, Current current); - + public override DispatchStatus dispatch__(IceInternal.Incoming inS__, Current current) { byte[] inEncaps = inS__.readParamEncaps(); @@ -578,5 +546,4 @@ namespace Ice return DispatchStatus.DispatchAsync; } } - } diff --git a/cs/src/Ice/OpaqueEndpointI.cs b/cs/src/Ice/OpaqueEndpointI.cs index 68c3be9b1bc..e5027960d64 100644 --- a/cs/src/Ice/OpaqueEndpointI.cs +++ b/cs/src/Ice/OpaqueEndpointI.cs @@ -165,7 +165,7 @@ namespace IceInternal public override void streamWrite(BasicStream s) { s.writeShort(_type); - s.startWriteEncaps(_rawEncoding); + s.startWriteEncaps(_rawEncoding, Ice.FormatType.DefaultFormat); s.writeBlob(_rawBytes); s.endWriteEncaps(); } diff --git a/cs/src/Ice/OptionalType.cs b/cs/src/Ice/OptionalType.cs new file mode 100644 index 00000000000..3523a2eeac3 --- /dev/null +++ b/cs/src/Ice/OptionalType.cs @@ -0,0 +1,30 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2012 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +namespace Ice +{ + /// <summary> + /// The optional type. + /// + /// An optional value is encoded with a specific optional type. This optional + /// type describes how the data is encoded and how it can be skipped by the + /// unmarshaling code if the optional is not known to the receiver. + /// </summary> + public enum OptionalType + { + F1 = 0, + F2 = 1, + F4 = 2, + F8 = 3, + Size = 4, + VSize = 5, + FSize = 6, + EndMarker = 7 + } +} diff --git a/cs/src/Ice/Outgoing.cs b/cs/src/Ice/Outgoing.cs index 813c7d23d98..1ef49cca09c 100644 --- a/cs/src/Ice/Outgoing.cs +++ b/cs/src/Ice/Outgoing.cs @@ -460,9 +460,9 @@ namespace IceInternal return _is.readEncaps(out _encoding); } - public BasicStream startWriteParams() + public BasicStream startWriteParams(Ice.FormatType format) { - _os.startWriteEncaps(_encoding); + _os.startWriteEncaps(_encoding, format); return _os; } @@ -498,7 +498,7 @@ namespace IceInternal try { _is.startReadEncaps(); - _is.throwException(); + _is.throwException(null); } catch(Ice.UserException) { diff --git a/cs/src/Ice/OutgoingAsync.cs b/cs/src/Ice/OutgoingAsync.cs index f2c483abc18..98ffd1be0e3 100644 --- a/cs/src/Ice/OutgoingAsync.cs +++ b/cs/src/Ice/OutgoingAsync.cs @@ -500,7 +500,7 @@ namespace IceInternal try { is_.startReadEncaps(); - is_.throwException(); + is_.throwException(null); } catch(Ice.UserException) { @@ -1172,9 +1172,9 @@ namespace IceInternal return is_.readEncaps(out _encoding); } - public BasicStream startWriteParams__() + public BasicStream startWriteParams__(Ice.FormatType format) { - os_.startWriteEncaps(_encoding); + os_.startWriteEncaps(_encoding, format); return os_; } diff --git a/cs/src/Ice/Proxy.cs b/cs/src/Ice/Proxy.cs index 2e74a47e9c2..b915070a4b5 100644 --- a/cs/src/Ice/Proxy.cs +++ b/cs/src/Ice/Proxy.cs @@ -368,7 +368,7 @@ namespace Ice /// <param name="mode">The operation mode (normal or idempotent).</param> /// <param name="inEncaps">The encoded in-parameters for the operation.</param> /// <returns>An asynchronous result object.</returns> - AsyncResult<Callback_Object_ice_invoke> begin_ice_invoke(string operation, OperationMode mode, + AsyncResult<Callback_Object_ice_invoke> begin_ice_invoke(string operation, OperationMode mode, byte[] inEncaps); /// <summary> @@ -379,7 +379,7 @@ namespace Ice /// <param name="inEncaps">The encoded in-parameters for the operation.</param> /// <param name="context__">The context dictionary for the invocation.</param> /// <returns>An asynchronous result object.</returns> - AsyncResult<Callback_Object_ice_invoke> begin_ice_invoke(string operation, OperationMode mode, + AsyncResult<Callback_Object_ice_invoke> begin_ice_invoke(string operation, OperationMode mode, byte[] inEncaps, Dictionary<string, string> context__); @@ -873,12 +873,11 @@ namespace Ice } private AsyncResult<Callback_Object_ice_isA> begin_ice_isA(string id, Dictionary<string, string> context__, - bool explicitContext__, - Ice.AsyncCallback cb__, - object cookie__) + bool explicitContext__, Ice.AsyncCallback cb__, + object cookie__) { - IceInternal.TwowayOutgoingAsync<Callback_Object_ice_isA> result__ = - new IceInternal.TwowayOutgoingAsync<Callback_Object_ice_isA>(this, __ice_isA_name, ice_isA_completed__, + IceInternal.TwowayOutgoingAsync<Callback_Object_ice_isA> result__ = + new IceInternal.TwowayOutgoingAsync<Callback_Object_ice_isA>(this, __ice_isA_name, ice_isA_completed__, cookie__); if(cb__ != null) { @@ -889,7 +888,7 @@ namespace Ice try { result__.prepare__(__ice_isA_name, OperationMode.Nonmutating, context__, explicitContext__); - IceInternal.BasicStream os__ = result__.startWriteParams__(); + IceInternal.BasicStream os__ = result__.startWriteParams__(FormatType.DefaultFormat); os__.writeString(id); result__.endWriteParams__(); result__.send__(true); @@ -994,13 +993,13 @@ namespace Ice end__(r__, __ice_ping_name); } - private AsyncResult<Callback_Object_ice_ping> begin_ice_ping(Dictionary<string, string> context__, + private AsyncResult<Callback_Object_ice_ping> begin_ice_ping(Dictionary<string, string> context__, bool explicitContext__, - Ice.AsyncCallback cb__, + Ice.AsyncCallback cb__, object cookie__) { - IceInternal.OnewayOutgoingAsync<Callback_Object_ice_ping> result__ = - new IceInternal.OnewayOutgoingAsync<Callback_Object_ice_ping>(this, __ice_ping_name, + IceInternal.OnewayOutgoingAsync<Callback_Object_ice_ping> result__ = + new IceInternal.OnewayOutgoingAsync<Callback_Object_ice_ping>(this, __ice_ping_name, ice_ping_completed__, cookie__); if(cb__ != null) { @@ -1122,10 +1121,10 @@ namespace Ice private AsyncResult<Callback_Object_ice_ids> begin_ice_ids(Dictionary<string, string> context__, bool explicitContext__, - Ice.AsyncCallback cb__, + Ice.AsyncCallback cb__, object cookie__) { - IceInternal.TwowayOutgoingAsync<Callback_Object_ice_ids> result__ = + IceInternal.TwowayOutgoingAsync<Callback_Object_ice_ids> result__ = new IceInternal.TwowayOutgoingAsync<Callback_Object_ice_ids>(this, __ice_ids_name, ice_ids_completed__, cookie__); if(cb__ != null) @@ -1258,13 +1257,13 @@ namespace Ice return ret__; } - private AsyncResult<Callback_Object_ice_id> begin_ice_id(Dictionary<string, string> context__, + private AsyncResult<Callback_Object_ice_id> begin_ice_id(Dictionary<string, string> context__, bool explicitContext__, - Ice.AsyncCallback cb__, + Ice.AsyncCallback cb__, object cookie__) { - IceInternal.TwowayOutgoingAsync<Callback_Object_ice_id> result__ = - new IceInternal.TwowayOutgoingAsync<Callback_Object_ice_id>(this, __ice_id_name, ice_id_completed__, + IceInternal.TwowayOutgoingAsync<Callback_Object_ice_id> result__ = + new IceInternal.TwowayOutgoingAsync<Callback_Object_ice_id>(this, __ice_id_name, ice_id_completed__, cookie__); if(cb__ != null) { @@ -1430,8 +1429,8 @@ namespace Ice return begin_ice_invoke(operation, mode, inEncaps, null, false, null, null); } - public AsyncResult<Callback_Object_ice_invoke> begin_ice_invoke(string operation, - OperationMode mode, + public AsyncResult<Callback_Object_ice_invoke> begin_ice_invoke(string operation, + OperationMode mode, byte[] inEncaps, Dictionary<string, string> context__) { @@ -1468,12 +1467,12 @@ namespace Ice return ok; } - private AsyncResult<Callback_Object_ice_invoke> begin_ice_invoke(string operation, + private AsyncResult<Callback_Object_ice_invoke> begin_ice_invoke(string operation, OperationMode mode, byte[] inEncaps, Dictionary<string, string> context__, bool explicitContext__, - Ice.AsyncCallback cb__, + Ice.AsyncCallback cb__, object cookie__) { IceInternal.TwowayOutgoingAsync<Callback_Object_ice_invoke> result__ = @@ -1497,7 +1496,7 @@ namespace Ice return result__; } - private void ice_invoke_completed__(AsyncResult r__, + private void ice_invoke_completed__(AsyncResult r__, Callback_Object_ice_invoke cb__, Ice.ExceptionCallback excb__) { @@ -2960,7 +2959,7 @@ namespace Ice { try { - IceInternal.BasicStream os__ = og__.startWriteParams(); + IceInternal.BasicStream os__ = og__.startWriteParams(FormatType.DefaultFormat); os__.writeString(id__); og__.endWriteParams(); } diff --git a/cs/src/Ice/SlicedData.cs b/cs/src/Ice/SlicedData.cs new file mode 100644 index 00000000000..c1dd39ce97b --- /dev/null +++ b/cs/src/Ice/SlicedData.cs @@ -0,0 +1,58 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +namespace Ice +{ + /// <summary> + /// SlicedData holds the slices of unknown class or exception types. + /// </summary> + public class SlicedData + { + public SlicedData(SliceInfo[] slices) + { + this.slices = slices; + } + + /** + * The details of each slice, in order of most-derived to least-derived. + **/ + public SliceInfo[] slices; + } + + /// <summary> + /// SliceInfo encapsulates the details of a slice for an unknown class or exception type. + /// </summary> + public class SliceInfo + { + /// <summary> + /// The Slice type ID for this slice. + /// </summary> + public string typeId; + + /// <summary> + /// The encoded bytes for this slice, including the leading size integer. + /// </summary> + public byte[] bytes; + + /// <summary> + /// The Ice objects referenced by this slice. + /// </summary> + public Ice.Object[] objects; + + /// <summary> + /// Whether or not the slice contains optional members. + /// </summary> + public bool hasOptionalMembers; + + /// <summary> + /// Whether or not this is the last slice. + /// </summary> + public bool isLastSlice; + } +} diff --git a/cs/src/Ice/Stream.cs b/cs/src/Ice/Stream.cs index 7a8218519fe..581b3c53d47 100644 --- a/cs/src/Ice/Stream.cs +++ b/cs/src/Ice/Stream.cs @@ -176,10 +176,12 @@ namespace Ice void readObject(ReadObjectCallback cb); /// <summary> - /// Extracts a Slice type ID from the stream. + /// Read an enumerated value. /// </summary> - /// <returns>The extracted type ID.</returns> - string readTypeId(); + /// + /// <param name="limit">The number of enumerators in the definition.</param> + /// <returns>The enumerator.</returns> + int readEnum(int limit); /// <summary> /// Extracts a user exception from the stream and throws it. @@ -187,9 +189,42 @@ namespace Ice void throwException(); /// <summary> + /// Extracts a user exception from the stream and throws it. + /// Extracts a user exception from the stream and throws it, using the supplied + /// factory to instantiate a UserExceptionReader. + /// </summary> + /// <param name="factory">A factory that creates UserExceptionReader instances.</param> + void throwException(UserExceptionReaderFactory factory); + + /// <summary> + /// Marks the start of an Ice object. + /// </summary> + void startObject(); + + /// <summary> + /// Marks the end of an Ice object. + /// </summary> + /// <param name="preserve">True if unknown slices should be preserved, false otherwise.</param> + /// <returns>A SlicedData object containing the preserved slices for unknown types.</returns> + SlicedData endObject(bool preserve); + + /// <summary> + /// Marks the start of a user exception. + /// </summary> + void startException(); + + /// <summary> + /// Marks the end of a user exception. + /// </summary> + /// <param name="preserve">True if unknown slices should be preserved, false otherwise.</param> + /// <returns>A SlicedData object containing the preserved slices for unknown types.</returns> + SlicedData endException(bool preserve); + + /// <summary> /// Reads the start of an object or exception slice. /// </summary> - void startSlice(); + /// <returns>The Slice type ID for this slice.</returns> + string startSlice(); /// <summary> /// Indicates that the end of an object or exception slice has been reached. @@ -204,7 +239,8 @@ namespace Ice /// <summary> /// Reads the start of an encapsulation. /// </summary> - void startEncapsulation(); + /// <returns>The encapsulation encoding version.</returns> + EncodingVersion startEncapsulation(); /// <summary> /// Indicates that the end of an encapsulation has been reached. @@ -214,19 +250,14 @@ namespace Ice /// <summary> /// Skips over an encapsulation. /// </summary> - void skipEncapsulation(); + /// <returns>The encapsulation encoding version.</returns> + EncodingVersion skipEncapsulation(); /// <summary> - /// Returns the size of the current encapsulation. + /// Determines the current encoding version. /// </summary> - /// <returns>The size of the current encapsulation.</returns> - int getEncapsulationSize(); - - /// <summary> - /// Reads the specified number of bytes from the stream. - /// </summary> - /// <returns>The bytes read.</returns> - byte[] readBlob(int size); + /// <returns>The encoding version.</returns> + EncodingVersion getEncoding(); /// <summary> /// Indicates that unmarshaling is complete, except for any Slice objects. The application must @@ -242,6 +273,31 @@ namespace Ice void rewind(); /// <summary> + /// Skips ahead in the stream. + /// </summary> + /// <param name="sz">The number of bytes to skip.</param> + void skip(int sz); + + /// <summary> + /// Skips over a size value. + /// </summary> + void skipSize(); + + /// <summary> + /// Determine if an optional value is available for reading. + /// </summary> + /// <param name="tag">The tag associated with the value.</param> + /// <param name="type">The optional type for the value.</param> + /// <returns>True if the value is present, false otherwise.</returns> + bool readOptional(int tag, OptionalType type); + + /// <summary> + /// Determine the current position in the stream. + /// </summary> + /// <returns>The current position.</returns> + int pos(); + + /// <summary> /// Destroys the stream and its associated resources. The application must call destroy prior /// to releasing the last reference to a stream; failure to do so may result in resource leaks. /// </summary> @@ -390,10 +446,11 @@ namespace Ice void writeObject(Ice.Object v); /// <summary> - /// Writes a Slice type ID to the stream. + /// Write an enumerated value. /// </summary> - /// <param name="id">The Slice type ID to write.</param> - void writeTypeId(string id); + /// <param name="v">The enumerator.</param> + /// <param name="limit">The number of enumerators in the definition.</param> + void writeEnum(int v, int limit); /// <summary> /// Writes a user exception to the stream. @@ -402,18 +459,49 @@ namespace Ice void writeException(UserException ex); /// <summary> - /// Writes the start of a slice to the stream. + /// Marks the start of an Ice object. + /// </summary> + /// <param name="slicedData">Preserved slices for this object, or null.</param> + void startObject(SlicedData slicedData); + + /// <summary> + /// Marks the end of an Ice object. /// </summary> - void startSlice(); + void endObject(); /// <summary> - /// Ends the previous slice. + /// Marks the start of a user exception. + /// </summary> + /// <param name="slicedData">Preserved slices for this object, or null.</param> + void startException(SlicedData slicedData); + + /// <summary> + /// Marks the end of a user exception. + /// </summary> + void endException(); + + /// <summary> + /// Marks the start of a new slice for an Ice object or user exception. + /// </summary> + /// <param name="typeId">The Slice type ID corresponding to this slice.</param> + /// <param name="last">True if this is the last slice, false otherwise.</param> + void startSlice(string typeId, bool last); + + /// <summary> + /// Marks the end of a slice for an Ice object or user exception. /// </summary> void endSlice(); /// <summary> /// Writes the start of an encapsulation to the stream. /// </summary> + /// <param name="encoding">The encoding version of the encapsulation.</param> + /// <param name="format">The format to use for encoding objects and user exceptions.</param> + void startEncapsulation(EncodingVersion encoding, FormatType format); + + /// <summary> + /// Writes the start of an encapsulation to the stream. + /// </summary> void startEncapsulation(); /// <summary> @@ -422,9 +510,10 @@ namespace Ice void endEncapsulation(); /// <summary> - /// Writes the specified bytes onto the stream. + /// Determines the current encoding version. /// </summary> - void writeBlob(byte[] data); + /// <returns>The encoding version.</returns> + EncodingVersion getEncoding(); /// <summary> /// Writes the state of Slice classes whose index was previously @@ -433,6 +522,39 @@ namespace Ice void writePendingObjects(); /// <summary> + /// Write the header information for an optional value. + /// </summary> + /// <param name="tag">The numeric tag associated with the value.</param> + /// <param name="type">The optional type of the value.</param> + /// <returns>True if the optional should be written, false otherwise.</returns> + bool writeOptional(int tag, OptionalType type); + + /// <summary> + /// Determines the current position in the stream. + /// </summary> + /// <returns>The current position.</returns> + int pos(); + + /// <summary> + /// Inserts a fixed 32-bit size value into the stream at the given position. + /// </summary> + /// <param name="sz">The 32-bit size value.</param> + /// <param name="pos">The position at which to write the value.</param> + void rewrite(int sz, int pos); + + /// <summary> + /// Records the current position and allocates four bytes for a fixed-length (32-bit) + /// size value. + /// </summary> + void startSize(); + + /// <summary> + /// Computes the amount of data written since the previous call to startSize and + /// writes that value at the saved position. + /// </summary> + void endSize(); + + /// <summary> /// Indicates that the marshaling of a request or reply is finished. /// </summary> /// <returns>The byte sequence containing the encoded request or reply.</returns> @@ -462,23 +584,20 @@ namespace Ice public abstract class ObjectReader : ObjectImpl { /// <summary> - /// @param in The input stream to read from. - /// @param rid If <code>true</code>, extraction begins by reading a Slice type ID - /// first. If <code>false</code>, the leading type ID is not read. This is used - /// by the unmarshaling code in case the type ID has already been read as part - /// of other unmarshaling activities. + /// Read the object's data members. /// </summary> - public abstract void read(InputStream inStream, bool rid); + /// <param name="inStream">The input stream to read from.</param> + public abstract void read(InputStream inStream); public override void write__(IceInternal.BasicStream os) { Debug.Assert(false); } - public override void read__(IceInternal.BasicStream istr, bool rid) + public override void read__(IceInternal.BasicStream istr) { InputStream stream = (InputStream)istr.closure(); - read(stream, rid); + read(stream); } } @@ -499,12 +618,51 @@ namespace Ice write(stream); } - public override void read__(IceInternal.BasicStream istr, bool rid) + public override void read__(IceInternal.BasicStream istr) { Debug.Assert(false); } } + public abstract class UserExceptionReader : UserException + { + public UserExceptionReader(Communicator communicator) + { + communicator_ = communicator; + } + + public abstract void read(Ice.InputStream istr); + + public override void write__(IceInternal.BasicStream ostr) + { + Debug.Assert(false); + } + + public override void read__(IceInternal.BasicStream istr) + { + InputStream stream = (InputStream)istr.closure(); + Debug.Assert(stream != null); + read(stream); + } + + public override void write__(Ice.OutputStream ostr) + { + Debug.Assert(false); + } + + public override void read__(Ice.InputStream istr) + { + read(istr); + } + + protected Communicator communicator_; + } + + public interface UserExceptionReaderFactory + { + void createAndThrow(string typeId); + } + public abstract class UserExceptionWriter : UserException { public UserExceptionWriter(Communicator communicator) @@ -513,7 +671,6 @@ namespace Ice } public abstract void write(OutputStream os); - public abstract bool usesClasses(); public override void write__(IceInternal.BasicStream os) { @@ -525,7 +682,7 @@ namespace Ice write(stream); } - public override void read__(IceInternal.BasicStream istr, bool rid) + public override void read__(IceInternal.BasicStream istr) { Debug.Assert(false); } @@ -535,16 +692,11 @@ namespace Ice write(ostr); } - public override void read__(Ice.InputStream istr, bool rid) + public override void read__(Ice.InputStream istr) { Debug.Assert(false); } - public override bool usesClasses__() - { - return usesClasses(); - } - protected Communicator communicator_; } } diff --git a/cs/src/Ice/StreamI.cs b/cs/src/Ice/StreamI.cs index cacdcef5059..e0c11c64c6d 100644 --- a/cs/src/Ice/StreamI.cs +++ b/cs/src/Ice/StreamI.cs @@ -155,19 +155,63 @@ namespace Ice _is.readObject(new Patcher<Ice.Object>(cb)); } - public string readTypeId() + public int readEnum(int limit) { - return _is.readTypeId(); + return _is.readEnum(limit); } public void throwException() { - _is.throwException(); + _is.throwException(null); } - public void startSlice() + internal class UserExceptionFactoryI : IceInternal.UserExceptionFactory { - _is.startReadSlice(); + internal UserExceptionFactoryI(UserExceptionReaderFactory factory) + { + _factory = factory; + } + + public void createAndThrow(string id) + { + _factory.createAndThrow(id); + } + + public void destroy() + { + } + + private UserExceptionReaderFactory _factory; + } + + public void throwException(UserExceptionReaderFactory factory) + { + _is.throwException(new UserExceptionFactoryI(factory)); + } + + public void startObject() + { + _is.startReadObject(); + } + + public SlicedData endObject(bool preserve) + { + return _is.endReadObject(preserve); + } + + public void startException() + { + _is.startReadException(); + } + + public SlicedData endException(bool preserve) + { + return _is.endReadException(preserve); + } + + public string startSlice() + { + return _is.startReadSlice(); } public void endSlice() @@ -180,9 +224,9 @@ namespace Ice _is.skipSlice(); } - public void startEncapsulation() + public EncodingVersion startEncapsulation() { - _is.startReadEncaps(); + return _is.startReadEncaps(); } public void endEncapsulation() @@ -190,19 +234,14 @@ namespace Ice _is.endReadEncapsChecked(); } - public void skipEncapsulation() + public EncodingVersion skipEncapsulation() { - _is.skipEncaps(); + return _is.skipEncaps(); } - public int getEncapsulationSize() + public EncodingVersion getEncoding() { - return _is.getReadEncapsSize(); - } - - public byte[] readBlob(int sz) - { - return _is.readBlob(sz); + return _is.getReadEncoding(); } public void readPendingObjects() @@ -216,6 +255,26 @@ namespace Ice _is.getBuffer().b.position(0); } + public void skip(int sz) + { + _is.skip(sz); + } + + public void skipSize() + { + _is.skipSize(); + } + + public bool readOptional(int tag, OptionalType type) + { + return _is.readOpt(tag, type); + } + + public int pos() + { + return _is.pos(); + } + public void destroy() { if(_is != null) @@ -356,9 +415,9 @@ namespace Ice _os.writeObject(v); } - public void writeTypeId(string id) + public void writeEnum(int v, int limit) { - _os.writeTypeId(id); + _os.writeEnum(v, limit); } public void writeException(UserException v) @@ -366,9 +425,29 @@ namespace Ice _os.writeUserException(v); } - public void startSlice() + public void startObject(SlicedData slicedData) + { + _os.startWriteObject(slicedData); + } + + public void endObject() + { + _os.endWriteObject(); + } + + public void startException(SlicedData slicedData) + { + _os.startWriteException(slicedData); + } + + public void endException() + { + _os.endWriteException(); + } + + public void startSlice(string typeId, bool last) { - _os.startWriteSlice(); + _os.startWriteSlice(typeId, last); } public void endSlice() @@ -376,6 +455,11 @@ namespace Ice _os.endWriteSlice(); } + public void startEncapsulation(EncodingVersion encoding, FormatType format) + { + _os.startWriteEncaps(encoding, format); + } + public void startEncapsulation() { _os.startWriteEncaps(); @@ -386,9 +470,9 @@ namespace Ice _os.endWriteEncapsChecked(); } - public void writeBlob(byte[] data) + public EncodingVersion getEncoding() { - _os.writeBlob(data); + return _os.getWriteEncoding(); } public void writePendingObjects() @@ -396,6 +480,31 @@ namespace Ice _os.writePendingObjects(); } + public bool writeOptional(int tag, OptionalType type) + { + return _os.writeOpt(tag, type); + } + + public int pos() + { + return _os.pos(); + } + + public void rewrite(int sz, int pos) + { + _os.rewriteInt(sz, pos); + } + + public void startSize() + { + _os.startSize(); + } + + public void endSize() + { + _os.endSize(); + } + public byte[] finished() { IceInternal.Buffer buf = _os.prepareWrite(); diff --git a/cs/src/Ice/UnknownSlicedObject.cs b/cs/src/Ice/UnknownSlicedObject.cs new file mode 100644 index 00000000000..54b633e3aec --- /dev/null +++ b/cs/src/Ice/UnknownSlicedObject.cs @@ -0,0 +1,50 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2012 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +namespace Ice +{ + /// <summary> + /// Unknown sliced object holds an instance of unknown type. + /// </summary> + public sealed class UnknownSlicedObject : ObjectImpl + { + /// <summary> + /// Instantiates the class for an Ice object having the given Slice type. + /// </summary> + /// <param name="unknownTypeId">The Slice type ID of the unknown object.</param> + public UnknownSlicedObject(string unknownTypeId) + { + _unknownTypeId = unknownTypeId; + } + + /// <summary> + /// Determine the Slice type ID associated with this object. + /// </summary> + /// <returns>The type ID.</returns> + public string getUnknownTypeId() + { + return _unknownTypeId; + } + + public override void write__(IceInternal.BasicStream os__) + { + os__.startWriteObject(_slicedData); + os__.endWriteObject(); + } + + public override void read__(IceInternal.BasicStream is__) + { + is__.startReadObject(); + _slicedData = is__.endReadObject(true); + } + + private string _unknownTypeId; + private SlicedData _slicedData; + } +} diff --git a/cs/src/Ice/UserExceptionFactory.cs b/cs/src/Ice/UserExceptionFactory.cs index 6d2fcd609e5..fa63892af2a 100644 --- a/cs/src/Ice/UserExceptionFactory.cs +++ b/cs/src/Ice/UserExceptionFactory.cs @@ -12,7 +12,7 @@ namespace IceInternal public interface UserExceptionFactory { - void createAndThrow(); + void createAndThrow(string typeId); void destroy(); } diff --git a/cs/test/Ice/slicing/exceptions/AllTests.cs b/cs/test/Ice/slicing/exceptions/AllTests.cs index ecb49286d00..7d84556a3a9 100644 --- a/cs/test/Ice/slicing/exceptions/AllTests.cs +++ b/cs/test/Ice/slicing/exceptions/AllTests.cs @@ -10,10 +10,10 @@ using System; using System.Diagnostics; using System.Threading; -using Test;
-
-#if SILVERLIGHT
-using System.Windows.Controls;
+using Test; + +#if SILVERLIGHT +using System.Windows.Controls; #endif public class AllTests : TestCommon.TestApp @@ -323,17 +323,59 @@ public class AllTests : TestCommon.TestApp private Callback callback = new Callback(); } -#if SILVERLIGHT
- public override Ice.InitializationData initData()
- {
- Ice.InitializationData initData = new Ice.InitializationData();
- initData.properties = Ice.Util.createProperties();
- initData.properties.setProperty("Ice.FactoryAssemblies", "exceptions,version=1.0.0.0");
- return initData;
- }
-
- override
- public void run(Ice.Communicator communicator)
+ private class RelayI : RelayDisp_ + { + public override void knownPreservedAsBase(Ice.Current current) + { + KnownPreservedDerived ex = new KnownPreservedDerived(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + throw ex; + } + + public override void knownPreservedAsKnownPreserved(Ice.Current current) + { + KnownPreservedDerived ex = new KnownPreservedDerived(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + throw ex; + } + + public override void unknownPreservedAsBase(Ice.Current current) + { + Preserved2 ex = new Preserved2(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + ex.p1 = new PreservedClass("bc", "pc"); + ex.p2 = ex.p1; + throw ex; + } + + public override void unknownPreservedAsKnownPreserved(Ice.Current current) + { + Preserved2 ex = new Preserved2(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + ex.p1 = new PreservedClass("bc", "pc"); + ex.p2 = ex.p1; + throw ex; + } + } + +#if SILVERLIGHT + public override Ice.InitializationData initData() + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.FactoryAssemblies", "exceptions,version=1.0.0.0"); + return initData; + } + + public override void run(Ice.Communicator communicator) #else public static TestIntfPrx allTests(Ice.Communicator communicator, bool collocated) #endif @@ -746,10 +788,168 @@ public class AllTests : TestCommon.TestApp { AsyncCallback cb = new AsyncCallback(); testPrx.begin_unknownMostDerived2AsBase().whenCompleted( - cb.response, cb.exception_unknownMostDerived2AsBase); + cb.response, cb.exception_unknownMostDerived2AsBase); cb.check(); } WriteLine("ok"); + + Write("unknown most derived in compact format... "); + Flush(); + { + try + { + testPrx.unknownMostDerived2AsBaseCompact(); + test(false); + } + catch(Base) + { + // + // For the 1.0 encoding, the unknown exception is sliced to Base. + // + test(testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)); + } + catch(Ice.MarshalException) + { + // + // A MarshalException is raised for the compact format because the + // most-derived type is unknown and the exception cannot be sliced. + // + test(!testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)); + } + catch(Exception) + { + test(false); + } + } + WriteLine("ok"); + + Write("preserved exceptions... "); + Flush(); + { + Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithEndpoints("Relay", "default"); + RelayPrx relay = RelayPrxHelper.uncheckedCast(adapter.addWithUUID(new RelayI())); + adapter.activate(); + + try + { + testPrx.relayKnownPreservedAsBase(relay); + test(false); + } + catch(KnownPreservedDerived ex) + { + test(ex.b.Equals("base")); + test(ex.kp.Equals("preserved")); + test(ex.kpd.Equals("derived")); + } + catch(Exception ex) + { +Write("\n\n*** Caught: " + ex); + test(false); + } + + try + { + testPrx.relayKnownPreservedAsKnownPreserved(relay); + test(false); + } + catch(KnownPreservedDerived ex) + { + test(ex.b.Equals("base")); + test(ex.kp.Equals("preserved")); + test(ex.kpd.Equals("derived")); + } + /* + catch(Exception) + { + test(false); + } + */ + catch(Exception ex) + { +Write("\n\n*** Caught: " + ex); + test(false); + } + + try + { + testPrx.relayUnknownPreservedAsBase(relay); + test(false); + } + catch(Preserved2 ex) + { + test(ex.b.Equals("base")); + test(ex.kp.Equals("preserved")); + test(ex.kpd.Equals("derived")); + test(ex.p1.ice_id().Equals(PreservedClass.ice_staticId())); + PreservedClass pc = ex.p1 as PreservedClass; + test(pc.bc.Equals("bc")); + test(pc.pc.Equals("pc")); + test(ex.p2 == ex.p1); + } + catch(KnownPreservedDerived ex) + { + // + // For the 1.0 encoding, the unknown exception is sliced to KnownPreserved. + // + test(testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)); + test(ex.b.Equals("base")); + test(ex.kp.Equals("preserved")); + test(ex.kpd.Equals("derived")); + } + /* + catch(Exception) + { + test(false); + } + */ + catch(Exception ex) + { +Write("\n\n*** Caught: " + ex); + test(false); + } + + try + { + testPrx.relayUnknownPreservedAsKnownPreserved(relay); + test(false); + } + catch(Preserved2 ex) + { + test(ex.b.Equals("base")); + test(ex.kp.Equals("preserved")); + test(ex.kpd.Equals("derived")); + test(ex.p1.ice_id().Equals(PreservedClass.ice_staticId())); + PreservedClass pc = ex.p1 as PreservedClass; + test(pc.bc.Equals("bc")); + test(pc.pc.Equals("pc")); + test(ex.p2 == ex.p1); + } + catch(KnownPreservedDerived ex) + { + // + // For the 1.0 encoding, the unknown exception is sliced to KnownPreserved. + // + test(testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)); + test(ex.b.Equals("base")); + test(ex.kp.Equals("preserved")); + test(ex.kpd.Equals("derived")); + } + /* + catch(Exception) + { + test(false); + } + */ + catch(Exception ex) + { +Write("\n\n*** Caught: " + ex); + test(false); + } + + adapter.destroy(); + } + WriteLine("ok"); + #if SILVERLIGHT testPrx.shutdown(); #else diff --git a/cs/test/Ice/slicing/exceptions/ClientPrivate.ice b/cs/test/Ice/slicing/exceptions/ClientPrivate.ice new file mode 100644 index 00000000000..029e6d5d37e --- /dev/null +++ b/cs/test/Ice/slicing/exceptions/ClientPrivate.ice @@ -0,0 +1,32 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2012 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Test.ice> + +module Test +{ + +class PreservedClass extends BaseClass +{ + string pc; +}; + +exception Preserved1 extends KnownPreservedDerived +{ + BaseClass p1; +}; + +exception Preserved2 extends Preserved1 +{ + BaseClass p2; +}; + +}; diff --git a/cs/test/Ice/slicing/exceptions/Makefile b/cs/test/Ice/slicing/exceptions/Makefile index 37fa5b0fa6b..248103aea8d 100644 --- a/cs/test/Ice/slicing/exceptions/Makefile +++ b/cs/test/Ice/slicing/exceptions/Makefile @@ -16,6 +16,7 @@ S_SRCS = Server.cs TestI.cs SAMD_SRCS = Server.cs TestAMDI.cs SLICE_SRCS = $(SDIR)/Test.ice +SLICE_C_SRCS = $(SDIR)/ClientPrivate.ice SLICE_S_SRCS = $(SDIR)/ServerPrivate.ice SLICE_AMD_SRCS = $(SDIR)/TestAMD.ice SLICE_SAMD_SRCS = $(SDIR)/ServerPrivateAMD.ice @@ -30,7 +31,7 @@ MCSFLAGS := $(MCSFLAGS) -target:exe SLICE2CSFLAGS := $(SLICE2CSFLAGS) -I. -client.exe: $(C_SRCS) $(GEN_SRCS) +client.exe: $(C_SRCS) $(GEN_SRCS) $(CGEN_SRCS) $(MCS) $(MCSFLAGS) -out:$@ $(call ref,Ice) $(subst /,$(DSEP),$^) server.exe: $(S_SRCS) $(GEN_SRCS) $(SGEN_SRCS) diff --git a/cs/test/Ice/slicing/exceptions/Makefile.mak b/cs/test/Ice/slicing/exceptions/Makefile.mak index a9d3b999ebb..38974588c2e 100644 --- a/cs/test/Ice/slicing/exceptions/Makefile.mak +++ b/cs/test/Ice/slicing/exceptions/Makefile.mak @@ -16,6 +16,7 @@ S_SRCS = Server.cs TestI.cs SAMD_SRCS = Server.cs TestAMDI.cs
GEN_SRCS = $(GDIR)\Test.cs
+CGEN_SRCS = $(GDIR)\ClientPrivate.cs
SGEN_SRCS = $(GDIR)\ServerPrivate.cs
GEN_AMD_SRCS = $(GDIR)\TestAMD.cs
SAMD_GEN_SRCS = $(GDIR)\ServerPrivateAMD.cs
@@ -30,8 +31,8 @@ MCSFLAGS = $(MCSFLAGS) -target:exe SLICE2CSFLAGS = $(SLICE2CSFLAGS) -I.
-client.exe: $(C_SRCS) $(GEN_SRCS)
- $(MCS) $(MCSFLAGS) -out:$@ -r:"$(refdir)\Ice.dll" $(C_SRCS) $(GEN_SRCS)
+client.exe: $(C_SRCS) $(GEN_SRCS) $(CGEN_SRCS)
+ $(MCS) $(MCSFLAGS) -out:$@ -r:"$(refdir)\Ice.dll" $(C_SRCS) $(GEN_SRCS) $(CGEN_SRCS)
server.exe: $(S_SRCS) $(GEN_SRCS) $(SGEN_SRCS)
$(MCS) $(MCSFLAGS) -out:$@ -r:"$(refdir)\Ice.dll" $(S_SRCS) $(GEN_SRCS) $(SGEN_SRCS)
diff --git a/cs/test/Ice/slicing/exceptions/ServerPrivate.ice b/cs/test/Ice/slicing/exceptions/ServerPrivate.ice index df89aa2efea..e03994a4641 100644 --- a/cs/test/Ice/slicing/exceptions/ServerPrivate.ice +++ b/cs/test/Ice/slicing/exceptions/ServerPrivate.ice @@ -34,4 +34,19 @@ exception UnknownMostDerived2 extends UnknownIntermediate string umd2; }; +class SPreservedClass extends BaseClass +{ + string spc; +}; + +exception SPreserved1 extends KnownPreservedDerived +{ + BaseClass p1; +}; + +exception SPreserved2 extends SPreserved1 +{ + BaseClass p2; +}; + }; diff --git a/cs/test/Ice/slicing/exceptions/ServerPrivateAMD.ice b/cs/test/Ice/slicing/exceptions/ServerPrivateAMD.ice index 59542af8d16..7d99c0182c4 100644 --- a/cs/test/Ice/slicing/exceptions/ServerPrivateAMD.ice +++ b/cs/test/Ice/slicing/exceptions/ServerPrivateAMD.ice @@ -34,4 +34,19 @@ exception UnknownMostDerived2 extends UnknownIntermediate string umd2; }; +class SPreservedClass extends BaseClass +{ + string spc; +}; + +exception SPreserved1 extends KnownPreservedDerived +{ + BaseClass p1; +}; + +exception SPreserved2 extends SPreserved1 +{ + BaseClass p2; +}; + }; diff --git a/cs/test/Ice/slicing/exceptions/Test.ice b/cs/test/Ice/slicing/exceptions/Test.ice index cb3953f8ef3..ddf84d47e82 100644 --- a/cs/test/Ice/slicing/exceptions/Test.ice +++ b/cs/test/Ice/slicing/exceptions/Test.ice @@ -32,6 +32,34 @@ exception KnownMostDerived extends KnownIntermediate string kmd; }; +["preserve-slice"] +exception KnownPreserved extends Base +{ + string kp; +}; + +exception KnownPreservedDerived extends KnownPreserved +{ + string kpd; +}; + +["preserve-slice"] +class BaseClass +{ + string bc; +}; + +["format:sliced"] +interface Relay +{ + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; +}; + +["ami", "format:sliced"] interface TestIntf { void baseAsBase() throws Base; @@ -50,6 +78,20 @@ interface TestIntf void unknownMostDerived1AsKnownIntermediate() throws KnownIntermediate; void unknownMostDerived2AsBase() throws Base; + ["format:compact"] void unknownMostDerived2AsBaseCompact() throws Base; + + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayKnownPreservedAsBase(Relay* r) throws Base; + void relayKnownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayUnknownPreservedAsBase(Relay* r) throws Base; + void relayUnknownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + void shutdown(); }; diff --git a/cs/test/Ice/slicing/exceptions/TestAMD.ice b/cs/test/Ice/slicing/exceptions/TestAMD.ice index 727c76699ca..9d5e2422550 100644 --- a/cs/test/Ice/slicing/exceptions/TestAMD.ice +++ b/cs/test/Ice/slicing/exceptions/TestAMD.ice @@ -32,7 +32,35 @@ exception KnownMostDerived extends KnownIntermediate string kmd; }; -["amd"] interface TestIntf +["preserve-slice"] +exception KnownPreserved extends Base +{ + string kp; +}; + +exception KnownPreservedDerived extends KnownPreserved +{ + string kpd; +}; + +["preserve-slice"] +class BaseClass +{ + string bc; +}; + +["format:sliced"] +interface Relay +{ + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; +}; + +["ami", "amd", "format:sliced"] +interface TestIntf { void baseAsBase() throws Base; void unknownDerivedAsBase() throws Base; @@ -50,6 +78,20 @@ exception KnownMostDerived extends KnownIntermediate void unknownMostDerived1AsKnownIntermediate() throws KnownIntermediate; void unknownMostDerived2AsBase() throws Base; + ["format:compact"] void unknownMostDerived2AsBaseCompact() throws Base; + + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayKnownPreservedAsBase(Relay* r) throws Base; + void relayKnownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayUnknownPreservedAsBase(Relay* r) throws Base; + void relayUnknownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + void shutdown(); }; diff --git a/cs/test/Ice/slicing/exceptions/TestAMDI.cs b/cs/test/Ice/slicing/exceptions/TestAMDI.cs index b0b270e8ba7..34d77634e91 100644 --- a/cs/test/Ice/slicing/exceptions/TestAMDI.cs +++ b/cs/test/Ice/slicing/exceptions/TestAMDI.cs @@ -12,23 +12,27 @@ using Test; public sealed class TestI : TestIntfDisp_ { - public TestI() + private static void test(bool b) { + if(!b) + { + throw new System.Exception(); + } } - + public override void shutdown_async(AMD_TestIntf_shutdown cb, Ice.Current current) { current.adapter.getCommunicator().shutdown(); cb.ice_response(); } - + public override void baseAsBase_async(AMD_TestIntf_baseAsBase cb, Ice.Current current) { Base b = new Base(); b.b = "Base.b"; cb.ice_exception(b); } - + public override void unknownDerivedAsBase_async(AMD_TestIntf_unknownDerivedAsBase cb, Ice.Current current) { UnknownDerived d = new UnknownDerived(); @@ -36,7 +40,7 @@ public sealed class TestI : TestIntfDisp_ d.ud = "UnknownDerived.ud"; cb.ice_exception(d); } - + public override void knownDerivedAsBase_async(AMD_TestIntf_knownDerivedAsBase cb, Ice.Current current) { KnownDerived d = new KnownDerived(); @@ -44,7 +48,7 @@ public sealed class TestI : TestIntfDisp_ d.kd = "KnownDerived.kd"; cb.ice_exception(d); } - + public override void knownDerivedAsKnownDerived_async(AMD_TestIntf_knownDerivedAsKnownDerived cb, Ice.Current current) { @@ -53,7 +57,7 @@ public sealed class TestI : TestIntfDisp_ d.kd = "KnownDerived.kd"; cb.ice_exception(d); } - + public override void unknownIntermediateAsBase_async(AMD_TestIntf_unknownIntermediateAsBase cb, Ice.Current current) { UnknownIntermediate ui = new UnknownIntermediate(); @@ -61,7 +65,7 @@ public sealed class TestI : TestIntfDisp_ ui.ui = "UnknownIntermediate.ui"; cb.ice_exception(ui); } - + public override void knownIntermediateAsBase_async(AMD_TestIntf_knownIntermediateAsBase cb, Ice.Current current) { KnownIntermediate ki = new KnownIntermediate(); @@ -69,7 +73,7 @@ public sealed class TestI : TestIntfDisp_ ki.ki = "KnownIntermediate.ki"; cb.ice_exception(ki); } - + public override void knownMostDerivedAsBase_async(AMD_TestIntf_knownMostDerivedAsBase cb, Ice.Current current) { KnownMostDerived kmd = new KnownMostDerived(); @@ -78,16 +82,16 @@ public sealed class TestI : TestIntfDisp_ kmd.kmd = "KnownMostDerived.kmd"; cb.ice_exception(kmd); } - + public override void knownIntermediateAsKnownIntermediate_async( - AMD_TestIntf_knownIntermediateAsKnownIntermediate cb, Ice.Current current) + AMD_TestIntf_knownIntermediateAsKnownIntermediate cb, Ice.Current current) { KnownIntermediate ki = new KnownIntermediate(); ki.b = "KnownIntermediate.b"; ki.ki = "KnownIntermediate.ki"; cb.ice_exception(ki); } - + public override void knownMostDerivedAsKnownIntermediate_async(AMD_TestIntf_knownMostDerivedAsKnownIntermediate cb, Ice.Current current) { @@ -97,7 +101,7 @@ public sealed class TestI : TestIntfDisp_ kmd.kmd = "KnownMostDerived.kmd"; cb.ice_exception(kmd); } - + public override void knownMostDerivedAsKnownMostDerived_async(AMD_TestIntf_knownMostDerivedAsKnownMostDerived cb, Ice.Current current) { @@ -107,7 +111,7 @@ public sealed class TestI : TestIntfDisp_ kmd.kmd = "KnownMostDerived.kmd"; cb.ice_exception(kmd); } - + public override void unknownMostDerived1AsBase_async(AMD_TestIntf_unknownMostDerived1AsBase cb, Ice.Current current) { UnknownMostDerived1 umd1 = new UnknownMostDerived1(); @@ -116,9 +120,9 @@ public sealed class TestI : TestIntfDisp_ umd1.umd1 = "UnknownMostDerived1.umd1"; cb.ice_exception(umd1); } - + public override void unknownMostDerived1AsKnownIntermediate_async( - AMD_TestIntf_unknownMostDerived1AsKnownIntermediate cb, Ice.Current current) + AMD_TestIntf_unknownMostDerived1AsKnownIntermediate cb, Ice.Current current) { UnknownMostDerived1 umd1 = new UnknownMostDerived1(); umd1.b = "UnknownMostDerived1.b"; @@ -126,7 +130,7 @@ public sealed class TestI : TestIntfDisp_ umd1.umd1 = "UnknownMostDerived1.umd1"; cb.ice_exception(umd1); } - + public override void unknownMostDerived2AsBase_async(AMD_TestIntf_unknownMostDerived2AsBase cb, Ice.Current current) { UnknownMostDerived2 umd2 = new UnknownMostDerived2(); @@ -135,4 +139,128 @@ public sealed class TestI : TestIntfDisp_ umd2.umd2 = "UnknownMostDerived2.umd2"; cb.ice_exception(umd2); } + + public override void unknownMostDerived2AsBaseCompact_async(AMD_TestIntf_unknownMostDerived2AsBaseCompact cb, + Ice.Current current) + { + UnknownMostDerived2 umd2 = new UnknownMostDerived2(); + umd2.b = "UnknownMostDerived2.b"; + umd2.ui = "UnknownMostDerived2.ui"; + umd2.umd2 = "UnknownMostDerived2.umd2"; + cb.ice_exception(umd2); + } + + public override void knownPreservedAsBase_async(AMD_TestIntf_knownPreservedAsBase cb, Ice.Current current) + { + KnownPreservedDerived ex = new KnownPreservedDerived(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + cb.ice_exception(ex); + } + + public override void knownPreservedAsKnownPreserved_async(AMD_TestIntf_knownPreservedAsKnownPreserved cb, + Ice.Current current) + { + KnownPreservedDerived ex = new KnownPreservedDerived(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + cb.ice_exception(ex); + } + + public override void relayKnownPreservedAsBase_async(AMD_TestIntf_relayKnownPreservedAsBase cb, + RelayPrx r, Ice.Current current) + { + try + { + r.knownPreservedAsBase(); + test(false); + } + catch(Ice.UserException ex) + { + cb.ice_exception(ex); + } + catch(Ice.LocalException ex) + { + cb.ice_exception(ex); + } + } + + public override void relayKnownPreservedAsKnownPreserved_async(AMD_TestIntf_relayKnownPreservedAsKnownPreserved cb, + RelayPrx r, Ice.Current current) + { + try + { + r.knownPreservedAsKnownPreserved(); + test(false); + } + catch(Ice.UserException ex) + { + cb.ice_exception(ex); + } + catch(Ice.LocalException ex) + { + cb.ice_exception(ex); + } + } + + public override void unknownPreservedAsBase_async(AMD_TestIntf_unknownPreservedAsBase cb, Ice.Current current) + { + SPreserved2 ex = new SPreserved2(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + ex.p1 = new SPreservedClass("bc", "spc"); + ex.p2 = ex.p1; + cb.ice_exception(ex); + } + + public override void unknownPreservedAsKnownPreserved_async(AMD_TestIntf_unknownPreservedAsKnownPreserved cb, + Ice.Current current) + { + SPreserved2 ex = new SPreserved2(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + ex.p1 = new SPreservedClass("bc", "spc"); + ex.p2 = ex.p1; + cb.ice_exception(ex); + } + + public override void relayUnknownPreservedAsBase_async(AMD_TestIntf_relayUnknownPreservedAsBase cb, + RelayPrx r, Ice.Current current) + { + try + { + r.unknownPreservedAsBase(); + test(false); + } + catch(Ice.UserException ex) + { + cb.ice_exception(ex); + } + catch(Ice.LocalException ex) + { + cb.ice_exception(ex); + } + } + + public override void relayUnknownPreservedAsKnownPreserved_async( + AMD_TestIntf_relayUnknownPreservedAsKnownPreserved cb, RelayPrx r, Ice.Current current) + { + try + { + r.unknownPreservedAsKnownPreserved(); + test(false); + } + catch(Ice.UserException ex) + { + cb.ice_exception(ex); + } + catch(Ice.LocalException ex) + { + cb.ice_exception(ex); + } + } } diff --git a/cs/test/Ice/slicing/exceptions/TestI.cs b/cs/test/Ice/slicing/exceptions/TestI.cs index 4aa808b0043..a7be9f3d6c1 100644 --- a/cs/test/Ice/slicing/exceptions/TestI.cs +++ b/cs/test/Ice/slicing/exceptions/TestI.cs @@ -11,22 +11,26 @@ using Test; public sealed class TestI : TestIntfDisp_ { - public TestI() + private static void test(bool b) { + if(!b) + { + throw new System.Exception(); + } } - + public override void shutdown(Ice.Current current) { current.adapter.getCommunicator().shutdown(); } - + public override void baseAsBase(Ice.Current current) { Base b = new Base(); b.b = "Base.b"; throw b; } - + public override void unknownDerivedAsBase(Ice.Current current) { UnknownDerived d = new UnknownDerived(); @@ -34,7 +38,7 @@ public sealed class TestI : TestIntfDisp_ d.ud = "UnknownDerived.ud"; throw d; } - + public override void knownDerivedAsBase(Ice.Current current) { KnownDerived d = new KnownDerived(); @@ -42,7 +46,7 @@ public sealed class TestI : TestIntfDisp_ d.kd = "KnownDerived.kd"; throw d; } - + public override void knownDerivedAsKnownDerived(Ice.Current current) { KnownDerived d = new KnownDerived(); @@ -50,7 +54,7 @@ public sealed class TestI : TestIntfDisp_ d.kd = "KnownDerived.kd"; throw d; } - + public override void unknownIntermediateAsBase(Ice.Current current) { UnknownIntermediate ui = new UnknownIntermediate(); @@ -58,7 +62,7 @@ public sealed class TestI : TestIntfDisp_ ui.ui = "UnknownIntermediate.ui"; throw ui; } - + public override void knownIntermediateAsBase(Ice.Current current) { KnownIntermediate ki = new KnownIntermediate(); @@ -66,7 +70,7 @@ public sealed class TestI : TestIntfDisp_ ki.ki = "KnownIntermediate.ki"; throw ki; } - + public override void knownMostDerivedAsBase(Ice.Current current) { KnownMostDerived kmd = new KnownMostDerived(); @@ -75,7 +79,7 @@ public sealed class TestI : TestIntfDisp_ kmd.kmd = "KnownMostDerived.kmd"; throw kmd; } - + public override void knownIntermediateAsKnownIntermediate(Ice.Current current) { KnownIntermediate ki = new KnownIntermediate(); @@ -83,7 +87,7 @@ public sealed class TestI : TestIntfDisp_ ki.ki = "KnownIntermediate.ki"; throw ki; } - + public override void knownMostDerivedAsKnownIntermediate(Ice.Current current) { KnownMostDerived kmd = new KnownMostDerived(); @@ -92,7 +96,7 @@ public sealed class TestI : TestIntfDisp_ kmd.kmd = "KnownMostDerived.kmd"; throw kmd; } - + public override void knownMostDerivedAsKnownMostDerived(Ice.Current current) { KnownMostDerived kmd = new KnownMostDerived(); @@ -101,7 +105,7 @@ public sealed class TestI : TestIntfDisp_ kmd.kmd = "KnownMostDerived.kmd"; throw kmd; } - + public override void unknownMostDerived1AsBase(Ice.Current current) { UnknownMostDerived1 umd1 = new UnknownMostDerived1(); @@ -110,7 +114,7 @@ public sealed class TestI : TestIntfDisp_ umd1.umd1 = "UnknownMostDerived1.umd1"; throw umd1; } - + public override void unknownMostDerived1AsKnownIntermediate(Ice.Current current) { UnknownMostDerived1 umd1 = new UnknownMostDerived1(); @@ -119,7 +123,7 @@ public sealed class TestI : TestIntfDisp_ umd1.umd1 = "UnknownMostDerived1.umd1"; throw umd1; } - + public override void unknownMostDerived2AsBase(Ice.Current current) { UnknownMostDerived2 umd2 = new UnknownMostDerived2(); @@ -128,4 +132,77 @@ public sealed class TestI : TestIntfDisp_ umd2.umd2 = "UnknownMostDerived2.umd2"; throw umd2; } + + public override void unknownMostDerived2AsBaseCompact(Ice.Current current) + { + UnknownMostDerived2 umd2 = new UnknownMostDerived2(); + umd2.b = "UnknownMostDerived2.b"; + umd2.ui = "UnknownMostDerived2.ui"; + umd2.umd2 = "UnknownMostDerived2.umd2"; + throw umd2; + } + + public override void knownPreservedAsBase(Ice.Current current) + { + KnownPreservedDerived ex = new KnownPreservedDerived(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + throw ex; + } + + public override void knownPreservedAsKnownPreserved(Ice.Current current) + { + KnownPreservedDerived ex = new KnownPreservedDerived(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + throw ex; + } + + public override void relayKnownPreservedAsBase(RelayPrx r, Ice.Current current) + { + r.knownPreservedAsBase(); + test(false); + } + + public override void relayKnownPreservedAsKnownPreserved(RelayPrx r, Ice.Current current) + { + r.knownPreservedAsKnownPreserved(); + test(false); + } + + public override void unknownPreservedAsBase(Ice.Current current) + { + SPreserved2 ex = new SPreserved2(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + ex.p1 = new SPreservedClass("bc", "spc"); + ex.p2 = ex.p1; + throw ex; + } + + public override void unknownPreservedAsKnownPreserved(Ice.Current current) + { + SPreserved2 ex = new SPreserved2(); + ex.b = "base"; + ex.kp = "preserved"; + ex.kpd = "derived"; + ex.p1 = new SPreservedClass("bc", "spc"); + ex.p2 = ex.p1; + throw ex; + } + + public override void relayUnknownPreservedAsBase(RelayPrx r, Ice.Current current) + { + r.unknownPreservedAsBase(); + test(false); + } + + public override void relayUnknownPreservedAsKnownPreserved(RelayPrx r, Ice.Current current) + { + r.unknownPreservedAsKnownPreserved(); + test(false); + } } diff --git a/cs/test/Ice/slicing/exceptions/run.py b/cs/test/Ice/slicing/exceptions/run.py index b4a4a066c90..1e7e887e28a 100755 --- a/cs/test/Ice/slicing/exceptions/run.py +++ b/cs/test/Ice/slicing/exceptions/run.py @@ -20,7 +20,11 @@ if len(path) == 0: sys.path.append(os.path.join(path[0], "scripts")) import TestUtil -print("tests with regular server.") +print("Running test with sliced format.") TestUtil.clientServerTest() -print("tests with AMD server.") +print("Running test with 1.0 encoding.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0", additionalServerOptions="--Ice.Default.EncodingVersion=1.0") +print("Running test with sliced format and AMD server.") TestUtil.clientServerTest(server="serveramd") +print("Running test with 1.0 encoding and AMD server.") +TestUtil.clientServerTest(server="serveramd", additionalClientOptions="--Ice.Default.EncodingVersion=1.0", additionalServerOptions="--Ice.Default.EncodingVersion=1.0") diff --git a/cs/test/Ice/slicing/objects/AllTests.cs b/cs/test/Ice/slicing/objects/AllTests.cs index 4e7b1162dc6..721a0a11196 100644 --- a/cs/test/Ice/slicing/objects/AllTests.cs +++ b/cs/test/Ice/slicing/objects/AllTests.cs @@ -11,10 +11,10 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; -using Test;
-
-#if SILVERLIGHT
-using System.Windows.Controls;
+using Test; + +#if SILVERLIGHT +using System.Windows.Controls; #endif public class AllTests : TestCommon.TestApp @@ -102,17 +102,29 @@ public class AllTests : TestCommon.TestApp callback.called(); } - public void response_SUnknownAsObject(Ice.Object o) + public void response_SUnknownAsObject1(Ice.Object o) { AllTests.test(false); } - public void exception_SUnknownAsObject(Ice.Exception exc) + public void exception_SUnknownAsObject1(Ice.Exception exc) { AllTests.test(exc.GetType().FullName.Equals("Ice.NoObjectFactoryException")); callback.called(); } + public void response_SUnknownAsObject2(Ice.Object o) + { + AllTests.test(o is Ice.UnknownSlicedObject); + AllTests.test((o as Ice.UnknownSlicedObject).getUnknownTypeId().Equals("::Test::SUnknown")); + callback.called(); + } + + public void exception_SUnknownAsObject2(Ice.Exception exc) + { + AllTests.test(false); + } + public void response_oneElementCycle(B b) { AllTests.test(b != null); @@ -281,7 +293,7 @@ public class AllTests : TestCommon.TestApp callback.called(); } - public void response_sequenceTest(SS ss) + public void response_sequenceTest(SS3 ss) { rss = ss; callback.called(); @@ -380,6 +392,62 @@ public class AllTests : TestCommon.TestApp callback.called(); } + public void response_exchangePBase1(PBase r) + { + PDerived p2 = (PDerived)r; + AllTests.test(p2.pi == 3); + AllTests.test(p2.ps.Equals("preserved")); + AllTests.test(p2.pb == p2); + callback.called(); + } + + public void response_exchangePBase2(PBase r) + { + AllTests.test(!(r is PCUnknown)); + AllTests.test(r.pi == 3); + callback.called(); + } + + public void response_exchangePBase3(PBase r) + { + AllTests.test(!(r is PCDerived)); + AllTests.test(r.pi == 3); + callback.called(); + } + + public void response_exchangePBase4(PBase r) + { + PCDerived p2 = r as PCDerived; + AllTests.test(p2.pi == 3); + AllTests.test(p2.pbs[0] == p2); + callback.called(); + } + + public void response_exchangePBase5(PBase r) + { + AllTests.test(!(r is PCDerived3)); + AllTests.test(r is Preserved); + AllTests.test(r.pi == 3); + callback.called(); + } + + public void response_exchangePBase6(PBase r) + { + PCDerived3 p3 = r as PCDerived3; + AllTests.test(p3.pi == 3); + for(int i = 0; i < 300; ++i) + { + PCDerived2 p2 = p3.pbs[i] as PCDerived2; + test(p2.pi == i); + test(p2.pbs.Length == 1); + test(p2.pbs[0] == null); + test(p2.pcd2 == i); + } + test(p3.pcd2 == p3.pi); + test(p3.pcd3 == p3.pbs[10]); + callback.called(); + } + public void response() { AllTests.test(false); @@ -396,32 +464,83 @@ public class AllTests : TestCommon.TestApp } public B rb; - public SS rss; + public SS3 rss; public Dictionary<int, B> rbdict; public Dictionary<int, B> obdict; private Callback callback = new Callback(); } -#if SILVERLIGHT
- public override Ice.InitializationData initData()
- {
- Ice.InitializationData initData = new Ice.InitializationData();
- initData.properties = Ice.Util.createProperties();
- initData.properties.setProperty("Ice.FactoryAssemblies", "objects,version=1.0.0.0");
- return initData;
- }
-
- override
- public void run(Ice.Communicator communicator)
+ private class PNodeI : PNode + { + public PNodeI() + { + ++counter; + } + + internal static int counter = 0; + } + + private class NodeFactoryI : Ice.ObjectFactory + { + public Ice.Object create(string id) + { + if(id.Equals(PNode.ice_staticId())) + { + return new PNodeI(); + } + return null; + } + + public void destroy() + { + } + } + + private class PreservedI : Preserved + { + public PreservedI() + { + ++counter; + } + + internal static int counter = 0; + } + + private class PreservedFactoryI : Ice.ObjectFactory + { + public Ice.Object create(string id) + { + if(id.Equals(Preserved.ice_staticId())) + { + return new PreservedI(); + } + return null; + } + + public void destroy() + { + } + } + +#if SILVERLIGHT + public override Ice.InitializationData initData() + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.FactoryAssemblies", "objects,version=1.0.0.0"); + return initData; + } + + override + public void run(Ice.Communicator communicator) #else public static TestIntfPrx allTests(Ice.Communicator communicator, bool collocated) #endif { Write("testing stringToProxy... "); Flush(); - string r = "Test:default -p 12010 -t 2000"; - Ice.ObjectPrx basePrx = communicator.stringToProxy(r); + Ice.ObjectPrx basePrx = communicator.stringToProxy("Test:default -p 12010 -t 2000"); test(basePrx != null); WriteLine("ok"); @@ -573,11 +692,15 @@ public class AllTests : TestCommon.TestApp { try { - testPrx.SUnknownAsObject(); - test(false); + Ice.Object o = testPrx.SUnknownAsObject(); + test(!testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)); + test(o is Ice.UnknownSlicedObject); + test((o as Ice.UnknownSlicedObject).getUnknownTypeId().Equals("::Test::SUnknown")); + testPrx.checkSUnknown(o); } catch(Ice.NoObjectFactoryException) { + test(testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)); } catch(Exception) { @@ -592,8 +715,16 @@ public class AllTests : TestCommon.TestApp try { AsyncCallback cb = new AsyncCallback(); - testPrx.begin_SUnknownAsObject().whenCompleted( - cb.response_SUnknownAsObject, cb.exception_SUnknownAsObject); + if(testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)) + { + testPrx.begin_SUnknownAsObject().whenCompleted( + cb.response_SUnknownAsObject1, cb.exception_SUnknownAsObject1); + } + else + { + testPrx.begin_SUnknownAsObject().whenCompleted( + cb.response_SUnknownAsObject2, cb.exception_SUnknownAsObject2); + } cb.check(); } catch(Exception) @@ -1323,7 +1454,7 @@ public class AllTests : TestCommon.TestApp { try { - SS ss; + SS3 ss; { B ss1b = new B(); ss1b.sb = "B.sb"; @@ -1411,7 +1542,7 @@ public class AllTests : TestCommon.TestApp Write("sequence slicing (AMI)... "); Flush(); { - SS ss; + SS3 ss; { B ss1b = new B(); ss1b.sb = "B.sb"; @@ -1766,10 +1897,327 @@ public class AllTests : TestCommon.TestApp } WriteLine("ok"); -#if SILVERLIGHT
+ Write("preserved classes... "); + Flush(); + + // + // Register a factory in order to substitute our own subclass of Preserved. This provides + // an easy way to determine how many unmarshaled instances currently exist. + // + // TODO: We have to install this now (even though it's not necessary yet), because otherwise + // the Ice run time will install its own internal factory for Preserved upon receiving the + // first instance. + // + communicator.addObjectFactory(new PreservedFactoryI(), Preserved.ice_staticId()); + + { + // + // Server knows the most-derived class PDerived. + // + PDerived pd = new PDerived(); + pd.pi = 3; + pd.ps = "preserved"; + pd.pb = pd; + + PBase r = testPrx.exchangePBase(pd); + PDerived p2 = r as PDerived; + test(p2.pi == 3); + test(p2.ps.Equals("preserved")); + test(p2.pb == p2); + } + + { + // + // Server only knows the base (non-preserved) type, so the object is sliced. + // + PCUnknown pu = new PCUnknown(); + pu.pi = 3; + pu.pu = "preserved"; + + PBase r = testPrx.exchangePBase(pu); + test(!(r is PCUnknown)); + test(r.pi == 3); + } + + { + // + // Server only knows the intermediate type Preserved. The object will be sliced to + // Preserved for the 1.0 encoding; otherwise it should be returned intact. + // + PCDerived pcd = new PCDerived(); + pcd.pi = 3; + pcd.pbs = new PBase[] { pcd }; + + PBase r = testPrx.exchangePBase(pcd); + if(testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)) + { + test(!(r is PCDerived)); + test(r.pi == 3); + } + else + { + PCDerived p2 = r as PCDerived; + test(p2.pi == 3); + test(p2.pbs[0] == p2); + } + } + + { + // + // Send an object that will have multiple preserved slices in the server. + // The object will be sliced to Preserved for the 1.0 encoding. + // + PCDerived3 pcd = new PCDerived3(); + pcd.pi = 3; + // + // Sending more than 254 objects exercises the encoding for object ids. + // + pcd.pbs = new PBase[300]; + int i; + for(i = 0; i < 300; ++i) + { + PCDerived2 p2 = new PCDerived2(); + p2.pi = i; + p2.pbs = new PBase[] { null }; // Nil reference. This slice should not have an indirection table. + p2.pcd2 = i; + pcd.pbs[i] = p2; + } + pcd.pcd2 = pcd.pi; + pcd.pcd3 = pcd.pbs[10]; + + PBase r = testPrx.exchangePBase(pcd); + if(testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)) + { + test(!(r is PCDerived3)); + test(r is Preserved); + test(r.pi == 3); + } + else + { + PCDerived3 p3 = r as PCDerived3; + test(p3.pi == 3); + for(i = 0; i < 300; ++i) + { + PCDerived2 p2 = p3.pbs[i] as PCDerived2; + test(p2.pi == i); + test(p2.pbs.Length == 1); + test(p2.pbs[0] == null); + test(p2.pcd2 == i); + } + test(p3.pcd2 == p3.pi); + test(p3.pcd3 == p3.pbs[10]); + } + } + + { + // + // Obtain an object with preserved slices and send it back to the server. + // The preserved slices should be excluded for the 1.0 encoding, otherwise + // they should be included. + // + Preserved p = testPrx.PBSUnknownAsPreserved(); + testPrx.checkPBSUnknown(p); + if(!testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)) + { + (testPrx.ice_encodingVersion(Ice.Util.Encoding_1_0) as TestIntfPrx).checkPBSUnknown(p); + } + } + + WriteLine("ok"); + + Write("preserved classes (AMI)... "); + Flush(); + { + // + // Server knows the most-derived class PDerived. + // + PDerived pd = new PDerived(); + pd.pi = 3; + pd.ps = "preserved"; + pd.pb = pd; + + AsyncCallback cb = new AsyncCallback(); + testPrx.begin_exchangePBase(pd).whenCompleted(cb.response_exchangePBase1, cb.exception); + cb.check(); + } + + { + // + // Server only knows the base (non-preserved) type, so the object is sliced. + // + PCUnknown pu = new PCUnknown(); + pu.pi = 3; + pu.pu = "preserved"; + + AsyncCallback cb = new AsyncCallback(); + testPrx.begin_exchangePBase(pu).whenCompleted(cb.response_exchangePBase2, cb.exception); + cb.check(); + } + + { + // + // Server only knows the intermediate type Preserved. The object will be sliced to + // Preserved for the 1.0 encoding; otherwise it should be returned intact. + // + PCDerived pcd = new PCDerived(); + pcd.pi = 3; + pcd.pbs = new PBase[] { pcd }; + + AsyncCallback cb = new AsyncCallback(); + if(testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)) + { + testPrx.begin_exchangePBase(pcd).whenCompleted(cb.response_exchangePBase3, cb.exception); + } + else + { + testPrx.begin_exchangePBase(pcd).whenCompleted(cb.response_exchangePBase4, cb.exception); + } + cb.check(); + } + + { + // + // Send an object that will have multiple preserved slices in the server. + // The object will be sliced to Preserved for the 1.0 encoding. + // + PCDerived3 pcd = new PCDerived3(); + pcd.pi = 3; + // + // Sending more than 254 objects exercises the encoding for object ids. + // + pcd.pbs = new PBase[300]; + int i; + for(i = 0; i < 300; ++i) + { + PCDerived2 p2 = new PCDerived2(); + p2.pi = i; + p2.pbs = new PBase[] { null }; // Nil reference. This slice should not have an indirection table. + p2.pcd2 = i; + pcd.pbs[i] = p2; + } + pcd.pcd2 = pcd.pi; + pcd.pcd3 = pcd.pbs[10]; + + AsyncCallback cb = new AsyncCallback(); + if(testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)) + { + testPrx.begin_exchangePBase(pcd).whenCompleted(cb.response_exchangePBase5, cb.exception); + } + else + { + testPrx.begin_exchangePBase(pcd).whenCompleted(cb.response_exchangePBase6, cb.exception); + } + cb.check(); + } + + { + // + // Obtain an object with preserved slices and send it back to the server. + // The preserved slices should be excluded for the 1.0 encoding, otherwise + // they should be included. + // + Preserved p = testPrx.PBSUnknownAsPreserved(); + testPrx.checkPBSUnknown(p); + if(!testPrx.ice_getEncodingVersion().Equals(Ice.Util.Encoding_1_0)) + { + (testPrx.ice_encodingVersion(Ice.Util.Encoding_1_0) as TestIntfPrx).checkPBSUnknown(p); + } + } + + WriteLine("ok"); + + Write("garbage collection for preserved classes... "); + Flush(); + { + // + // Register a factory in order to substitute our own subclass of PNode. This provides + // an easy way to determine how many unmarshaled instances currently exist. + // + communicator.addObjectFactory(new NodeFactoryI(), PNode.ice_staticId()); + + // + // Relay a graph through the server. + // + { + PNode c = new PNode(); + c.next = new PNode(); + c.next.next = new PNode(); + c.next.next.next = c; + + test(PNodeI.counter == 0); + PNode n = testPrx.exchangePNode(c); + + test(PNodeI.counter == 3); + PNodeI.counter = 0; + n.next = null; + } + + // + // Obtain a preserved object from the server where the most-derived + // type is unknown. The preserved slice refers to a graph of PNode + // objects. + // + { + test(PNodeI.counter == 0); + Preserved p = testPrx.PBSUnknownAsPreservedWithGraph(); + testPrx.checkPBSUnknownWithGraph(p); + test(PNodeI.counter == 3); + PNodeI.counter = 0; + } + + // + // Obtain a preserved object from the server where the most-derived + // type is unknown. A data member in the preserved slice refers to the + // outer object, so the chain of references looks like this: + // + // outer.slicedData.outer + // + { + PreservedI.counter = 0; + Preserved p = testPrx.PBSUnknown2AsPreservedWithGraph(); + testPrx.checkPBSUnknown2WithGraph(p); + test(PreservedI.counter == 1); + PreservedI.counter = 0; + } + + // + // Throw a preserved exception where the most-derived type is unknown. + // The preserved exception slice contains a class data member. This + // object is also preserved, and its most-derived type is also unknown. + // The preserved slice of the object contains a class data member that + // refers to itself. + // + // The chain of references looks like this: + // + // ex.slicedData.obj.slicedData.obj + // + try + { + test(PreservedI.counter == 0); + + try + { + testPrx.throwPreservedException(); + } + catch(PreservedException) + { + test(PreservedI.counter == 1); + } + + PreservedI.counter = 0; + } + catch(Exception) + { + test(false); + } + } + + WriteLine("ok"); + +#if SILVERLIGHT testPrx.shutdown(); #else return testPrx; -#endif
+#endif } } diff --git a/cs/test/Ice/slicing/objects/ClientPrivate.ice b/cs/test/Ice/slicing/objects/ClientPrivate.ice index b4e22a0d495..f8708d424c3 100644 --- a/cs/test/Ice/slicing/objects/ClientPrivate.ice +++ b/cs/test/Ice/slicing/objects/ClientPrivate.ice @@ -20,4 +20,25 @@ class D3 extends B B pd3; }; +["preserve-slice"] +class PCUnknown extends PBase +{ + string pu; +}; + +class PCDerived extends PDerived +{ + PBaseSeq pbs; +}; + +class PCDerived2 extends PCDerived +{ + int pcd2; +}; + +class PCDerived3 extends PCDerived2 +{ + Object pcd3; +}; + }; diff --git a/cs/test/Ice/slicing/objects/ServerPrivate.ice b/cs/test/Ice/slicing/objects/ServerPrivate.ice index 7a1da786d48..3bc27fc8108 100644 --- a/cs/test/Ice/slicing/objects/ServerPrivate.ice +++ b/cs/test/Ice/slicing/objects/ServerPrivate.ice @@ -42,4 +42,26 @@ exception UnknownDerivedException extends BaseException D2 pd2; }; +class MyClass +{ + int i; +}; + +class PSUnknown extends Preserved +{ + string psu; + PNode graph; + MyClass cl; +}; + +class PSUnknown2 extends Preserved +{ + PBase pb; +}; + +exception PSUnknownException extends PreservedException +{ + PSUnknown2 p; +}; + }; diff --git a/cs/test/Ice/slicing/objects/ServerPrivateAMD.ice b/cs/test/Ice/slicing/objects/ServerPrivateAMD.ice index 41a00ae682a..515ddbaf322 100644 --- a/cs/test/Ice/slicing/objects/ServerPrivateAMD.ice +++ b/cs/test/Ice/slicing/objects/ServerPrivateAMD.ice @@ -42,4 +42,26 @@ exception UnknownDerivedException extends BaseException D2 pd2; }; +class MyClass +{ + int i; +}; + +class PSUnknown extends Preserved +{ + string psu; + PNode graph; + MyClass cl; +}; + +class PSUnknown2 extends Preserved +{ + PBase pb; +}; + +exception PSUnknownException extends PreservedException +{ + PSUnknown2 p; +}; + }; diff --git a/cs/test/Ice/slicing/objects/Test.ice b/cs/test/Ice/slicing/objects/Test.ice index 640793d1c4d..804be23a3d4 100644 --- a/cs/test/Ice/slicing/objects/Test.ice +++ b/cs/test/Ice/slicing/objects/Test.ice @@ -46,7 +46,7 @@ class SS2 BSeq s; }; -struct SS +struct SS3 { SS1 c1; SS2 c2; @@ -68,6 +68,36 @@ exception DerivedException extends BaseException class Forward; /* Forward-declared class defined in another compilation unit */ +class PBase +{ + int pi; +}; + +sequence<PBase> PBaseSeq; + +["preserve-slice"] +class Preserved extends PBase +{ + string ps; +}; + +class PDerived extends Preserved +{ + PBase pb; +}; + +["preserve-slice"] +class PNode +{ + PNode next; +}; + +["preserve-slice"] +exception PreservedException +{ +}; + +["ami", "format:sliced"] interface TestIntf { Object SBaseAsObject(); @@ -77,7 +107,10 @@ interface TestIntf SBase SBSUnknownDerivedAsSBase(); + ["format:compact"] SBase SBSUnknownDerivedAsSBaseCompact(); + Object SUnknownAsObject(); + void checkSUnknown(Object o); B oneElementCycle(); B twoElementCycle(); @@ -94,14 +127,28 @@ interface TestIntf B returnTest2(out B p2, out B p1); B returnTest3(B p1, B p2); - SS sequenceTest(SS1 p1, SS2 p2); + SS3 sequenceTest(SS1 p1, SS2 p2); BDict dictionaryTest(BDict bin, out BDict bout); + PBase exchangePBase(PBase pb); + + Preserved PBSUnknownAsPreserved(); + void checkPBSUnknown(Preserved p); + + ["amd"] Preserved PBSUnknownAsPreservedWithGraph(); + void checkPBSUnknownWithGraph(Preserved p); + + ["amd"] Preserved PBSUnknown2AsPreservedWithGraph(); + void checkPBSUnknown2WithGraph(Preserved p); + + PNode exchangePNode(PNode pn); + void throwBaseAsBase() throws BaseException; void throwDerivedAsBase() throws BaseException; void throwDerivedAsDerived() throws DerivedException; void throwUnknownDerivedAsBase() throws BaseException; + ["amd"] void throwPreservedException() throws PreservedException; void useForward(out Forward f); /* Use of forward-declared class to verify that code is generated correctly. */ @@ -109,3 +156,4 @@ interface TestIntf }; }; + diff --git a/cs/test/Ice/slicing/objects/TestAMD.ice b/cs/test/Ice/slicing/objects/TestAMD.ice index 74bfd888378..cf095cac432 100644 --- a/cs/test/Ice/slicing/objects/TestAMD.ice +++ b/cs/test/Ice/slicing/objects/TestAMD.ice @@ -46,7 +46,7 @@ class SS2 BSeq s; }; -struct SS +struct SS3 { SS1 c1; SS2 c2; @@ -66,9 +66,39 @@ exception DerivedException extends BaseException D1 pd1; }; -class Forward; /* Forward-declared class defined in another compilation unit */ +class Forward; // Forward-declared class defined in another compilation unit -["amd"] interface TestIntf +class PBase +{ + int pi; +}; + +sequence<PBase> PBaseSeq; + +["preserve-slice"] +class Preserved extends PBase +{ + string ps; +}; + +class PDerived extends Preserved +{ + PBase pb; +}; + +["preserve-slice"] +class PNode +{ + PNode next; +}; + +["preserve-slice"] +exception PreservedException +{ +}; + +["ami", "amd", "format:sliced"] +interface TestIntf { Object SBaseAsObject(); SBase SBaseAsSBase(); @@ -77,7 +107,10 @@ class Forward; /* Forward-declared class defined in another compilation SBase SBSUnknownDerivedAsSBase(); + ["format:compact"] SBase SBSUnknownDerivedAsSBaseCompact(); + Object SUnknownAsObject(); + void checkSUnknown(Object o); B oneElementCycle(); B twoElementCycle(); @@ -94,14 +127,28 @@ class Forward; /* Forward-declared class defined in another compilation B returnTest2(out B p2, out B p1); B returnTest3(B p1, B p2); - SS sequenceTest(SS1 p1, SS2 p2); + SS3 sequenceTest(SS1 p1, SS2 p2); BDict dictionaryTest(BDict bin, out BDict bout); + PBase exchangePBase(PBase pb); + + Preserved PBSUnknownAsPreserved(); + void checkPBSUnknown(Preserved p); + + Preserved PBSUnknownAsPreservedWithGraph(); + void checkPBSUnknownWithGraph(Preserved p); + + Preserved PBSUnknown2AsPreservedWithGraph(); + void checkPBSUnknown2WithGraph(Preserved p); + + PNode exchangePNode(PNode pn); + void throwBaseAsBase() throws BaseException; void throwDerivedAsBase() throws BaseException; void throwDerivedAsDerived() throws DerivedException; void throwUnknownDerivedAsBase() throws BaseException; + void throwPreservedException() throws PreservedException; void useForward(out Forward f); /* Use of forward-declared class to verify that code is generated correctly. */ diff --git a/cs/test/Ice/slicing/objects/TestAMDI.cs b/cs/test/Ice/slicing/objects/TestAMDI.cs index 4922bac1533..114327a532c 100644 --- a/cs/test/Ice/slicing/objects/TestAMDI.cs +++ b/cs/test/Ice/slicing/objects/TestAMDI.cs @@ -13,30 +13,34 @@ using Test; public sealed class TestI : TestIntfDisp_ { - public TestI() + private static void test(bool b) { + if(!b) + { + throw new System.Exception(); + } } - + public override void shutdown_async(AMD_TestIntf_shutdown cb, Ice.Current current) { current.adapter.getCommunicator().shutdown(); cb.ice_response(); } - + public override void SBaseAsObject_async(AMD_TestIntf_SBaseAsObject cb, Ice.Current current) { SBase sb = new SBase(); sb.sb = "SBase.sb"; cb.ice_response(sb); } - + public override void SBaseAsSBase_async(AMD_TestIntf_SBaseAsSBase cb, Ice.Current current) { SBase sb = new SBase(); sb.sb = "SBase.sb"; cb.ice_response(sb); } - + public override void SBSKnownDerivedAsSBase_async(AMD_TestIntf_SBSKnownDerivedAsSBase cb, Ice.Current current) { SBSKnownDerived sbskd = new SBSKnownDerived(); @@ -44,15 +48,16 @@ public sealed class TestI : TestIntfDisp_ sbskd.sbskd = "SBSKnownDerived.sbskd"; cb.ice_response(sbskd); } - - public override void SBSKnownDerivedAsSBSKnownDerived_async(AMD_TestIntf_SBSKnownDerivedAsSBSKnownDerived cb, Ice.Current current) + + public override void SBSKnownDerivedAsSBSKnownDerived_async(AMD_TestIntf_SBSKnownDerivedAsSBSKnownDerived cb, + Ice.Current current) { SBSKnownDerived sbskd = new SBSKnownDerived(); sbskd.sb = "SBSKnownDerived.sb"; sbskd.sbskd = "SBSKnownDerived.sbskd"; cb.ice_response(sbskd); } - + public override void SBSUnknownDerivedAsSBase_async(AMD_TestIntf_SBSUnknownDerivedAsSBase cb, Ice.Current current) { SBSUnknownDerived sbsud = new SBSUnknownDerived(); @@ -60,14 +65,37 @@ public sealed class TestI : TestIntfDisp_ sbsud.sbsud = "SBSUnknownDerived.sbsud"; cb.ice_response(sbsud); } - + + public override void SBSUnknownDerivedAsSBaseCompact_async(AMD_TestIntf_SBSUnknownDerivedAsSBaseCompact cb, + Ice.Current current) + { + SBSUnknownDerived sbsud = new SBSUnknownDerived(); + sbsud.sb = "SBSUnknownDerived.sb"; + sbsud.sbsud = "SBSUnknownDerived.sbsud"; + cb.ice_response(sbsud); + } + public override void SUnknownAsObject_async(AMD_TestIntf_SUnknownAsObject cb, Ice.Current current) { SUnknown su = new SUnknown(); su.su = "SUnknown.su"; cb.ice_response(su); } - + + public override void checkSUnknown_async(AMD_TestIntf_checkSUnknown cb, Ice.Object obj, Ice.Current current) + { + if(current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + test(!(obj is SUnknown)); + } + else + { + SUnknown su = obj as SUnknown; + test(su.su.Equals("SUnknown.su")); + } + cb.ice_response(); + } + public override void oneElementCycle_async(AMD_TestIntf_oneElementCycle cb, Ice.Current current) { B b = new B(); @@ -75,7 +103,7 @@ public sealed class TestI : TestIntfDisp_ b.pb = b; cb.ice_response(b); } - + public override void twoElementCycle_async(AMD_TestIntf_twoElementCycle cb, Ice.Current current) { B b1 = new B(); @@ -86,7 +114,7 @@ public sealed class TestI : TestIntfDisp_ b1.pb = b2; cb.ice_response(b1); } - + public override void D1AsB_async(AMD_TestIntf_D1AsB cb, Ice.Current current) { D1 d1 = new D1(); @@ -101,7 +129,7 @@ public sealed class TestI : TestIntfDisp_ d1.pd1 = d2; cb.ice_response(d1); } - + public override void D1AsD1_async(AMD_TestIntf_D1AsD1 cb, Ice.Current current) { D1 d1 = new D1(); @@ -116,7 +144,7 @@ public sealed class TestI : TestIntfDisp_ d1.pd1 = d2; cb.ice_response(d1); } - + public override void D2AsB_async(AMD_TestIntf_D2AsB cb, Ice.Current current) { D2 d2 = new D2(); @@ -131,7 +159,7 @@ public sealed class TestI : TestIntfDisp_ d2.pd2 = d1; cb.ice_response(d2); } - + public override void paramTest1_async(AMD_TestIntf_paramTest1 cb, Ice.Current current) { D1 d1 = new D1(); @@ -146,7 +174,7 @@ public sealed class TestI : TestIntfDisp_ d1.pd1 = d2; cb.ice_response(d1, d2); } - + public override void paramTest2_async(AMD_TestIntf_paramTest2 cb, Ice.Current current) { D1 d1 = new D1(); @@ -161,26 +189,26 @@ public sealed class TestI : TestIntfDisp_ d1.pd1 = d2; cb.ice_response(d2, d1); } - + public override void paramTest3_async(AMD_TestIntf_paramTest3 cb, Ice.Current current) { D2 d2 = new D2(); d2.sb = "D2.sb (p1 1)"; d2.pb = null; d2.sd2 = "D2.sd2 (p1 1)"; - + D1 d1 = new D1(); d1.sb = "D1.sb (p1 2)"; d1.pb = null; d1.sd1 = "D1.sd2 (p1 2)"; d1.pd1 = null; d2.pd2 = d1; - + D2 d4 = new D2(); d4.sb = "D2.sb (p2 1)"; d4.pb = null; d4.sd2 = "D2.sd2 (p2 1)"; - + D1 d3 = new D1(); d3.sb = "D1.sb (p2 2)"; d3.pb = null; @@ -189,7 +217,7 @@ public sealed class TestI : TestIntfDisp_ d4.pd2 = d3; cb.ice_response(d3, d2, d4); } - + public override void paramTest4_async(AMD_TestIntf_paramTest4 cb, Ice.Current current) { D4 d4 = new D4(); @@ -201,7 +229,7 @@ public sealed class TestI : TestIntfDisp_ d4.p2.sb = "B.sb (2)"; cb.ice_response(d4.p2, d4); } - + public override void returnTest1_async(AMD_TestIntf_returnTest1 cb, Ice.Current current) { D1 d1 = new D1(); @@ -216,7 +244,7 @@ public sealed class TestI : TestIntfDisp_ d1.pd1 = d2; cb.ice_response(d2, d2, d1); } - + public override void returnTest2_async(AMD_TestIntf_returnTest2 cb, Ice.Current current) { D1 d1 = new D1(); @@ -231,20 +259,20 @@ public sealed class TestI : TestIntfDisp_ d1.pd1 = d2; cb.ice_response(d1, d1, d2); } - + public override void returnTest3_async(AMD_TestIntf_returnTest3 cb, B p1, B p2, Ice.Current current) { cb.ice_response(p1); } - + public override void sequenceTest_async(AMD_TestIntf_sequenceTest cb, SS1 p1, SS2 p2, Ice.Current current) { - SS ss = new SS(); + SS3 ss = new SS3(); ss.c1 = p1; ss.c2 = p2; cb.ice_response(ss); } - + public override void dictionaryTest_async(AMD_TestIntf_dictionaryTest cb, Dictionary<int, B> bin, Ice.Current current) { @@ -273,7 +301,124 @@ public sealed class TestI : TestIntfDisp_ } cb.ice_response(r, bout); } - + + public override void exchangePBase_async(AMD_TestIntf_exchangePBase cb, PBase pb, Ice.Current current) + { + cb.ice_response(pb); + } + + public override void PBSUnknownAsPreserved_async(AMD_TestIntf_PBSUnknownAsPreserved cb, Ice.Current current) + { + PSUnknown r = new PSUnknown(); + r.pi = 5; + r.ps = "preserved"; + r.psu = "unknown"; + r.graph = null; + if(!current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + // + // 1.0 encoding doesn't support unmarshaling unknown classes even if referenced + // from unread slice. + // + r.cl = new MyClass(15); + } + cb.ice_response(r); + } + + public override void checkPBSUnknown_async(AMD_TestIntf_checkPBSUnknown cb, Preserved p, Ice.Current current) + { + if(current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + test(!(p is PSUnknown)); + test(p.pi == 5); + test(p.ps.Equals("preserved")); + } + else + { + PSUnknown pu = p as PSUnknown; + test(pu.pi == 5); + test(pu.ps.Equals("preserved")); + test(pu.psu.Equals("unknown")); + test(pu.graph == null); + test(pu.cl != null && pu.cl.i == 15); + } + cb.ice_response(); + } + + public override void PBSUnknownAsPreservedWithGraph_async(AMD_TestIntf_PBSUnknownAsPreservedWithGraph cb, + Ice.Current current) + { + PSUnknown r = new PSUnknown(); + r.pi = 5; + r.ps = "preserved"; + r.psu = "unknown"; + r.graph = new PNode(); + r.graph.next = new PNode(); + r.graph.next.next = new PNode(); + r.graph.next.next.next = r.graph; + cb.ice_response(r); + r.graph.next.next.next = null; // Break the cycle. + } + + public override void checkPBSUnknownWithGraph_async(AMD_TestIntf_checkPBSUnknownWithGraph cb, + Preserved p, Ice.Current current) + { + if(current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + test(!(p is PSUnknown)); + test(p.pi == 5); + test(p.ps.Equals("preserved")); + } + else + { + PSUnknown pu = p as PSUnknown; + test(pu.pi == 5); + test(pu.ps.Equals("preserved")); + test(pu.psu.Equals("unknown")); + test(pu.graph != pu.graph.next); + test(pu.graph.next != pu.graph.next.next); + test(pu.graph.next.next.next == pu.graph); + pu.graph.next.next.next = null; // Break the cycle. + } + cb.ice_response(); + } + + public override void PBSUnknown2AsPreservedWithGraph_async(AMD_TestIntf_PBSUnknown2AsPreservedWithGraph cb, + Ice.Current current) + { + PSUnknown2 r = new PSUnknown2(); + r.pi = 5; + r.ps = "preserved"; + r.pb = r; + cb.ice_response(r); + r.pb = null; // Break the cycle. + } + + public override void checkPBSUnknown2WithGraph_async(AMD_TestIntf_checkPBSUnknown2WithGraph cb, Preserved p, + Ice.Current current) + { + if(current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + test(!(p is PSUnknown2)); + test(p.pi == 5); + test(p.ps.Equals("preserved")); + } + else + { + PSUnknown2 pu = p as PSUnknown2; + test(pu.pi == 5); + test(pu.ps.Equals("preserved")); + test(pu.pb == pu); + pu.pb = null; // Break the cycle. + } + cb.ice_response(); + } + + public override void exchangePNode_async(AMD_TestIntf_exchangePNode cb, PNode pn, Ice.Current current) + { + cb.ice_response(pn); + } + public override void throwBaseAsBase_async(AMD_TestIntf_throwBaseAsBase cb, Ice.Current current) { BaseException be = new BaseException(); @@ -283,7 +428,7 @@ public sealed class TestI : TestIntfDisp_ be.pb.pb = be.pb; cb.ice_exception(be); } - + public override void throwDerivedAsBase_async(AMD_TestIntf_throwDerivedAsBase cb, Ice.Current current) { DerivedException de = new DerivedException(); @@ -299,7 +444,7 @@ public sealed class TestI : TestIntfDisp_ de.pd1.pd1 = de.pd1; cb.ice_exception(de); } - + public override void throwDerivedAsDerived_async(AMD_TestIntf_throwDerivedAsDerived cb, Ice.Current current) { DerivedException de = new DerivedException(); @@ -315,7 +460,7 @@ public sealed class TestI : TestIntfDisp_ de.pd1.pd1 = de.pd1; cb.ice_exception(de); } - + public override void throwUnknownDerivedAsBase_async(AMD_TestIntf_throwUnknownDerivedAsBase cb, Ice.Current current) { D2 d2 = new D2(); @@ -323,7 +468,7 @@ public sealed class TestI : TestIntfDisp_ d2.pb = d2; d2.sd2 = "sd2 d2"; d2.pd2 = d2; - + UnknownDerivedException ude = new UnknownDerivedException(); ude.sbe = "sbe"; ude.pb = d2; @@ -331,7 +476,18 @@ public sealed class TestI : TestIntfDisp_ ude.pd2 = d2; cb.ice_exception(ude); } - + + public override void throwPreservedException_async(AMD_TestIntf_throwPreservedException cb, Ice.Current current) + { + PSUnknownException ue = new PSUnknownException(); + ue.p = new PSUnknown2(); + ue.p.pi = 5; + ue.p.ps = "preserved"; + ue.p.pb = ue.p; + cb.ice_exception(ue); + ue.p.pb = null; // Break the cycle. + } + public override void useForward_async(AMD_TestIntf_useForward cb, Ice.Current current) { Forward f = new Forward(); diff --git a/cs/test/Ice/slicing/objects/TestI.cs b/cs/test/Ice/slicing/objects/TestI.cs index 21622f41492..695a348887a 100644 --- a/cs/test/Ice/slicing/objects/TestI.cs +++ b/cs/test/Ice/slicing/objects/TestI.cs @@ -13,29 +13,33 @@ using Test; public sealed class TestI : TestIntfDisp_ { - public TestI() + private static void test(bool b) { + if(!b) + { + throw new System.Exception(); + } } - + public override void shutdown(Ice.Current current) { current.adapter.getCommunicator().shutdown(); } - + public override Ice.Object SBaseAsObject(Ice.Current current) { SBase sb = new SBase(); sb.sb = "SBase.sb"; return sb; } - + public override SBase SBaseAsSBase(Ice.Current current) { SBase sb = new SBase(); sb.sb = "SBase.sb"; return sb; } - + public override SBase SBSKnownDerivedAsSBase(Ice.Current current) { SBSKnownDerived sbskd = new SBSKnownDerived(); @@ -43,7 +47,7 @@ public sealed class TestI : TestIntfDisp_ sbskd.sbskd = "SBSKnownDerived.sbskd"; return sbskd; } - + public override SBSKnownDerived SBSKnownDerivedAsSBSKnownDerived(Ice.Current current) { SBSKnownDerived sbskd = new SBSKnownDerived(); @@ -51,7 +55,7 @@ public sealed class TestI : TestIntfDisp_ sbskd.sbskd = "SBSKnownDerived.sbskd"; return sbskd; } - + public override SBase SBSUnknownDerivedAsSBase(Ice.Current current) { SBSUnknownDerived sbsud = new SBSUnknownDerived(); @@ -59,14 +63,35 @@ public sealed class TestI : TestIntfDisp_ sbsud.sbsud = "SBSUnknownDerived.sbsud"; return sbsud; } - + + public override SBase SBSUnknownDerivedAsSBaseCompact(Ice.Current current) + { + SBSUnknownDerived sbsud = new SBSUnknownDerived(); + sbsud.sb = "SBSUnknownDerived.sb"; + sbsud.sbsud = "SBSUnknownDerived.sbsud"; + return sbsud; + } + public override Ice.Object SUnknownAsObject(Ice.Current current) { SUnknown su = new SUnknown(); su.su = "SUnknown.su"; return su; } - + + public override void checkSUnknown(Ice.Object obj, Ice.Current current) + { + if(current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + test(!(obj is SUnknown)); + } + else + { + SUnknown su = obj as SUnknown; + test(su.su.Equals("SUnknown.su")); + } + } + public override B oneElementCycle(Ice.Current current) { B b = new B(); @@ -74,7 +99,7 @@ public sealed class TestI : TestIntfDisp_ b.pb = b; return b; } - + public override B twoElementCycle(Ice.Current current) { B b1 = new B(); @@ -85,7 +110,7 @@ public sealed class TestI : TestIntfDisp_ b1.pb = b2; return b1; } - + public override B D1AsB(Ice.Current current) { D1 d1 = new D1(); @@ -100,7 +125,7 @@ public sealed class TestI : TestIntfDisp_ d1.pd1 = d2; return d1; } - + public override D1 D1AsD1(Ice.Current current) { D1 d1 = new D1(); @@ -115,7 +140,7 @@ public sealed class TestI : TestIntfDisp_ d1.pd1 = d2; return d1; } - + public override B D2AsB(Ice.Current current) { D2 d2 = new D2(); @@ -130,7 +155,7 @@ public sealed class TestI : TestIntfDisp_ d2.pd2 = d1; return d2; } - + public override void paramTest1(out B p1, out B p2, Ice.Current current) { D1 d1 = new D1(); @@ -146,12 +171,12 @@ public sealed class TestI : TestIntfDisp_ p1 = d1; p2 = d2; } - + public override void paramTest2(out B p1, out B p2, Ice.Current current) { paramTest1(out p2, out p1, current); } - + public override B paramTest3(out B p1, out B p2, Ice.Current current) { D2 d2 = new D2(); @@ -159,30 +184,30 @@ public sealed class TestI : TestIntfDisp_ d2.pb = null; d2.sd2 = "D2.sd2 (p1 1)"; p1 = d2; - + D1 d1 = new D1(); d1.sb = "D1.sb (p1 2)"; d1.pb = null; d1.sd1 = "D1.sd2 (p1 2)"; d1.pd1 = null; d2.pd2 = d1; - + D2 d4 = new D2(); d4.sb = "D2.sb (p2 1)"; d4.pb = null; d4.sd2 = "D2.sd2 (p2 1)"; p2 = d4; - + D1 d3 = new D1(); d3.sb = "D1.sb (p2 2)"; d3.pb = null; d3.sd1 = "D1.sd2 (p2 2)"; d3.pd1 = null; d4.pd2 = d3; - + return d3; } - + public override B paramTest4(out B p1, Ice.Current current) { D4 d4 = new D4(); @@ -195,32 +220,32 @@ public sealed class TestI : TestIntfDisp_ p1 = d4; return d4.p2; } - + public override B returnTest1(out B p1, out B p2, Ice.Current current) { paramTest1(out p1, out p2, current); return p1; } - + public override B returnTest2(out B p1, out B p2, Ice.Current current) { paramTest1(out p2, out p1, current); return p1; } - + public override B returnTest3(B p1, B p2, Ice.Current current) { return p1; } - - public override SS sequenceTest(SS1 p1, SS2 p2, Ice.Current current) + + public override SS3 sequenceTest(SS1 p1, SS2 p2, Ice.Current current) { - SS ss = new SS(); + SS3 ss = new SS3(); ss.c1 = p1; ss.c2 = p2; return ss; } - + public override Dictionary<int, B> dictionaryTest(Dictionary<int, B> bin, out Dictionary<int, B> bout, Ice.Current current) { @@ -249,7 +274,119 @@ public sealed class TestI : TestIntfDisp_ } return r; } - + + public override PBase exchangePBase(PBase pb, Ice.Current current) + { + return pb; + } + + public override Preserved PBSUnknownAsPreserved(Ice.Current current) + { + PSUnknown r = new PSUnknown(); + r.pi = 5; + r.ps = "preserved"; + r.psu = "unknown"; + r.graph = null; + if(!current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + // + // 1.0 encoding doesn't support unmarshaling unknown classes even if referenced + // from unread slice. + // + r.cl = new MyClass(15); + } + return r; + } + + public override void checkPBSUnknown(Preserved p, Ice.Current current) + { + if(current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + test(!(p is PSUnknown)); + test(p.pi == 5); + test(p.ps.Equals("preserved")); + } + else + { + PSUnknown pu = p as PSUnknown; + test(pu.pi == 5); + test(pu.ps.Equals("preserved")); + test(pu.psu.Equals("unknown")); + test(pu.graph == null); + test(pu.cl != null && pu.cl.i == 15); + } + } + + public override void PBSUnknownAsPreservedWithGraph_async(AMD_TestIntf_PBSUnknownAsPreservedWithGraph cb, + Ice.Current current) + { + PSUnknown r = new PSUnknown(); + r.pi = 5; + r.ps = "preserved"; + r.psu = "unknown"; + r.graph = new PNode(); + r.graph.next = new PNode(); + r.graph.next.next = new PNode(); + r.graph.next.next.next = r.graph; + cb.ice_response(r); + r.graph.next.next.next = null; // Break the cycle. + } + + public override void checkPBSUnknownWithGraph(Preserved p, Ice.Current current) + { + if(current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + test(!(p is PSUnknown)); + test(p.pi == 5); + test(p.ps.Equals("preserved")); + } + else + { + PSUnknown pu = p as PSUnknown; + test(pu.pi == 5); + test(pu.ps.Equals("preserved")); + test(pu.psu.Equals("unknown")); + test(pu.graph != pu.graph.next); + test(pu.graph.next != pu.graph.next.next); + test(pu.graph.next.next.next == pu.graph); + pu.graph.next.next.next = null; // Break the cycle. + } + } + + public override void PBSUnknown2AsPreservedWithGraph_async(AMD_TestIntf_PBSUnknown2AsPreservedWithGraph cb, + Ice.Current current) + { + PSUnknown2 r = new PSUnknown2(); + r.pi = 5; + r.ps = "preserved"; + r.pb = r; + cb.ice_response(r); + r.pb = null; // Break the cycle. + } + + public override void checkPBSUnknown2WithGraph(Preserved p, Ice.Current current) + { + if(current.encoding.Equals(Ice.Util.Encoding_1_0)) + { + test(!(p is PSUnknown2)); + test(p.pi == 5); + test(p.ps.Equals("preserved")); + } + else + { + PSUnknown2 pu = p as PSUnknown2; + test(pu.pi == 5); + test(pu.ps.Equals("preserved")); + test(pu.pb == pu); + pu.pb = null; // Break the cycle. + } + } + + public override PNode exchangePNode(PNode pn, Ice.Current current) + { + return pn; + } + public override void throwBaseAsBase(Ice.Current current) { BaseException be = new BaseException(); @@ -259,7 +396,7 @@ public sealed class TestI : TestIntfDisp_ be.pb.pb = be.pb; throw be; } - + public override void throwDerivedAsBase(Ice.Current current) { DerivedException de = new DerivedException(); @@ -275,7 +412,7 @@ public sealed class TestI : TestIntfDisp_ de.pd1.pd1 = de.pd1; throw de; } - + public override void throwDerivedAsDerived(Ice.Current current) { DerivedException de = new DerivedException(); @@ -291,7 +428,7 @@ public sealed class TestI : TestIntfDisp_ de.pd1.pd1 = de.pd1; throw de; } - + public override void throwUnknownDerivedAsBase(Ice.Current current) { D2 d2 = new D2(); @@ -299,7 +436,7 @@ public sealed class TestI : TestIntfDisp_ d2.pb = d2; d2.sd2 = "sd2 d2"; d2.pd2 = d2; - + UnknownDerivedException ude = new UnknownDerivedException(); ude.sbe = "sbe"; ude.pb = d2; @@ -307,7 +444,18 @@ public sealed class TestI : TestIntfDisp_ ude.pd2 = d2; throw ude; } - + + public override void throwPreservedException_async(AMD_TestIntf_throwPreservedException cb, Ice.Current current) + { + PSUnknownException ue = new PSUnknownException(); + ue.p = new PSUnknown2(); + ue.p.pi = 5; + ue.p.ps = "preserved"; + ue.p.pb = ue.p; + cb.ice_exception(ue); + ue.p.pb = null; // Break the cycle. + } + public override void useForward(out Forward f, Ice.Current current) { f = new Forward(); diff --git a/cs/test/Ice/slicing/objects/run.py b/cs/test/Ice/slicing/objects/run.py index b4a4a066c90..1e7e887e28a 100755 --- a/cs/test/Ice/slicing/objects/run.py +++ b/cs/test/Ice/slicing/objects/run.py @@ -20,7 +20,11 @@ if len(path) == 0: sys.path.append(os.path.join(path[0], "scripts")) import TestUtil -print("tests with regular server.") +print("Running test with sliced format.") TestUtil.clientServerTest() -print("tests with AMD server.") +print("Running test with 1.0 encoding.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0", additionalServerOptions="--Ice.Default.EncodingVersion=1.0") +print("Running test with sliced format and AMD server.") TestUtil.clientServerTest(server="serveramd") +print("Running test with 1.0 encoding and AMD server.") +TestUtil.clientServerTest(server="serveramd", additionalClientOptions="--Ice.Default.EncodingVersion=1.0", additionalServerOptions="--Ice.Default.EncodingVersion=1.0") |