// -*- Mode: C++; -*-
// Package : omniORBpy
// pyServant.cc Created on: 1999/07/29
// Author : Duncan Grisby (dpg1)
//
// Copyright (C) 1999 AT&T Laboratories Cambridge
//
// This file is part of the omniORBpy library
//
// The omniORBpy library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any later
// version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA
//
//
// Description:
// Implementation of Python servant object
// $Id: pyServant.cc,v 1.1.4.9 2006/07/05 10:47:14 dgrisby Exp $
// $Log: pyServant.cc,v $
// Revision 1.1.4.9 2006/07/05 10:47:14 dgrisby
// Propagate exceptions out of _default_POA.
//
// Revision 1.1.4.8 2005/11/09 12:33:32 dgrisby
// Support POA LocalObjects.
//
// Revision 1.1.4.7 2005/07/22 17:41:07 dgrisby
// Update from omnipy2_develop.
//
// Revision 1.1.4.6 2005/06/24 17:36:00 dgrisby
// Support for receiving valuetypes inside Anys; relax requirement for
// old style classes in a lot of places.
//
// Revision 1.1.4.5 2005/04/14 13:50:59 dgrisby
// New traceTime, traceInvocationReturns functions; removal of omniORB::logf.
//
// Revision 1.1.4.4 2005/01/25 11:45:48 dgrisby
// Merge from omnipy2_develop; set RPM version.
//
// Revision 1.1.4.3 2005/01/07 00:22:33 dgrisby
// Big merge from omnipy2_develop.
//
// Revision 1.1.4.2 2003/05/20 17:10:24 dgrisby
// Preliminary valuetype support.
//
// Revision 1.1.4.1 2003/03/23 21:51:57 dgrisby
// New omnipy3_develop branch.
//
// Revision 1.1.2.13 2003/01/27 11:56:58 dgrisby
// Correctly handle invalid returns from application code.
//
// Revision 1.1.2.12 2002/03/18 12:40:38 dpg1
// Support overriding _non_existent.
//
// Revision 1.1.2.11 2002/03/11 15:40:04 dpg1
// _get_interface support, exception minor codes.
//
// Revision 1.1.2.10 2002/01/18 15:49:44 dpg1
// Context support. New system exception construction. Fix None call problem.
//
// Revision 1.1.2.9 2001/09/24 10:48:28 dpg1
// Meaningful minor codes.
//
// Revision 1.1.2.8 2001/06/15 10:59:26 dpg1
// Apply fixes from omnipy1_develop.
//
// Revision 1.1.2.7 2001/06/01 11:09:26 dpg1
// Make use of new omni::ptrStrCmp() and omni::strCmp().
//
// Revision 1.1.2.6 2001/05/29 17:10:14 dpg1
// Support for in process identity.
//
// Revision 1.1.2.5 2001/05/14 12:47:22 dpg1
// Fix memory leaks.
//
// Revision 1.1.2.4 2001/05/10 15:16:03 dpg1
// Big update to support new omniORB 4 internals.
//
// Revision 1.1.2.3 2001/03/13 10:38:08 dpg1
// Fixes from omnipy1_develop
//
// Revision 1.1.2.2 2000/12/04 18:57:24 dpg1
// Fix deadlock when trying to lock omniORB internal lock while holding
// the Python interpreter lock.
//
// Revision 1.1.2.1 2000/10/13 13:55:27 dpg1
// Initial support for omniORB 4.
//
#include <omnipy.h>
#include <pyThreadCache.h>
#include <omniORB4/callHandle.h>
#include <omniORB4/IOP_S.h>
// Implementation classes for ServantManagers and AdapterActivator
class Py_ServantActivatorSvt :
public virtual POA_PortableServer::ServantActivator,
public virtual omniPy::Py_omniServant
{
public:
Py_ServantActivatorSvt(PyObject* pysa, PyObject* opdict, const char* repoId)
: PY_OMNISERVANT_BASE(pysa, opdict, repoId), impl_(pysa) { }
virtual ~Py_ServantActivatorSvt() { }
PortableServer::Servant incarnate(const PortableServer::ObjectId& oid,
PortableServer::POA_ptr poa)
{
return impl_.incarnate(oid, poa);
}
void etherealize(const PortableServer::ObjectId& oid,
PortableServer::POA_ptr poa,
PortableServer::Servant serv,
CORBA::Boolean cleanup_in_progress,
CORBA::Boolean remaining_activations)
{
impl_.etherealize(oid, poa, serv, cleanup_in_progress,
remaining_activations);
}
void* _ptrToInterface(const char* repoId);
CORBA::Boolean _is_a(const char* logical_type_id) {
return PY_OMNISERVANT_BASE::_is_a(logical_type_id);
}
PortableServer::POA_ptr _default_POA() {
return PY_OMNISERVANT_BASE::_default_POA();
}
const char* _mostDerivedRepoId() {
return PY_OMNISERVANT_BASE::_mostDerivedRepoId();
}
CORBA::Boolean _dispatch(omniCallHandle& handle) {
return PY_OMNISERVANT_BASE::_dispatch(handle);
}
private:
omniPy::Py_ServantActivator impl_;
// Not implemented
Py_ServantActivatorSvt(const Py_ServantActivatorSvt&);
Py_ServantActivatorSvt& operator=(const Py_ServantActivatorSvt&);
};
class Py_ServantLocatorSvt :
public virtual POA_PortableServer::ServantLocator,
public virtual omniPy::Py_omniServant
{
public:
Py_ServantLocatorSvt(PyObject* pysl, PyObject* opdict, const char* repoId)
: PY_OMNISERVANT_BASE(pysl, opdict, repoId), impl_(pysl) { }
virtual ~Py_ServantLocatorSvt() { }
PortableServer::Servant preinvoke(const PortableServer::ObjectId& oid,
PortableServer::POA_ptr poa,
const char* operation,
void*& cookie)
{
return impl_.preinvoke(oid, poa, operation, cookie);
}
void postinvoke(const PortableServer::ObjectId& oid,
PortableServer::POA_ptr poa,
const char* operation,
void* cookie,
PortableServer::Servant serv)
{
impl_.postinvoke(oid, poa, operation, cookie, serv);
}
void* _ptrToInterface(const char* repoId);
CORBA::Boolean _is_a(const char* logical_type_id) {
return PY_OMNISERVANT_BASE::_is_a(logical_type_id);
}
PortableServer::POA_ptr _default_POA() {
return PY_OMNISERVANT_BASE::_default_POA();
}
const char* _mostDerivedRepoId() {
return PY_OMNISERVANT_BASE::_mostDerivedRepoId();
}
CORBA::Boolean _dispatch(omniCallHandle& handle) {
return PY_OMNISERVANT_BASE::_dispatch(handle);
}
private:
omniPy::Py_ServantLocator impl_;
// Not implemented
Py_ServantLocatorSvt(const Py_ServantLocatorSvt&);
Py_ServantLocatorSvt& operator=(const Py_ServantLocatorSvt&);
};
class Py_AdapterActivatorSvt :
public virtual POA_PortableServer::AdapterActivator,
public virtual omniPy::Py_omniServant
{
public:
Py_AdapterActivatorSvt(PyObject* pyaa, PyObject* opdict, const char* repoId)
: PY_OMNISERVANT_BASE(pyaa, opdict, repoId), impl_(pyaa) { }
virtual ~Py_AdapterActivatorSvt() { }
CORBA::Boolean unknown_adapter(PortableServer::POA_ptr parent,
const char* name)
{
return impl_.unknown_adapter(parent, name);
}
void* _ptrToInterface(const char* repoId);
CORBA::Boolean _is_a(const char* logical_type_id) {
return PY_OMNISERVANT_BASE::_is_a(logical_type_id);
}
PortableServer::POA_ptr _default_POA() {
return PY_OMNISERVANT_BASE::_default_POA();
}
const char* _mostDerivedRepoId() {
return PY_OMNISERVANT_BASE::_mostDerivedRepoId();
}
CORBA::Boolean _dispatch(omniCallHandle& handle) {
return PY_OMNISERVANT_BASE::_dispatch(handle);
}
private:
omniPy::Py_AdapterActivator impl_;
// Not implemented
Py_AdapterActivatorSvt(const Py_AdapterActivatorSvt&);
Py_AdapterActivatorSvt& operator=(const Py_AdapterActivatorSvt&);
};
// Implementation of Py_omniServant
omniPy::
Py_omniServant::Py_omniServant(PyObject* pyservant, PyObject* opdict,
const char* repoId)
: pyservant_(pyservant), opdict_(opdict), refcount_(1)
{
repoId_ = CORBA::string_dup(repoId);
OMNIORB_ASSERT(PyDict_Check(opdict));
Py_INCREF(pyservant_);
Py_INCREF(opdict_);
pyskeleton_ = PyObject_GetAttrString(pyservant_, (char*)"_omni_skeleton");
OMNIORB_ASSERT(pyskeleton_);
omniPy::setTwin(pyservant, (omniPy::Py_omniServant*)this, SERVANT_TWIN);
}
omniPy::
Py_omniServant::~Py_omniServant()
{
omniPy::remTwin(pyservant_, SERVANT_TWIN);
Py_DECREF(pyservant_);
Py_DECREF(opdict_);
Py_DECREF(pyskeleton_);
CORBA::string_free(repoId_);
}
void
omniPy::
Py_omniServant::_add_ref()
{
omnipyThreadCache::lock _t;
OMNIORB_ASSERT(refcount_ > 0);
++refcount_;
}
void
omniPy::
Py_omniServant::_locked_add_ref()
{
OMNIORB_ASSERT(refcount_ > 0);
++refcount_;
}
void
omniPy::
Py_omniServant::_remove_ref()
{
omnipyThreadCache::lock _t;
if (--refcount_ > 0) return;
OMNIORB_ASSERT(refcount_ == 0);
delete this;
}
void
omniPy::
Py_omniServant::_locked_remove_ref()
{
if (--refcount_ > 0) return;
OMNIORB_ASSERT(refcount_ == 0);
delete this;
}
void*
omniPy::
Py_omniServant::_ptrToInterface(const char* repoId)
{
OMNIORB_ASSERT(repoId);
if (omni::ptrStrMatch(repoId, omniPy::string_Py_omniServant))
return (Py_omniServant*)this;
if (omni::ptrStrMatch(repoId, CORBA::Object::_PD_repoId))
return (void*)1;
return 0;
}
const char*
omniPy::
Py_omniServant::_mostDerivedRepoId()
{
return repoId_;
}
PortableServer::POA_ptr
omniPy::
Py_omniServant::_default_POA()
{
{
omnipyThreadCache::lock _t;
PyObject* pyPOA = PyObject_CallMethod(pyservant_,
(char*)"_default_POA", 0);
if (pyPOA) {
PortableServer::POA_ptr poa =
(PortableServer::POA_ptr)omniPy::getTwin(pyPOA, POA_TWIN);
Py_DECREF(pyPOA);
if (poa) {
return PortableServer::POA::_duplicate(poa);
}
else {
omniORB::logs(1, "Python servant returned an invalid object from "
"_default_POA.");
OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType,
CORBA::COMPLETED_NO);
}
}
else {
// The call raised a Python exception
omniORB::logs(1, "Python servant raised an exception in _default_POA.");
omniPy::handlePythonException();
}
}
}
CORBA::Boolean
omniPy::
Py_omniServant::_non_existent()
{
omnipyThreadCache::lock _t;
PyObject* result = PyObject_CallMethod(pyservant_,
(char*)"_non_existent", 0);
if (!result) {
if (omniORB::trace(1)) {
{
omniORB::logger l;
l << "Exception trying to call _non_existent. Raising UNKNOWN.\n";
}
PyErr_Print();
}
else {
PyErr_Clear();
}
OMNIORB_THROW(UNKNOWN, UNKNOWN_PythonException, CORBA::COMPLETED_NO);
}
if (!PyInt_Check(result))
OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, CORBA::COMPLETED_NO);
long i = PyInt_AS_LONG(result);
Py_DECREF(result);
return i ? 1 : 0;
}
PyObject*
omniPy::
Py_omniServant::py_this()
{
CORBA::Object_ptr lobjref;
{
omniPy::InterpreterUnlocker _u;
{
CORBA::Object_var objref;
objref = (CORBA::Object_ptr)_do_this(CORBA::Object::_PD_repoId);
lobjref = omniPy::makeLocalObjRef(repoId_, objref);
}
}
return omniPy::createPyCorbaObjRef(repoId_, lobjref);
}
CORBA::Boolean
omniPy::
Py_omniServant::_is_a(const char* logical_type_id)
{
if (omni::ptrStrMatch(logical_type_id, repoId_))
return 1;
else if (omni::ptrStrMatch(logical_type_id, CORBA::Object::_PD_repoId))
return 1;
else {
omnipyThreadCache::lock _t;
PyObject* pyisa = PyObject_CallMethod(omniPy::pyomniORBmodule,
(char*)"static_is_a", (char*)"Os",
pyskeleton_, logical_type_id);
if (!pyisa) PyErr_Print();
OMNIORB_ASSERT(pyisa && PyInt_Check(pyisa));
CORBA::Boolean isa = PyInt_AS_LONG(pyisa);
Py_DECREF(pyisa);
if (isa)
return 1;
// Last resort -- does the servant have an _is_a method?
if (PyObject_HasAttrString(pyservant_, (char*)"_is_a")) {
pyisa = PyObject_CallMethod(pyservant_, (char*)"_is_a",
(char*)"s", logical_type_id);
if (pyisa && PyInt_Check(pyisa)) {
CORBA::Boolean isa = PyInt_AS_LONG(pyisa);
Py_DECREF(pyisa);
return isa;
}
if (!pyisa) {
omniPy::handlePythonException();
}
}
}
return 0;
}
CORBA::Boolean
omniPy::
Py_omniServant::_dispatch(omniCallHandle& handle)
{
int i;
omnipyThreadCache::lock _t;
const char* op = handle.operation_name();
PyObject* desc = PyDict_GetItemString(opdict_, (char*)op);
if (!desc) {
if (omni::strMatch(op, "_interface")) {
// Special case: _interface call maps to _get_interface
//
// If the IR stubs have been loaded, the descriptor for the
// _interface call will be in the CORBA module. If they have not
// been loaded, there will be no descriptor, and we fall back to
// the ORB core version of _interface.
desc = PyObject_GetAttrString(omniPy::pyCORBAmodule,
(char*)"_d_Object_interface");
if (desc)
Py_DECREF(desc);
else
PyErr_Clear();
}
if (!desc)
return 0; // Unknown operation name
}
OMNIORB_ASSERT(PyTuple_Check(desc));
PyObject* in_d = PyTuple_GET_ITEM(desc,0);
PyObject* out_d = PyTuple_GET_ITEM(desc,1);
PyObject* exc_d = PyTuple_GET_ITEM(desc,2);
PyObject* ctxt_d;
if (PyTuple_GET_SIZE(desc) == 4)
ctxt_d = PyTuple_GET_ITEM(desc,3);
else
ctxt_d = 0;
Py_omniCallDescriptor call_desc(op, 0,
(out_d == Py_None),
in_d, out_d, exc_d, ctxt_d, 0, 1);
try {
omniPy::InterpreterUnlocker _u;
handle.upcall(this, call_desc);
}
catch (omniPy::PyUserException& ex) {
if (handle.iop_s()) {
try {
omniPy::InterpreterUnlocker _u;
handle.iop_s()->SendException(&ex);
}
catch (...) {
ex.decrefPyException();
throw;
}
ex.decrefPyException();
}
else
throw;
}
return 1;
}
void
omniPy::
Py_omniServant::remote_dispatch(Py_omniCallDescriptor* pycd)
{
const char* op = pycd->op();
PyObject* method = PyObject_GetAttrString(pyservant_, (char*)op);
if (!method && omni::strMatch(op, "_interface")) {
PyErr_Clear();
method = PyObject_GetAttrString(pyservant_, (char*)"_get_interface");
}
if (!method) {
if (omniORB::trace(1)) {
omniORB::logger l;
l << "Python servant for `" << repoId_ << "' has no method named `"
<< op << "'.\n";
}
PyErr_Clear();
OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_NoPythonMethod,
CORBA::COMPLETED_NO);
}
PyObject* args = pycd->args();
PyObject* result = PyEval_CallObject(method, args);
Py_DECREF(method);
if (result) {
// No exception was thrown. Set the return value
pycd->setAndValidateReturnedValues(result);
}
else {
// An exception of some sort was thrown
PyObject *etype, *evalue, *etraceback;
PyObject *erepoId = 0;
PyErr_Fetch(&etype, &evalue, &etraceback);
PyErr_NormalizeException(&etype, &evalue, &etraceback);
OMNIORB_ASSERT(etype);
if (evalue)
erepoId = PyObject_GetAttrString(evalue, (char*)"_NP_RepositoryId");
if (!(erepoId && PyString_Check(erepoId))) {
Py_XDECREF(erepoId);
if (omniORB::trace(1)) {
{
omniORB::logger l;
l << "Caught an unexpected Python exception during up-call.\n";
}
PyErr_Restore(etype, evalue, etraceback);
PyErr_Print();
}
else {
Py_DECREF(etype); Py_XDECREF(evalue); Py_XDECREF(etraceback);
}
OMNIORB_THROW(UNKNOWN, UNKNOWN_PythonException, CORBA::COMPLETED_MAYBE);
}
PyObject* exc_d = pycd->exc_d_;
// Is it a user exception?
if (exc_d != Py_None) {
OMNIORB_ASSERT(PyDict_Check(exc_d));
PyObject* edesc = PyDict_GetItem(exc_d, erepoId);
if (edesc) {
Py_DECREF(erepoId); Py_DECREF(etype); Py_XDECREF(etraceback);
PyUserException ex(edesc, evalue, CORBA::COMPLETED_MAYBE);
ex._raise();
}
}
// Is it a LOCATION_FORWARD?
if (omni::strMatch(PyString_AS_STRING(erepoId),
"omniORB.LOCATION_FORWARD")) {
Py_DECREF(erepoId); Py_DECREF(etype); Py_XDECREF(etraceback);
omniPy::handleLocationForward(evalue);
}
// System exception or unknown user exception
omniPy::produceSystemException(evalue, erepoId, etype, etraceback);
}
}
void
omniPy::
Py_omniServant::local_dispatch(Py_omniCallDescriptor* pycd)
{
const char* op = pycd->op();
PyObject* method = PyObject_GetAttrString(pyservant_, (char*)op);
if (!method && omni::strMatch(op, "_interface")) {
PyErr_Clear();
method = PyObject_GetAttrString(pyservant_, (char*)"_get_interface");
}
if (!method) {
if (omniORB::trace(1)) {
omniORB::logger l;
l << "Python servant for `" << repoId_ << "' has no method named `"
<< op << "'.\n";
}
PyErr_Clear();
OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_NoPythonMethod,
CORBA::COMPLETED_NO);
}
PyObject* in_d = pycd->in_d_;
int in_l = pycd->in_l_;
PyObject* out_d = pycd->out_d_;
int out_l = pycd->out_l_;
PyObject* exc_d = pycd->exc_d_;
PyObject* ctxt_d = pycd->ctxt_d_;
PyObject* args = pycd->args();
// Copy args which would otherwise have reference semantics
PyObject* argtuple = PyTuple_New(in_l + (ctxt_d ? 1 : 0));
PyObject* t_o;
int i;
try {
for (i=0; i < in_l; ++i) {
t_o = copyArgument(PyTuple_GET_ITEM(in_d, i),
PyTuple_GET_ITEM(args, i),
CORBA::COMPLETED_NO);
OMNIORB_ASSERT(t_o);
PyTuple_SET_ITEM(argtuple, i, t_o);
}
if (ctxt_d) {
t_o = filterContext(ctxt_d, PyTuple_GET_ITEM(args, in_l));
OMNIORB_ASSERT(t_o);
PyTuple_SET_ITEM(argtuple, in_l, t_o);
}
}
catch (...) {
Py_DECREF(argtuple);
Py_DECREF(method);
throw;
}
//
// Do the call
PyObject* result = PyEval_CallObject(method, argtuple);
Py_DECREF(method);
Py_DECREF(argtuple);
if (result) {
PyObject* retval = 0;
try {
if (out_l == -1 || out_l == 0) {
if (result == Py_None) {
pycd->setReturnedValues(result);
return;
}
else
OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType,
CORBA::COMPLETED_MAYBE);
}
else if (out_l == 1) {
retval = copyArgument(PyTuple_GET_ITEM(out_d, 0),
result, CORBA::COMPLETED_MAYBE);
}
else {
if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != out_l)
OMNIORB_THROW(BAD_PARAM,
BAD_PARAM_WrongPythonType,
CORBA::COMPLETED_MAYBE);
retval = PyTuple_New(out_l);
for (i=0; i < out_l; ++i) {
t_o = copyArgument(PyTuple_GET_ITEM(out_d, i),
PyTuple_GET_ITEM(result, i),
CORBA::COMPLETED_MAYBE);
PyTuple_SET_ITEM(retval, i, t_o);
}
}
}
catch (...) {
Py_DECREF(result);
Py_XDECREF(retval);
throw;
}
Py_DECREF(result);
pycd->setReturnedValues(retval);
}
else {
// The call raised a Python exception
PyObject *etype, *evalue, *etraceback;
PyObject *erepoId = 0;
PyErr_Fetch(&etype, &evalue, &etraceback);
PyErr_NormalizeException(&etype, &evalue, &etraceback);
OMNIORB_ASSERT(etype);
if (evalue)
erepoId = PyObject_GetAttrString(evalue, (char*)"_NP_RepositoryId");
if (!(erepoId && PyString_Check(erepoId))) {
Py_XDECREF(erepoId);
if (omniORB::trace(1)) {
{
omniORB::logger l;
l << "Caught an unexpected Python exception during up-call.\n";
}
PyErr_Restore(etype, evalue, etraceback);
PyErr_Print();
}
else {
Py_DECREF(etype); Py_XDECREF(evalue); Py_XDECREF(etraceback);
}
OMNIORB_THROW(UNKNOWN, UNKNOWN_PythonException, CORBA::COMPLETED_MAYBE);
}
// Is it a user exception?
if (exc_d != Py_None) {
OMNIORB_ASSERT(PyDict_Check(exc_d));
PyObject* edesc = PyDict_GetItem(exc_d, erepoId);
if (edesc) {
Py_DECREF(erepoId); Py_DECREF(etype); Py_XDECREF(etraceback);
PyUserException ex(edesc, evalue, CORBA::COMPLETED_MAYBE);
ex._raise();
}
}
// Is it a LOCATION_FORWARD?
if (omni::strMatch(PyString_AS_STRING(erepoId),
"omniORB.LOCATION_FORWARD")) {
Py_DECREF(erepoId); Py_DECREF(etype); Py_XDECREF(etraceback);
omniPy::handleLocationForward(evalue);
}
// System exception or unknown user exception
omniPy::produceSystemException(evalue, erepoId, etype, etraceback);
}
}
// Py_ServantActivatorSvt
void*
Py_ServantActivatorSvt::_ptrToInterface(const char* repoId)
{
if (omni::ptrStrMatch(repoId, PortableServer::ServantActivator::_PD_repoId))
return (PortableServer::_impl_ServantActivator*)this;
if (omni::ptrStrMatch(repoId, omniPy::string_Py_omniServant))
return (omniPy::Py_omniServant*)this;
if (omni::ptrStrMatch(repoId, PortableServer::ServantManager::_PD_repoId))
return (PortableServer::_impl_ServantManager*)this;
if (omni::ptrStrMatch(repoId, CORBA::Object::_PD_repoId))
return (void*)1;
return 0;
}
// Py_ServantLocatorSvt
void*
Py_ServantLocatorSvt::_ptrToInterface(const char* repoId)
{
if (omni::ptrStrMatch(repoId, PortableServer::ServantLocator::_PD_repoId))
return (PortableServer::_impl_ServantLocator*)this;
if (omni::ptrStrMatch(repoId, omniPy::string_Py_omniServant))
return (omniPy::Py_omniServant*)this;
if (omni::ptrStrMatch(repoId, PortableServer::ServantManager::_PD_repoId))
return (PortableServer::_impl_ServantManager*)this;
if (omni::ptrStrMatch(repoId, CORBA::Object::_PD_repoId))
return (void*)1;
return 0;
}
// Py_AdapterActivatorSvt
void*
Py_AdapterActivatorSvt::_ptrToInterface(const char* repoId)
{
if (omni::ptrStrMatch(repoId, PortableServer::AdapterActivator::_PD_repoId))
return (PortableServer::_impl_AdapterActivator*)this;
if (omni::ptrStrMatch(repoId, omniPy::string_Py_omniServant))
return (omniPy::Py_omniServant*)this;
if (omni::ptrStrMatch(repoId, CORBA::Object::_PD_repoId))
return (void*)1;
return 0;
}
// Functions to create Py_omniServant objects
static
omniPy::Py_omniServant*
newSpecialServant(PyObject* pyservant, PyObject* opdict, char* repoId)
{
if (omni::ptrStrMatch(repoId, PortableServer::ServantActivator::_PD_repoId))
return new Py_ServantActivatorSvt(pyservant, opdict, repoId);
if (omni::ptrStrMatch(repoId, PortableServer::ServantLocator::_PD_repoId))
return new Py_ServantLocatorSvt(pyservant, opdict, repoId);
if (omni::ptrStrMatch(repoId, PortableServer::AdapterActivator::_PD_repoId))
return new Py_AdapterActivatorSvt(pyservant, opdict, repoId);
OMNIORB_ASSERT(0);
return 0;
}
omniPy::Py_omniServant*
omniPy::getServantForPyObject(PyObject* pyservant)
{
Py_omniServant* pyos;
// Is there a Py_omniServant already?
pyos = (omniPy::Py_omniServant*)omniPy::getTwin(pyservant, SERVANT_TWIN);
if (pyos) {
pyos->_locked_add_ref();
return pyos;
}
// Is it an instance of the right class?
if (!omniPy::isInstance(pyservant, omniPy::pyServantClass))
return 0;
PyObject* opdict = PyObject_GetAttrString(pyservant, (char*)"_omni_op_d");
if (!(opdict && PyDict_Check(opdict)))
return 0;
PyObject* pyrepoId = PyObject_GetAttrString(pyservant,
(char*)"_NP_RepositoryId");
if (!(pyrepoId && PyString_Check(pyrepoId))) {
Py_DECREF(opdict);
return 0;
}
if (PyObject_HasAttrString(pyservant, (char*)"_omni_special")) {
pyos = newSpecialServant(pyservant, opdict, PyString_AS_STRING(pyrepoId));
}
else {
pyos = new omniPy::Py_omniServant(pyservant, opdict,
PyString_AS_STRING(pyrepoId));
}
Py_DECREF(opdict);
Py_DECREF(pyrepoId);
return pyos;
}
syntax highlighted by Code2HTML, v. 0.9.1