summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2012-11-09 16:22:47 -0800
committerMark Spruiell <mes@zeroc.com>2012-11-09 16:22:47 -0800
commit493caea19fd83663eb03b4eeaf7714f99ac07b97 (patch)
tree39f8b7dc983394288cb25961a0907ebe0b0f5847
parentICE-4914 - Update Database/Oracle demos (diff)
downloadice-493caea19fd83663eb03b4eeaf7714f99ac07b97.tar.bz2
ice-493caea19fd83663eb03b4eeaf7714f99ac07b97.tar.xz
ice-493caea19fd83663eb03b4eeaf7714f99ac07b97.zip
ICE-4930 - fixes for scripting languages
-rw-r--r--cpp/include/Ice/Stream.h6
-rw-r--r--cpp/include/Slice/Parser.h6
-rw-r--r--cpp/src/Ice/Stream.cpp12
-rw-r--r--cpp/src/Slice/Parser.cpp16
-rw-r--r--cpp/src/slice2cpp/Gen.cpp22
-rw-r--r--cpp/src/slice2cs/Gen.cpp16
-rw-r--r--cpp/src/slice2java/Gen.cpp20
-rw-r--r--cpp/test/Ice/objects/AllTests.cpp2
-rw-r--r--cpp/test/Ice/objects/TestI.cpp1
-rw-r--r--cpp/test/Ice/optional/AllTests.cpp28
-rw-r--r--cpp/test/Ice/optional/Test.ice5
-rw-r--r--cpp/test/Ice/optional/TestI.cpp11
-rw-r--r--cpp/test/Ice/optional/TestI.h4
-rw-r--r--java/test/Ice/optional/AMDInitialI.java13
-rw-r--r--java/test/Ice/optional/AllTests.java30
-rw-r--r--java/test/Ice/optional/InitialI.java11
-rw-r--r--java/test/Ice/optional/Test.ice7
-rw-r--r--java/test/Ice/optional/TestAMD.ice7
-rw-r--r--php/src/IcePHP/Operation.cpp35
-rw-r--r--php/src/IcePHP/Types.cpp57
-rw-r--r--php/src/IcePHP/Types.h12
-rw-r--r--php/test/Ice/objects/Client.php9
-rw-r--r--php/test/Ice/objects/Test.ice21
-rw-r--r--php/test/Ice/optional/Client.php27
-rw-r--r--php/test/Ice/optional/Test.ice7
-rw-r--r--py/modules/IcePy/Operation.cpp40
-rw-r--r--py/modules/IcePy/Types.cpp69
-rw-r--r--py/modules/IcePy/Types.h15
-rw-r--r--py/test/Ice/objects/AllTests.py8
-rw-r--r--py/test/Ice/objects/Test.ice20
-rw-r--r--py/test/Ice/objects/TestI.py3
-rw-r--r--py/test/Ice/optional/AllTests.py21
-rwxr-xr-xpy/test/Ice/optional/Server.py10
-rwxr-xr-xpy/test/Ice/optional/ServerAMD.py10
-rw-r--r--py/test/Ice/optional/Test.ice5
-rw-r--r--py/test/Ice/optional/TestAMD.ice5
-rw-r--r--rb/src/IceRuby/Operation.cpp30
-rw-r--r--rb/src/IceRuby/Types.cpp57
-rw-r--r--rb/src/IceRuby/Types.h12
-rw-r--r--rb/test/Ice/objects/AllTests.rb8
-rw-r--r--rb/test/Ice/objects/Test.ice23
-rw-r--r--rb/test/Ice/optional/AllTests.rb22
-rw-r--r--rb/test/Ice/optional/Test.ice7
43 files changed, 685 insertions, 65 deletions
diff --git a/cpp/include/Ice/Stream.h b/cpp/include/Ice/Stream.h
index b9119787ecb..67dd4610343 100644
--- a/cpp/include/Ice/Stream.h
+++ b/cpp/include/Ice/Stream.h
@@ -63,6 +63,7 @@ public:
~UserExceptionReader() throw();
virtual void read(const InputStreamPtr&) const = 0;
+ virtual bool usesClasses() const = 0;
virtual ::std::string ice_name() const = 0;
virtual UserException* ice_clone() const = 0;
@@ -71,6 +72,8 @@ public:
virtual void __write(IceInternal::BasicStream*) const;
virtual void __read(IceInternal::BasicStream*);
+ virtual bool __usesClasses() const;
+
#ifdef __SUNPRO_CC
using UserException::__read;
using UserException::__write;
@@ -402,6 +405,7 @@ public:
~UserExceptionWriter() throw();
virtual void write(const OutputStreamPtr&) const = 0;
+ virtual bool usesClasses() const = 0;
virtual ::std::string ice_name() const = 0;
virtual UserException* ice_clone() const = 0;
@@ -410,6 +414,8 @@ public:
virtual void __write(IceInternal::BasicStream*) const;
virtual void __read(IceInternal::BasicStream*);
+ virtual bool __usesClasses() const;
+
#ifdef __SUNPRO_CC
using UserException::__read;
using UserException::__write;
diff --git a/cpp/include/Slice/Parser.h b/cpp/include/Slice/Parser.h
index 3c24cdcf520..38c27bd3b14 100644
--- a/cpp/include/Slice/Parser.h
+++ b/cpp/include/Slice/Parser.h
@@ -601,8 +601,8 @@ public:
void setExceptionList(const ExceptionList&);
virtual ContainedType containedType() const;
virtual bool uses(const ContainedPtr&) const;
- bool sendsClasses() const;
- bool returnsClasses() const;
+ bool sendsClasses(bool) const;
+ bool returnsClasses(bool) const;
bool returnsData() const;
int attributes() const;
FormatType format() const;
@@ -723,7 +723,7 @@ public:
virtual bool isLocal() const;
virtual ContainedType containedType() const;
virtual bool uses(const ContainedPtr&) const;
- bool usesClasses() const;
+ bool usesClasses(bool) const;
bool hasDefaultValues() const;
bool inheritsMetaData(const std::string&) const;
virtual std::string kindOf() const;
diff --git a/cpp/src/Ice/Stream.cpp b/cpp/src/Ice/Stream.cpp
index 58d98324113..c483a261a56 100644
--- a/cpp/src/Ice/Stream.cpp
+++ b/cpp/src/Ice/Stream.cpp
@@ -28,6 +28,12 @@ Ice::UserExceptionReader::__readImpl(::IceInternal::BasicStream*)
assert(false); // Should never be called.
}
+bool
+Ice::UserExceptionReader::__usesClasses() const
+{
+ return usesClasses();
+}
+
void
Ice::UserExceptionWriter::__writeImpl(::IceInternal::BasicStream*) const
{
@@ -39,3 +45,9 @@ Ice::UserExceptionWriter::__readImpl(::IceInternal::BasicStream*)
{
assert(false); // Should never be called.
}
+
+bool
+Ice::UserExceptionWriter::__usesClasses() const
+{
+ return usesClasses();
+}
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index a0855fc7771..673a9a0d222 100644
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -3969,19 +3969,19 @@ Slice::Exception::uses(const ContainedPtr&) const
}
bool
-Slice::Exception::usesClasses() const
+Slice::Exception::usesClasses(bool includeOptional) const
{
DataMemberList dml = dataMembers();
for(DataMemberList::const_iterator i = dml.begin(); i != dml.end(); ++i)
{
- if((*i)->type()->usesClasses())
+ if((*i)->type()->usesClasses() && (includeOptional || !(*i)->optional()))
{
return true;
}
}
if(_base)
{
- return _base->usesClasses();
+ return _base->usesClasses(includeOptional);
}
return false;
}
@@ -5131,12 +5131,12 @@ Slice::Operation::uses(const ContainedPtr& contained) const
}
bool
-Slice::Operation::sendsClasses() const
+Slice::Operation::sendsClasses(bool includeOptional) const
{
ParamDeclList pdl = parameters();
for(ParamDeclList::const_iterator i = pdl.begin(); i != pdl.end(); ++i)
{
- if(!(*i)->isOutParam() && (*i)->type()->usesClasses())
+ if(!(*i)->isOutParam() && (*i)->type()->usesClasses() && (includeOptional || !(*i)->optional()))
{
return true;
}
@@ -5145,17 +5145,17 @@ Slice::Operation::sendsClasses() const
}
bool
-Slice::Operation::returnsClasses() const
+Slice::Operation::returnsClasses(bool includeOptional) const
{
TypePtr t = returnType();
- if(t && t->usesClasses())
+ if(t && t->usesClasses() && (includeOptional || !_returnIsOptional))
{
return true;
}
ParamDeclList pdl = parameters();
for(ParamDeclList::const_iterator i = pdl.begin(); i != pdl.end(); ++i)
{
- if((*i)->isOutParam() && (*i)->type()->usesClasses())
+ if((*i)->isOutParam() && (*i)->type()->usesClasses() && (includeOptional || !(*i)->optional()))
{
return true;
}
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index f7e0f4b615f..c9463b8c32a 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -877,9 +877,9 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
C << nl << "throw *this;";
C << eb;
- if(!p->isLocal() && p->usesClasses())
+ if(!p->isLocal() && p->usesClasses(false))
{
- if(!base || (base && !base->usesClasses()))
+ if(!base || (base && !base->usesClasses(false)))
{
H << sp << nl << "virtual bool __usesClasses() const;";
@@ -2170,7 +2170,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
{
C << nl << "::IceInternal::BasicStream* __os = __result->__startWriteParams(" << opFormatTypeToString(p) <<");";
writeMarshalCode(C, inParams, 0, TypeContextInParam);
- if(p->sendsClasses())
+ if(p->sendsClasses(false))
{
C << nl << "__os->writePendingObjects();";
}
@@ -2237,7 +2237,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
{
C << nl << "::IceInternal::BasicStream* __is = __result->__startReadParams();";
writeUnmarshalCode(C, outParams, p, _useWstring | TypeContextAMIEnd);
- if(p->returnsClasses())
+ if(p->returnsClasses(false))
{
C << nl << "__is->readPendingObjects();";
}
@@ -2307,7 +2307,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
{
C << nl << "::IceInternal::BasicStream* __is = __result->__startReadParams();";
writeUnmarshalCode(C, outParams, p, _useWstring | TypeContextAMIPrivateEnd);
- if(p->returnsClasses())
+ if(p->returnsClasses(false))
{
C << nl << "__is->readPendingObjects();";
}
@@ -2729,7 +2729,7 @@ Slice::Gen::DelegateMVisitor::visitOperation(const OperationPtr& p)
C << sb;
C << nl<< "::IceInternal::BasicStream* __os = __og.startWriteParams(" << opFormatTypeToString(p) << ");";
writeMarshalCode(C, inParams, 0, TypeContextInParam);
- if(p->sendsClasses())
+ if(p->sendsClasses(false))
{
C << nl << "__os->writePendingObjects();";
}
@@ -2815,7 +2815,7 @@ Slice::Gen::DelegateMVisitor::visitOperation(const OperationPtr& p)
{
C << nl << "::IceInternal::BasicStream* __is = __og.startReadParams();";
writeUnmarshalCode(C, outParams, p);
- if(p->returnsClasses())
+ if(p->returnsClasses(false))
{
C << nl << "__is->readPendingObjects();";
}
@@ -4272,7 +4272,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
C << nl << "::IceInternal::BasicStream* __is = __inS.startReadParams();";
writeAllocateCode(C, inParams, 0, _useWstring | TypeContextInParam);
writeUnmarshalCode(C, inParams, 0, TypeContextInParam);
- if(p->sendsClasses())
+ if(p->sendsClasses(false))
{
C << nl << "__is->readPendingObjects();";
}
@@ -4300,7 +4300,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
C << nl << "::IceInternal::BasicStream* __os = __inS.__startWriteParams("
<< opFormatTypeToString(p) << ");";
writeMarshalCode(C, outParams, p);
- if(p->returnsClasses())
+ if(p->returnsClasses(false))
{
C << nl << "__os->writePendingObjects();";
}
@@ -4334,7 +4334,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
C << nl << "::IceInternal::BasicStream* __is = __inS.startReadParams();";
writeAllocateCode(C, inParams, 0, _useWstring | TypeContextInParam);
writeUnmarshalCode(C, inParams, 0, TypeContextInParam);
- if(p->sendsClasses())
+ if(p->sendsClasses(false))
{
C << nl << "__is->readPendingObjects();";
}
@@ -5929,7 +5929,7 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
C << sb;
C << nl << "::IceInternal::BasicStream* __os = __startWriteParams(" << opFormatTypeToString(p) << ");";
writeMarshalCode(C, outParams, p, TypeContextInParam);
- if(p->returnsClasses())
+ if(p->returnsClasses(false))
{
C << nl << "__os->writePendingObjects();";
}
diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp
index 3e6290ad7c8..c910332a141 100644
--- a/cpp/src/slice2cs/Gen.cpp
+++ b/cpp/src/slice2cs/Gen.cpp
@@ -870,7 +870,7 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream)
}
}
writeMarshalUnmarshalParams(inParams, 0, false);
- if(op->sendsClasses())
+ if(op->sendsClasses(false))
{
_out << nl << "is__.readPendingObjects();";
}
@@ -944,7 +944,7 @@ Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p, bool stream)
_out << nl << "IceInternal.BasicStream os__ = inS__.startWriteParams__("
<< opFormatTypeToString(op) << ");";
writeMarshalUnmarshalParams(outParams, op, true);
- if(op->returnsClasses())
+ if(op->returnsClasses(false))
{
_out << nl << "os__.writePendingObjects();";
}
@@ -3608,7 +3608,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
_out << eb;
}
- if((!base || (base && !base->usesClasses())) && p->usesClasses())
+ if((!base || (base && !base->usesClasses(false))) && p->usesClasses(false))
{
_out << sp;
emitGeneratedCodeAttribute();
@@ -4993,7 +4993,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p)
}
}
writeMarshalUnmarshalParams(outParams, op, false);
- if(op->returnsClasses())
+ if(op->returnsClasses(false))
{
_out << nl << "is__.readPendingObjects();";
}
@@ -5060,7 +5060,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p)
_out << nl << "IceInternal.BasicStream os__ = result__.startWriteParams__("
<< opFormatTypeToString(op) << ");";
writeMarshalUnmarshalParams(inParams, 0, true);
- if(op->sendsClasses())
+ if(op->sendsClasses(false))
{
_out << nl << "os__.writePendingObjects();";
}
@@ -5947,7 +5947,7 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p)
_out << sb;
_out << nl << "IceInternal.BasicStream os__ = og__.startWriteParams(" << opFormatTypeToString(op) << ");";
writeMarshalUnmarshalParams(inParams, 0, true);
- if(op->sendsClasses())
+ if(op->sendsClasses(false))
{
_out << nl << "os__.writePendingObjects();";
}
@@ -6049,7 +6049,7 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p)
}
}
writeMarshalUnmarshalParams(outParams, op, false);
- if(op->returnsClasses())
+ if(op->returnsClasses(false))
{
_out << nl << "is__.readPendingObjects();";
}
@@ -6573,7 +6573,7 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
_out << sb;
_out << nl << "IceInternal.BasicStream os__ = startWriteParams__(" << opFormatTypeToString(p) << ");";
writeMarshalUnmarshalParams(outParams, p, true);
- if(p->returnsClasses())
+ if(p->returnsClasses(false))
{
_out << nl << "os__.writePendingObjects();";
}
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index e5dc96633cc..5d8c60fad01 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -991,7 +991,7 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr&
}
iter = 0;
writeMarshalUnmarshalParams(out, package, inParams, 0, iter, false, true, true);
- if(op->sendsClasses())
+ if(op->sendsClasses(false))
{
out << nl << "__is.readPendingObjects();";
}
@@ -1056,7 +1056,7 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr&
out << nl << "IceInternal.BasicStream __os = __inS.__startWriteParams("
<< opFormatTypeToString(op) << ");";
writeMarshalUnmarshalParams(out, package, outParams, op, iter, true, optionalMapping, true);
- if(op->returnsClasses())
+ if(op->returnsClasses(false))
{
out << nl << "__os.writePendingObjects();";
}
@@ -1134,7 +1134,7 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr&
}
}
writeMarshalUnmarshalParams(out, package, inParams, 0, iter, false, true, true);
- if(op->sendsClasses())
+ if(op->sendsClasses(false))
{
out << nl << "__is.readPendingObjects();";
}
@@ -3366,9 +3366,9 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
out << eb;
}
- if(p->usesClasses())
+ if(p->usesClasses(false))
{
- if(!base || (base && !base->usesClasses()))
+ if(!base || (base && !base->usesClasses(false)))
{
out << sp << nl << "public boolean" << nl << "__usesClasses()";
out << sb;
@@ -4473,7 +4473,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p)
}
}
writeMarshalUnmarshalParams(out, package, pl, 0, iter, true, optionalMapping);
- if(op->sendsClasses())
+ if(op->sendsClasses(false))
{
out << nl << "__os.writePendingObjects();";
}
@@ -4552,7 +4552,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p)
}
}
writeMarshalUnmarshalParams(out, package, pl, op, iter, false, true);
- if(op->returnsClasses())
+ if(op->returnsClasses(false))
{
out << nl << "__is.readPendingObjects();";
}
@@ -5485,7 +5485,7 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p)
out << sb;
out << nl << "IceInternal.BasicStream __os = __og.startWriteParams(" << opFormatTypeToString(op) << ");";
writeMarshalUnmarshalParams(out, package, inParams, 0, iter, true, optionalMapping);
- if(op->sendsClasses())
+ if(op->sendsClasses(false))
{
out << nl << "__os.writePendingObjects();";
}
@@ -5532,7 +5532,7 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p)
{
out << nl << "IceInternal.BasicStream __is = __og.startReadParams();";
writeMarshalUnmarshalParams(out, package, outParams, op, iter, false, true);
- if(op->returnsClasses())
+ if(op->returnsClasses(false))
{
out << nl << "__is.readPendingObjects();";
}
@@ -6602,7 +6602,7 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
out << nl << "IceInternal.BasicStream __os = this.__startWriteParams("
<< opFormatTypeToString(p) << ");";
writeMarshalUnmarshalParams(out, classPkg, outParams, p, iter, true, optionalMapping, false);
- if(p->returnsClasses())
+ if(p->returnsClasses(false))
{
out << nl << "__os.writePendingObjects();";
}
diff --git a/cpp/test/Ice/objects/AllTests.cpp b/cpp/test/Ice/objects/AllTests.cpp
index 04b56d01a83..c4522b7a5e0 100644
--- a/cpp/test/Ice/objects/AllTests.cpp
+++ b/cpp/test/Ice/objects/AllTests.cpp
@@ -215,7 +215,7 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
initial->setI(h);
cout << "ok" << endl;
- cout << "testing sequences..." << flush;
+ cout << "testing sequences... " << flush;
BaseSeq inS, outS, retS;
retS = initial->opBaseSeq(inS, outS);
diff --git a/cpp/test/Ice/objects/TestI.cpp b/cpp/test/Ice/objects/TestI.cpp
index 246864b2019..12cd0e1915c 100644
--- a/cpp/test/Ice/objects/TestI.cpp
+++ b/cpp/test/Ice/objects/TestI.cpp
@@ -210,7 +210,6 @@ InitialI::setI(const IPtr&, const Ice::Current&)
{
}
-
BaseSeq
InitialI::opBaseSeq(const BaseSeq& inSeq, BaseSeq& outSeq, const Ice::Current&)
{
diff --git a/cpp/test/Ice/optional/AllTests.cpp b/cpp/test/Ice/optional/AllTests.cpp
index 22c0d3cdb3c..6719dca601e 100644
--- a/cpp/test/Ice/optional/AllTests.cpp
+++ b/cpp/test/Ice/optional/AllTests.cpp
@@ -548,6 +548,19 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
in->endEncapsulation();
test(obj && dynamic_cast<TestObjectReader*>(obj.get()));
factory->setEnabled(false);
+
+ //
+ // Use the 1.0 encoding with operations whose only class parameters are optional.
+ //
+ IceUtil::Optional<OneOptionalPtr> oo(new OneOptional(53));
+ initial->sendOptionalClass(true, oo);
+ initial->ice_encodingVersion(Ice::Encoding_1_0)->sendOptionalClass(true, oo);
+
+ initial->returnOptionalClass(true, oo);
+ test(oo);
+ initial->ice_encodingVersion(Ice::Encoding_1_0)->returnOptionalClass(true, oo);
+ test(!oo);
+
cout << "ok" << endl;
cout << "testing marshalling of large containers with fixed size elements..." << flush;
@@ -1092,6 +1105,21 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
test(ex.b == string("test"));
test((*ex.o)->a = 53);
}
+
+ try
+ {
+ //
+ // Use the 1.0 encoding with an exception whose only class members are optional.
+ //
+ initial->ice_encodingVersion(Ice::Encoding_1_0)->
+ opOptionalException(30, string("test"), OneOptionalPtr(new OneOptional(53)));
+ }
+ catch(const OptionalException& ex)
+ {
+ test(!ex.a);
+ test(!ex.b);
+ test(!ex.o);
+ }
}
cout << "ok" << endl;
diff --git a/cpp/test/Ice/optional/Test.ice b/cpp/test/Ice/optional/Test.ice
index baea70cb293..d693ae649a2 100644
--- a/cpp/test/Ice/optional/Test.ice
+++ b/cpp/test/Ice/optional/Test.ice
@@ -138,6 +138,7 @@ class WD
exception OptionalException
{
+ bool req = false;
optional(1) int a = 5;
optional(2) string b;
optional(50) OneOptional o;
@@ -253,6 +254,10 @@ class Initial
void opClassAndUnknownOptional(A p);
+ void sendOptionalClass(bool req, optional(1) OneOptional o);
+
+ void returnOptionalClass(bool req, out optional(1) OneOptional o);
+
bool supportsRequiredParams();
bool supportsJavaSerializable();
diff --git a/cpp/test/Ice/optional/TestI.cpp b/cpp/test/Ice/optional/TestI.cpp
index b40ee6cf67d..f26194e934a 100644
--- a/cpp/test/Ice/optional/TestI.cpp
+++ b/cpp/test/Ice/optional/TestI.cpp
@@ -344,6 +344,17 @@ InitialI::opClassAndUnknownOptional(const APtr& a, const Ice::Current&)
{
}
+void
+InitialI::sendOptionalClass(bool, const Optional<OneOptionalPtr>&, const Ice::Current&)
+{
+}
+
+void
+InitialI::returnOptionalClass(bool, Optional<OneOptionalPtr>& o, const Ice::Current&)
+{
+ o = new OneOptional(53);
+}
+
bool
InitialI::supportsRequiredParams(const Ice::Current&)
{
diff --git a/cpp/test/Ice/optional/TestI.h b/cpp/test/Ice/optional/TestI.h
index 2114639de63..aab81137006 100644
--- a/cpp/test/Ice/optional/TestI.h
+++ b/cpp/test/Ice/optional/TestI.h
@@ -172,6 +172,10 @@ public:
virtual void opClassAndUnknownOptional(const Test::APtr&, const Ice::Current&);
+ virtual void sendOptionalClass(bool, const IceUtil::Optional<Test::OneOptionalPtr>&, const Ice::Current&);
+
+ virtual void returnOptionalClass(bool, IceUtil::Optional<Test::OneOptionalPtr>&, const Ice::Current&);
+
virtual bool supportsRequiredParams(const Ice::Current&);
virtual bool supportsJavaSerializable(const Ice::Current&);
diff --git a/java/test/Ice/optional/AMDInitialI.java b/java/test/Ice/optional/AMDInitialI.java
index 69b7a0b3dae..9a67487788c 100644
--- a/java/test/Ice/optional/AMDInitialI.java
+++ b/java/test/Ice/optional/AMDInitialI.java
@@ -485,6 +485,19 @@ public final class AMDInitialI extends Initial
}
public void
+ sendOptionalClass_async(AMD_Initial_sendOptionalClass cb, boolean req, Ice.Optional<OneOptional> o,
+ Ice.Current current)
+ {
+ cb.ice_response();
+ }
+
+ public void
+ returnOptionalClass_async(AMD_Initial_returnOptionalClass cb, boolean req, Ice.Current current)
+ {
+ cb.ice_response(new Ice.Optional<OneOptional>(new OneOptional(53)));
+ }
+
+ public void
supportsRequiredParams_async(AMD_Initial_supportsRequiredParams cb, Ice.Current current)
{
cb.ice_response(true);
diff --git a/java/test/Ice/optional/AllTests.java b/java/test/Ice/optional/AllTests.java
index 95e2a815d43..4782a02b03f 100644
--- a/java/test/Ice/optional/AllTests.java
+++ b/java/test/Ice/optional/AllTests.java
@@ -383,6 +383,19 @@ public class AllTests
test(cb.obj != null && cb.obj instanceof TestObjectReader);
factory.setEnabled(false);
+ //
+ // Use the 1.0 encoding with operations whose only class parameters are optional.
+ //
+ Ice.Optional<OneOptional> oo = new Ice.Optional<OneOptional>(new OneOptional(53));
+ initial.sendOptionalClass(true, oo);
+ InitialPrx initial2 = (InitialPrx)initial.ice_encodingVersion(Ice.Util.Encoding_1_0);
+ initial2.sendOptionalClass(true, oo);
+
+ initial.returnOptionalClass(true, oo);
+ test(oo.isSet());
+ initial2.returnOptionalClass(true, oo);
+ test(!oo.isSet());
+
out.println("ok");
out.print("testing marshaling of large containers with fixed size elements... ");
@@ -2068,6 +2081,23 @@ public class AllTests
try
{
+ //
+ // Use the 1.0 encoding with an exception whose only class members are optional.
+ //
+ Ice.IntOptional a = new Ice.IntOptional(30);
+ Ice.Optional<String> b = new Ice.Optional<String>("test");
+ Ice.Optional<OneOptional> o = new Ice.Optional<OneOptional>(new OneOptional(53));
+ initial2.opOptionalException(a, b, o);
+ }
+ catch(OptionalException ex)
+ {
+ test(!ex.hasA());
+ test(!ex.hasB());
+ test(!ex.hasO());
+ }
+
+ try
+ {
Ice.IntOptional a = new Ice.IntOptional();
Ice.Optional<String> b = new Ice.Optional<String>();
Ice.Optional<OneOptional> o = new Ice.Optional<OneOptional>();
diff --git a/java/test/Ice/optional/InitialI.java b/java/test/Ice/optional/InitialI.java
index e07bb4a1a2c..d16c997c82d 100644
--- a/java/test/Ice/optional/InitialI.java
+++ b/java/test/Ice/optional/InitialI.java
@@ -534,6 +534,17 @@ public final class InitialI extends Initial
{
}
+ public void
+ sendOptionalClass(boolean req, Ice.Optional<OneOptional> o, Ice.Current current)
+ {
+ }
+
+ public void
+ returnOptionalClass(boolean req, Ice.Optional<OneOptional> o, Ice.Current current)
+ {
+ o.set(new OneOptional(53));
+ }
+
public boolean
supportsRequiredParams(Ice.Current current)
{
diff --git a/java/test/Ice/optional/Test.ice b/java/test/Ice/optional/Test.ice
index 3fbe93fbfff..b506ae5303e 100644
--- a/java/test/Ice/optional/Test.ice
+++ b/java/test/Ice/optional/Test.ice
@@ -137,6 +137,7 @@ class WD
exception OptionalException
{
+ bool req = false;
optional(1) int a = 5;
optional(2) string b;
optional(50) OneOptional o;
@@ -282,6 +283,12 @@ class Initial
void opClassAndUnknownOptional(A p);
+ ["java:optional"]
+ void sendOptionalClass(bool req, optional(1) OneOptional o);
+
+ ["java:optional"]
+ void returnOptionalClass(bool req, out optional(1) OneOptional o);
+
bool supportsRequiredParams();
bool supportsJavaSerializable();
diff --git a/java/test/Ice/optional/TestAMD.ice b/java/test/Ice/optional/TestAMD.ice
index bfdfd0e175e..acb84d0dc02 100644
--- a/java/test/Ice/optional/TestAMD.ice
+++ b/java/test/Ice/optional/TestAMD.ice
@@ -137,6 +137,7 @@ class WD
exception OptionalException
{
+ bool req = false;
optional(1) int a = 5;
optional(2) string b;
optional(50) OneOptional o;
@@ -282,6 +283,12 @@ class Initial
void opClassAndUnknownOptional(A p);
+ ["java:optional"]
+ void sendOptionalClass(bool req, optional(1) OneOptional o);
+
+ ["java:optional"]
+ void returnOptionalClass(bool req, out optional(1) OneOptional o);
+
bool supportsRequiredParams();
bool supportsJavaSerializable();
diff --git a/php/src/IcePHP/Operation.cpp b/php/src/IcePHP/Operation.cpp
index 82e5bc7a6d8..4dee27a4ae2 100644
--- a/php/src/IcePHP/Operation.cpp
+++ b/php/src/IcePHP/Operation.cpp
@@ -80,13 +80,15 @@ public:
ParamInfoList optionalOutParams;
ParamInfoPtr returnType;
ExceptionInfoList exceptions;
+ bool sendsClasses;
+ bool returnsClasses;
int numParams;
private:
zend_internal_function* _zendFunction;
- static void convertParams(zval*, ParamInfoList& TSRMLS_DC);
+ static void convertParams(zval*, ParamInfoList&, bool& TSRMLS_DC);
static ParamInfoPtr convertParam(zval*, int TSRMLS_DC);
static void getArgInfo(zend_arg_info&, const ParamInfoPtr&, bool);
};
@@ -220,17 +222,19 @@ IcePHP::OperationI::OperationI(const char* n, Ice::OperationMode m, Ice::Operati
//
// inParams
//
+ sendsClasses = false;
if(in)
{
- convertParams(in, inParams TSRMLS_CC);
+ convertParams(in, inParams, sendsClasses TSRMLS_CC);
}
//
// outParams
//
+ returnsClasses = false;
if(out)
{
- convertParams(out, outParams TSRMLS_CC);
+ convertParams(out, outParams, returnsClasses TSRMLS_CC);
}
//
@@ -239,6 +243,10 @@ IcePHP::OperationI::OperationI(const char* n, Ice::OperationMode m, Ice::Operati
if(ret)
{
returnType = convertParam(ret, 0 TSRMLS_CC);
+ if(!returnsClasses)
+ {
+ returnsClasses = returnType->type->usesClasses();
+ }
}
numParams = static_cast<int>(inParams.size() + outParams.size());
@@ -355,7 +363,7 @@ IcePHP::OperationI::function()
}
void
-IcePHP::OperationI::convertParams(zval* p, ParamInfoList& params TSRMLS_DC)
+IcePHP::OperationI::convertParams(zval* p, ParamInfoList& params, bool& usesClasses TSRMLS_DC)
{
assert(Z_TYPE_P(p) == IS_ARRAY);
HashTable* arr = Z_ARRVAL_P(p);
@@ -366,7 +374,12 @@ IcePHP::OperationI::convertParams(zval* p, ParamInfoList& params TSRMLS_DC)
while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
{
zval** val = reinterpret_cast<zval**>(data);
- params.push_back(convertParam(*val, i TSRMLS_CC));
+ ParamInfoPtr param = convertParam(*val, i TSRMLS_CC);
+ params.push_back(param);
+ if(!param->optional && !usesClasses)
+ {
+ usesClasses = param->type->usesClasses();
+ }
zend_hash_move_forward_ex(arr, &pos);
++i;
}
@@ -521,6 +534,11 @@ IcePHP::TypedInvocation::prepareRequest(int argc, zval** args, Ice::ByteSeq& byt
}
}
+ if(_op->sendsClasses)
+ {
+ os->writePendingObjects();
+ }
+
os->endEncapsulation();
os->finished(bytes);
}
@@ -596,7 +614,7 @@ IcePHP::TypedInvocation::unmarshalResults(int argc, zval** args, zval* ret,
ParamInfoPtr info = *p;
ResultCallbackPtr cb = new ResultCallback;
- if(info->tag == _op->returnType->tag)
+ if(_op->returnType && info->tag == _op->returnType->tag)
{
retCallback = cb;
}
@@ -615,6 +633,11 @@ IcePHP::TypedInvocation::unmarshalResults(int argc, zval** args, zval* ret,
}
}
+ if(_op->returnsClasses)
+ {
+ is->readPendingObjects();
+ }
+
is->endEncapsulation();
util.update(TSRMLS_C);
diff --git a/php/src/IcePHP/Types.cpp b/php/src/IcePHP/Types.cpp
index 323bd1d3e90..976073c3217 100644
--- a/php/src/IcePHP/Types.cpp
+++ b/php/src/IcePHP/Types.cpp
@@ -583,6 +583,12 @@ IcePHP::TypeInfo::TypeInfo()
{
}
+bool
+IcePHP::TypeInfo::usesClasses() const
+{
+ return false;
+}
+
void
IcePHP::TypeInfo::unmarshaled(zval*, zval*, void* TSRMLS_DC)
{
@@ -1305,6 +1311,20 @@ IcePHP::StructInfo::optionalFormat() const
return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
}
+bool
+IcePHP::StructInfo::usesClasses() const
+{
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ if((*p)->type->usesClasses())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void
IcePHP::StructInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional TSRMLS_DC)
{
@@ -1462,6 +1482,12 @@ IcePHP::SequenceInfo::optionalFormat() const
return elementType->variableLength() ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
}
+bool
+IcePHP::SequenceInfo::usesClasses() const
+{
+ return elementType->usesClasses();
+}
+
void
IcePHP::SequenceInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional TSRMLS_DC)
{
@@ -2015,6 +2041,12 @@ IcePHP::DictionaryInfo::optionalFormat() const
return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
}
+bool
+IcePHP::DictionaryInfo::usesClasses() const
+{
+ return valueType->usesClasses();
+}
+
void
IcePHP::DictionaryInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional TSRMLS_DC)
{
@@ -2436,6 +2468,12 @@ IcePHP::ClassInfo::optionalFormat() const
return Ice::OptionalFormatSize;
}
+bool
+IcePHP::ClassInfo::usesClasses() const
+{
+ return true;
+}
+
void
IcePHP::ClassInfo::marshal(zval* zv, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool TSRMLS_DC)
{
@@ -3284,6 +3322,12 @@ IcePHP::ExceptionReader::read(const Ice::InputStreamPtr& is) const
const_cast<Ice::SlicedDataPtr&>(_slicedData) = is->endException(_info->preserve);
}
+bool
+IcePHP::ExceptionReader::usesClasses() const
+{
+ return _info->usesClasses;
+}
+
string
IcePHP::ExceptionReader::ice_name() const
{
@@ -3633,6 +3677,19 @@ ZEND_FUNCTION(IcePHP_defineException)
convertDataMembers(members, ex->members, ex->optionalMembers, true TSRMLS_CC);
}
+ ex->usesClasses = false;
+
+ //
+ // Only examine the required members to see if any use classes.
+ //
+ for(DataMemberList::iterator p = ex->members.begin(); p != ex->members.end(); ++p)
+ {
+ if(!ex->usesClasses)
+ {
+ ex->usesClasses = (*p)->type->usesClasses();
+ }
+ }
+
ex->zce = nameToClass(ex->name TSRMLS_CC);
assert(!getExceptionInfo(ex->id TSRMLS_CC));
diff --git a/php/src/IcePHP/Types.h b/php/src/IcePHP/Types.h
index d3d4825e3eb..f682d0f3cf4 100644
--- a/php/src/IcePHP/Types.h
+++ b/php/src/IcePHP/Types.h
@@ -117,6 +117,8 @@ public:
virtual int wireSize() const = 0;
virtual Ice::OptionalFormat optionalFormat() const = 0;
+ virtual bool usesClasses() const; // Default implementation returns false.
+
virtual void unmarshaled(zval*, zval*, void* TSRMLS_DC); // Default implementation is assert(false).
virtual void destroy();
@@ -239,6 +241,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const;
+
virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool TSRMLS_DC);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
zval*, void*, bool TSRMLS_DC);
@@ -276,6 +280,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const;
+
virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool TSRMLS_DC);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
zval*, void*, bool TSRMLS_DC);
@@ -314,6 +320,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const;
+
virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool TSRMLS_DC);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
zval*, void*, bool TSRMLS_DC);
@@ -385,6 +393,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const;
+
virtual void marshal(zval*, const Ice::OutputStreamPtr&, ObjectMap*, bool TSRMLS_DC);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&,
zval*, void*, bool TSRMLS_DC);
@@ -468,6 +478,7 @@ public:
ExceptionInfoPtr base;
DataMemberList members;
DataMemberList optionalMembers;
+ bool usesClasses;
zend_class_entry* zce;
};
@@ -550,6 +561,7 @@ public:
~ExceptionReader() throw();
virtual void read(const Ice::InputStreamPtr&) const;
+ virtual bool usesClasses() const;
virtual std::string ice_name() const;
virtual ExceptionReader* ice_clone() const;
diff --git a/php/test/Ice/objects/Client.php b/php/test/Ice/objects/Client.php
index 5af9c43ce11..82961397cae 100644
--- a/php/test/Ice/objects/Client.php
+++ b/php/test/Ice/objects/Client.php
@@ -354,6 +354,15 @@ function allTests($communicator)
$initial->setI($h);
echo "ok\n";
+ echo "testing sequences... ";
+ flush();
+ $outS = null;
+ $initial->opBaseSeq(array(), $outS);
+
+ $retS = $initial->opBaseSeq(array(new Test_Base()), $outS);
+ test(count($retS) == 1 && count($outS) == 1);
+ echo "ok\n";
+
echo "testing UnexpectedObjectException... ";
flush();
$ref = "uoet:default -p 12010";
diff --git a/php/test/Ice/objects/Test.ice b/php/test/Ice/objects/Test.ice
index 1758598a2ca..5768ef51606 100644
--- a/php/test/Ice/objects/Test.ice
+++ b/php/test/Ice/objects/Test.ice
@@ -12,6 +12,22 @@
module Test
{
+struct S
+{
+ string str;
+};
+
+class Base
+{
+ S theS;
+ string str;
+};
+
+class AbstractBase extends Base
+{
+ void op();
+};
+
class B;
class C;
@@ -75,10 +91,11 @@ class H implements I
{
};
+sequence<Base> BaseSeq;
+
class Initial
{
void shutdown();
-
B getB1();
B getB2();
C getC();
@@ -93,6 +110,8 @@ class Initial
I getH();
void setI(I theI);
+
+ BaseSeq opBaseSeq(BaseSeq inSeq, out BaseSeq outSeq);
};
class Empty
diff --git a/php/test/Ice/optional/Client.php b/php/test/Ice/optional/Client.php
index f3f8b469da4..cdd0a032d5e 100644
--- a/php/test/Ice/optional/Client.php
+++ b/php/test/Ice/optional/Client.php
@@ -32,6 +32,7 @@ function test($b)
function allTests($communicator)
{
global $NS;
+ global $Ice_Encoding_1_0;
$enum = $NS ? constant("Test\\MyEnum::MyEnumMember") : constant("Test_MyEnum::MyEnumMember");
@@ -325,6 +326,18 @@ function allTests($communicator)
test($mo9->bos == Ice_Unset);
+ //
+ // Use the 1.0 encoding with operations whose only class parameters are optional.
+ //
+ $oo = new $oocls(53);
+ $initial->sendOptionalClass(true, $oo);
+ $initial->ice_encodingVersion($Ice_Encoding_1_0)->sendOptionalClass(true, $oo);
+
+ $initial->returnOptionalClass(true, $oo);
+ test($oo != Ice_Unset);
+ $initial->ice_encodingVersion($Ice_Encoding_1_0)->returnOptionalClass(true, $oo);
+ test($oo == Ice_Unset);
+
echo "ok\n";
echo "testing marshaling of large containers with fixed size elements... ";
@@ -670,6 +683,20 @@ function allTests($communicator)
try
{
+ //
+ // Use the 1.0 encoding with an exception whose only class members are optional.
+ //
+ $initial->ice_encodingVersion($Ice_Encoding_1_0)->opOptionalException(30, "test", new $oocls(53));
+ }
+ catch(Exception $ex)
+ {
+ test($ex->a == Ice_Unset);
+ test($ex->b == Ice_Unset);
+ test($ex->o == Ice_Unset);
+ }
+
+ try
+ {
$initial->opDerivedException(Ice_Unset, Ice_Unset, Ice_Unset);
}
catch(Exception $ex)
diff --git a/php/test/Ice/optional/Test.ice b/php/test/Ice/optional/Test.ice
index 7f0342b8df4..8cc213df42c 100644
--- a/php/test/Ice/optional/Test.ice
+++ b/php/test/Ice/optional/Test.ice
@@ -136,6 +136,7 @@ class WD
exception OptionalException
{
+ bool req = false;
optional(1) int a = 5;
optional(2) string b;
optional(50) OneOptional o;
@@ -230,12 +231,18 @@ class Initial
optional(1) VarStructSeq opVarStructSeq(optional(2) VarStructSeq p1, out optional(3) VarStructSeq p3);
+ optional(1) Serializable opSerializable(optional(2) Serializable p1, out optional(3) Serializable p3);
+
optional(1) IntIntDict opIntIntDict(optional(2) IntIntDict p1, out optional(3) IntIntDict p3);
optional(1) StringIntDict opStringIntDict(optional(2) StringIntDict p1, out optional(3) StringIntDict p3);
void opClassAndUnknownOptional(A p);
+ void sendOptionalClass(bool req, optional(1) OneOptional o);
+
+ void returnOptionalClass(bool req, out optional(1) OneOptional o);
+
bool supportsRequiredParams();
bool supportsJavaSerializable();
diff --git a/py/modules/IcePy/Operation.cpp b/py/modules/IcePy/Operation.cpp
index 0cbbee3b77a..ea9bffcc263 100644
--- a/py/modules/IcePy/Operation.cpp
+++ b/py/modules/IcePy/Operation.cpp
@@ -77,13 +77,15 @@ public:
ParamInfoPtr returnType;
ExceptionInfoList exceptions;
string dispatchName;
+ bool sendsClasses;
+ bool returnsClasses;
bool pseudoOp;
private:
string _deprecateMessage;
- static void convertParams(PyObject*, ParamInfoList&, int);
+ static void convertParams(PyObject*, ParamInfoList&, int, bool&);
static ParamInfoPtr convertParam(PyObject*, int);
};
typedef IceUtil::Handle<Operation> OperationPtr;
@@ -1074,20 +1076,26 @@ IcePy::Operation::Operation(const char* n, PyObject* m, PyObject* sm, int amdFla
//
// returnType
//
+ returnsClasses = false;
if(ret != Py_None)
{
returnType = convertParam(ret, 0);
+ if(!returnType->optional)
+ {
+ returnsClasses = returnType->type->usesClasses();
+ }
}
//
// inParams
//
- convertParams(in, inParams, 0);
+ sendsClasses = false;
+ convertParams(in, inParams, 0, sendsClasses);
//
// outParams
//
- convertParams(out, outParams, returnType ? 1 : 0);
+ convertParams(out, outParams, returnType ? 1 : 0, returnsClasses);
class SortFn
{
@@ -1153,7 +1161,7 @@ IcePy::Operation::deprecate(const string& msg)
}
void
-IcePy::Operation::convertParams(PyObject* p, ParamInfoList& params, int posOffset)
+IcePy::Operation::convertParams(PyObject* p, ParamInfoList& params, int posOffset, bool& usesClasses)
{
int sz = static_cast<int>(PyTuple_GET_SIZE(p));
for(int i = 0; i < sz; ++i)
@@ -1161,6 +1169,10 @@ IcePy::Operation::convertParams(PyObject* p, ParamInfoList& params, int posOffse
PyObject* item = PyTuple_GET_ITEM(p, i);
ParamInfoPtr param = convertParam(item, i + posOffset);
params.push_back(param);
+ if(!param->optional && !usesClasses)
+ {
+ usesClasses = param->type->usesClasses();
+ }
}
}
@@ -1555,6 +1567,11 @@ IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, vect
}
}
+ if(_op->sendsClasses)
+ {
+ os->writePendingObjects();
+ }
+
os->endEncapsulation();
os->finished(bytes);
}
@@ -1643,6 +1660,11 @@ IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice:
}
}
+ if(_op->returnsClasses)
+ {
+ is->readPendingObjects();
+ }
+
is->endEncapsulation();
util.update();
@@ -3255,6 +3277,11 @@ IcePy::TypedUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, con
}
}
+ if(_op->sendsClasses)
+ {
+ is->readPendingObjects();
+ }
+
is->endEncapsulation();
util.update();
@@ -3458,6 +3485,11 @@ IcePy::TypedUpcall::response(PyObject* args, const Ice::EncodingVersion& encodin
}
}
+ if(_op->returnsClasses)
+ {
+ os->writePendingObjects();
+ }
+
os->endEncapsulation();
Ice::ByteSeq bytes;
diff --git a/py/modules/IcePy/Types.cpp b/py/modules/IcePy/Types.cpp
index 5cda768dd1c..84efd5d9081 100644
--- a/py/modules/IcePy/Types.cpp
+++ b/py/modules/IcePy/Types.cpp
@@ -503,6 +503,12 @@ IcePy::TypeInfo::TypeInfo()
{
}
+bool
+IcePy::TypeInfo::usesClasses() const
+{
+ return false;
+}
+
void
IcePy::TypeInfo::unmarshaled(PyObject*, PyObject*, void*)
{
@@ -1161,6 +1167,20 @@ IcePy::StructInfo::optionalFormat() const
return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
}
+bool
+IcePy::StructInfo::usesClasses() const
+{
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ if((*p)->type->usesClasses())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void
IcePy::StructInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional,
const Ice::StringSeq*)
@@ -1325,6 +1345,12 @@ IcePy::SequenceInfo::optionalFormat() const
return elementType->variableLength() ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
}
+bool
+IcePy::SequenceInfo::usesClasses() const
+{
+ return elementType->usesClasses();
+}
+
void
IcePy::SequenceInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional,
const Ice::StringSeq* metaData)
@@ -2219,6 +2245,12 @@ IcePy::CustomInfo::optionalFormat() const
return Ice::OptionalFormatVSize;
}
+bool
+IcePy::CustomInfo::usesClasses() const
+{
+ return false;
+}
+
void
IcePy::CustomInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool,
const Ice::StringSeq* metaData)
@@ -2385,6 +2417,12 @@ IcePy::DictionaryInfo::optionalFormat() const
return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
}
+bool
+IcePy::DictionaryInfo::usesClasses() const
+{
+ return valueType->usesClasses();
+}
+
void
IcePy::DictionaryInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional,
const Ice::StringSeq*)
@@ -2647,6 +2685,12 @@ IcePy::ClassInfo::optionalFormat() const
return Ice::OptionalFormatSize;
}
+bool
+IcePy::ClassInfo::usesClasses() const
+{
+ return true;
+}
+
void
IcePy::ClassInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool,
const Ice::StringSeq*)
@@ -3467,6 +3511,12 @@ IcePy::ExceptionWriter::write(const Ice::OutputStreamPtr& os) const
_info->marshal(_ex.get(), os, const_cast<ObjectMap*>(&_objects));
}
+bool
+IcePy::ExceptionWriter::usesClasses() const
+{
+ return _info->usesClasses;
+}
+
string
IcePy::ExceptionWriter::ice_name() const
{
@@ -3512,6 +3562,12 @@ IcePy::ExceptionReader::read(const Ice::InputStreamPtr& is) const
const_cast<Ice::SlicedDataPtr&>(_slicedData) = is->endException(_info->preserve);
}
+bool
+IcePy::ExceptionReader::usesClasses() const
+{
+ return _info->usesClasses;
+}
+
string
IcePy::ExceptionReader::ice_name() const
{
@@ -4048,6 +4104,19 @@ IcePy_defineException(PyObject*, PyObject* args)
convertDataMembers(members, info->members, info->optionalMembers, true);
+ info->usesClasses = false;
+
+ //
+ // Only examine the required members to see if any use classes.
+ //
+ for(DataMemberList::iterator p = info->members.begin(); p != info->members.end(); ++p)
+ {
+ if(!info->usesClasses)
+ {
+ info->usesClasses = (*p)->type->usesClasses();
+ }
+ }
+
info->pythonType = type;
Py_INCREF(type);
diff --git a/py/modules/IcePy/Types.h b/py/modules/IcePy/Types.h
index cf969fbb1f0..fe20b242976 100644
--- a/py/modules/IcePy/Types.h
+++ b/py/modules/IcePy/Types.h
@@ -107,6 +107,8 @@ public:
virtual int wireSize() const = 0;
virtual Ice::OptionalFormat optionalFormat() const = 0;
+ virtual bool usesClasses() const; // Default implementation returns false.
+
virtual void unmarshaled(PyObject*, PyObject*, void*); // Default implementation is assert(false).
virtual void destroy();
@@ -232,6 +234,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const;
+
virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool,
const Ice::StringSeq* = 0);
@@ -268,6 +272,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const;
+
virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool,
const Ice::StringSeq* = 0);
@@ -326,6 +332,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const;
+
virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool,
const Ice::StringSeq* = 0);
@@ -356,6 +364,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const;
+
virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool,
const Ice::StringSeq* = 0);
@@ -404,6 +414,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const;
+
virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool,
const Ice::StringSeq* = 0);
@@ -477,6 +489,7 @@ public:
ExceptionInfoPtr base;
DataMemberList members;
DataMemberList optionalMembers;
+ bool usesClasses;
PyObjectHandle pythonType;
private:
@@ -545,6 +558,7 @@ public:
~ExceptionWriter() throw();
virtual void write(const Ice::OutputStreamPtr&) const;
+ virtual bool usesClasses() const;
virtual std::string ice_name() const;
virtual Ice::UserException* ice_clone() const;
@@ -568,6 +582,7 @@ public:
~ExceptionReader() throw();
virtual void read(const Ice::InputStreamPtr&) const;
+ virtual bool usesClasses() const;
virtual std::string ice_name() const;
virtual Ice::UserException* ice_clone() const;
diff --git a/py/test/Ice/objects/AllTests.py b/py/test/Ice/objects/AllTests.py
index 97305076274..7316549b80b 100644
--- a/py/test/Ice/objects/AllTests.py
+++ b/py/test/Ice/objects/AllTests.py
@@ -184,6 +184,14 @@ def allTests(communicator, collocated):
test(d.theB.theC.postUnmarshalInvoked())
print("ok")
+ sys.stdout.write("testing sequences... ")
+ sys.stdout.flush()
+ initial.opBaseSeq([])
+
+ retS, outS = initial.opBaseSeq([Test.Base()])
+ test(len(retS) == 1 and len(outS) == 1)
+ print("ok")
+
if not collocated:
sys.stdout.write("testing UnexpectedObjectException... ")
sys.stdout.flush()
diff --git a/py/test/Ice/objects/Test.ice b/py/test/Ice/objects/Test.ice
index 120426ee074..c83b928c0c2 100644
--- a/py/test/Ice/objects/Test.ice
+++ b/py/test/Ice/objects/Test.ice
@@ -12,6 +12,22 @@
module Test
{
+struct S
+{
+ string str;
+};
+
+class Base
+{
+ S theS;
+ string str;
+};
+
+class AbstractBase extends Base
+{
+ void op();
+};
+
class B;
class C;
@@ -75,6 +91,8 @@ class H implements I
{
};
+sequence<Base> BaseSeq;
+
class Initial
{
void shutdown();
@@ -92,6 +110,8 @@ class Initial
I getH();
void setI(I theI);
+
+ BaseSeq opBaseSeq(BaseSeq inSeq, out BaseSeq outSeq);
};
};
diff --git a/py/test/Ice/objects/TestI.py b/py/test/Ice/objects/TestI.py
index 7f1f2791c2f..7e8b2931e75 100644
--- a/py/test/Ice/objects/TestI.py
+++ b/py/test/Ice/objects/TestI.py
@@ -151,6 +151,9 @@ class InitialI(Test.Initial):
def setI(self, i, current=None):
pass
+ def opBaseSeq(self, inSeq, current=None):
+ return (inSeq, inSeq)
+
class UnexpectedObjectExceptionTestI(Test.UnexpectedObjectExceptionTest):
def op(self, current=None):
return Test.AlsoEmpty()
diff --git a/py/test/Ice/optional/AllTests.py b/py/test/Ice/optional/AllTests.py
index b5e25d02e36..c762a1188fb 100644
--- a/py/test/Ice/optional/AllTests.py
+++ b/py/test/Ice/optional/AllTests.py
@@ -306,6 +306,17 @@ def allTests(communicator):
test(mo9.bos == Ice.Unset)
+ #
+ # Use the 1.0 encoding with operations whose only class parameters are optional.
+ #
+ initial.sendOptionalClass(True, Test.OneOptional(53))
+ initial.ice_encodingVersion(Ice.Encoding_1_0).sendOptionalClass(True, Test.OneOptional(53))
+
+ r = initial.returnOptionalClass(True)
+ test(r != Ice.Unset)
+ r = initial.ice_encodingVersion(Ice.Encoding_1_0).returnOptionalClass(True)
+ test(r == Ice.Unset)
+
print("ok")
sys.stdout.write("testing marshaling of large containers with fixed size elements... ")
@@ -690,6 +701,16 @@ def allTests(communicator):
test(ex.o.a == 53)
try:
+ #
+ # Use the 1.0 encoding with an exception whose only class members are optional.
+ #
+ initial.ice_encodingVersion(Ice.Encoding_1_0).opOptionalException(30, "test", Test.OneOptional(53))
+ except Test.OptionalException as ex:
+ test(ex.a == Ice.Unset)
+ test(ex.b == Ice.Unset)
+ test(ex.o == Ice.Unset)
+
+ try:
initial.opDerivedException(Ice.Unset, Ice.Unset, Ice.Unset)
except Test.DerivedException as ex:
test(ex.a == Ice.Unset)
diff --git a/py/test/Ice/optional/Server.py b/py/test/Ice/optional/Server.py
index 87fe29db70c..a3225fb8552 100755
--- a/py/test/Ice/optional/Server.py
+++ b/py/test/Ice/optional/Server.py
@@ -23,10 +23,10 @@ class InitialI(Test.Initial):
return o
def opOptionalException(self, a, b, o, current=None):
- raise Test.OptionalException(a, b, o)
+ raise Test.OptionalException(False, a, b, o)
def opDerivedException(self, a, b, o, current=None):
- raise Test.DerivedException(a, b, o, b, o)
+ raise Test.DerivedException(False, a, b, o, b, o)
def opRequiredException(self, a, b, o, current=None):
e = Test.RequiredException()
@@ -132,6 +132,12 @@ class InitialI(Test.Initial):
def opClassAndUnknownOptional(self, p, current=None):
pass
+ def sendOptionalClass(self, req, o, current=None):
+ pass
+
+ def returnOptionalClass(self, req, current=None):
+ return Test.OneOptional(5)
+
def supportsRequiredParams(self, current=None):
return False
diff --git a/py/test/Ice/optional/ServerAMD.py b/py/test/Ice/optional/ServerAMD.py
index 8d89cd6f533..11306afb888 100755
--- a/py/test/Ice/optional/ServerAMD.py
+++ b/py/test/Ice/optional/ServerAMD.py
@@ -24,10 +24,10 @@ class InitialI(Test.Initial):
cb.ice_response(o)
def opOptionalException_async(self, cb, a, b, o, current=None):
- cb.ice_exception(Test.OptionalException(a, b, o))
+ cb.ice_exception(Test.OptionalException(False, a, b, o))
def opDerivedException_async(self, cb, a, b, o, current=None):
- cb.ice_exception(Test.DerivedException(a, b, o, b, o))
+ cb.ice_exception(Test.DerivedException(False, a, b, o, b, o))
def opRequiredException_async(self, cb, a, b, o, current=None):
e = Test.RequiredException()
@@ -133,6 +133,12 @@ class InitialI(Test.Initial):
def opClassAndUnknownOptional_async(self, cb, p, current=None):
cb.ice_response()
+ def sendOptionalClass_async(self, cb, req, o, current=None):
+ cb.ice_response()
+
+ def returnOptionalClass_async(self, cb, req, current=None):
+ cb.ice_response(Test.OneOptional(5))
+
def supportsRequiredParams_async(self, cb, current=None):
cb.ice_response(False)
diff --git a/py/test/Ice/optional/Test.ice b/py/test/Ice/optional/Test.ice
index 9783959248c..3d4bb6ac635 100644
--- a/py/test/Ice/optional/Test.ice
+++ b/py/test/Ice/optional/Test.ice
@@ -136,6 +136,7 @@ class WD
exception OptionalException
{
+ bool req = false;
optional(1) int a = 5;
optional(2) string b;
optional(50) OneOptional o;
@@ -238,6 +239,10 @@ class Initial
void opClassAndUnknownOptional(A p);
+ void sendOptionalClass(bool req, optional(1) OneOptional o);
+
+ void returnOptionalClass(bool req, out optional(1) OneOptional o);
+
bool supportsRequiredParams();
bool supportsJavaSerializable();
diff --git a/py/test/Ice/optional/TestAMD.ice b/py/test/Ice/optional/TestAMD.ice
index 005d58d4ce3..bbd6251eed9 100644
--- a/py/test/Ice/optional/TestAMD.ice
+++ b/py/test/Ice/optional/TestAMD.ice
@@ -136,6 +136,7 @@ class WD
exception OptionalException
{
+ bool req = false;
optional(1) int a = 5;
optional(2) string b;
optional(50) OneOptional o;
@@ -238,6 +239,10 @@ class Initial
void opClassAndUnknownOptional(A p);
+ void sendOptionalClass(bool req, optional(1) OneOptional o);
+
+ void returnOptionalClass(bool req, out optional(1) OneOptional o);
+
bool supportsRequiredParams();
bool supportsJavaSerializable();
diff --git a/rb/src/IceRuby/Operation.cpp b/rb/src/IceRuby/Operation.cpp
index 6cebeea2f55..f4e16f7c683 100644
--- a/rb/src/IceRuby/Operation.cpp
+++ b/rb/src/IceRuby/Operation.cpp
@@ -65,9 +65,11 @@ private:
ParamInfoPtr _returnType;
ExceptionInfoList _exceptions;
string _dispatchName;
+ bool _sendsClasses;
+ bool _returnsClasses;
string _deprecateMessage;
- void convertParams(VALUE, ParamInfoList&, int);
+ void convertParams(VALUE, ParamInfoList&, int, bool&);
ParamInfoPtr convertParam(VALUE, int);
void prepareRequest(const Ice::ObjectPrx&, VALUE, vector<Ice::Byte>&);
VALUE unmarshalResults(const vector<Ice::Byte>&, const Ice::CommunicatorPtr&);
@@ -220,20 +222,26 @@ IceRuby::OperationI::OperationI(VALUE name, VALUE mode, VALUE sendMode, VALUE am
//
// returnType
//
+ _returnsClasses = false;
if(!NIL_P(returnType))
{
_returnType = convertParam(returnType, 0);
+ if(!_returnType->optional)
+ {
+ _returnsClasses = _returnType->type->usesClasses();
+ }
}
//
// inParams
//
- convertParams(inParams, _inParams, 0);
+ _sendsClasses = false;
+ convertParams(inParams, _inParams, 0, _sendsClasses);
//
// outParams
//
- convertParams(outParams, _outParams, NIL_P(returnType) ? 0 : 1);
+ convertParams(outParams, _outParams, NIL_P(returnType) ? 0 : 1, _returnsClasses);
class SortFn
{
@@ -368,7 +376,7 @@ IceRuby::OperationI::deprecate(const string& msg)
}
void
-IceRuby::OperationI::convertParams(VALUE v, ParamInfoList& params, int posOffset)
+IceRuby::OperationI::convertParams(VALUE v, ParamInfoList& params, int posOffset, bool& usesClasses)
{
assert(TYPE(v) == T_ARRAY);
@@ -376,6 +384,10 @@ IceRuby::OperationI::convertParams(VALUE v, ParamInfoList& params, int posOffset
{
ParamInfoPtr param = convertParam(RARRAY_PTR(v)[i], i + posOffset);
params.push_back(param);
+ if(!param->optional && !usesClasses)
+ {
+ usesClasses = param->type->usesClasses();
+ }
}
}
@@ -457,6 +469,11 @@ IceRuby::OperationI::prepareRequest(const Ice::ObjectPrx& proxy, VALUE args, vec
}
}
+ if(_sendsClasses)
+ {
+ os->writePendingObjects();
+ }
+
os->endEncapsulation();
os->finished(bytes);
}
@@ -532,6 +549,11 @@ IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice:
}
}
+ if(_returnsClasses)
+ {
+ is->readPendingObjects();
+ }
+
is->endEncapsulation();
util.update();
diff --git a/rb/src/IceRuby/Types.cpp b/rb/src/IceRuby/Types.cpp
index da4ec6df9f0..e8c7a21c3db 100644
--- a/rb/src/IceRuby/Types.cpp
+++ b/rb/src/IceRuby/Types.cpp
@@ -390,6 +390,12 @@ IceRuby::TypeInfo::TypeInfo()
{
}
+bool
+IceRuby::TypeInfo::usesClasses() const
+{
+ return false;
+}
+
void
IceRuby::TypeInfo::unmarshaled(VALUE, VALUE, void*)
{
@@ -939,6 +945,20 @@ IceRuby::StructInfo::optionalFormat() const
return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
}
+bool
+IceRuby::StructInfo::usesClasses() const
+{
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ if((*p)->type->usesClasses())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void
IceRuby::StructInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
{
@@ -1092,6 +1112,12 @@ IceRuby::SequenceInfo::optionalFormat() const
return elementType->variableLength() ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
}
+bool
+IceRuby::SequenceInfo::usesClasses() const
+{
+ return elementType->usesClasses();
+}
+
void
IceRuby::SequenceInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional)
{
@@ -1621,6 +1647,12 @@ IceRuby::DictionaryInfo::optionalFormat() const
return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize;
}
+bool
+IceRuby::DictionaryInfo::usesClasses() const
+{
+ return valueType->usesClasses();
+}
+
namespace
{
struct DictionaryMarshalIterator : public IceRuby::HashIterator
@@ -1956,6 +1988,12 @@ IceRuby::ClassInfo::optionalFormat() const
return Ice::OptionalFormatSize;
}
+bool
+IceRuby::ClassInfo::usesClasses() const
+{
+ return true;
+}
+
void
IceRuby::ClassInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool)
{
@@ -2683,6 +2721,12 @@ IceRuby::ExceptionReader::read(const Ice::InputStreamPtr& is) const
const_cast<Ice::SlicedDataPtr&>(_slicedData) = is->endException(_info->preserve);
}
+bool
+IceRuby::ExceptionReader::usesClasses() const
+{
+ return _info->usesClasses;
+}
+
string
IceRuby::ExceptionReader::ice_name() const
{
@@ -2847,6 +2891,19 @@ IceRuby_defineException(VALUE /*self*/, VALUE id, VALUE type, VALUE preserve, VA
convertDataMembers(members, info->members, info->optionalMembers, true);
+ info->usesClasses = false;
+
+ //
+ // Only examine the required members to see if any use classes.
+ //
+ for(DataMemberList::iterator p = info->members.begin(); p != info->members.end(); ++p)
+ {
+ if(!info->usesClasses)
+ {
+ info->usesClasses = (*p)->type->usesClasses();
+ }
+ }
+
info->rubyClass = type;
addExceptionInfo(info->id, info);
diff --git a/rb/src/IceRuby/Types.h b/rb/src/IceRuby/Types.h
index fa9c9a73ee6..9acf1e15d4d 100644
--- a/rb/src/IceRuby/Types.h
+++ b/rb/src/IceRuby/Types.h
@@ -109,6 +109,8 @@ public:
virtual int wireSize() const = 0;
virtual Ice::OptionalFormat optionalFormat() const = 0;
+ virtual bool usesClasses() const; // Default implementation returns false.
+
virtual void unmarshaled(VALUE, VALUE, void*); // Default implementation is assert(false).
virtual void destroy();
@@ -234,6 +236,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const; // Default implementation returns false.
+
virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
@@ -269,6 +273,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const; // Default implementation returns false.
+
virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
virtual void unmarshaled(VALUE, VALUE, void*);
@@ -305,6 +311,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const; // Default implementation returns false.
+
virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
void marshalElement(VALUE, VALUE, const Ice::OutputStreamPtr&, ObjectMap*);
@@ -354,6 +362,8 @@ public:
virtual int wireSize() const;
virtual Ice::OptionalFormat optionalFormat() const;
+ virtual bool usesClasses() const; // Default implementation returns false.
+
virtual void marshal(VALUE, const Ice::OutputStreamPtr&, ObjectMap*, bool);
virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, VALUE, void*, bool);
@@ -429,6 +439,7 @@ public:
ExceptionInfoPtr base;
DataMemberList members;
DataMemberList optionalMembers;
+ bool usesClasses;
VALUE rubyClass;
};
@@ -491,6 +502,7 @@ public:
~ExceptionReader() throw();
virtual void read(const Ice::InputStreamPtr&) const;
+ virtual bool usesClasses() const;
virtual std::string ice_name() const;
virtual Ice::UserException* ice_clone() const;
diff --git a/rb/test/Ice/objects/AllTests.rb b/rb/test/Ice/objects/AllTests.rb
index 767c70e036b..6994e62bf5c 100644
--- a/rb/test/Ice/objects/AllTests.rb
+++ b/rb/test/Ice/objects/AllTests.rb
@@ -200,6 +200,14 @@ def allTests(communicator)
initial.setI(h)
puts "ok"
+ print "testing sequences... "
+ STDOUT.flush
+ initial.opBaseSeq([])
+
+ retS, outS = initial.opBaseSeq([Test::Base.new])
+ test(retS.length == 1 && outS.length == 1)
+ puts "ok"
+
print "testing UnexpectedObjectException... "
STDOUT.flush
ref = "uoet:default -p 12010"
diff --git a/rb/test/Ice/objects/Test.ice b/rb/test/Ice/objects/Test.ice
index f8b3d7df87f..c83b928c0c2 100644
--- a/rb/test/Ice/objects/Test.ice
+++ b/rb/test/Ice/objects/Test.ice
@@ -12,6 +12,22 @@
module Test
{
+struct S
+{
+ string str;
+};
+
+class Base
+{
+ S theS;
+ string str;
+};
+
+class AbstractBase extends Base
+{
+ void op();
+};
+
class B;
class C;
@@ -75,14 +91,11 @@ class H implements I
{
};
-class K implements J
-{
-};
+sequence<Base> BaseSeq;
class Initial
{
void shutdown();
-
B getB1();
B getB2();
C getC();
@@ -97,6 +110,8 @@ class Initial
I getH();
void setI(I theI);
+
+ BaseSeq opBaseSeq(BaseSeq inSeq, out BaseSeq outSeq);
};
};
diff --git a/rb/test/Ice/optional/AllTests.rb b/rb/test/Ice/optional/AllTests.rb
index e09a0c5317a..ff149b93781 100644
--- a/rb/test/Ice/optional/AllTests.rb
+++ b/rb/test/Ice/optional/AllTests.rb
@@ -300,6 +300,17 @@ def allTests(communicator)
test(mo9.bos == Ice::Unset)
+ #
+ # Use the 1.0 encoding with operations whose only class parameters are optional.
+ #
+ initial.sendOptionalClass(true, Test::OneOptional.new(53))
+ initial.ice_encodingVersion(Ice::Encoding_1_0).sendOptionalClass(true, Test::OneOptional.new(53))
+
+ r = initial.returnOptionalClass(true)
+ test(r != Ice::Unset)
+ r = initial.ice_encodingVersion(Ice::Encoding_1_0).returnOptionalClass(true)
+ test(r == Ice::Unset)
+
puts "ok"
print "testing marshaling of large containers with fixed size elements... "
@@ -633,6 +644,17 @@ def allTests(communicator)
end
begin
+ #
+ # Use the 1.0 encoding with an exception whose only class members are optional.
+ #
+ initial.ice_encodingVersion(Ice::Encoding_1_0).opOptionalException(30, "test", Test::OneOptional.new(53))
+ rescue Test::OptionalException => ex
+ test(ex.a == Ice::Unset)
+ test(ex.b == Ice::Unset)
+ test(ex.o == Ice::Unset)
+ end
+
+ begin
initial.opDerivedException(Ice::Unset, Ice::Unset, Ice::Unset)
rescue Test::DerivedException => ex
test(ex.a == Ice::Unset)
diff --git a/rb/test/Ice/optional/Test.ice b/rb/test/Ice/optional/Test.ice
index 7f0342b8df4..8cc213df42c 100644
--- a/rb/test/Ice/optional/Test.ice
+++ b/rb/test/Ice/optional/Test.ice
@@ -136,6 +136,7 @@ class WD
exception OptionalException
{
+ bool req = false;
optional(1) int a = 5;
optional(2) string b;
optional(50) OneOptional o;
@@ -230,12 +231,18 @@ class Initial
optional(1) VarStructSeq opVarStructSeq(optional(2) VarStructSeq p1, out optional(3) VarStructSeq p3);
+ optional(1) Serializable opSerializable(optional(2) Serializable p1, out optional(3) Serializable p3);
+
optional(1) IntIntDict opIntIntDict(optional(2) IntIntDict p1, out optional(3) IntIntDict p3);
optional(1) StringIntDict opStringIntDict(optional(2) StringIntDict p1, out optional(3) StringIntDict p3);
void opClassAndUnknownOptional(A p);
+ void sendOptionalClass(bool req, optional(1) OneOptional o);
+
+ void returnOptionalClass(bool req, out optional(1) OneOptional o);
+
bool supportsRequiredParams();
bool supportsJavaSerializable();