diff options
author | Dwayne Boone <dwayne@zeroc.com> | 2009-10-16 09:38:13 -0230 |
---|---|---|
committer | Dwayne Boone <dwayne@zeroc.com> | 2009-10-16 09:38:13 -0230 |
commit | b8b803f51c8ff622491d2a160663e4912f7dba03 (patch) | |
tree | b4ded20bd5b2fa37a18943a5ac0665ce2d525128 /py | |
parent | Added support for per-OA ACM and fix for retry on CloseConnectionException (diff) | |
download | ice-b8b803f51c8ff622491d2a160663e4912f7dba03.tar.bz2 ice-b8b803f51c8ff622491d2a160663e4912f7dba03.tar.xz ice-b8b803f51c8ff622491d2a160663e4912f7dba03.zip |
Added support for EndpointInfo and ConnectionInfo to python.
Set endpoint in Connection getInfo implementations.
Removed unused _stateTime from ConnectionI.
Remove ["cpp:virtual"] from SSLEndpointInfo slice definition.
Diffstat (limited to 'py')
-rw-r--r-- | py/modules/IcePy/Connection.cpp | 22 | ||||
-rw-r--r-- | py/modules/IcePy/ConnectionInfo.cpp | 363 | ||||
-rw-r--r-- | py/modules/IcePy/ConnectionInfo.h | 28 | ||||
-rw-r--r-- | py/modules/IcePy/Endpoint.cpp | 24 | ||||
-rw-r--r-- | py/modules/IcePy/EndpointInfo.cpp | 534 | ||||
-rw-r--r-- | py/modules/IcePy/EndpointInfo.h | 28 | ||||
-rw-r--r-- | py/modules/IcePy/Init.cpp | 10 | ||||
-rw-r--r-- | py/modules/IcePy/Makefile | 2 | ||||
-rw-r--r-- | py/modules/IcePy/Makefile.mak | 2 | ||||
-rw-r--r-- | py/python/Ice.py | 27 | ||||
-rw-r--r-- | py/test/Ice/proxy/AllTests.py | 49 |
11 files changed, 1056 insertions, 33 deletions
diff --git a/py/modules/IcePy/Connection.cpp b/py/modules/IcePy/Connection.cpp index 3bf3e761639..e373f1c1f17 100644 --- a/py/modules/IcePy/Connection.cpp +++ b/py/modules/IcePy/Connection.cpp @@ -11,6 +11,7 @@ # include <IceUtil/Config.h> #endif #include <Connection.h> +#include <ConnectionInfo.h> #include <ObjectAdapter.h> #include <Proxy.h> #include <Util.h> @@ -281,6 +282,25 @@ connectionToString(ConnectionObject* self) return createString(str); } +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionGetInfo(ConnectionObject* self) +{ + assert(self->connection); + try + { + Ice::ConnectionInfoPtr info = (*self->connection)->getInfo(); + return createConnectionInfo(info); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + static PyMethodDef ConnectionMethods[] = { { STRCAST("close"), reinterpret_cast<PyCFunction>(connectionClose), METH_VARARGS, @@ -299,6 +319,8 @@ static PyMethodDef ConnectionMethods[] = PyDoc_STR(STRCAST("timeout() -> int")) }, { STRCAST("toString"), reinterpret_cast<PyCFunction>(connectionToString), METH_NOARGS, PyDoc_STR(STRCAST("toString() -> string")) }, + { STRCAST("getInfo"), reinterpret_cast<PyCFunction>(connectionGetInfo), METH_NOARGS, + PyDoc_STR(STRCAST("getInfo() -> Ice.ConnectionInfo")) }, { 0, 0 } /* sentinel */ }; diff --git a/py/modules/IcePy/ConnectionInfo.cpp b/py/modules/IcePy/ConnectionInfo.cpp new file mode 100644 index 00000000000..5220728a5ea --- /dev/null +++ b/py/modules/IcePy/ConnectionInfo.cpp @@ -0,0 +1,363 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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 <ConnectionInfo.h> +#include <EndpointInfo.h> +#include <Util.h> +#include <structmember.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +struct ConnectionInfoObject +{ + PyObject_HEAD + + // Ice::ConnectionInfo + PyObject* endpoint; + + // Ice::TcpConnectionInfo + // Ice::UdpConnectionInfo + PyObject* localAddress; + int localPort; + PyObject* remoteAddress; + int remotePort; + + // Ice::UdpConnectionInfo + PyObject* mcastAddress; + int mcastPort; + + Ice::ConnectionInfoPtr* connectionInfo; +}; + +extern PyTypeObject TcpConnectionInfoType; +extern PyTypeObject UdpConnectionInfoType; + +} + +#ifdef WIN32 +extern "C" +#endif +static ConnectionInfoObject* +connectionInfoNew(PyObject* /*arg*/) +{ + PyErr_Format(PyExc_RuntimeError, STRCAST("An connection info cannot be created directly")); + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +connectionInfoDealloc(ConnectionInfoObject* self) +{ + if(Ice::TcpConnectionInfoPtr::dynamicCast(*self->connectionInfo)) + { + Py_DECREF(self->localAddress); + Py_DECREF(self->remoteAddress); + } + else if(Ice::UdpConnectionInfoPtr::dynamicCast(*self->connectionInfo)) + { + Py_DECREF(self->localAddress); + Py_DECREF(self->remoteAddress); + Py_DECREF(self->mcastAddress); + } + + delete self->connectionInfo; + Py_DECREF(self->endpoint); + PyObject_Del(self); +} + +static PyMemberDef ConnectionInfoMembers[] = +{ + { STRCAST("endpoint"), T_OBJECT, offsetof(ConnectionInfoObject, endpoint), READONLY, + PyDoc_STR(STRCAST("endpoint used to establish the connection")) }, + { 0, 0 } /* sentinel */ +}; + +static PyMemberDef TcpConnectionInfoMembers[] = +{ + { STRCAST("localAddress"), T_OBJECT, offsetof(ConnectionInfoObject, localAddress), READONLY, + PyDoc_STR(STRCAST("local address")) }, + { STRCAST("localPort"), T_INT, offsetof(ConnectionInfoObject, localPort), READONLY, + PyDoc_STR(STRCAST("local port")) }, + { STRCAST("remoteAddress"), T_OBJECT, offsetof(ConnectionInfoObject, remoteAddress), READONLY, + PyDoc_STR(STRCAST("remote address")) }, + { STRCAST("remotePort"), T_INT, offsetof(ConnectionInfoObject, remotePort), READONLY, + PyDoc_STR(STRCAST("remote port")) }, + { 0, 0 } /* sentinel */ +}; + +static PyMemberDef UdpConnectionInfoMembers[] = +{ + { STRCAST("localAddress"), T_OBJECT, offsetof(ConnectionInfoObject, localAddress), READONLY, + PyDoc_STR(STRCAST("local address")) }, + { STRCAST("localPort"), T_INT, offsetof(ConnectionInfoObject, localPort), READONLY, + PyDoc_STR(STRCAST("local port")) }, + { STRCAST("remoteAddress"), T_OBJECT, offsetof(ConnectionInfoObject, remoteAddress), READONLY, + PyDoc_STR(STRCAST("remote address")) }, + { STRCAST("remotePort"), T_INT, offsetof(ConnectionInfoObject, remotePort), READONLY, + PyDoc_STR(STRCAST("remote port")) }, + { STRCAST("mcastAddress"), T_OBJECT, offsetof(ConnectionInfoObject, mcastAddress), READONLY, + PyDoc_STR(STRCAST("multicast address")) }, + { STRCAST("mcastPort"), T_INT, offsetof(ConnectionInfoObject, mcastPort), READONLY, + PyDoc_STR(STRCAST("multicast port")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject ConnectionInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(0) + 0, /* ob_size */ + STRCAST("IcePy.ConnectionInfo"), /* tp_name */ + sizeof(ConnectionInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)connectionInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 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 | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + ConnectionInfoMembers, /* 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 */ + (newfunc)connectionInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject TcpConnectionInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(0) + 0, /* ob_size */ + STRCAST("IcePy.TcpConnectionInfo"),/* tp_name */ + sizeof(ConnectionInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)connectionInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 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 | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + TcpConnectionInfoMembers, /* 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 */ + (newfunc)connectionInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject UdpConnectionInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(0) + 0, /* ob_size */ + STRCAST("IcePy.UdpConnectionInfo"),/* tp_name */ + sizeof(ConnectionInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)connectionInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 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 | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + UdpConnectionInfoMembers, /* 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 */ + (newfunc)connectionInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initConnectionInfo(PyObject* module) +{ + if(PyType_Ready(&ConnectionInfoType) < 0) + { + return false; + } + PyTypeObject* type = &ConnectionInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("ConnectionInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + TcpConnectionInfoType.tp_base = &ConnectionInfoType; // Force inheritance from ConnectionInfoType. + if(PyType_Ready(&TcpConnectionInfoType) < 0) + { + return false; + } + type = &TcpConnectionInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("TcpConnectionInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + UdpConnectionInfoType.tp_base = &ConnectionInfoType; // Force inheritance from ConnectionType. + if(PyType_Ready(&UdpConnectionInfoType) < 0) + { + return false; + } + type = &UdpConnectionInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("UdpConnectionInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +Ice::ConnectionInfoPtr +IcePy::getConnectionInfo(PyObject* obj) +{ + assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&ConnectionInfoType))); + ConnectionInfoObject* eobj = reinterpret_cast<ConnectionInfoObject*>(obj); + return *eobj->connectionInfo; +} + +PyObject* +IcePy::createConnectionInfo(const Ice::ConnectionInfoPtr& connectionInfo) +{ + ConnectionInfoObject* obj; + if(Ice::TcpConnectionInfoPtr::dynamicCast(connectionInfo)) + { + obj = PyObject_New(ConnectionInfoObject, &TcpConnectionInfoType); + if(!obj) + { + return 0; + } + + Ice::TcpConnectionInfoPtr tcpConnectionInfo = Ice::TcpConnectionInfoPtr::dynamicCast(connectionInfo); + obj->localAddress = IcePy::createString(tcpConnectionInfo->localAddress); + obj->localPort = static_cast<int>(tcpConnectionInfo->localPort); + obj->remoteAddress = IcePy::createString(tcpConnectionInfo->remoteAddress); + obj->remotePort = static_cast<int>(tcpConnectionInfo->remotePort); + } + else if(Ice::UdpConnectionInfoPtr::dynamicCast(connectionInfo)) + { + obj = PyObject_New(ConnectionInfoObject, &UdpConnectionInfoType); + if(!obj) + { + return 0; + } + + Ice::UdpConnectionInfoPtr udpConnectionInfo = Ice::UdpConnectionInfoPtr::dynamicCast(connectionInfo); + obj->localAddress = IcePy::createString(udpConnectionInfo->localAddress); + obj->localPort = static_cast<int>(udpConnectionInfo->localPort); + obj->remoteAddress = IcePy::createString(udpConnectionInfo->remoteAddress); + obj->remotePort = static_cast<int>(udpConnectionInfo->remotePort); + obj->mcastAddress = IcePy::createString(udpConnectionInfo->mcastAddress); + obj->mcastPort = static_cast<int>(udpConnectionInfo->mcastPort); + } + else + { + obj = PyObject_New(ConnectionInfoObject, &ConnectionInfoType); + if(!obj) + { + return 0; + } + } + + obj->connectionInfo = new Ice::ConnectionInfoPtr(connectionInfo); + Ice::EndpointInfoPtr info = connectionInfo->endpoint; + obj->endpoint = IcePy::createEndpointInfo(connectionInfo->endpoint); + + return (PyObject*)obj; +} diff --git a/py/modules/IcePy/ConnectionInfo.h b/py/modules/IcePy/ConnectionInfo.h new file mode 100644 index 00000000000..db30b23345d --- /dev/null +++ b/py/modules/IcePy/ConnectionInfo.h @@ -0,0 +1,28 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef ICEPY_CONNECTION_INFO_H +#define ICEPY_CONNECTION_INFO_H + +#include <Config.h> +#include <Ice/Connection.h> + +namespace IcePy +{ + +extern PyTypeObject ConnectionInfoType; + +bool initConnectionInfo(PyObject*); + +PyObject* createConnectionInfo(const Ice::ConnectionInfoPtr&); +Ice::ConnectionInfoPtr getConnectionInfo(PyObject*); + +} + +#endif diff --git a/py/modules/IcePy/Endpoint.cpp b/py/modules/IcePy/Endpoint.cpp index 3dee6fae2d4..1c9eefd52ad 100644 --- a/py/modules/IcePy/Endpoint.cpp +++ b/py/modules/IcePy/Endpoint.cpp @@ -11,6 +11,7 @@ # include <IceUtil/Config.h> #endif #include <Endpoint.h> +#include <EndpointInfo.h> #include <Util.h> using namespace std; @@ -75,10 +76,31 @@ endpointRepr(EndpointObject* self) return endpointToString(self); } +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointGetInfo(EndpointObject* self) +{ + assert(self->endpoint); + try + { + Ice::EndpointInfoPtr info = (*self->endpoint)->getInfo(); + return createEndpointInfo(info); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + static PyMethodDef EndpointMethods[] = { { STRCAST("toString"), reinterpret_cast<PyCFunction>(endpointToString), METH_NOARGS, PyDoc_STR(STRCAST("toString() -> string")) }, + { STRCAST("getInfo"), reinterpret_cast<PyCFunction>(endpointGetInfo), METH_NOARGS, + PyDoc_STR(STRCAST("getInfo() -> Ice.EndpointInfo")) }, { 0, 0 } /* sentinel */ }; @@ -91,7 +113,7 @@ PyTypeObject EndpointType = * to be portable to Windows without using C++. */ PyObject_HEAD_INIT(0) 0, /* ob_size */ - STRCAST("Ice.Endpoint"), /* tp_name */ + STRCAST("IcePy.Endpoint"), /* tp_name */ sizeof(EndpointObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ diff --git a/py/modules/IcePy/EndpointInfo.cpp b/py/modules/IcePy/EndpointInfo.cpp new file mode 100644 index 00000000000..52ebd1175fc --- /dev/null +++ b/py/modules/IcePy/EndpointInfo.cpp @@ -0,0 +1,534 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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 <EndpointInfo.h> +#include <Util.h> +#include <structmember.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +struct EndpointInfoObject +{ + PyObject_HEAD + + // Ice::EndpointInfo + int timeout; + PyObject* compress; + + // Ice::TcpEndpointInfo + // Ice::UdpEndpointInfo + PyObject* host; + int port; + + // Ice::UdpEndpointInfo + unsigned char protocolMajor; + unsigned char protocolMinor; + unsigned char encodingMajor; + unsigned char encodingMinor; + PyObject* mcastInterface; + int mcastTtl; + + // Ice::OpaqueEndpointInfo + PyObject* rawBytes; + + Ice::EndpointInfoPtr* endpointInfo; +}; + +extern PyTypeObject TcpEndpointInfoType; +extern PyTypeObject UdpEndpointInfoType; +extern PyTypeObject OpaqueEndpointInfoType; + +} + +#ifdef WIN32 +extern "C" +#endif +static EndpointInfoObject* +endpointInfoNew(PyObject* /*arg*/) +{ + PyErr_Format(PyExc_RuntimeError, STRCAST("An endpoint info cannot be created directly")); + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +endpointInfoDealloc(EndpointInfoObject* self) +{ + if(Ice::TcpEndpointInfoPtr::dynamicCast(*self->endpointInfo)) + { + Py_DECREF(self->host); + } + else if(Ice::UdpEndpointInfoPtr::dynamicCast(*self->endpointInfo)) + { + Py_DECREF(self->host); + Py_DECREF(self->mcastInterface); + } + else if(Ice::OpaqueEndpointInfoPtr::dynamicCast(*self->endpointInfo)) + { + Py_DECREF(self->rawBytes); + } + + delete self->endpointInfo; + Py_DECREF(self->compress); + PyObject_Del(self); +} + +// +// Ice::EndpointInfo::type +// +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointInfoType(EndpointInfoObject* self) +{ + assert(self->endpointInfo); + try + { + Ice::Short type = (*self->endpointInfo)->type(); + return PyInt_FromLong(type); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +// +// Ice::EndpointInfo::datagram +// +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointInfoDatagram(EndpointInfoObject* self) +{ + assert(self->endpointInfo); + PyObject* b; + try + { + b = (*self->endpointInfo)->datagram() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +// +// Ice::EndpointInfo::datagram +// +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointInfoSecure(EndpointInfoObject* self) +{ + assert(self->endpointInfo); + PyObject* b; + try + { + b = (*self->endpointInfo)->secure() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +static PyMethodDef EndpointInfoMethods[] = +{ + { STRCAST("type"), reinterpret_cast<PyCFunction>(endpointInfoType), METH_NOARGS, + PyDoc_STR(STRCAST("type() -> int")) }, + { STRCAST("datagram"), reinterpret_cast<PyCFunction>(endpointInfoDatagram), METH_NOARGS, + PyDoc_STR(STRCAST("datagram() -> bool")) }, + { STRCAST("secure"), reinterpret_cast<PyCFunction>(endpointInfoSecure), METH_NOARGS, + PyDoc_STR(STRCAST("secure() -> bool")) }, + { 0, 0 } /* sentinel */ +}; + +static PyMemberDef EndpointInfoMembers[] = +{ + { STRCAST("timeout"), T_INT, offsetof(EndpointInfoObject, timeout), READONLY, + PyDoc_STR(STRCAST("timeout in milliseconds")) }, + { STRCAST("compress"), T_OBJECT, offsetof(EndpointInfoObject, compress), READONLY, + PyDoc_STR(STRCAST("compression status")) }, + { 0, 0 } /* sentinel */ +}; + +static PyMemberDef TcpEndpointInfoMembers[] = +{ + { STRCAST("host"), T_OBJECT, offsetof(EndpointInfoObject, host), READONLY, + PyDoc_STR(STRCAST("host name or ip address")) }, + { STRCAST("port"), T_INT, offsetof(EndpointInfoObject, port), READONLY, + PyDoc_STR(STRCAST("tcp port number")) }, + { 0, 0 } /* sentinel */ +}; + +static PyMemberDef UdpEndpointInfoMembers[] = +{ + { STRCAST("host"), T_OBJECT, offsetof(EndpointInfoObject, host), READONLY, + PyDoc_STR(STRCAST("host name or ip address")) }, + { STRCAST("port"), T_INT, offsetof(EndpointInfoObject, port), READONLY, + PyDoc_STR(STRCAST("udp port number")) }, + { STRCAST("protocolMajor"), T_BYTE, offsetof(EndpointInfoObject, protocolMajor), READONLY, + PyDoc_STR(STRCAST("protocol major version")) }, + { STRCAST("protocolMinor"), T_BYTE, offsetof(EndpointInfoObject, protocolMinor), READONLY, + PyDoc_STR(STRCAST("protocol minor version")) }, + { STRCAST("encodingMajor"), T_BYTE, offsetof(EndpointInfoObject, encodingMajor), READONLY, + PyDoc_STR(STRCAST("encoding major version")) }, + { STRCAST("encodingMinor"), T_BYTE, offsetof(EndpointInfoObject, encodingMinor), READONLY, + PyDoc_STR(STRCAST("encoding minor version")) }, + { STRCAST("mcastInterface"), T_OBJECT, offsetof(EndpointInfoObject, mcastInterface), READONLY, + PyDoc_STR(STRCAST("multicast interface")) }, + { STRCAST("mcastTtl"), T_INT, offsetof(EndpointInfoObject, mcastTtl), READONLY, + PyDoc_STR(STRCAST("mulitcast time-to-live")) }, + { 0, 0 } /* sentinel */ +}; + +static PyMemberDef OpaqueEndpointInfoMembers[] = +{ + { STRCAST("rawBytes"), T_OBJECT, offsetof(EndpointInfoObject, rawBytes), READONLY, + PyDoc_STR(STRCAST("raw encoding")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject EndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(0) + 0, /* ob_size */ + STRCAST("IcePy.EndpointInfo"), /* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)endpointInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 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 | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + EndpointInfoMethods, /* tp_methods */ + EndpointInfoMembers, /* 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 */ + (newfunc)endpointInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject TcpEndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(0) + 0, /* ob_size */ + STRCAST("IcePy.TcpEndpointInfo"),/* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)endpointInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 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 | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + TcpEndpointInfoMembers, /* 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 */ + (newfunc)endpointInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject UdpEndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(0) + 0, /* ob_size */ + STRCAST("IcePy.UdpEndpointInfo"),/* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)endpointInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 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 | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + UdpEndpointInfoMembers, /* 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 */ + (newfunc)endpointInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject OpaqueEndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(0) + 0, /* ob_size */ + STRCAST("IcePy.OpaqueEndpointInfo"),/* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)endpointInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 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 | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + OpaqueEndpointInfoMembers, /* 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 */ + (newfunc)endpointInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initEndpointInfo(PyObject* module) +{ + if(PyType_Ready(&EndpointInfoType) < 0) + { + return false; + } + PyTypeObject* type = &EndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("EndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + TcpEndpointInfoType.tp_base = &EndpointInfoType; // Force inheritance from EndpointInfoType. + if(PyType_Ready(&TcpEndpointInfoType) < 0) + { + return false; + } + type = &TcpEndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("TcpEndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + UdpEndpointInfoType.tp_base = &EndpointInfoType; // Force inheritance from EndpointType. + if(PyType_Ready(&UdpEndpointInfoType) < 0) + { + return false; + } + type = &UdpEndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("UdpEndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + OpaqueEndpointInfoType.tp_base = &EndpointInfoType; // Force inheritance from EndpointType. + if(PyType_Ready(&OpaqueEndpointInfoType) < 0) + { + return false; + } + type = &OpaqueEndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("OpaqueEndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +Ice::EndpointInfoPtr +IcePy::getEndpointInfo(PyObject* obj) +{ + assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&EndpointInfoType))); + EndpointInfoObject* eobj = reinterpret_cast<EndpointInfoObject*>(obj); + return *eobj->endpointInfo; +} + +PyObject* +IcePy::createEndpointInfo(const Ice::EndpointInfoPtr& endpointInfo) +{ + EndpointInfoObject* obj; + if(Ice::TcpEndpointInfoPtr::dynamicCast(endpointInfo)) + { + obj = PyObject_New(EndpointInfoObject, &TcpEndpointInfoType); + if(!obj) + { + return 0; + } + + Ice::TcpEndpointInfoPtr tcpEndpointInfo = Ice::TcpEndpointInfoPtr::dynamicCast(endpointInfo); + obj->host = IcePy::createString(tcpEndpointInfo->host); + obj->port = static_cast<int>(tcpEndpointInfo->port); + } + else if(Ice::UdpEndpointInfoPtr::dynamicCast(endpointInfo)) + { + obj = PyObject_New(EndpointInfoObject, &UdpEndpointInfoType); + if(!obj) + { + return 0; + } + + Ice::UdpEndpointInfoPtr udpEndpointInfo = Ice::UdpEndpointInfoPtr::dynamicCast(endpointInfo); + obj->host = IcePy::createString(udpEndpointInfo->host); + obj->port = static_cast<int>(udpEndpointInfo->port); + obj->protocolMajor = static_cast<unsigned char>(udpEndpointInfo->protocolMajor); + obj->protocolMinor = static_cast<unsigned char>(udpEndpointInfo->protocolMinor); + obj->encodingMajor = static_cast<unsigned char>(udpEndpointInfo->encodingMajor); + obj->encodingMinor = static_cast<unsigned char>(udpEndpointInfo->encodingMinor); + obj->mcastInterface = IcePy::createString(udpEndpointInfo->mcastInterface); + obj->mcastTtl = static_cast<int>(udpEndpointInfo->mcastTtl); + } + else if(Ice::OpaqueEndpointInfoPtr::dynamicCast(endpointInfo)) + { + obj = PyObject_New(EndpointInfoObject, &OpaqueEndpointInfoType); + if(!obj) + { + return 0; + } + + Ice::OpaqueEndpointInfoPtr opaqueEndpointInfo = Ice::OpaqueEndpointInfoPtr::dynamicCast(endpointInfo); + Ice::ByteSeq& b = opaqueEndpointInfo->rawBytes; + obj->rawBytes = PyString_FromStringAndSize(reinterpret_cast<const char*>(&b[0]), static_cast<int>(b.size())); + } + else + { + obj = PyObject_New(EndpointInfoObject, &EndpointInfoType); + if(!obj) + { + return 0; + } + } + + obj->endpointInfo = new Ice::EndpointInfoPtr(endpointInfo); + obj->timeout = static_cast<int>(endpointInfo->timeout); + obj->compress = endpointInfo->compress ? getTrue() : getFalse(); + + return (PyObject*)obj; +} diff --git a/py/modules/IcePy/EndpointInfo.h b/py/modules/IcePy/EndpointInfo.h new file mode 100644 index 00000000000..d769097eb66 --- /dev/null +++ b/py/modules/IcePy/EndpointInfo.h @@ -0,0 +1,28 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#ifndef ICEPY_ENDPOINT_INFO_H +#define ICEPY_ENDPOINT_INFO_H + +#include <Config.h> +#include <Ice/Endpoint.h> + +namespace IcePy +{ + +extern PyTypeObject EndpointInfoType; + +bool initEndpointInfo(PyObject*); + +PyObject* createEndpointInfo(const Ice::EndpointInfoPtr&); +Ice::EndpointInfoPtr getEndpointInfo(PyObject*); + +} + +#endif diff --git a/py/modules/IcePy/Init.cpp b/py/modules/IcePy/Init.cpp index 7dd2bf3329c..209a8e59c74 100644 --- a/py/modules/IcePy/Init.cpp +++ b/py/modules/IcePy/Init.cpp @@ -12,8 +12,10 @@ #endif #include <Communicator.h> #include <Connection.h> +#include <ConnectionInfo.h> #include <Current.h> #include <Endpoint.h> +#include <EndpointInfo.h> #include <ImplicitContext.h> #include <Logger.h> #include <ObjectAdapter.h> @@ -131,6 +133,10 @@ initIcePy(void) { return; } + if(!initConnectionInfo(module)) + { + return; + } if(!initImplicitContext(module)) { return; @@ -139,4 +145,8 @@ initIcePy(void) { return; } + if(!initEndpointInfo(module)) + { + return; + } } diff --git a/py/modules/IcePy/Makefile b/py/modules/IcePy/Makefile index 477530247cb..88f92ebba34 100644 --- a/py/modules/IcePy/Makefile +++ b/py/modules/IcePy/Makefile @@ -17,8 +17,10 @@ TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(li OBJS = Communicator.o \ Connection.o \ + ConnectionInfo.o \ Current.o \ Endpoint.o \ + EndpointInfo.o \ ImplicitContext.o \ Init.o \ Logger.o \ diff --git a/py/modules/IcePy/Makefile.mak b/py/modules/IcePy/Makefile.mak index 5617b4c8725..69e431522db 100644 --- a/py/modules/IcePy/Makefile.mak +++ b/py/modules/IcePy/Makefile.mak @@ -16,8 +16,10 @@ TARGETS = $(LIBNAME) $(DLLNAME) OBJS = Communicator.obj \
Connection.obj \
+ ConnectionInfo.obj \
Current.obj \
Endpoint.obj \
+ EndpointInfo.obj \
ImplicitContext.obj \
Init.obj \
Logger.obj \
diff --git a/py/python/Ice.py b/py/python/Ice.py index 39ca9d6ef50..872b37dbf55 100644 --- a/py/python/Ice.py +++ b/py/python/Ice.py @@ -250,18 +250,29 @@ import Ice_ObjectFactory_ice import Ice_Properties_ice import Ice_Router_ice import Ice_ServantLocator_ice +import Ice_Connection_ice # # Replace EndpointInfo with our implementation. # -#del EndpointInfo -#Endpoint = IcePy.EndpointInfo -#del TcpEndpointInfo -#TcpEndpointInfo = IcePy.TcpEndpointInfo -#del UdpEndpointInfo -#UdpEndpointInfo = IcePy.UdpEndpointInfo -#del OpaqueEndpointInfo -#OpaqueEndpointInfo = IcePy.OpaqueEndpointInfo +del EndpointInfo +EndpointInfo = IcePy.EndpointInfo +del TcpEndpointInfo +TcpEndpointInfo = IcePy.TcpEndpointInfo +del UdpEndpointInfo +UdpEndpointInfo = IcePy.UdpEndpointInfo +del OpaqueEndpointInfo +OpaqueEndpointInfo = IcePy.OpaqueEndpointInfo + +# +# Replace ConnectionInfo with our implementation. +# +del ConnectionInfo +ConnectionInfo = IcePy.ConnectionInfo +del TcpConnectionInfo +TcpConnectionInfo = IcePy.TcpConnectionInfo +del UdpConnectionInfo +UdpConnectionInfo = IcePy.UdpConnectionInfo class ThreadNotification(object): '''Base class for thread notification callbacks. A subclass must diff --git a/py/test/Ice/proxy/AllTests.py b/py/test/Ice/proxy/AllTests.py index 4402a7e49b7..fb4d47b847e 100644 --- a/py/test/Ice/proxy/AllTests.py +++ b/py/test/Ice/proxy/AllTests.py @@ -609,29 +609,30 @@ def allTests(communicator, collocated): print "ok" - #print "testing endpoint information...", - - #p1 = communicator.stringToProxy("test -t:tcp -h tcphost -p 10000 -t 1200 -z:udp -h udphost -p 10001 --interface eth0 --ttl 5:opaque -t 100 -v ABCD"); - #endps = p1.ice_getEndpoints(); - - #test(isinstance(endps[0], Ice.TcpEndpoint)); - #tcpEndpoint = endps[0]; - #test(tcpEndpoint.host() == "tcphost"); - #test(tcpEndpoint.port() == 10000); - #test(tcpEndpoint.timeout() == 1200); - #test(tcpEndpoint.compress()); - - #test(isinstance(endps[1], Ice.UdpEndpoint)); - #udpEndpoint = endps[1]; - #test(udpEndpoint.host() == "udphost"); - #test(udpEndpoint.port() == 10001); - #test(udpEndpoint.mcastInterface() == "eth0"); - #test(udpEndpoint.mcastTtl() == 5); - #test(udpEndpoint.timeout() == -1); - #test(not udpEndpoint.compress()); - - #test(isinstance(endps[2], Ice.OpaqueEndpoint)); - - #print "ok" + print "testing endpoint information...", + + p1 = communicator.stringToProxy("test -t:tcp -h tcphost -p 10000 -t 1200 -z:udp -h udphost -p 10001 --interface eth0 --ttl 5:opaque -t 100 -v ABCD"); + endps = p1.ice_getEndpoints(); + + info = endps[0].getInfo() + test(isinstance(info, Ice.TcpEndpointInfo)); + test(info.host == "tcphost"); + test(info.port == 10000); + test(info.timeout == 1200); + test(info.compress); + + info = endps[1].getInfo() + test(isinstance(info, Ice.UdpEndpointInfo)); + test(info.host == "udphost"); + test(info.port == 10001); + test(info.mcastInterface == "eth0"); + test(info.mcastTtl == 5); + test(info.timeout == -1); + test(not info.compress); + + info = endps[2].getInfo() + test(isinstance(info, Ice.OpaqueEndpointInfo)); + + print "ok" return cl |