summaryrefslogtreecommitdiff
path: root/py/modules/IcePy/Proxy.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2004-09-03 22:10:30 +0000
committerMark Spruiell <mes@zeroc.com>2004-09-03 22:10:30 +0000
commita7dad57c553430519573cd808b326126d4affffb (patch)
tree9ee6aba6d6f03cf6feb8b08cae6382b294682355 /py/modules/IcePy/Proxy.cpp
parentRenamed IceInternal.Connection to Ice.ConnectionI (diff)
downloadice-a7dad57c553430519573cd808b326126d4affffb.tar.bz2
ice-a7dad57c553430519573cd808b326126d4affffb.tar.xz
ice-a7dad57c553430519573cd808b326126d4affffb.zip
type refactoring
Diffstat (limited to 'py/modules/IcePy/Proxy.cpp')
-rw-r--r--py/modules/IcePy/Proxy.cpp282
1 files changed, 3 insertions, 279 deletions
diff --git a/py/modules/IcePy/Proxy.cpp b/py/modules/IcePy/Proxy.cpp
index 91e4dca1243..d1afd79afee 100644
--- a/py/modules/IcePy/Proxy.cpp
+++ b/py/modules/IcePy/Proxy.cpp
@@ -10,10 +10,8 @@
#include <Proxy.h>
#include <structmember.h>
#include <Identity.h>
-#include <Marshal.h>
-#include <Types.h>
+#include <Operation.h>
#include <Util.h>
-#include <Ice/Initialize.h>
#include <Ice/LocalException.h>
#include <Ice/Proxy.h>
@@ -30,29 +28,6 @@ struct ProxyObject
Ice::CommunicatorPtr* communicator;
};
-//
-// Represents a user-defined operation.
-//
-class Operation : public IceUtil::Shared
-{
-public:
-
- Operation(const OperationInfoPtr&);
- ~Operation();
-
- PyObject* invoke(const Ice::ObjectPrx&, const Ice::CommunicatorPtr&, PyObject*);
-
-private:
-
- void throwUserException(const Ice::CommunicatorPtr&, const Ice::InputStreamPtr&);
-
- OperationInfoPtr _info;
- MarshalerPtr _resultMarshaler;
- vector<MarshalerPtr> _inParams;
- vector<MarshalerPtr> _outParams;
-};
-typedef IceUtil::Handle<Operation> OperationPtr;
-
}
static ProxyObject*
@@ -70,254 +45,6 @@ allocateProxy(const Ice::ObjectPrx& proxy, const Ice::CommunicatorPtr& communica
return p;
}
-IcePy::Operation::Operation(const OperationInfoPtr& info) :
- _info(info)
-{
- if(_info->returnType)
- {
- _resultMarshaler = Marshaler::createMarshaler(_info->returnType);
- }
-
- TypeInfoList::iterator p;
-
- for(p = _info->inParams.begin(); p != _info->inParams.end(); ++p)
- {
- _inParams.push_back(Marshaler::createMarshaler(*p));
- }
-
- for(p = _info->outParams.begin(); p != _info->outParams.end(); ++p)
- {
- _outParams.push_back(Marshaler::createMarshaler(*p));
- }
-}
-
-IcePy::Operation::~Operation()
-{
-}
-
-PyObject*
-IcePy::Operation::invoke(const Ice::ObjectPrx& proxy, const Ice::CommunicatorPtr& communicator, PyObject* args)
-{
- assert(PyTuple_Check(args));
-
- string fixedName = fixIdent(_info->name);
-
- //
- // Validate the number of arguments. There may be an extra argument for the context.
- //
- int argc = PyTuple_GET_SIZE(args);
- int paramCount = static_cast<int>(_inParams.size());
- if(argc != paramCount && argc != paramCount + 1)
- {
- PyErr_Format(PyExc_RuntimeError, "%s expects %d in parameters", fixedName.c_str(), _inParams.size());
- return NULL;
- }
-
- //
- // Retrieve the context if any.
- //
- Ice::Context ctx;
- bool haveContext = false;
- if(argc == paramCount + 1)
- {
- PyObject* pyctx = PyTuple_GET_ITEM(args, argc - 1);
- if(pyctx != Py_None)
- {
- if(!PyDict_Check(pyctx))
- {
- PyErr_Format(PyExc_ValueError, "context argument must be a dictionary");
- return NULL;
- }
-
- if(!dictionaryToContext(pyctx, ctx))
- {
- return NULL;
- }
-
- haveContext = true;
- }
- }
-
- try
- {
- //
- // Marshal the in parameters.
- //
- Ice::OutputStreamPtr os = Ice::createOutputStream(communicator);
- ObjectMap objectMap;
- int i = 0;
- for(vector<MarshalerPtr>::iterator p = _inParams.begin(); p != _inParams.end(); ++p, ++i)
- {
- PyObject* arg = PyTuple_GET_ITEM(args, i);
- (*p)->marshal(arg, os, &objectMap);
- }
-
- Ice::ByteSeq params;
- os->finished(params);
-
- //
- // Invoke the operation. Use _info->name here, not fixedName.
- //
- Ice::ByteSeq result;
- bool status;
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
-
- if(haveContext)
- {
- status = proxy->ice_invoke(_info->name, (Ice::OperationMode)_info->mode, params, result, ctx);
- }
- else
- {
- status = proxy->ice_invoke(_info->name, (Ice::OperationMode)_info->mode, params, result);
- }
- }
-
- //
- // Process the reply.
- //
- if(proxy->ice_isTwoway())
- {
- Ice::InputStreamPtr is = Ice::createInputStream(communicator, result);
-
- if(!status)
- {
- //
- // Unmarshal and "throw" a user exception.
- //
- throwUserException(communicator, is);
- return NULL;
- }
- else if(_outParams.size() > 0 || _resultMarshaler)
- {
- //
- // 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.
- //
- // TODO: Check for oneway/datagram errors
- //
-
- i = _resultMarshaler ? 1 : 0;
- int numResults = static_cast<int>(_outParams.size()) + i;
- PyObjectHandle results = PyTuple_New(numResults);
- if(results.get() == NULL)
- {
- return NULL;
- }
-
- for(vector<MarshalerPtr>::iterator q = _outParams.begin(); q != _outParams.end(); ++q, ++i)
- {
- ObjectMarshalerPtr om = ObjectMarshalerPtr::dynamicCast(*q);
- if(om)
- {
- om->unmarshalObject(communicator, is, new TupleReceiver(om->info(), results.get(), i));
- }
- else
- {
- PyObjectHandle outParam = (*q)->unmarshal(communicator, is);
- if(outParam.get() == NULL)
- {
- return NULL;
- }
- PyTuple_SET_ITEM(results.get(), i, outParam.release()); // PyTuple_SET_ITEM steals a reference.
- }
- }
-
- if(_resultMarshaler)
- {
- ObjectMarshalerPtr om = ObjectMarshalerPtr::dynamicCast(_resultMarshaler);
- if(om)
- {
- om->unmarshalObject(communicator, is, new TupleReceiver(om->info(), results.get(), 0));
- }
- else
- {
- PyObjectHandle r = _resultMarshaler->unmarshal(communicator, is);
- if(r.get() == NULL)
- {
- return NULL;
- }
- PyTuple_SET_ITEM(results.get(), 0, r.release()); // PyTuple_SET_ITEM steals a reference.
- }
- }
-
- is->finished();
-
- if(numResults > 1)
- {
- return results.release();
- }
- else
- {
- PyObject* ret = PyTuple_GET_ITEM(results.get(), 0);
- Py_INCREF(ret);
- return ret;
- }
- }
- }
- }
- catch(const AbortMarshaling&)
- {
- return NULL;
- }
- catch(const Ice::Exception& ex)
- {
- setPythonException(ex);
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-void
-IcePy::Operation::throwUserException(const Ice::CommunicatorPtr& communicator, const Ice::InputStreamPtr& is)
-{
- is->readBool(); // usesClasses
-
- string id = is->readString();
- while(!id.empty())
- {
- ExceptionInfoPtr info = getExceptionInfo(id);
- if(info)
- {
- MarshalerPtr marshaler = Marshaler::createExceptionMarshaler(info);
- PyObjectHandle ex = marshaler->unmarshal(communicator, is);
- is->finished();
-
- if(_info->validateException(ex.get()))
- {
- //
- // Set the Python exception.
- //
- assert(PyInstance_Check(ex.get()));
- PyObject* type = (PyObject*)((PyInstanceObject*)ex.get())->in_class;
- Py_INCREF(type);
- PyErr_Restore(type, ex.release(), NULL);
- }
- else
- {
- throwPythonException(ex.get());
- }
-
- return;
- }
- else
- {
- is->skipSlice();
- id = is->readString();
- }
- }
-
- //
- // Getting here should be impossible: we can get here only if the
- // sender has marshaled a sequence of type IDs, none of which we
- // have factory for. This means that sender and receiver disagree
- // about the Slice definitions they use.
- //
- throw Ice::UnknownUserException(__FILE__, __LINE__);
-}
-
#ifdef WIN32
extern "C"
#endif
@@ -1038,11 +765,8 @@ proxyIceOperation(ProxyObject* self, PyObject* args)
return NULL;
}
- ClassInfoPtr info = ClassInfoPtr::dynamicCast(getTypeInfo(type));
- assert(info);
- OperationInfoPtr opInfo = info->findOperation(name);
- assert(opInfo);
- OperationPtr op = new Operation(opInfo); // TODO: Cache this
+ OperationPtr op = getOperation(type, name);
+ assert(op);
return op->invoke(*self->proxy, *self->communicator, opArgs);
}