summaryrefslogtreecommitdiff
path: root/py/modules/IcePy/Operation.cpp
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2015-03-21 15:35:40 -0230
committerMatthew Newhook <matthew@zeroc.com>2015-03-21 15:35:40 -0230
commit630a37d2fe66f24518299e705f958b571803c522 (patch)
tree969723791bdc4d73bb099c19d45554d0ca241ad9 /py/modules/IcePy/Operation.cpp
parentFix some README.md markdown formatting (diff)
downloadice-630a37d2fe66f24518299e705f958b571803c522.tar.bz2
ice-630a37d2fe66f24518299e705f958b571803c522.tar.xz
ice-630a37d2fe66f24518299e705f958b571803c522.zip
py -> python
rb -> ruby objc -> objective-c cs -> csharp
Diffstat (limited to 'py/modules/IcePy/Operation.cpp')
-rw-r--r--py/modules/IcePy/Operation.cpp4219
1 files changed, 0 insertions, 4219 deletions
diff --git a/py/modules/IcePy/Operation.cpp b/py/modules/IcePy/Operation.cpp
deleted file mode 100644
index 5ca673898f4..00000000000
--- a/py/modules/IcePy/Operation.cpp
+++ /dev/null
@@ -1,4219 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2015 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.
-//
-// **********************************************************************
-
-#ifdef _WIN32
-# include <IceUtil/Config.h>
-#endif
-#include <Operation.h>
-#include <Communicator.h>
-#include <Current.h>
-#include <Proxy.h>
-#include <Thread.h>
-#include <Types.h>
-#include <Connection.h>
-#include <Util.h>
-#include <Ice/Communicator.h>
-#include <Ice/IncomingAsync.h>
-#include <Ice/Initialize.h>
-#include <Ice/LocalException.h>
-#include <Ice/Logger.h>
-#include <Ice/ObjectAdapter.h>
-#include <Ice/AsyncResult.h>
-#include <Ice/Properties.h>
-#include <Ice/Proxy.h>
-#include <Slice/PythonUtil.h>
-
-using namespace std;
-using namespace IcePy;
-using namespace Slice::Python;
-
-namespace IcePy
-{
-
-//
-// Information about an operation's parameter.
-//
-class ParamInfo : public UnmarshalCallback
-{
-public:
-
- virtual void unmarshaled(PyObject*, PyObject*, void*);
-
- Ice::StringSeq metaData;
- TypeInfoPtr type;
- bool optional;
- int tag;
- int pos;
-};
-typedef IceUtil::Handle<ParamInfo> ParamInfoPtr;
-typedef list<ParamInfoPtr> ParamInfoList;
-
-//
-// Encapsulates attributes of an operation.
-//
-class Operation : public IceUtil::Shared
-{
-public:
-
- Operation(const char*, PyObject*, PyObject*, int, PyObject*, PyObject*, PyObject*, PyObject*, PyObject*, PyObject*);
-
- void deprecate(const string&);
-
- string name;
- Ice::OperationMode mode;
- Ice::OperationMode sendMode;
- bool amd;
- Ice::FormatType format;
- Ice::StringSeq metaData;
- ParamInfoList inParams;
- ParamInfoList optionalInParams;
- ParamInfoList outParams;
- ParamInfoList optionalOutParams;
- ParamInfoPtr returnType;
- ExceptionInfoList exceptions;
- string dispatchName;
- bool sendsClasses;
- bool returnsClasses;
- bool pseudoOp;
-
-private:
-
- string _deprecateMessage;
-
- static void convertParams(PyObject*, ParamInfoList&, int, bool&);
- static ParamInfoPtr convertParam(PyObject*, int);
-};
-typedef IceUtil::Handle<Operation> OperationPtr;
-
-//
-// The base class for client-side invocations.
-//
-class Invocation : virtual public IceUtil::Shared
-{
-public:
-
- Invocation(const Ice::ObjectPrx&);
-
- virtual PyObject* invoke(PyObject*, PyObject* = 0) = 0;
-
-protected:
-
- Ice::ObjectPrx _prx;
-};
-typedef IceUtil::Handle<Invocation> InvocationPtr;
-
-//
-// TypedInvocation uses the information in the given Operation to validate, marshal, and unmarshal
-// parameters and exceptions.
-//
-class TypedInvocation : virtual public Invocation
-{
-public:
-
- TypedInvocation(const Ice::ObjectPrx&, const OperationPtr&);
-
-protected:
-
- OperationPtr _op;
- Ice::CommunicatorPtr _communicator;
-
- enum MappingType { SyncMapping, AsyncMapping, OldAsyncMapping };
-
- bool prepareRequest(PyObject*, MappingType, Ice::OutputStreamPtr&, pair<const Ice::Byte*, const Ice::Byte*>&);
- PyObject* unmarshalResults(const pair<const Ice::Byte*, const Ice::Byte*>&);
- PyObject* unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>&);
- bool validateException(PyObject*) const;
- void checkTwowayOnly(const Ice::ObjectPrx&) const;
-};
-
-//
-// Synchronous typed invocation.
-//
-class SyncTypedInvocation : virtual public TypedInvocation
-{
-public:
-
- SyncTypedInvocation(const Ice::ObjectPrx&, const OperationPtr&);
-
- virtual PyObject* invoke(PyObject*, PyObject* = 0);
-};
-
-//
-// Asynchronous typed invocation.
-//
-class AsyncTypedInvocation : virtual public TypedInvocation
-{
-public:
-
- AsyncTypedInvocation(const Ice::ObjectPrx&, PyObject*, const OperationPtr&);
- ~AsyncTypedInvocation();
-
- virtual PyObject* invoke(PyObject*, PyObject* = 0);
- PyObject* end(const Ice::ObjectPrx&, const OperationPtr&, const Ice::AsyncResultPtr&);
-
- string opName() const;
-
- void response(bool, const pair<const Ice::Byte*, const Ice::Byte*>&);
- void exception(const Ice::Exception&);
- void sent(bool);
-
-protected:
-
- void checkAsyncTwowayOnly(const Ice::ObjectPrx&) const;
-
- PyObject* _pyProxy;
- PyObject* _response;
- PyObject* _ex;
- PyObject* _sent;
-};
-typedef IceUtil::Handle<AsyncTypedInvocation> AsyncTypedInvocationPtr;
-
-//
-// Old-style asynchronous typed invocation.
-//
-class OldAsyncTypedInvocation : virtual public TypedInvocation
-{
-public:
-
- OldAsyncTypedInvocation(const Ice::ObjectPrx&, const OperationPtr&);
- ~OldAsyncTypedInvocation();
-
- virtual PyObject* invoke(PyObject*, PyObject* = 0);
-
- void response(bool, const pair<const Ice::Byte*, const Ice::Byte*>&);
- void exception(const Ice::Exception&);
- void sent(bool);
-
-protected:
-
- PyObject* _callback;
-};
-
-//
-// Synchronous blobject invocation.
-//
-class SyncBlobjectInvocation : virtual public Invocation
-{
-public:
-
- SyncBlobjectInvocation(const Ice::ObjectPrx&);
-
- virtual PyObject* invoke(PyObject*, PyObject* = 0);
-};
-
-//
-// Asynchronous blobject invocation.
-//
-class AsyncBlobjectInvocation : virtual public Invocation
-{
-public:
-
- AsyncBlobjectInvocation(const Ice::ObjectPrx&, PyObject*);
- ~AsyncBlobjectInvocation();
-
- virtual PyObject* invoke(PyObject*, PyObject* = 0);
- PyObject* end(const Ice::ObjectPrx&, const Ice::AsyncResultPtr&);
-
- void response(bool, const pair<const Ice::Byte*, const Ice::Byte*>&);
- void exception(const Ice::Exception&);
- void sent(bool);
-
-protected:
-
- PyObject* _pyProxy;
- string _op;
- PyObject* _response;
- PyObject* _ex;
- PyObject* _sent;
-};
-typedef IceUtil::Handle<AsyncBlobjectInvocation> AsyncBlobjectInvocationPtr;
-
-//
-// Old-style asynchronous blobject invocation.
-//
-class OldAsyncBlobjectInvocation : virtual public Invocation
-{
-public:
-
- OldAsyncBlobjectInvocation(const Ice::ObjectPrx&);
- ~OldAsyncBlobjectInvocation();
-
- virtual PyObject* invoke(PyObject*, PyObject* = 0);
-
- void response(bool, const pair<const Ice::Byte*, const Ice::Byte*>&);
- void exception(const Ice::Exception&);
- void sent(bool);
-
-protected:
-
- string _op;
- PyObject* _callback;
-};
-
-//
-// The base class for server-side upcalls.
-//
-class Upcall : virtual public IceUtil::Shared
-{
-public:
-
- virtual void dispatch(PyObject*, const pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&) = 0;
- virtual void response(PyObject*, const Ice::EncodingVersion&) = 0;
- virtual void exception(PyException&, const Ice::EncodingVersion&) = 0;
-};
-typedef IceUtil::Handle<Upcall> UpcallPtr;
-
-//
-// TypedInvocation uses the information in the given Operation to validate, marshal, and unmarshal
-// parameters and exceptions.
-//
-class TypedUpcall : virtual public Upcall
-{
-public:
-
- TypedUpcall(const OperationPtr&, const Ice::AMD_Object_ice_invokePtr&, const Ice::CommunicatorPtr&);
-
- virtual void dispatch(PyObject*, const pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&);
- virtual void response(PyObject*, const Ice::EncodingVersion&);
- virtual void exception(PyException&, const Ice::EncodingVersion&);
-
-private:
-
- bool validateException(PyObject*) const;
-
- OperationPtr _op;
- Ice::AMD_Object_ice_invokePtr _callback;
- Ice::CommunicatorPtr _communicator;
- bool _finished;
-};
-
-//
-// Upcall for blobject servants.
-//
-class BlobjectUpcall : virtual public Upcall
-{
-public:
-
- BlobjectUpcall(bool, const Ice::AMD_Object_ice_invokePtr&);
-
- virtual void dispatch(PyObject*, const pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&);
- virtual void response(PyObject*, const Ice::EncodingVersion&);
- virtual void exception(PyException&, const Ice::EncodingVersion&);
-
-private:
-
- bool _amd;
- Ice::AMD_Object_ice_invokePtr _callback;
- bool _finished;
-};
-
-//
-// TypedServantWrapper uses the information in Operation to validate, marshal, and unmarshal
-// parameters and exceptions.
-//
-class TypedServantWrapper : public ServantWrapper
-{
-public:
-
- TypedServantWrapper(PyObject*);
-
- virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&,
- const pair<const Ice::Byte*, const Ice::Byte*>&,
- const Ice::Current&);
-
-private:
-
- typedef map<string, OperationPtr> OperationMap;
- OperationMap _operationMap;
- OperationMap::iterator _lastOp;
-};
-
-//
-// Encapsulates a blobject servant.
-//
-class BlobjectServantWrapper : public ServantWrapper
-{
-public:
-
- BlobjectServantWrapper(PyObject*, bool);
-
- virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&,
- const pair<const Ice::Byte*, const Ice::Byte*>&,
- const Ice::Current&);
-
-private:
-
- bool _amd;
-};
-
-struct OperationObject
-{
- PyObject_HEAD
- OperationPtr* op;
-};
-
-struct AMDCallbackObject
-{
- PyObject_HEAD
- UpcallPtr* upcall;
- Ice::EncodingVersion encoding;
-};
-
-struct AsyncResultObject
-{
- PyObject_HEAD
- Ice::AsyncResultPtr* result;
- InvocationPtr* invocation;
- PyObject* proxy;
- PyObject* connection;
- PyObject* communicator;
-};
-
-extern PyTypeObject OperationType;
-extern PyTypeObject AMDCallbackType;
-
-class UserExceptionReaderFactoryI : public Ice::UserExceptionReaderFactory
-{
-public:
-
- UserExceptionReaderFactoryI(const Ice::CommunicatorPtr& communicator) :
- _communicator(communicator)
- {
- }
-
- virtual void createAndThrow(const string& id) const
- {
- ExceptionInfoPtr info = lookupExceptionInfo(id);
- if(info)
- {
- throw ExceptionReader(_communicator, info);
- }
- }
-
-private:
-
- const Ice::CommunicatorPtr _communicator;
-};
-
-}
-
-namespace
-{
-
-OperationPtr
-getOperation(PyObject* p)
-{
- assert(PyObject_IsInstance(p, reinterpret_cast<PyObject*>(&OperationType)) == 1);
- OperationObject* obj = reinterpret_cast<OperationObject*>(p);
- return *obj->op;
-}
-
-void
-handleException()
-{
- assert(PyErr_Occurred());
-
- PyException ex; // Retrieve it before another Python API call clears it.
-
- //
- // A callback that calls sys.exit() will raise the SystemExit exception.
- // This is normally caught by the interpreter, causing it to exit.
- // However, we have no way to pass this exception to the interpreter,
- // so we act on it directly.
- //
- ex.checkSystemExit();
-
- ex.raise();
-}
-
-void
-callException(PyObject* method, PyObject* ex)
-{
- PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), ex);
- PyObjectHandle tmp = PyObject_Call(method, args.get(), 0);
- if(PyErr_Occurred())
- {
- handleException(); // Callback raised an exception.
- }
-}
-
-void
-callException(PyObject* method, const Ice::Exception& ex)
-{
- PyObjectHandle exh = convertException(ex);
- assert(exh.get());
- callException(method, exh.get());
-}
-
-void
-callException(PyObject* callback, const string& op, const string& method, PyObject* ex)
-{
- if(!PyObject_HasAttrString(callback, STRCAST(method.c_str())))
- {
- ostringstream ostr;
- ostr << "AMI callback object for operation `" << op << "' does not define " << method << "()";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- }
- else
- {
- PyObjectHandle m = PyObject_GetAttrString(callback, STRCAST(method.c_str()));
- assert(m.get());
- callException(m.get(), ex);
- }
-}
-
-void
-callException(PyObject* callback, const string& op, const string& method, const Ice::Exception& ex)
-{
- PyObjectHandle exh = convertException(ex);
- assert(exh.get());
- callException(callback, op, method, exh.get());
-}
-
-void
-callSent(PyObject* method, bool sentSynchronously, bool passArg)
-{
- PyObjectHandle args;
- if(passArg)
- {
- args = Py_BuildValue(STRCAST("(O)"), sentSynchronously ? getTrue() : getFalse());
- }
- else
- {
- args = PyTuple_New(0);
- }
- PyObjectHandle tmp = PyObject_Call(method, args.get(), 0);
- if(PyErr_Occurred())
- {
- handleException(); // Callback raised an exception.
- }
-}
-
-void
-callSent(PyObject* callback, const string& method, bool sentSynchronously, bool passArg)
-{
- if(PyObject_HasAttrString(callback, STRCAST(method.c_str())))
- {
- PyObjectHandle m = PyObject_GetAttrString(callback, STRCAST(method.c_str()));
- assert(m.get());
- callSent(m.get(), sentSynchronously, passArg);
- }
-}
-
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static OperationObject*
-operationNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/)
-{
- OperationObject* self = reinterpret_cast<OperationObject*>(type->tp_alloc(type, 0));
- if(!self)
- {
- return 0;
- }
- self->op = 0;
- return self;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static int
-operationInit(OperationObject* self, PyObject* args, PyObject* /*kwds*/)
-{
- char* name;
- PyObject* modeType = lookupType("Ice.OperationMode");
- assert(modeType);
- PyObject* mode;
- PyObject* sendMode;
- int amd;
- PyObject* format;
- PyObject* metaData;
- PyObject* inParams;
- PyObject* outParams;
- PyObject* returnType;
- PyObject* exceptions;
- if(!PyArg_ParseTuple(args, STRCAST("sO!O!iOO!O!O!OO!"), &name, modeType, &mode, modeType, &sendMode, &amd,
- &format, &PyTuple_Type, &metaData, &PyTuple_Type, &inParams, &PyTuple_Type, &outParams,
- &returnType, &PyTuple_Type, &exceptions))
- {
- return -1;
- }
-
- OperationPtr op = new Operation(name, mode, sendMode, amd, format, metaData, inParams, outParams, returnType,
- exceptions);
- self->op = new OperationPtr(op);
-
- return 0;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static void
-operationDealloc(OperationObject* self)
-{
- delete self->op;
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-operationInvoke(OperationObject* self, PyObject* args)
-{
- PyObject* pyProxy;
- PyObject* opArgs;
- if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &pyProxy, &PyTuple_Type, &opArgs))
- {
- return 0;
- }
-
- Ice::ObjectPrx prx = getProxy(pyProxy);
- assert(self->op);
-
- InvocationPtr i = new SyncTypedInvocation(prx, *self->op);
- return i->invoke(opArgs);
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-operationInvokeAsync(OperationObject* self, PyObject* args)
-{
- PyObject* pyProxy;
- PyObject* opArgs;
- if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &pyProxy, &PyTuple_Type, &opArgs))
- {
- return 0;
- }
-
- Ice::ObjectPrx prx = getProxy(pyProxy);
- assert(self->op);
-
- InvocationPtr i = new OldAsyncTypedInvocation(prx, *self->op);
- return i->invoke(opArgs);
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-operationBegin(OperationObject* self, PyObject* args)
-{
- PyObject* proxy;
- PyObject* opArgs;
- if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &proxy, &PyTuple_Type, &opArgs))
- {
- return 0;
- }
-
- Ice::ObjectPrx p = getProxy(proxy);
- InvocationPtr i = new AsyncTypedInvocation(p, proxy, *self->op);
- return i->invoke(opArgs);
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-operationEnd(OperationObject* self, PyObject* args)
-{
- PyObject* proxy;
- PyObject* result;
- if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &proxy, &AsyncResultType, &result))
- {
- return 0;
- }
-
- AsyncResultObject* ar = reinterpret_cast<AsyncResultObject*>(result);
- assert(ar);
- AsyncTypedInvocationPtr i = AsyncTypedInvocationPtr::dynamicCast(*ar->invocation);
- if(!i)
- {
- PyErr_Format(PyExc_ValueError, STRCAST("invalid AsyncResult object passed to end_%s"),
- (*self->op)->name.c_str());
- return 0;
- }
- Ice::ObjectPrx p = getProxy(proxy);
- return i->end(p, *self->op, *ar->result);
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-operationDeprecate(OperationObject* self, PyObject* args)
-{
- char* msg;
- if(!PyArg_ParseTuple(args, STRCAST("s"), &msg))
- {
- return 0;
- }
-
- assert(self->op);
- (*self->op)->deprecate(msg);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-//
-// AMDCallback operations
-//
-
-#ifdef WIN32
-extern "C"
-#endif
-static AMDCallbackObject*
-amdCallbackNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/)
-{
- AMDCallbackObject* self = reinterpret_cast<AMDCallbackObject*>(type->tp_alloc(type, 0));
- if(!self)
- {
- return 0;
- }
- self->upcall = 0;
- return self;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static void
-amdCallbackDealloc(AMDCallbackObject* self)
-{
- delete self->upcall;
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-amdCallbackIceResponse(AMDCallbackObject* self, PyObject* args)
-{
- try
- {
- assert(self->upcall);
- (*self->upcall)->response(args, self->encoding);
- }
- catch(...)
- {
- //
- // No exceptions should propagate to Python.
- //
- assert(false);
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-amdCallbackIceException(AMDCallbackObject* self, PyObject* args)
-{
- PyObject* ex;
- if(!PyArg_ParseTuple(args, STRCAST("O"), &ex))
- {
- return 0;
- }
-
- if(!PyObject_IsInstance(ex, PyExc_Exception))
- {
- PyErr_Format(PyExc_TypeError, "ice_exception argument is not an exception");
- return 0;
- }
-
- try
- {
- assert(self->upcall);
- PyException pye(ex); // No traceback information available.
- (*self->upcall)->exception(pye, self->encoding);
- }
- catch(...)
- {
- //
- // No exceptions should propagate to Python.
- //
- assert(false);
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-//
-// AsyncResult operations
-//
-
-#ifdef WIN32
-extern "C"
-#endif
-static AsyncResultObject*
-asyncResultNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/)
-{
- AsyncResultObject* self = reinterpret_cast<AsyncResultObject*>(type->tp_alloc(type, 0));
- if(!self)
- {
- return 0;
- }
- self->result = 0;
- self->invocation = 0;
- self->proxy = 0;
- self->connection = 0;
- self->communicator = 0;
- return self;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static void
-asyncResultDealloc(AsyncResultObject* self)
-{
- delete self->result;
- delete self->invocation;
- Py_XDECREF(self->proxy);
- Py_XDECREF(self->connection);
- Py_XDECREF(self->communicator);
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultGetCommunicator(AsyncResultObject* self)
-{
- if(self->communicator)
- {
- Py_INCREF(self->communicator);
- return self->communicator;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultCancel(AsyncResultObject* self)
-{
- try
- {
- (*self->result)->cancel();
- }
- catch(...)
- {
- assert(false);
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultGetConnection(AsyncResultObject* self)
-{
- if(self->connection)
- {
- Py_INCREF(self->connection);
- return self->connection;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultGetProxy(AsyncResultObject* self)
-{
- if(self->proxy)
- {
- Py_INCREF(self->proxy);
- return self->proxy;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultIsCompleted(AsyncResultObject* self)
-{
- bool b = false;
-
- try
- {
- assert(self->result);
- b = (*self->result)->isCompleted();
- }
- catch(...)
- {
- assert(false);
- }
-
- PyRETURN_BOOL(b);
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultWaitForCompleted(AsyncResultObject* self)
-{
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- try
- {
- assert(self->result);
- (*self->result)->waitForCompleted();
- }
- catch(...)
- {
- assert(false);
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultIsSent(AsyncResultObject* self)
-{
- bool b = false;
-
- try
- {
- assert(self->result);
- b = (*self->result)->isSent();
- }
- catch(...)
- {
- assert(false);
- }
-
- PyRETURN_BOOL(b);
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultWaitForSent(AsyncResultObject* self)
-{
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- try
- {
- assert(self->result);
- (*self->result)->waitForSent();
- }
- catch(...)
- {
- assert(false);
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultThrowLocalException(AsyncResultObject* self)
-{
- try
- {
- assert(self->result);
- (*self->result)->throwLocalException();
- }
- catch(const Ice::LocalException& ex)
- {
- setPythonException(ex);
- return 0;
- }
- catch(...)
- {
- assert(false);
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultSentSynchronously(AsyncResultObject* self)
-{
- bool b = false;
-
- try
- {
- assert(self->result);
- b = (*self->result)->sentSynchronously();
- }
- catch(...)
- {
- assert(false);
- }
-
- PyRETURN_BOOL(b);
-}
-
-#ifdef WIN32
-extern "C"
-#endif
-static PyObject*
-asyncResultGetOperation(AsyncResultObject* self)
-{
- string op;
-
- try
- {
- //
- // Since the extension uses the Blobject API, calling (*self->result)->getOperation()
- // always returns "ice_invoke" as the operation name. If the caller used a regular
- // (typed) proxy method, we obtain the actual operation name from the invocation.
- //
- if(self->invocation)
- {
- AsyncTypedInvocationPtr i = AsyncTypedInvocationPtr::dynamicCast(*self->invocation);
- if(i)
- {
- op = i->opName();
- }
- }
- if(op.empty())
- {
- assert(self->result);
- op = (*self->result)->getOperation();
- }
- }
- catch(...)
- {
- assert(false);
- }
-
- return createString(op);
-}
-
-//
-// ParamInfo implementation.
-//
-void
-IcePy::ParamInfo::unmarshaled(PyObject* val, PyObject* target, void* closure)
-{
- assert(PyTuple_Check(target));
- long i = reinterpret_cast<long>(closure);
- PyTuple_SET_ITEM(target, i, val);
- Py_INCREF(val); // PyTuple_SET_ITEM steals a reference.
-}
-
-//
-// Operation implementation.
-//
-IcePy::Operation::Operation(const char* n, PyObject* m, PyObject* sm, int amdFlag, PyObject* fmt, PyObject* meta,
- PyObject* in, PyObject* out, PyObject* ret, PyObject* ex)
-{
- name = n;
-
- //
- // mode
- //
- PyObjectHandle modeValue = PyObject_GetAttrString(m, STRCAST("value"));
- mode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(modeValue.get()));
- assert(!PyErr_Occurred());
-
- //
- // sendMode
- //
- PyObjectHandle sendModeValue = PyObject_GetAttrString(sm, STRCAST("value"));
- sendMode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(sendModeValue.get()));
- assert(!PyErr_Occurred());
-
- //
- // amd
- //
- amd = amdFlag ? true : false;
- if(amd)
- {
- dispatchName = name + "_async";
- }
- else
- {
- dispatchName = fixIdent(name);
- }
-
- //
- // format
- //
- if(fmt == Py_None)
- {
- format = Ice::DefaultFormat;
- }
- else
- {
- PyObjectHandle formatValue = PyObject_GetAttrString(fmt, STRCAST("value"));
- format = (Ice::FormatType)static_cast<int>(PyLong_AsLong(formatValue.get()));
- assert(!PyErr_Occurred());
- }
-
- //
- // metaData
- //
- assert(PyTuple_Check(meta));
-#ifndef NDEBUG
- bool b =
-#endif
- tupleToStringSeq(meta, metaData);
- assert(b);
-
- //
- // returnType
- //
- returnsClasses = false;
- if(ret != Py_None)
- {
- returnType = convertParam(ret, 0);
- if(!returnType->optional)
- {
- returnsClasses = returnType->type->usesClasses();
- }
- }
-
- //
- // inParams
- //
- sendsClasses = false;
- convertParams(in, inParams, 0, sendsClasses);
-
- //
- // outParams
- //
- convertParams(out, outParams, returnType ? 1 : 0, returnsClasses);
-
- class SortFn
- {
- public:
- static bool compare(const ParamInfoPtr& lhs, const ParamInfoPtr& rhs)
- {
- return lhs->tag < rhs->tag;
- }
-
- static bool isRequired(const ParamInfoPtr& i)
- {
- return !i->optional;
- }
- };
-
- //
- // The inParams list represents the parameters in the order of declaration.
- // We also need a sorted list of optional parameters.
- //
- ParamInfoList l = inParams;
- copy(l.begin(), remove_if(l.begin(), l.end(), SortFn::isRequired), back_inserter(optionalInParams));
- optionalInParams.sort(SortFn::compare);
-
- //
- // The outParams list represents the parameters in the order of declaration.
- // We also need a sorted list of optional parameters. If the return value is
- // optional, we must include it in this list.
- //
- l = outParams;
- copy(l.begin(), remove_if(l.begin(), l.end(), SortFn::isRequired), back_inserter(optionalOutParams));
- if(returnType && returnType->optional)
- {
- optionalOutParams.push_back(returnType);
- }
- optionalOutParams.sort(SortFn::compare);
-
- //
- // exceptions
- //
- Py_ssize_t sz = PyTuple_GET_SIZE(ex);
- for(Py_ssize_t i = 0; i < sz; ++i)
- {
- exceptions.push_back(getException(PyTuple_GET_ITEM(ex, i)));
- }
-
- //
- // Does the operation name start with "ice_"?
- //
- pseudoOp = name.find("ice_") == 0;
-}
-
-void
-IcePy::Operation::deprecate(const string& msg)
-{
- if(!msg.empty())
- {
- _deprecateMessage = msg;
- }
- else
- {
- _deprecateMessage = "operation " + name + " is deprecated";
- }
-}
-
-void
-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)
- {
- 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();
- }
- }
-}
-
-ParamInfoPtr
-IcePy::Operation::convertParam(PyObject* p, int pos)
-{
- assert(PyTuple_Check(p));
- assert(PyTuple_GET_SIZE(p) == 4);
-
- ParamInfoPtr param = new ParamInfo;
-
- //
- // metaData
- //
- PyObject* meta = PyTuple_GET_ITEM(p, 0);
- assert(PyTuple_Check(meta));
-#ifndef NDEBUG
- bool b =
-#endif
- tupleToStringSeq(meta, param->metaData);
- assert(b);
-
- //
- // type
- //
- PyObject* type = PyTuple_GET_ITEM(p, 1);
- if(type != Py_None)
- {
- param->type = getType(type);
- }
-
- //
- // optional
- //
- param->optional = PyObject_IsTrue(PyTuple_GET_ITEM(p, 2)) == 1;
-
- //
- // tag
- //
- param->tag = static_cast<int>(PyLong_AsLong(PyTuple_GET_ITEM(p, 3)));
-
- //
- // position
- //
- param->pos = pos;
-
- return param;
-}
-
-static PyMethodDef OperationMethods[] =
-{
- { STRCAST("invoke"), reinterpret_cast<PyCFunction>(operationInvoke), METH_VARARGS,
- PyDoc_STR(STRCAST("internal function")) },
- { STRCAST("invokeAsync"), reinterpret_cast<PyCFunction>(operationInvokeAsync), METH_VARARGS,
- PyDoc_STR(STRCAST("internal function")) },
- { STRCAST("begin"), reinterpret_cast<PyCFunction>(operationBegin), METH_VARARGS,
- PyDoc_STR(STRCAST("internal function")) },
- { STRCAST("end"), reinterpret_cast<PyCFunction>(operationEnd), METH_VARARGS,
- PyDoc_STR(STRCAST("internal function")) },
- { STRCAST("deprecate"), reinterpret_cast<PyCFunction>(operationDeprecate), METH_VARARGS,
- PyDoc_STR(STRCAST("internal function")) },
- { 0, 0 } /* sentinel */
-};
-
-static PyMethodDef AMDCallbackMethods[] =
-{
- { STRCAST("ice_response"), reinterpret_cast<PyCFunction>(amdCallbackIceResponse), METH_VARARGS,
- PyDoc_STR(STRCAST("internal function")) },
- { STRCAST("ice_exception"), reinterpret_cast<PyCFunction>(amdCallbackIceException), METH_VARARGS,
- PyDoc_STR(STRCAST("internal function")) },
- { 0, 0 } /* sentinel */
-};
-
-static PyMethodDef AsyncResultMethods[] =
-{
- { STRCAST("cancel"), reinterpret_cast<PyCFunction>(asyncResultCancel), METH_NOARGS,
- PyDoc_STR(STRCAST("cancels the invocation")) },
- { STRCAST("getCommunicator"), reinterpret_cast<PyCFunction>(asyncResultGetCommunicator), METH_NOARGS,
- PyDoc_STR(STRCAST("returns the communicator for the invocation")) },
- { STRCAST("getConnection"), reinterpret_cast<PyCFunction>(asyncResultGetConnection), METH_NOARGS,
- PyDoc_STR(STRCAST("returns the connection for the invocation")) },
- { STRCAST("getProxy"), reinterpret_cast<PyCFunction>(asyncResultGetProxy), METH_NOARGS,
- PyDoc_STR(STRCAST("returns the proxy for the invocation")) },
- { STRCAST("isCompleted"), reinterpret_cast<PyCFunction>(asyncResultIsCompleted), METH_NOARGS,
- PyDoc_STR(STRCAST("returns true if the request is complete")) },
- { STRCAST("waitForCompleted"), reinterpret_cast<PyCFunction>(asyncResultWaitForCompleted), METH_NOARGS,
- PyDoc_STR(STRCAST("blocks until the request is complete")) },
- { STRCAST("isSent"), reinterpret_cast<PyCFunction>(asyncResultIsSent), METH_NOARGS,
- PyDoc_STR(STRCAST("returns true if the request is sent")) },
- { STRCAST("waitForSent"), reinterpret_cast<PyCFunction>(asyncResultWaitForSent), METH_NOARGS,
- PyDoc_STR(STRCAST("blocks until the request is sent")) },
- { STRCAST("throwLocalException"), reinterpret_cast<PyCFunction>(asyncResultThrowLocalException), METH_NOARGS,
- PyDoc_STR(STRCAST("throw location exception if the request failed with a local exception")) },
- { STRCAST("sentSynchronously"), reinterpret_cast<PyCFunction>(asyncResultSentSynchronously), METH_NOARGS,
- PyDoc_STR(STRCAST("returns true if the request was sent synchronously")) },
- { STRCAST("getOperation"), reinterpret_cast<PyCFunction>(asyncResultGetOperation), METH_NOARGS,
- PyDoc_STR(STRCAST("returns the name of the operation")) },
- { 0, 0 } /* sentinel */
-};
-
-namespace IcePy
-{
-
-PyTypeObject OperationType =
-{
- /* The ob_type field must be initialized in the module init function
- * to be portable to Windows without using C++. */
- PyVarObject_HEAD_INIT(0, 0)
- STRCAST("IcePy.Operation"), /* tp_name */
- sizeof(OperationObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- reinterpret_cast<destructor>(operationDealloc), /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- OperationMethods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- reinterpret_cast<initproc>(operationInit), /* tp_init */
- 0, /* tp_alloc */
- reinterpret_cast<newfunc>(operationNew), /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
-};
-
-PyTypeObject AMDCallbackType =
-{
- /* The ob_type field must be initialized in the module init function
- * to be portable to Windows without using C++. */
- PyVarObject_HEAD_INIT(0, 0)
- STRCAST("IcePy.AMDCallback"), /* tp_name */
- sizeof(AMDCallbackObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- reinterpret_cast<destructor>(amdCallbackDealloc), /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- AMDCallbackMethods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- reinterpret_cast<newfunc>(amdCallbackNew), /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
-};
-
-PyTypeObject AsyncResultType =
-{
- /* The ob_type field must be initialized in the module init function
- * to be portable to Windows without using C++. */
- PyVarObject_HEAD_INIT(0, 0)
- STRCAST("IcePy.AsyncResult"), /* tp_name */
- sizeof(AsyncResultObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- reinterpret_cast<destructor>(asyncResultDealloc), /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- AsyncResultMethods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- reinterpret_cast<newfunc>(asyncResultNew), /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
-};
-
-}
-
-bool
-IcePy::initOperation(PyObject* module)
-{
- if(PyType_Ready(&OperationType) < 0)
- {
- return false;
- }
- PyTypeObject* opType = &OperationType; // Necessary to prevent GCC's strict-alias warnings.
- if(PyModule_AddObject(module, STRCAST("Operation"), reinterpret_cast<PyObject*>(opType)) < 0)
- {
- return false;
- }
-
- if(PyType_Ready(&AMDCallbackType) < 0)
- {
- return false;
- }
- PyTypeObject* cbType = &AMDCallbackType; // Necessary to prevent GCC's strict-alias warnings.
- if(PyModule_AddObject(module, STRCAST("AMDCallback"), reinterpret_cast<PyObject*>(cbType)) < 0)
- {
- return false;
- }
-
- if(PyType_Ready(&AsyncResultType) < 0)
- {
- return false;
- }
- PyTypeObject* arType = &AsyncResultType; // Necessary to prevent GCC's strict-alias warnings.
- if(PyModule_AddObject(module, STRCAST("AsyncResult"), reinterpret_cast<PyObject*>(arType)) < 0)
- {
- return false;
- }
-
- return true;
-}
-
-//
-// Invocation
-//
-IcePy::Invocation::Invocation(const Ice::ObjectPrx& prx) :
- _prx(prx)
-{
-}
-
-//
-// TypedInvocation
-//
-IcePy::TypedInvocation::TypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op) :
- Invocation(prx), _op(op), _communicator(prx->ice_getCommunicator())
-{
-}
-
-bool
-IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, Ice::OutputStreamPtr& os,
- pair<const Ice::Byte*, const Ice::Byte*>& params)
-{
- assert(PyTuple_Check(args));
- params.first = params.second = static_cast<const Ice::Byte*>(0);
-
- //
- // Validate the number of arguments.
- //
- Py_ssize_t argc = PyTuple_GET_SIZE(args);
- Py_ssize_t paramCount = static_cast<Py_ssize_t>(_op->inParams.size());
- if(argc != paramCount)
- {
- string opName;
- if(mapping == OldAsyncMapping)
- {
- opName = _op->name + "_async";
- }
- else if(mapping == AsyncMapping)
- {
- opName = "begin_" + _op->name;
- }
- else
- {
- opName = fixIdent(_op->name);
- }
- PyErr_Format(PyExc_RuntimeError, STRCAST("%s expects %d in parameters"), opName.c_str(),
- static_cast<int>(paramCount));
- return false;
- }
-
- if(!_op->inParams.empty())
- {
- try
- {
- //
- // Marshal the in parameters.
- //
- os = Ice::createOutputStream(_communicator);
- os->startEncapsulation(_prx->ice_getEncodingVersion(), _op->format);
-
- ObjectMap objectMap;
- ParamInfoList::iterator p;
-
- //
- // Validate the supplied arguments.
- //
- for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- PyObject* arg = PyTuple_GET_ITEM(args, info->pos);
- if((!info->optional || arg != Unset) && !info->type->validate(arg))
- {
- string name;
- if(mapping == OldAsyncMapping)
- {
- name = _op->name + "_async";
- }
- else if(mapping == AsyncMapping)
- {
- name = "begin_" + _op->name;
- }
- else
- {
- name = fixIdent(_op->name);
- }
- PyErr_Format(PyExc_ValueError, STRCAST("invalid value for argument %d in operation `%s'"),
- mapping == OldAsyncMapping ? info->pos + 2 : info->pos + 1,
- const_cast<char*>(name.c_str()));
- return false;
- }
- }
-
- //
- // Marshal the required parameters.
- //
- for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- if(!info->optional)
- {
- PyObject* arg = PyTuple_GET_ITEM(args, info->pos);
- info->type->marshal(arg, os, &objectMap, false, &info->metaData);
- }
- }
-
- //
- // Marshal the optional parameters.
- //
- for(p = _op->optionalInParams.begin(); p != _op->optionalInParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- PyObject* arg = PyTuple_GET_ITEM(args, info->pos);
- if(arg != Unset && os->writeOptional(info->tag, info->type->optionalFormat()))
- {
- info->type->marshal(arg, os, &objectMap, true, &info->metaData);
- }
- }
-
- if(_op->sendsClasses)
- {
- os->writePendingObjects();
- }
-
- os->endEncapsulation();
- params = os->finished();
- }
- catch(const AbortMarshaling&)
- {
- assert(PyErr_Occurred());
- return false;
- }
- catch(const Ice::Exception& ex)
- {
- setPythonException(ex);
- return false;
- }
- }
-
- return true;
-}
-
-PyObject*
-IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice::Byte*>& bytes)
-{
- Py_ssize_t numResults = static_cast<Py_ssize_t>(_op->outParams.size());
- if(_op->returnType)
- {
- numResults++;
- }
-
- PyObjectHandle results = PyTuple_New(numResults);
- if(results.get() && numResults > 0)
- {
- Ice::InputStreamPtr is = Ice::wrapInputStream(_communicator, bytes);
-
- //
- // Store a pointer to a local SlicedDataUtil object as the stream's closure.
- // This is necessary to support object unmarshaling (see ObjectReader).
- //
- SlicedDataUtil util;
- assert(!is->closure());
- is->closure(&util);
-
- is->startEncapsulation();
-
- ParamInfoList::iterator p;
-
- //
- // Unmarshal the required out parameters.
- //
- for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- if(!info->optional)
- {
- void* closure = reinterpret_cast<void*>(info->pos);
- info->type->unmarshal(is, info, results.get(), closure, false, &info->metaData);
- }
- }
-
- //
- // Unmarshal the required return value, if any.
- //
- if(_op->returnType && !_op->returnType->optional)
- {
- assert(_op->returnType->pos == 0);
- void* closure = reinterpret_cast<void*>(_op->returnType->pos);
- _op->returnType->type->unmarshal(is, _op->returnType, results.get(), closure, false, &_op->metaData);
- }
-
- //
- // Unmarshal the optional results. This includes an optional return value.
- //
- for(p = _op->optionalOutParams.begin(); p != _op->optionalOutParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- if(is->readOptional(info->tag, info->type->optionalFormat()))
- {
- void* closure = reinterpret_cast<void*>(info->pos);
- info->type->unmarshal(is, info, results.get(), closure, true, &info->metaData);
- }
- else
- {
- if(PyTuple_SET_ITEM(results.get(), info->pos, Unset) < 0)
- {
- return 0;
- }
- Py_INCREF(Unset); // PyTuple_SET_ITEM steals a reference.
- }
- }
-
- if(_op->returnsClasses)
- {
- is->readPendingObjects();
- }
-
- is->endEncapsulation();
-
- util.update();
- }
-
- return results.release();
-}
-
-PyObject*
-IcePy::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& bytes)
-{
- Ice::InputStreamPtr is = Ice::wrapInputStream(_communicator, bytes);
-
- //
- // Store a pointer to a local SlicedDataUtil object as the stream's closure.
- // This is necessary to support object unmarshaling (see ObjectReader).
- //
- SlicedDataUtil util;
- assert(!is->closure());
- is->closure(&util);
-
- is->startEncapsulation();
-
- try
- {
- Ice::UserExceptionReaderFactoryPtr factory = new UserExceptionReaderFactoryI(_communicator);
- is->throwException(factory);
- }
- catch(const ExceptionReader& r)
- {
- is->endEncapsulation();
-
- PyObject* ex = r.getException();
-
- if(validateException(ex))
- {
- util.update();
-
- Ice::SlicedDataPtr slicedData = r.getSlicedData();
- if(slicedData)
- {
- SlicedDataUtil::setMember(ex, slicedData);
- }
-
- Py_INCREF(ex);
- return ex;
- }
- else
- {
- PyException pye(ex); // No traceback information available.
- pye.raise();
- }
- }
-
- throw Ice::UnknownUserException(__FILE__, __LINE__, "unknown exception");
-#ifdef __SUNPRO_CC
- return 0;
-#endif
-}
-
-bool
-IcePy::TypedInvocation::validateException(PyObject* ex) const
-{
- for(ExceptionInfoList::const_iterator p = _op->exceptions.begin(); p != _op->exceptions.end(); ++p)
- {
- if(PyObject_IsInstance(ex, (*p)->pythonType.get()))
- {
- return true;
- }
- }
-
- return false;
-}
-
-void
-IcePy::TypedInvocation::checkTwowayOnly(const Ice::ObjectPrx& proxy) const
-{
- if((_op->returnType != 0 || !_op->outParams.empty() || !_op->exceptions.empty()) && !proxy->ice_isTwoway())
- {
- Ice::TwowayOnlyException ex(__FILE__, __LINE__);
- ex.operation = _op->name;
- throw ex;
- }
-}
-
-//
-// SyncTypedInvocation
-//
-IcePy::SyncTypedInvocation::SyncTypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op) :
- Invocation(prx), TypedInvocation(prx, op)
-{
-}
-
-PyObject*
-IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
-{
- assert(PyTuple_Check(args));
- assert(PyTuple_GET_SIZE(args) == 2); // Format is ((params...), context|None)
- PyObject* pyparams = PyTuple_GET_ITEM(args, 0);
- assert(PyTuple_Check(pyparams));
- PyObject* pyctx = PyTuple_GET_ITEM(args, 1);
-
- //
- // Marshal the input parameters to a byte sequence.
- //
- Ice::OutputStreamPtr os;
- pair<const Ice::Byte*, const Ice::Byte*> params;
- if(!prepareRequest(pyparams, SyncMapping, os, params))
- {
- return 0;
- }
-
- try
- {
- checkTwowayOnly(_prx);
-
- //
- // Invoke the operation.
- //
- vector<Ice::Byte> result;
- bool status;
- {
- if(pyctx != Py_None)
- {
- Ice::Context ctx;
-
- if(!PyDict_Check(pyctx))
- {
- PyErr_Format(PyExc_ValueError, STRCAST("context argument must be None or a dictionary"));
- return 0;
- }
-
- if(!dictionaryToContext(pyctx, ctx))
- {
- return 0;
- }
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- status = _prx->ice_invoke(_op->name, _op->sendMode, params, result, ctx);
- }
- else
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- status = _prx->ice_invoke(_op->name, _op->sendMode, params, result);
- }
- }
-
- //
- // Process the reply.
- //
- if(_prx->ice_isTwoway())
- {
- if(!status)
- {
- //
- // Unmarshal a user exception.
- //
- pair<const Ice::Byte*, const Ice::Byte*> rb(static_cast<const Ice::Byte*>(0),
- static_cast<const Ice::Byte*>(0));
- if(!result.empty())
- {
- rb.first = &result[0];
- rb.second = &result[0] + result.size();
- }
- PyObjectHandle ex = unmarshalException(rb);
-
- //
- // Set the Python exception.
- //
- setPythonException(ex.get());
- return 0;
- }
- else if(_op->outParams.size() > 0 || _op->returnType)
- {
- //
- // Unmarshal the results. If there is more than one value to be returned, then return them
- // in a tuple of the form (result, outParam1, ...). Otherwise just return the value.
- //
- pair<const Ice::Byte*, const Ice::Byte*> rb(static_cast<const Ice::Byte*>(0),
- static_cast<const Ice::Byte*>(0));
- if(!result.empty())
- {
- rb.first = &result[0];
- rb.second = &result[0] + result.size();
- }
- PyObjectHandle results = unmarshalResults(rb);
- if(!results.get())
- {
- return 0;
- }
-
- if(PyTuple_GET_SIZE(results.get()) > 1)
- {
- return results.release();
- }
- else
- {
- PyObject* ret = PyTuple_GET_ITEM(results.get(), 0);
- if(!ret)
- {
- return 0;
- }
- else
- {
- Py_INCREF(ret);
- return ret;
- }
- }
- }
- }
- }
- catch(const AbortMarshaling&)
- {
- assert(PyErr_Occurred());
- return 0;
- }
- catch(const Ice::Exception& ex)
- {
- setPythonException(ex);
- return 0;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-//
-// AsyncTypedInvocation
-//
-IcePy::AsyncTypedInvocation::AsyncTypedInvocation(const Ice::ObjectPrx& prx, PyObject* pyProxy,
- const OperationPtr& op) :
- Invocation(prx), TypedInvocation(prx, op), _pyProxy(pyProxy), _response(0), _ex(0), _sent(0)
-{
- Py_INCREF(_pyProxy);
-}
-
-IcePy::AsyncTypedInvocation::~AsyncTypedInvocation()
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- Py_DECREF(_pyProxy);
- Py_XDECREF(_response);
- Py_XDECREF(_ex);
- Py_XDECREF(_sent);
-}
-
-PyObject*
-IcePy::AsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
-{
- assert(PyTuple_Check(args));
- assert(PyTuple_GET_SIZE(args) == 5); // Format is ((params...), response|None, exception|None, sent|None, ctx|None)
- PyObject* pyparams = PyTuple_GET_ITEM(args, 0);
- assert(PyTuple_Check(pyparams));
-
- PyObject* callable;
-
- callable = PyTuple_GET_ITEM(args, 1);
- if(PyCallable_Check(callable))
- {
- _response = callable;
- Py_INCREF(_response);
- }
- else if(callable != Py_None)
- {
- PyErr_Format(PyExc_RuntimeError, STRCAST("response callback must be a callable object or None"));
- return 0;
- }
-
- callable = PyTuple_GET_ITEM(args, 2);
- if(PyCallable_Check(callable))
- {
- _ex = callable;
- Py_INCREF(_ex);
- }
- else if(callable != Py_None)
- {
- PyErr_Format(PyExc_RuntimeError, STRCAST("exception callback must be a callable object or None"));
- return 0;
- }
-
- callable = PyTuple_GET_ITEM(args, 3);
- if(PyCallable_Check(callable))
- {
- _sent = callable;
- Py_INCREF(_sent);
- }
- else if(callable != Py_None)
- {
- PyErr_Format(PyExc_RuntimeError, STRCAST("sent callback must be a callable object or None"));
- return 0;
- }
-
- if(!_ex && (_response || _sent))
- {
- PyErr_Format(PyExc_RuntimeError,
- STRCAST("exception callback must also be provided when response or sent callbacks are used"));
- return 0;
- }
-
- PyObject* pyctx = PyTuple_GET_ITEM(args, 4);
- if(pyctx != Py_None && !PyDict_Check(pyctx))
- {
- PyErr_Format(PyExc_RuntimeError, STRCAST("context must be a dictionary or None"));
- return 0;
- }
-
- //
- // Marshal the input parameters to a byte sequence.
- //
- Ice::OutputStreamPtr os;
- pair<const Ice::Byte*, const Ice::Byte*> params;
- if(!prepareRequest(pyparams, AsyncMapping, os, params))
- {
- return 0;
- }
-
- Ice::AsyncResultPtr result;
- try
- {
- checkAsyncTwowayOnly(_prx);
-
- Ice::Callback_Object_ice_invokePtr cb;
- if(_response || _ex || _sent)
- {
- cb = Ice::newCallback_Object_ice_invoke(this, &AsyncTypedInvocation::response,
- &AsyncTypedInvocation::exception, &AsyncTypedInvocation::sent);
- }
-
- //
- // Invoke the operation asynchronously.
- //
- if(pyctx != Py_None)
- {
- Ice::Context ctx;
- if(!dictionaryToContext(pyctx, ctx))
- {
- return 0;
- }
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- if(cb)
- {
- result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx, cb);
- }
- else
- {
- result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx);
- }
- }
- else
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- if(cb)
- {
- result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, cb);
- }
- else
- {
- result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params);
- }
- }
- }
- catch(const Ice::CommunicatorDestroyedException& ex)
- {
- //
- // CommunicatorDestroyedException can propagate directly.
- //
- setPythonException(ex);
- return 0;
- }
- catch(const IceUtil::IllegalArgumentException& ex)
- {
- //
- // IllegalArgumentException can propagate directly.
- // (Raised by checkAsyncTwowayOnly)
- //
- PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str()));
- return 0;
- }
- catch(const Ice::Exception&)
- {
- //
- // No other exceptions should be raised by begin_ice_invoke.
- //
- assert(false);
- }
-
- assert(result);
- AsyncResultObject* obj = asyncResultNew(&AsyncResultType, 0, 0);
- if(!obj)
- {
- return 0;
- }
- obj->result = new Ice::AsyncResultPtr(result);
- obj->invocation = new InvocationPtr(this);
- obj->proxy = _pyProxy;
- Py_INCREF(obj->proxy);
- obj->communicator = getCommunicatorWrapper(_communicator);
- return reinterpret_cast<PyObject*>(obj);
-}
-
-PyObject*
-IcePy::AsyncTypedInvocation::end(const Ice::ObjectPrx& proxy, const OperationPtr& op, const Ice::AsyncResultPtr& r)
-{
- try
- {
- if(op.get() != _op.get())
- {
- throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "end_" + op->name +
- " called with AsyncResult object from begin_" + _op->name);
- }
-
- pair<const Ice::Byte*, const Ice::Byte*> results;
- bool ok;
-
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking operations.
- ok = proxy->___end_ice_invoke(results, r);
- }
-
- if(ok)
- {
- //
- // Unmarshal the results.
- //
- PyObjectHandle args = unmarshalResults(results);
- if(args.get())
- {
- //
- // If there are no results, return None. If there's only one element
- // in the tuple, return the element. Otherwise, return the tuple.
- //
- assert(PyTuple_Check(args.get()));
- if(PyTuple_GET_SIZE(args.get()) == 0)
- {
- Py_INCREF(Py_None);
- return Py_None;
- }
- else if(PyTuple_GET_SIZE(args.get()) == 1)
- {
- PyObject* res = PyTuple_GET_ITEM(args.get(), 0);
- Py_INCREF(res);
- return res;
- }
- else
- {
- return args.release();
- }
- }
- }
- else
- {
- PyObjectHandle ex = unmarshalException(results);
- setPythonException(ex.get());
- }
- }
- catch(const AbortMarshaling&)
- {
- // Nothing to do.
- }
- catch(const IceUtil::IllegalArgumentException& ex)
- {
- PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str()));
- }
- catch(const Ice::Exception& ex)
- {
- setPythonException(ex);
- }
-
- assert(PyErr_Occurred());
- return 0;
-}
-
-string
-IcePy::AsyncTypedInvocation::opName() const
-{
- return _op->name;
-}
-
-void
-IcePy::AsyncTypedInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- try
- {
- if(ok)
- {
- if(_response)
- {
- //
- // Unmarshal the results.
- //
- PyObjectHandle args;
- try
- {
- args = unmarshalResults(results);
- if(!args.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
- }
- catch(const Ice::Exception& ex)
- {
- assert(_ex);
- callException(_ex, ex);
- return;
- }
-
- PyObjectHandle tmp = PyObject_Call(_response, args.get(), 0);
- if(PyErr_Occurred())
- {
- handleException(); // Callback raised an exception.
- }
- }
- }
- else
- {
- assert(_ex);
- PyObjectHandle ex = unmarshalException(results);
- callException(_ex, ex.get());
- }
- }
- catch(const AbortMarshaling&)
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- }
-}
-
-void
-IcePy::AsyncTypedInvocation::exception(const Ice::Exception& ex)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
- assert(_ex);
- callException(_ex, ex);
-}
-
-void
-IcePy::AsyncTypedInvocation::sent(bool sentSynchronously)
-{
- if(_sent)
- {
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
- callSent(_sent, sentSynchronously, true);
- }
-}
-
-void
-IcePy::AsyncTypedInvocation::checkAsyncTwowayOnly(const Ice::ObjectPrx& proxy) const
-{
- if((_op->returnType != 0 || !_op->outParams.empty() || !_op->exceptions.empty()) && !proxy->ice_isTwoway())
- {
- throw IceUtil::IllegalArgumentException(__FILE__, __LINE__,
- "`" + _op->name + "' can only be called with a twoway proxy");
- }
-
- if((_op->returnType != 0 || !_op->outParams.empty()) && (!_response && (_ex || _sent)))
- {
- throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "`" + _op->name + "' requires a response callback");
- }
-}
-
-//
-// OldAsyncTypedInvocation
-//
-IcePy::OldAsyncTypedInvocation::OldAsyncTypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op)
- : Invocation(prx), TypedInvocation(prx, op), _callback(0)
-{
-}
-
-IcePy::OldAsyncTypedInvocation::~OldAsyncTypedInvocation()
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- Py_XDECREF(_callback);
-}
-
-PyObject*
-IcePy::OldAsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
-{
- assert(PyTuple_Check(args));
- assert(PyTuple_GET_SIZE(args) == 3); // Format is (callback, (params...), context|None)
- _callback = PyTuple_GET_ITEM(args, 0);
- Py_INCREF(_callback);
- PyObject* pyparams = PyTuple_GET_ITEM(args, 1);
- assert(PyTuple_Check(pyparams));
- PyObject* pyctx = PyTuple_GET_ITEM(args, 2);
-
- //
- // Marshal the input parameters to a byte sequence.
- //
- Ice::OutputStreamPtr os;
- pair<const Ice::Byte*, const Ice::Byte*> params;
- if(!prepareRequest(pyparams, OldAsyncMapping, os, params))
- {
- return 0;
- }
-
- bool sentSynchronously = false;
- try
- {
- checkTwowayOnly(_prx);
-
- Ice::Callback_Object_ice_invokePtr cb =
- Ice::newCallback_Object_ice_invoke(this, &OldAsyncTypedInvocation::response,
- &OldAsyncTypedInvocation::exception, &OldAsyncTypedInvocation::sent);
-
- Ice::AsyncResultPtr result;
-
- //
- // Invoke the operation asynchronously.
- //
- if(pyctx != Py_None)
- {
- Ice::Context ctx;
-
- if(!PyDict_Check(pyctx))
- {
- PyErr_Format(PyExc_ValueError, STRCAST("context argument must be None or a dictionary"));
- return 0;
- }
-
- if(!dictionaryToContext(pyctx, ctx))
- {
- return 0;
- }
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx, cb);
- }
- else
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, cb);
- }
-
- sentSynchronously = result->sentSynchronously();
- }
- catch(const Ice::CommunicatorDestroyedException& ex)
- {
- //
- // CommunicatorDestroyedException can propagate directly.
- //
- setPythonException(ex);
- return 0;
- }
- catch(const Ice::TwowayOnlyException& ex)
- {
- //
- // Raised by checkTwowayOnly.
- //
- callException(_callback, _op->name, "ice_exception", ex);
- }
- catch(const Ice::Exception&)
- {
- //
- // No other exceptions should be raised by begin_ice_invoke.
- //
- assert(false);
- }
-
- PyRETURN_BOOL(sentSynchronously);
-}
-
-void
-IcePy::OldAsyncTypedInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- assert(_callback);
-
- try
- {
- if(ok)
- {
- //
- // Unmarshal the results.
- //
- PyObjectHandle args;
- try
- {
- args = unmarshalResults(results);
- if(!args.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
- }
- catch(const Ice::Exception& ex)
- {
- callException(_callback, _op->name, "ice_exception", ex);
- return;
- }
-
- const string methodName = "ice_response";
- if(!PyObject_HasAttrString(_callback, STRCAST(methodName.c_str())))
- {
- ostringstream ostr;
- ostr << "AMI callback object for operation `" << _op->name << "' does not define " << methodName
- << "()";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- }
- else
- {
- PyObjectHandle method = PyObject_GetAttrString(_callback, STRCAST(methodName.c_str()));
- assert(method.get());
- PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0);
- if(PyErr_Occurred())
- {
- handleException(); // Callback raised an exception.
- }
- }
- }
- else
- {
- PyObjectHandle ex = unmarshalException(results);
- callException(_callback, _op->name, "ice_exception", ex.get());
- }
- }
- catch(const AbortMarshaling&)
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- }
-}
-
-void
-IcePy::OldAsyncTypedInvocation::exception(const Ice::Exception& ex)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- callException(_callback, _op->name, "ice_exception", ex);
-}
-
-void
-IcePy::OldAsyncTypedInvocation::sent(bool)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- callSent(_callback, "ice_sent", false, false);
-}
-
-//
-// SyncBlobjectInvocation
-//
-IcePy::SyncBlobjectInvocation::SyncBlobjectInvocation(const Ice::ObjectPrx& prx)
- : Invocation(prx)
-{
-}
-
-PyObject*
-IcePy::SyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */)
-{
- char* operation;
- PyObject* mode;
- PyObject* inParams;
- PyObject* operationModeType = lookupType("Ice.OperationMode");
- PyObject* ctx = 0;
-#if PY_VERSION_HEX >= 0x03000000
- if(!PyArg_ParseTuple(args, STRCAST("sO!O!|O"), &operation, operationModeType, &mode, &PyBytes_Type, &inParams,
- &ctx))
- {
- return 0;
- }
-#else
- if(!PyArg_ParseTuple(args, STRCAST("sO!O!|O"), &operation, operationModeType, &mode, &PyBuffer_Type, &inParams,
- &ctx))
- {
- return 0;
- }
-#endif
-
- PyObjectHandle modeValue = PyObject_GetAttrString(mode, STRCAST("value"));
- Ice::OperationMode sendMode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(modeValue.get()));
- assert(!PyErr_Occurred());
-
-#if PY_VERSION_HEX >= 0x03000000
- Py_ssize_t sz = PyBytes_GET_SIZE(inParams);
- pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0),
- static_cast<const Ice::Byte*>(0));
- if(sz > 0)
- {
- in.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(inParams));
- in.second = in.first + sz;
- }
-#else
- //
- // Use the array API to avoid copying the data.
- //
- char* charBuf = 0;
- Py_ssize_t sz = inParams->ob_type->tp_as_buffer->bf_getcharbuffer(inParams, 0, &charBuf);
- const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf);
- pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0),
- static_cast<const Ice::Byte*>(0));
- if(sz > 0)
- {
- in.first = mem;
- in.second = mem + sz;
- }
-#endif
-
- try
- {
- vector<Ice::Byte> out;
-
- bool ok;
- if(ctx == 0 || ctx == Py_None)
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- ok = _prx->ice_invoke(operation, sendMode, in, out);
- }
- else
- {
- Ice::Context context;
- if(!dictionaryToContext(ctx, context))
- {
- return 0;
- }
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- ok = _prx->ice_invoke(operation, sendMode, in, out, context);
- }
-
- //
- // Prepare the result as a tuple of the bool and out param buffer.
- //
- PyObjectHandle result = PyTuple_New(2);
- if(!result.get())
- {
- throwPythonException();
- }
-
- if(PyTuple_SET_ITEM(result.get(), 0, ok ? getTrue() : getFalse()) < 0)
- {
- throwPythonException();
- }
-
-#if PY_VERSION_HEX >= 0x03000000
- PyObjectHandle op;
- if(out.empty())
- {
- op = PyBytes_FromString("");
- }
- else
- {
- op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(&out[0]), out.size());
- }
- if(!op.get())
- {
- throwPythonException();
- }
-#else
- //
- // Create the output buffer and copy in the outParams.
- //
- PyObjectHandle op = PyBuffer_New(out.size());
- if(!op.get())
- {
- throwPythonException();
- }
- if(!out.empty())
- {
- void* buf;
- Py_ssize_t sz;
- if(PyObject_AsWriteBuffer(op.get(), &buf, &sz))
- {
- throwPythonException();
- }
- memcpy(buf, &out[0], sz);
- }
-#endif
-
- if(PyTuple_SET_ITEM(result.get(), 1, op.get()) < 0)
- {
- throwPythonException();
- }
- op.release(); // PyTuple_SET_ITEM steals a reference.
-
- return result.release();
- }
- catch(const Ice::Exception& ex)
- {
- setPythonException(ex);
- return 0;
- }
-}
-
-//
-// AsyncBlobjectInvocation
-//
-IcePy::AsyncBlobjectInvocation::AsyncBlobjectInvocation(const Ice::ObjectPrx& prx, PyObject* pyProxy) :
- Invocation(prx), _pyProxy(pyProxy), _response(0), _ex(0), _sent(0)
-{
- Py_INCREF(_pyProxy);
-}
-
-IcePy::AsyncBlobjectInvocation::~AsyncBlobjectInvocation()
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- Py_DECREF(_pyProxy);
- Py_XDECREF(_response);
- Py_XDECREF(_ex);
- Py_XDECREF(_sent);
-}
-
-PyObject*
-IcePy::AsyncBlobjectInvocation::invoke(PyObject* args, PyObject* kwds)
-{
- static char* argNames[] =
- {
- const_cast<char*>("op"),
- const_cast<char*>("mode"),
- const_cast<char*>("inParams"),
- const_cast<char*>("_response"),
- const_cast<char*>("_ex"),
- const_cast<char*>("_sent"),
- const_cast<char*>("_ctx"),
- 0
- };
- char* operation;
- PyObject* mode;
- PyObject* inParams;
- PyObject* operationModeType = lookupType("Ice.OperationMode");
- PyObject* response = Py_None;
- PyObject* ex = Py_None;
- PyObject* sent = Py_None;
- PyObject* pyctx = Py_None;
-#if PY_VERSION_HEX >= 0x03000000
- if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("sO!O!|OOOO"), argNames, &operation, operationModeType, &mode,
- &PyBytes_Type, &inParams, &response, &ex, &sent, &pyctx))
- {
- return 0;
- }
-#else
- if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("sO!O!|OOOO"), argNames, &operation, operationModeType, &mode,
- &PyBuffer_Type, &inParams, &response, &ex, &sent, &pyctx))
- {
- return 0;
- }
-#endif
-
- _op = operation;
-
- PyObjectHandle modeValue = PyObject_GetAttrString(mode, STRCAST("value"));
- Ice::OperationMode sendMode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(modeValue.get()));
- assert(!PyErr_Occurred());
-
- if(PyCallable_Check(response))
- {
- _response = response;
- Py_INCREF(_response);
- }
- else if(response != Py_None)
- {
- PyErr_Format(PyExc_RuntimeError, STRCAST("response callback must be a callable object or None"));
- return 0;
- }
-
- if(PyCallable_Check(ex))
- {
- _ex = ex;
- Py_INCREF(_ex);
- }
- else if(ex != Py_None)
- {
- PyErr_Format(PyExc_RuntimeError, STRCAST("exception callback must be a callable object or None"));
- return 0;
- }
-
- if(PyCallable_Check(sent))
- {
- _sent = sent;
- Py_INCREF(_sent);
- }
- else if(sent != Py_None)
- {
- PyErr_Format(PyExc_RuntimeError, STRCAST("sent callback must be a callable object or None"));
- return 0;
- }
-
- if(!_ex && (_response || _sent))
- {
- PyErr_Format(PyExc_RuntimeError,
- STRCAST("exception callback must also be provided when response or sent callbacks are used"));
- return 0;
- }
-
- if(pyctx != Py_None && !PyDict_Check(pyctx))
- {
- PyErr_Format(PyExc_RuntimeError, STRCAST("context must be a dictionary or None"));
- return 0;
- }
-
-#if PY_VERSION_HEX >= 0x03000000
- Py_ssize_t sz = PyBytes_GET_SIZE(inParams);
- pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0),
- static_cast<const Ice::Byte*>(0));
- if(sz > 0)
- {
- in.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(inParams));
- in.second = in.first + sz;
- }
-#else
- //
- // Use the array API to avoid copying the data.
- //
- char* charBuf = 0;
- Py_ssize_t sz = inParams->ob_type->tp_as_buffer->bf_getcharbuffer(inParams, 0, &charBuf);
- const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf);
- pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0),
- static_cast<const Ice::Byte*>(0));
- if(sz > 0)
- {
- in.first = mem;
- in.second = mem + sz;
- }
-#endif
-
- Ice::AsyncResultPtr result;
- try
- {
- Ice::Callback_Object_ice_invokePtr cb;
- if(_response || _ex || _sent)
- {
- cb = Ice::newCallback_Object_ice_invoke(this, &AsyncBlobjectInvocation::response,
- &AsyncBlobjectInvocation::exception,
- &AsyncBlobjectInvocation::sent);
- }
-
- if(pyctx == Py_None)
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- if(cb)
- {
- result = _prx->begin_ice_invoke(operation, sendMode, in, cb);
- }
- else
- {
- result = _prx->begin_ice_invoke(operation, sendMode, in);
- }
- }
- else
- {
- Ice::Context context;
- if(!dictionaryToContext(pyctx, context))
- {
- return 0;
- }
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- if(cb)
- {
- result = _prx->begin_ice_invoke(operation, sendMode, in, context, cb);
- }
- else
- {
- result = _prx->begin_ice_invoke(operation, sendMode, in, context);
- }
- }
- }
- catch(const Ice::CommunicatorDestroyedException& ex)
- {
- //
- // CommunicatorDestroyedException is the only exception that can propagate directly.
- //
- setPythonException(ex);
- return 0;
- }
- catch(const Ice::Exception&)
- {
- //
- // No other exceptions should be raised by begin_ice_invoke.
- //
- assert(false);
- }
-
- assert(result);
- AsyncResultObject* obj = asyncResultNew(&AsyncResultType, 0, 0);
- if(!obj)
- {
- return 0;
- }
- obj->result = new Ice::AsyncResultPtr(result);
- obj->invocation = new InvocationPtr(this);
- obj->proxy = _pyProxy;
- Py_INCREF(obj->proxy);
- obj->communicator = getCommunicatorWrapper(_prx->ice_getCommunicator());
- return reinterpret_cast<PyObject*>(obj);
-}
-
-PyObject*
-IcePy::AsyncBlobjectInvocation::end(const Ice::ObjectPrx& proxy, const Ice::AsyncResultPtr& r)
-{
- try
- {
- pair<const Ice::Byte*, const Ice::Byte*> results;
- bool ok;
-
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking operations.
- ok = proxy->___end_ice_invoke(results, r);
- }
-
- //
- // Prepare the results as a tuple of the bool and out param buffer.
- //
- PyObjectHandle args = PyTuple_New(2);
- if(!args.get())
- {
- return 0;
- }
-
- if(PyTuple_SET_ITEM(args.get(), 0, ok ? getTrue() : getFalse()) < 0)
- {
- return 0;
- }
-
-#if PY_VERSION_HEX >= 0x03000000
- Py_ssize_t sz = results.second - results.first;
- PyObjectHandle op;
- if(sz == 0)
- {
- op = PyBytes_FromString("");
- }
- else
- {
- op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(results.first), sz);
- }
- if(!op.get())
- {
- return 0;
- }
-#else
- //
- // Create the output buffer and copy in the outParams.
- //
- PyObjectHandle op = PyBuffer_New(results.second - results.first);
- if(!op.get())
- {
- return 0;
- }
-
- void* buf;
- Py_ssize_t sz;
- if(PyObject_AsWriteBuffer(op.get(), &buf, &sz))
- {
- return 0;
- }
- assert(sz == results.second - results.first);
- memcpy(buf, results.first, sz);
-#endif
-
- if(PyTuple_SET_ITEM(args.get(), 1, op.get()) < 0)
- {
- return 0;
- }
- op.release(); // PyTuple_SET_ITEM steals a reference.
-
- return args.release();
- }
- catch(const AbortMarshaling&)
- {
- // Nothing to do.
- }
- catch(const IceUtil::IllegalArgumentException& ex)
- {
- PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str()));
- }
- catch(const Ice::Exception& ex)
- {
- setPythonException(ex);
- }
-
- assert(PyErr_Occurred());
- return 0;
-}
-
-void
-IcePy::AsyncBlobjectInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results)
-{
- if(_response)
- {
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- //
- // Prepare the args as a tuple of the bool and out param buffer.
- //
- PyObjectHandle args = PyTuple_New(2);
- if(!args.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
-
- if(PyTuple_SET_ITEM(args.get(), 0, ok ? getTrue() : getFalse()) < 0)
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
-
-#if PY_VERSION_HEX >= 0x03000000
- Py_ssize_t sz = results.second - results.first;
- PyObjectHandle op;
- if(sz == 0)
- {
- op = PyBytes_FromString("");
- }
- else
- {
- op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(results.first), sz);
- }
- if(!op.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
-#else
- //
- // Create the output buffer and copy in the outParams.
- //
- PyObjectHandle op = PyBuffer_New(results.second - results.first);
- if(!op.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
-
- void* buf;
- Py_ssize_t sz;
- if(PyObject_AsWriteBuffer(op.get(), &buf, &sz))
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
- assert(sz == results.second - results.first);
- memcpy(buf, results.first, sz);
-#endif
-
- if(PyTuple_SET_ITEM(args.get(), 1, op.get()) < 0)
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
- op.release(); // PyTuple_SET_ITEM steals a reference.
-
- PyObjectHandle tmp = PyObject_Call(_response, args.get(), 0);
- if(PyErr_Occurred())
- {
- handleException(); // Callback raised an exception.
- }
- }
-}
-
-void
-IcePy::AsyncBlobjectInvocation::exception(const Ice::Exception& ex)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
- assert(_ex);
- callException(_ex, ex);
-}
-
-void
-IcePy::AsyncBlobjectInvocation::sent(bool sentSynchronously)
-{
- if(_sent)
- {
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
- callSent(_sent, sentSynchronously, true);
- }
-}
-
-//
-// OldAsyncBlobjectInvocation
-//
-IcePy::OldAsyncBlobjectInvocation::OldAsyncBlobjectInvocation(const Ice::ObjectPrx& prx) :
- Invocation(prx), _callback(0)
-{
-}
-
-IcePy::OldAsyncBlobjectInvocation::~OldAsyncBlobjectInvocation()
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- Py_XDECREF(_callback);
-}
-
-PyObject*
-IcePy::OldAsyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */)
-{
- char* operation;
- PyObject* mode;
- PyObject* inParams;
- PyObject* operationModeType = lookupType("Ice.OperationMode");
- PyObject* ctx = 0;
-#if PY_VERSION_HEX >= 0x03000000
- if(!PyArg_ParseTuple(args, STRCAST("OsO!O!|O"), &_callback, &operation, operationModeType, &mode,
- &PyBytes_Type, &inParams, &ctx))
- {
- return 0;
- }
-#else
- if(!PyArg_ParseTuple(args, STRCAST("OsO!O!|O"), &_callback, &operation, operationModeType, &mode,
- &PyBuffer_Type, &inParams, &ctx))
- {
- return 0;
- }
-#endif
-
- Py_INCREF(_callback);
- _op = operation;
-
- PyObjectHandle modeValue = PyObject_GetAttrString(mode, STRCAST("value"));
- Ice::OperationMode sendMode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(modeValue.get()));
- assert(!PyErr_Occurred());
-
-#if PY_VERSION_HEX >= 0x03000000
- Py_ssize_t sz = PyBytes_GET_SIZE(inParams);
- pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0),
- static_cast<const Ice::Byte*>(0));
- if(sz > 0)
- {
- in.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(inParams));
- in.second = in.first + sz;
- }
-#else
- //
- // Use the array API to avoid copying the data.
- //
- char* charBuf = 0;
- Py_ssize_t sz = inParams->ob_type->tp_as_buffer->bf_getcharbuffer(inParams, 0, &charBuf);
- const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf);
- pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0),
- static_cast<const Ice::Byte*>(0));
- if(sz > 0)
- {
- in.first = mem;
- in.second = mem + sz;
- }
-#endif
-
- bool sentSynchronously = false;
- try
- {
- Ice::AsyncResultPtr result;
- Ice::Callback_Object_ice_invokePtr cb =
- Ice::newCallback_Object_ice_invoke(this, &OldAsyncBlobjectInvocation::response,
- &OldAsyncBlobjectInvocation::exception,
- &OldAsyncBlobjectInvocation::sent);
-
- if(ctx == 0 || ctx == Py_None)
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- result = _prx->begin_ice_invoke(operation, sendMode, in, cb);
- }
- else
- {
- Ice::Context context;
- if(!dictionaryToContext(ctx, context))
- {
- return 0;
- }
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- result = _prx->begin_ice_invoke(operation, sendMode, in, context, cb);
- }
-
- sentSynchronously = result->sentSynchronously();
- }
- catch(const Ice::CommunicatorDestroyedException& ex)
- {
- //
- // CommunicatorDestroyedException is the only exception that can propagate directly.
- //
- setPythonException(ex);
- return 0;
- }
- catch(const Ice::Exception&)
- {
- //
- // No other exceptions should be raised by begin_ice_invoke.
- //
- assert(false);
- }
-
- PyRETURN_BOOL(sentSynchronously);
-}
-
-void
-IcePy::OldAsyncBlobjectInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- try
- {
- //
- // Prepare the args as a tuple of the bool and out param buffer.
- //
- PyObjectHandle args = PyTuple_New(2);
- if(!args.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
-
- if(PyTuple_SET_ITEM(args.get(), 0, ok ? getTrue() : getFalse()) < 0)
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
-
-#if PY_VERSION_HEX >= 0x03000000
- Py_ssize_t sz = results.second - results.first;
- PyObjectHandle op;
- if(sz == 0)
- {
- op = PyBytes_FromString("");
- }
- else
- {
- op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(results.first), sz);
- }
- if(!op.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
-#else
- //
- // Create the output buffer and copy in the outParams.
- //
- PyObjectHandle op = PyBuffer_New(results.second - results.first);
- if(!op.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
-
- void* buf;
- Py_ssize_t sz;
- if(PyObject_AsWriteBuffer(op.get(), &buf, &sz))
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
- assert(sz == results.second - results.first);
- memcpy(buf, results.first, sz);
-#endif
-
- if(PyTuple_SET_ITEM(args.get(), 1, op.get()) < 0)
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
- op.release(); // PyTuple_SET_ITEM steals a reference.
-
- const string methodName = "ice_response";
- if(!PyObject_HasAttrString(_callback, STRCAST(methodName.c_str())))
- {
- ostringstream ostr;
- ostr << "AMI callback object for operation `ice_invoke_async' does not define " << methodName << "()";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- }
- else
- {
- PyObjectHandle method = PyObject_GetAttrString(_callback, STRCAST(methodName.c_str()));
- assert(method.get());
- PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0);
- if(PyErr_Occurred())
- {
- handleException(); // Callback raised an exception.
- }
- }
- }
- catch(const Ice::Exception& ex)
- {
- ostringstream ostr;
- ostr << "Exception raised by AMI callback for operation `ice_invoke_async':" << ex;
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- }
-}
-
-void
-IcePy::OldAsyncBlobjectInvocation::exception(const Ice::Exception& ex)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- callException(_callback, "ice_invoke", "ice_exception", ex);
-}
-
-void
-IcePy::OldAsyncBlobjectInvocation::sent(bool)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- callSent(_callback, "ice_sent", false, false);
-}
-
-//
-// TypedUpcall
-//
-IcePy::TypedUpcall::TypedUpcall(const OperationPtr& op, const Ice::AMD_Object_ice_invokePtr& callback,
- const Ice::CommunicatorPtr& communicator) :
- _op(op), _callback(callback), _communicator(communicator), _finished(false)
-{
-}
-
-void
-IcePy::TypedUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, const Ice::Byte*>& inBytes,
- const Ice::Current& current)
-{
- //
- // Unmarshal the in parameters. We have to leave room in the arguments for a trailing
- // Ice::Current object.
- //
- Py_ssize_t count = static_cast<Py_ssize_t>(_op->inParams.size()) + 1;
-
- Py_ssize_t offset = 0;
- if(_op->amd)
- {
- ++count; // Leave room for a leading AMD callback argument.
- offset = 1;
- }
-
- PyObjectHandle args = PyTuple_New(count);
- if(!args.get())
- {
- throwPythonException();
- }
-
- if(!_op->inParams.empty())
- {
- Ice::InputStreamPtr is = Ice::wrapInputStream(_communicator, inBytes);
-
- //
- // Store a pointer to a local SlicedDataUtil object as the stream's closure.
- // This is necessary to support object unmarshaling (see ObjectReader).
- //
- SlicedDataUtil util;
- assert(!is->closure());
- is->closure(&util);
-
- try
- {
- is->startEncapsulation();
-
- ParamInfoList::iterator p;
-
- //
- // Unmarshal the required parameters.
- //
- for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- if(!info->optional)
- {
- void* closure = reinterpret_cast<void*>(info->pos + offset);
- info->type->unmarshal(is, info, args.get(), closure, false, &info->metaData);
- }
- }
-
- //
- // Unmarshal the optional parameters.
- //
- for(p = _op->optionalInParams.begin(); p != _op->optionalInParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- if(is->readOptional(info->tag, info->type->optionalFormat()))
- {
- void* closure = reinterpret_cast<void*>(info->pos + offset);
- info->type->unmarshal(is, info, args.get(), closure, true, &info->metaData);
- }
- else
- {
- if(PyTuple_SET_ITEM(args.get(), info->pos + offset, Unset) < 0)
- {
- throwPythonException();
- }
- Py_INCREF(Unset); // PyTuple_SET_ITEM steals a reference.
- }
- }
-
- if(_op->sendsClasses)
- {
- is->readPendingObjects();
- }
-
- is->endEncapsulation();
-
- util.update();
- }
- catch(const AbortMarshaling&)
- {
- throwPythonException();
- }
- }
-
- //
- // Create an object to represent Ice::Current. We need to append this to the argument tuple.
- //
- PyObjectHandle curr = createCurrent(current);
- if(PyTuple_SET_ITEM(args.get(), PyTuple_GET_SIZE(args.get()) - 1, curr.get()) < 0)
- {
- throwPythonException();
- }
- curr.release(); // PyTuple_SET_ITEM steals a reference.
-
- if(_op->amd)
- {
- //
- // Create the callback object and pass it as the first argument.
- //
- AMDCallbackObject* obj = amdCallbackNew(&AMDCallbackType, 0, 0);
- if(!obj)
- {
- throwPythonException();
- }
- obj->upcall = new UpcallPtr(this);
- obj->encoding = current.encoding;
- if(PyTuple_SET_ITEM(args.get(), 0, (PyObject*)obj) < 0) // PyTuple_SET_ITEM steals a reference.
- {
- Py_DECREF(obj);
- throwPythonException();
- }
- }
-
- //
- // Dispatch the operation. Use _dispatchName here, not current.operation.
- //
- PyObjectHandle method = PyObject_GetAttrString(servant, const_cast<char*>(_op->dispatchName.c_str()));
- if(!method.get())
- {
- ostringstream ostr;
- ostr << "servant for identity " << _communicator->identityToString(current.id)
- << " does not define operation `" << _op->dispatchName << "'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- Ice::UnknownException ex(__FILE__, __LINE__);
- ex.unknown = str;
- throw ex;
- }
-
- PyObjectHandle result = PyObject_Call(method.get(), args.get(), 0);
-
- //
- // Check for exceptions.
- //
- if(PyErr_Occurred())
- {
- PyException ex; // Retrieve it before another Python API call clears it.
- exception(ex, current.encoding);
- return;
- }
-
- if(!_op->amd)
- {
- response(result.get(), current.encoding);
- }
-}
-
-void
-IcePy::TypedUpcall::response(PyObject* args, const Ice::EncodingVersion& encoding)
-{
- if(_finished)
- {
- //
- // This method could be called more than once if the application calls
- // ice_response multiple times. We ignore subsequent calls.
- //
- return;
- }
-
- _finished = true;
-
- try
- {
- //
- // Marshal the results. If there is more than one value to be returned, then they must be
- // returned in a tuple of the form (result, outParam1, ...).
- //
- Ice::OutputStreamPtr os = Ice::createOutputStream(_communicator);
- try
- {
- Py_ssize_t numResults = static_cast<Py_ssize_t>(_op->outParams.size());
- if(_op->returnType)
- {
- numResults++;
- }
-
- if(numResults > 1 && (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) != numResults))
- {
- ostringstream ostr;
- ostr << "operation `" << fixIdent(_op->name) << "' should return a tuple of length " << numResults;
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
-
- //
- // Normalize the args value. For an AMD operation, or when there are multiple
- // result values, args is already a tuple. Otherwise, we create a tuple to
- // make the code a little simpler.
- //
- PyObjectHandle t;
- if(_op->amd || numResults > 1)
- {
- t = args;
- }
- else
- {
- t = PyTuple_New(1);
- if(!t.get())
- {
- throw AbortMarshaling();
- }
- PyTuple_SET_ITEM(t.get(), 0, args);
- }
- Py_INCREF(args);
-
- os->startEncapsulation(encoding, _op->format);
-
- ObjectMap objectMap;
- ParamInfoList::iterator p;
-
- //
- // Validate the results.
- //
- for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos);
- if((!info->optional || arg != Unset) && !info->type->validate(arg))
- {
- // TODO: Provide the parameter name instead?
- ostringstream ostr;
- ostr << "invalid value for out argument " << (info->pos + 1) << " in operation `"
- << _op->dispatchName << "'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
- }
- if(_op->returnType)
- {
- PyObject* res = PyTuple_GET_ITEM(t.get(), 0);
- if((!_op->returnType->optional || res != Unset) && !_op->returnType->type->validate(res))
- {
- ostringstream ostr;
- ostr << "invalid return value for operation `" << _op->dispatchName << "'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
- }
-
- //
- // Marshal the required out parameters.
- //
- for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- if(!info->optional)
- {
- PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos);
- info->type->marshal(arg, os, &objectMap, false, &info->metaData);
- }
- }
-
- //
- // Marshal the required return value, if any.
- //
- if(_op->returnType && !_op->returnType->optional)
- {
- PyObject* res = PyTuple_GET_ITEM(t.get(), 0);
- _op->returnType->type->marshal(res, os, &objectMap, false, &_op->metaData);
- }
-
- //
- // Marshal the optional results.
- //
- for(p = _op->optionalOutParams.begin(); p != _op->optionalOutParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos);
- if(arg != Unset && os->writeOptional(info->tag, info->type->optionalFormat()))
- {
- info->type->marshal(arg, os, &objectMap, true, &info->metaData);
- }
- }
-
- if(_op->returnsClasses)
- {
- os->writePendingObjects();
- }
-
- os->endEncapsulation();
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_response(true, os->finished());
- }
- catch(const AbortMarshaling&)
- {
- throwPythonException();
- }
- }
- catch(const Ice::Exception& ex)
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_exception(ex);
- }
-}
-
-void
-IcePy::TypedUpcall::exception(PyException& ex, const Ice::EncodingVersion& encoding)
-{
- if(_finished)
- {
- //
- // An asynchronous response or exception has already been sent. We just
- // raise an exception and let the C++ run time handle it.
- //
- ex.raise();
- }
-
- _finished = true;
-
- try
- {
- try
- {
- //
- // A servant that calls sys.exit() will raise the SystemExit exception.
- // This is normally caught by the interpreter, causing it to exit.
- // However, we have no way to pass this exception to the interpreter,
- // so we act on it directly.
- //
- ex.checkSystemExit();
-
- PyObject* userExceptionType = lookupType("Ice.UserException");
-
- if(PyObject_IsInstance(ex.ex.get(), userExceptionType))
- {
- //
- // Get the exception's type and verify that it is legal to be thrown from this operation.
- //
- PyObjectHandle iceType = PyObject_GetAttrString(ex.ex.get(), STRCAST("_ice_type"));
- assert(iceType.get());
- ExceptionInfoPtr info = ExceptionInfoPtr::dynamicCast(getException(iceType.get()));
- assert(info);
- if(!validateException(ex.ex.get()))
- {
- ex.raise(); // Raises UnknownUserException.
- }
- else
- {
- Ice::OutputStreamPtr os = Ice::createOutputStream(_communicator);
- os->startEncapsulation(encoding, _op->format);
-
- ExceptionWriter writer(_communicator, ex.ex, info);
- os->writeException(writer);
-
- os->endEncapsulation();
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_response(false, os->finished());
- }
- }
- else
- {
- ex.raise();
- }
- }
- catch(const AbortMarshaling&)
- {
- throwPythonException();
- }
- }
- catch(const Ice::Exception& ex)
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_exception(ex);
- }
-}
-
-bool
-IcePy::TypedUpcall::validateException(PyObject* ex) const
-{
- for(ExceptionInfoList::const_iterator p = _op->exceptions.begin(); p != _op->exceptions.end(); ++p)
- {
- if(PyObject_IsInstance(ex, (*p)->pythonType.get()))
- {
- return true;
- }
- }
-
- return false;
-}
-
-//
-// BlobjectUpcall
-//
-IcePy::BlobjectUpcall::BlobjectUpcall(bool amd, const Ice::AMD_Object_ice_invokePtr& callback) :
- _amd(amd), _callback(callback), _finished(false)
-{
-}
-
-void
-IcePy::BlobjectUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, const Ice::Byte*>& inBytes,
- const Ice::Current& current)
-{
- Ice::CommunicatorPtr communicator = current.adapter->getCommunicator();
-
- Py_ssize_t count = 2; // First is the inParams, second is the Ice::Current object.
-
- Py_ssize_t start = 0;
- if(_amd)
- {
- ++count; // Leave room for a leading AMD callback argument.
- start = 1;
- }
-
- PyObjectHandle args = PyTuple_New(count);
- if(!args.get())
- {
- throwPythonException();
- }
-
- PyObjectHandle ip;
-
-#if PY_VERSION_HEX >= 0x03000000
- if(inBytes.second == inBytes.first)
- {
- ip = PyBytes_FromString("");
- }
- else
- {
- ip = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(inBytes.first), inBytes.second - inBytes.first);
- }
-#else
- //
- // If using AMD we need to copy the bytes since the bytes may be
- // accessed after this method is over, otherwise
- // PyBuffer_FromMemory can be used which doesn't do a copy.
- //
- if(!_amd)
- {
- ip = PyBuffer_FromMemory((void*)inBytes.first, inBytes.second - inBytes.first);
- if(!ip.get())
- {
- throwPythonException();
- }
- }
- else
- {
- ip = PyBuffer_New(inBytes.second - inBytes.first);
- if(!ip.get())
- {
- throwPythonException();
- }
- void* buf;
- Py_ssize_t sz;
- if(PyObject_AsWriteBuffer(ip.get(), &buf, &sz))
- {
- throwPythonException();
- }
- assert(sz == inBytes.second - inBytes.first);
- memcpy(buf, inBytes.first, sz);
- }
-#endif
-
- if(PyTuple_SET_ITEM(args.get(), start, ip.get()) < 0)
- {
- throwPythonException();
- }
- ++start;
- ip.release(); // PyTuple_SET_ITEM steals a reference.
-
- //
- // Create an object to represent Ice::Current. We need to append
- // this to the argument tuple.
- //
- PyObjectHandle curr = createCurrent(current);
- if(PyTuple_SET_ITEM(args.get(), start, curr.get()) < 0)
- {
- throwPythonException();
- }
- curr.release(); // PyTuple_SET_ITEM steals a reference.
-
- string dispatchName = "ice_invoke";
- if(_amd)
- {
- dispatchName += "_async";
- //
- // Create the callback object and pass it as the first argument.
- //
- AMDCallbackObject* obj = amdCallbackNew(&AMDCallbackType, 0, 0);
- if(!obj)
- {
- throwPythonException();
- }
- obj->upcall = new UpcallPtr(this);
- obj->encoding = current.encoding;
- if(PyTuple_SET_ITEM(args.get(), 0, (PyObject*)obj) < 0) // PyTuple_SET_ITEM steals a reference.
- {
- Py_DECREF(obj);
- throwPythonException();
- }
- }
-
- //
- // Dispatch the operation.
- //
- PyObjectHandle method = PyObject_GetAttrString(servant, const_cast<char*>(dispatchName.c_str()));
- if(!method.get())
- {
- ostringstream ostr;
- ostr << "servant for identity " << communicator->identityToString(current.id)
- << " does not define operation `" << dispatchName << "'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- Ice::UnknownException ex(__FILE__, __LINE__);
- ex.unknown = str;
- throw ex;
- }
-
- PyObjectHandle result = PyObject_Call(method.get(), args.get(), 0);
-
- //
- // Check for exceptions.
- //
- if(PyErr_Occurred())
- {
- PyException ex; // Retrieve it before another Python API call clears it.
- exception(ex, current.encoding);
- return;
- }
-
- if(!_amd)
- {
- response(result.get(), current.encoding);
- }
-}
-
-void
-IcePy::BlobjectUpcall::response(PyObject* args, const Ice::EncodingVersion&)
-{
- if(_finished)
- {
- //
- // This method could be called more than once if the application calls
- // ice_response multiple times. We ignore subsequent calls.
- //
- return;
- }
-
- _finished = true;
-
- //
- // The return value is a tuple of (bool, results).
- //
- if(!PyTuple_Check(args) || PyTuple_GET_SIZE(args) != 2)
- {
- ostringstream ostr;
- string name = "ice_invoke";
- if(_amd)
- {
- name += "_async";
- }
- ostr << "operation `" << name << "' should return a tuple of length 2";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
-
- PyObject* arg = PyTuple_GET_ITEM(args, 0);
- bool isTrue = PyObject_IsTrue(arg) == 1;
-
- arg = PyTuple_GET_ITEM(args, 1);
-
-#if PY_VERSION_HEX >= 0x03000000
- if(!PyBytes_Check(arg))
- {
- ostringstream ostr;
- ostr << "invalid return value for operation `ice_invoke'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
-
- Py_ssize_t sz = PyBytes_GET_SIZE(arg);
- pair<const ::Ice::Byte*, const ::Ice::Byte*> r(static_cast<const Ice::Byte*>(0),static_cast<const Ice::Byte*>(0));
- if(sz > 0)
- {
- r.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(arg));
- r.second = r.first + sz;
- }
-#else
- if(!PyBuffer_Check(arg))
- {
- ostringstream ostr;
- ostr << "invalid return value for operation `ice_invoke'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
-
- char* charBuf = 0;
- Py_ssize_t sz = arg->ob_type->tp_as_buffer->bf_getcharbuffer(arg, 0, &charBuf);
- const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf);
- const pair<const ::Ice::Byte*, const ::Ice::Byte*> r(mem, mem + sz);
-#endif
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_response(isTrue, r);
-}
-
-void
-IcePy::BlobjectUpcall::exception(PyException& ex, const Ice::EncodingVersion&)
-{
- if(_finished)
- {
- //
- // An asynchronous response or exception has already been sent. We just
- // raise an exception and let the C++ run time handle it.
- //
- ex.raise();
- }
-
- _finished = true;
-
- try
- {
- //
- // A servant that calls sys.exit() will raise the SystemExit exception.
- // This is normally caught by the interpreter, causing it to exit.
- // However, we have no way to pass this exception to the interpreter,
- // so we act on it directly.
- //
- ex.checkSystemExit();
-
- ex.raise();
- }
- catch(const Ice::Exception& ex)
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_exception(ex);
- }
-}
-
-PyObject*
-IcePy::invokeBuiltin(PyObject* proxy, const string& builtin, PyObject* args)
-{
- string name = "_op_" + builtin;
- PyObject* objectType = lookupType("Ice.Object");
- assert(objectType);
- PyObjectHandle obj = PyObject_GetAttrString(objectType, STRCAST(name.c_str()));
- assert(obj.get());
-
- OperationPtr op = getOperation(obj.get());
- assert(op);
-
- Ice::ObjectPrx p = getProxy(proxy);
- InvocationPtr i = new SyncTypedInvocation(p, op);
- return i->invoke(args);
-}
-
-PyObject*
-IcePy::beginBuiltin(PyObject* proxy, const string& builtin, PyObject* args)
-{
- string name = "_op_" + builtin;
- PyObject* objectType = lookupType("Ice.Object");
- assert(objectType);
- PyObjectHandle obj = PyObject_GetAttrString(objectType, STRCAST(name.c_str()));
- assert(obj.get());
-
- OperationPtr op = getOperation(obj.get());
- assert(op);
-
- Ice::ObjectPrx p = getProxy(proxy);
- InvocationPtr i = new AsyncTypedInvocation(p, proxy, op);
- return i->invoke(args);
-}
-
-PyObject*
-IcePy::endBuiltin(PyObject* proxy, const string& builtin, PyObject* args)
-{
- PyObject* result;
- if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result))
- {
- return 0;
- }
-
- string name = "_op_" + builtin;
- PyObject* objectType = lookupType("Ice.Object");
- assert(objectType);
- PyObjectHandle obj = PyObject_GetAttrString(objectType, STRCAST(name.c_str()));
- assert(obj.get());
-
- OperationPtr op = getOperation(obj.get());
- assert(op);
-
- AsyncResultObject* ar = reinterpret_cast<AsyncResultObject*>(result);
- assert(ar);
- AsyncTypedInvocationPtr i = AsyncTypedInvocationPtr::dynamicCast(*ar->invocation);
- if(!i)
- {
- PyErr_Format(PyExc_ValueError, STRCAST("invalid AsyncResult object passed to end_%s"), op->name.c_str());
- return 0;
- }
- Ice::ObjectPrx p = getProxy(proxy);
- return i->end(p, op, *ar->result);
-}
-
-PyObject*
-IcePy::iceInvoke(PyObject* proxy, PyObject* args)
-{
- Ice::ObjectPrx p = getProxy(proxy);
- InvocationPtr i = new SyncBlobjectInvocation(p);
- return i->invoke(args);
-}
-
-PyObject*
-IcePy::iceInvokeAsync(PyObject* proxy, PyObject* args)
-{
- Ice::ObjectPrx p = getProxy(proxy);
- InvocationPtr i = new OldAsyncBlobjectInvocation(p);
- return i->invoke(args);
-}
-
-PyObject*
-IcePy::beginIceInvoke(PyObject* proxy, PyObject* args, PyObject* kwds)
-{
- Ice::ObjectPrx p = getProxy(proxy);
- InvocationPtr i = new AsyncBlobjectInvocation(p, proxy);
- return i->invoke(args, kwds);
-}
-
-PyObject*
-IcePy::endIceInvoke(PyObject* proxy, PyObject* args)
-{
- PyObject* result;
- if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result))
- {
- return 0;
- }
-
- AsyncResultObject* ar = reinterpret_cast<AsyncResultObject*>(result);
- assert(ar);
- AsyncBlobjectInvocationPtr i = AsyncBlobjectInvocationPtr::dynamicCast(*ar->invocation);
- if(!i)
- {
- PyErr_Format(PyExc_ValueError, STRCAST("invalid AsyncResult object passed to end_ice_invoke"));
- return 0;
- }
- Ice::ObjectPrx p = getProxy(proxy);
- return i->end(p, *ar->result);
-}
-
-PyObject*
-IcePy::createAsyncResult(const Ice::AsyncResultPtr& r, PyObject* proxy, PyObject* connection, PyObject* communicator)
-{
- AsyncResultObject* obj = asyncResultNew(&AsyncResultType, 0, 0);
- if(!obj)
- {
- return 0;
- }
- obj->result = new Ice::AsyncResultPtr(r);
- obj->proxy = proxy;
- Py_XINCREF(obj->proxy);
- obj->connection = connection;
- Py_XINCREF(obj->connection);
- obj->communicator = communicator;
- Py_XINCREF(obj->communicator);
- return reinterpret_cast<PyObject*>(obj);
-}
-
-Ice::AsyncResultPtr
-IcePy::getAsyncResult(PyObject* p)
-{
- assert(PyObject_IsInstance(p, reinterpret_cast<PyObject*>(&AsyncResultType)) == 1);
- AsyncResultObject* obj = reinterpret_cast<AsyncResultObject*>(p);
- return *obj->result;
-}
-
-IcePy::FlushCallback::FlushCallback(PyObject* ex, PyObject* sent, const string& op) :
- _ex(ex), _sent(sent), _op(op)
-{
- assert(_ex);
- Py_INCREF(_ex);
- Py_XINCREF(_sent);
-}
-
-IcePy::FlushCallback::~FlushCallback()
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- Py_DECREF(_ex);
- Py_XDECREF(_sent);
-}
-
-void
-IcePy::FlushCallback::exception(const Ice::Exception& ex)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- callException(_ex, ex);
-}
-
-void
-IcePy::FlushCallback::sent(bool sentSynchronously)
-{
- if(_sent)
- {
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
- callSent(_sent, sentSynchronously, true);
- }
-}
-
-IcePy::GetConnectionCallback::GetConnectionCallback(const Ice::CommunicatorPtr& communicator,
- PyObject* response, PyObject* ex, const string& op) :
- _communicator(communicator), _response(response), _ex(ex), _op(op)
-{
- assert(_response);
- Py_INCREF(_response);
- Py_XINCREF(_ex);
-}
-
-IcePy::GetConnectionCallback::~GetConnectionCallback()
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- Py_DECREF(_response);
- Py_XDECREF(_ex);
-}
-
-void
-IcePy::GetConnectionCallback::response(const Ice::ConnectionPtr& conn)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- PyObjectHandle pyConn = createConnection(conn, _communicator);
- PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), pyConn.get());
- PyObjectHandle tmp = PyObject_Call(_response, args.get(), 0);
- if(PyErr_Occurred())
- {
- handleException(); // Callback raised an exception.
- }
-}
-
-void
-IcePy::GetConnectionCallback::exception(const Ice::Exception& ex)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- callException(_ex, ex);
-}
-
-//
-// ServantWrapper implementation.
-//
-IcePy::ServantWrapper::ServantWrapper(PyObject* servant) :
- _servant(servant)
-{
- Py_INCREF(_servant);
-}
-
-IcePy::ServantWrapper::~ServantWrapper()
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- Py_DECREF(_servant);
-}
-
-PyObject*
-IcePy::ServantWrapper::getObject()
-{
- Py_INCREF(_servant);
- return _servant;
-}
-
-//
-// TypedServantWrapper implementation.
-//
-IcePy::TypedServantWrapper::TypedServantWrapper(PyObject* servant) :
- ServantWrapper(servant), _lastOp(_operationMap.end())
-{
-}
-
-void
-IcePy::TypedServantWrapper::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb,
- const pair<const Ice::Byte*, const Ice::Byte*>& inParams,
- const Ice::Current& current)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- try
- {
- //
- // Locate the Operation object. As an optimization we keep a reference
- // to the most recent operation we've dispatched, so check that first.
- //
- OperationPtr op;
- if(_lastOp != _operationMap.end() && _lastOp->first == current.operation)
- {
- op = _lastOp->second;
- }
- else
- {
- //
- // Next check our cache of operations.
- //
- _lastOp = _operationMap.find(current.operation);
- if(_lastOp == _operationMap.end())
- {
- //
- // Look for the Operation object in the servant's type.
- //
- string attrName = "_op_" + current.operation;
- PyObjectHandle h = PyObject_GetAttrString((PyObject*)_servant->ob_type,
- const_cast<char*>(attrName.c_str()));
- if(!h.get())
- {
- PyErr_Clear();
- Ice::OperationNotExistException ex(__FILE__, __LINE__);
- ex.id = current.id;
- ex.facet = current.facet;
- ex.operation = current.operation;
- throw ex;
- }
-
- assert(PyObject_IsInstance(h.get(), reinterpret_cast<PyObject*>(&OperationType)) == 1);
- OperationObject* obj = reinterpret_cast<OperationObject*>(h.get());
- op = *obj->op;
- _lastOp = _operationMap.insert(OperationMap::value_type(current.operation, op)).first;
- }
- else
- {
- op = _lastOp->second;
- }
- }
-
- //
- // See bug 4976.
- //
- if(!op->pseudoOp)
- {
- __checkMode(op->mode, current.mode);
- }
-
- UpcallPtr up = new TypedUpcall(op, cb, current.adapter->getCommunicator());
- up->dispatch(_servant, inParams, current);
- }
- catch(const Ice::Exception& ex)
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- cb->ice_exception(ex);
- }
-}
-
-//
-// BlobjectServantWrapper implementation.
-//
-IcePy::BlobjectServantWrapper::BlobjectServantWrapper(PyObject* servant, bool amd) :
- ServantWrapper(servant), _amd(amd)
-{
-}
-
-void
-IcePy::BlobjectServantWrapper::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb,
- const pair<const Ice::Byte*, const Ice::Byte*>& inParams,
- const Ice::Current& current)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- try
- {
- UpcallPtr up = new BlobjectUpcall(_amd, cb);
- up->dispatch(_servant, inParams, current);
- }
- catch(const Ice::Exception& ex)
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- cb->ice_exception(ex);
- }
-}
-
-IcePy::ServantWrapperPtr
-IcePy::createServantWrapper(PyObject* servant)
-{
- ServantWrapperPtr wrapper;
- PyObject* blobjectType = lookupType("Ice.Blobject");
- PyObject* blobjectAsyncType = lookupType("Ice.BlobjectAsync");
- if(PyObject_IsInstance(servant, blobjectType))
- {
- return new BlobjectServantWrapper(servant, false);
- }
- else if(PyObject_IsInstance(servant, blobjectAsyncType))
- {
- return new BlobjectServantWrapper(servant, true);
- }
-
- return new TypedServantWrapper(servant);
-}