summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2012-08-10 16:28:35 -0700
committerMark Spruiell <mes@zeroc.com>2012-08-10 16:28:35 -0700
commit964aa286240139ca51486dadefd4debe7cd52991 (patch)
tree37d831468615213d23b490ce8e4c1353048ae817
parentMerge branch 'master' into encoding11 (diff)
downloadice-964aa286240139ca51486dadefd4debe7cd52991.tar.bz2
ice-964aa286240139ca51486dadefd4debe7cd52991.tar.xz
ice-964aa286240139ca51486dadefd4debe7cd52991.zip
implementing preserved slices in C#
-rw-r--r--cpp/src/Slice/CsUtil.cpp14
-rw-r--r--cpp/src/slice2cs/Gen.cpp450
-rw-r--r--cpp/src/slice2cs/Gen.h5
-rw-r--r--cs/src/Ice/BasicStream.cs3138
-rw-r--r--cs/src/Ice/ByteBuffer.cs6
-rw-r--r--cs/src/Ice/DefaultsAndOverrides.cs20
-rw-r--r--cs/src/Ice/Exception.cs11
-rw-r--r--cs/src/Ice/FormatType.cs21
-rw-r--r--cs/src/Ice/Incoming.cs13
-rw-r--r--cs/src/Ice/Makefile4
-rw-r--r--cs/src/Ice/Makefile.mak4
-rw-r--r--cs/src/Ice/Object.cs121
-rw-r--r--cs/src/Ice/OpaqueEndpointI.cs2
-rw-r--r--cs/src/Ice/OptionalType.cs30
-rw-r--r--cs/src/Ice/Outgoing.cs6
-rw-r--r--cs/src/Ice/OutgoingAsync.cs6
-rw-r--r--cs/src/Ice/Proxy.cs47
-rw-r--r--cs/src/Ice/SlicedData.cs58
-rw-r--r--cs/src/Ice/Stream.cs232
-rw-r--r--cs/src/Ice/StreamI.cs153
-rw-r--r--cs/src/Ice/UnknownSlicedObject.cs50
-rw-r--r--cs/src/Ice/UserExceptionFactory.cs2
-rw-r--r--cs/test/Ice/slicing/exceptions/AllTests.cs232
-rw-r--r--cs/test/Ice/slicing/exceptions/ClientPrivate.ice32
-rw-r--r--cs/test/Ice/slicing/exceptions/Makefile3
-rw-r--r--cs/test/Ice/slicing/exceptions/Makefile.mak5
-rw-r--r--cs/test/Ice/slicing/exceptions/ServerPrivate.ice15
-rw-r--r--cs/test/Ice/slicing/exceptions/ServerPrivateAMD.ice15
-rw-r--r--cs/test/Ice/slicing/exceptions/Test.ice42
-rw-r--r--cs/test/Ice/slicing/exceptions/TestAMD.ice44
-rw-r--r--cs/test/Ice/slicing/exceptions/TestAMDI.cs162
-rw-r--r--cs/test/Ice/slicing/exceptions/TestI.cs107
-rwxr-xr-xcs/test/Ice/slicing/exceptions/run.py8
-rw-r--r--cs/test/Ice/slicing/objects/AllTests.cs506
-rw-r--r--cs/test/Ice/slicing/objects/ClientPrivate.ice21
-rw-r--r--cs/test/Ice/slicing/objects/ServerPrivate.ice22
-rw-r--r--cs/test/Ice/slicing/objects/ServerPrivateAMD.ice22
-rw-r--r--cs/test/Ice/slicing/objects/Test.ice52
-rw-r--r--cs/test/Ice/slicing/objects/TestAMD.ice55
-rw-r--r--cs/test/Ice/slicing/objects/TestAMDI.cs222
-rw-r--r--cs/test/Ice/slicing/objects/TestI.cs216
-rwxr-xr-xcs/test/Ice/slicing/objects/run.py8
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")