summaryrefslogtreecommitdiff
path: root/py
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 /py
parentICE-4914 - Update Database/Oracle demos (diff)
downloadice-493caea19fd83663eb03b4eeaf7714f99ac07b97.tar.bz2
ice-493caea19fd83663eb03b4eeaf7714f99ac07b97.tar.xz
ice-493caea19fd83663eb03b4eeaf7714f99ac07b97.zip
ICE-4930 - fixes for scripting languages
Diffstat (limited to 'py')
-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
11 files changed, 198 insertions, 8 deletions
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();