1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4
5 #include <Endpoint.h>
6 #include <EndpointInfo.h>
7 #include <Util.h>
8
9 using namespace std;
10 using namespace IcePy;
11
12 namespace IcePy
13 {
14
15 struct EndpointObject
16 {
17 PyObject_HEAD
18 Ice::EndpointPtr* endpoint;
19 };
20
21 }
22
23 #ifdef WIN32
24 extern "C"
25 #endif
26 static EndpointObject*
endpointNew(PyTypeObject *,PyObject *,PyObject *)27 endpointNew(PyTypeObject* /*type*/, PyObject* /*args*/, PyObject* /*kwds*/)
28 {
29 PyErr_Format(PyExc_RuntimeError, STRCAST("An endpoint cannot be created directly"));
30 return 0;
31 }
32
33 #ifdef WIN32
34 extern "C"
35 #endif
36 static void
endpointDealloc(EndpointObject * self)37 endpointDealloc(EndpointObject* self)
38 {
39 delete self->endpoint;
40 Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
41 }
42
43 #ifdef WIN32
44 extern "C"
45 #endif
46 static PyObject*
endpointCompare(EndpointObject * p1,PyObject * other,int op)47 endpointCompare(EndpointObject* p1, PyObject* other, int op)
48 {
49 bool result = false;
50
51 if(PyObject_TypeCheck(other, &EndpointType))
52 {
53 EndpointObject* p2 = reinterpret_cast<EndpointObject*>(other);
54
55 switch(op)
56 {
57 case Py_EQ:
58 result = *p1->endpoint == *p2->endpoint;
59 break;
60 case Py_NE:
61 result = *p1->endpoint != *p2->endpoint;
62 break;
63 case Py_LE:
64 result = *p1->endpoint <= *p2->endpoint;
65 break;
66 case Py_GE:
67 result = *p1->endpoint >= *p2->endpoint;
68 break;
69 case Py_LT:
70 result = *p1->endpoint < *p2->endpoint;
71 break;
72 case Py_GT:
73 result = *p1->endpoint > *p2->endpoint;
74 break;
75 }
76 }
77 else
78 {
79 if(op == Py_EQ)
80 {
81 result = false;
82 }
83 else if(op == Py_NE)
84 {
85 result = true;
86 }
87 else
88 {
89 PyErr_Format(PyExc_TypeError, "can't compare %s to %s", Py_TYPE(p1)->tp_name, Py_TYPE(other)->tp_name);
90 return 0;
91 }
92 }
93
94 return result ? incTrue() : incFalse();
95 }
96
97 #ifdef WIN32
98 extern "C"
99 #endif
100 static PyObject*
endpointToString(EndpointObject * self,PyObject *)101 endpointToString(EndpointObject* self, PyObject* /*args*/)
102 {
103 assert(self->endpoint);
104 try
105 {
106 string str = (*self->endpoint)->toString();
107 return createString(str);
108 }
109 catch(const Ice::Exception& ex)
110 {
111 setPythonException(ex);
112 return 0;
113 }
114 }
115
116 #ifdef WIN32
117 extern "C"
118 #endif
119 static PyObject*
endpointRepr(EndpointObject * self)120 endpointRepr(EndpointObject* self)
121 {
122 return endpointToString(self, 0);
123 }
124
125 #ifdef WIN32
126 extern "C"
127 #endif
128 static PyObject*
endpointGetInfo(EndpointObject * self,PyObject *)129 endpointGetInfo(EndpointObject* self, PyObject* /*args*/)
130 {
131 assert(self->endpoint);
132 try
133 {
134 Ice::EndpointInfoPtr info = (*self->endpoint)->getInfo();
135 return createEndpointInfo(info);
136 }
137 catch(const Ice::Exception& ex)
138 {
139 setPythonException(ex);
140 return 0;
141 }
142 }
143
144 static PyMethodDef EndpointMethods[] =
145 {
146 { STRCAST("toString"), reinterpret_cast<PyCFunction>(endpointToString), METH_NOARGS,
147 PyDoc_STR(STRCAST("toString() -> string")) },
148 { STRCAST("getInfo"), reinterpret_cast<PyCFunction>(endpointGetInfo), METH_NOARGS,
149 PyDoc_STR(STRCAST("getInfo() -> Ice.EndpointInfo")) },
150 { 0, 0 } /* sentinel */
151 };
152
153 namespace IcePy
154 {
155
156 PyTypeObject EndpointType =
157 {
158 /* The ob_type field must be initialized in the module init function
159 * to be portable to Windows without using C++. */
160 PyVarObject_HEAD_INIT(0, 0)
161 STRCAST("IcePy.Endpoint"), /* tp_name */
162 sizeof(EndpointObject), /* tp_basicsize */
163 0, /* tp_itemsize */
164 /* methods */
165 reinterpret_cast<destructor>(endpointDealloc), /* tp_dealloc */
166 0, /* tp_print */
167 0, /* tp_getattr */
168 0, /* tp_setattr */
169 0, /* tp_reserved */
170 reinterpret_cast<reprfunc>(endpointRepr), /* tp_repr */
171 0, /* tp_as_number */
172 0, /* tp_as_sequence */
173 0, /* tp_as_mapping */
174 0, /* tp_hash */
175 0, /* tp_call */
176 0, /* tp_str */
177 0, /* tp_getattro */
178 0, /* tp_setattro */
179 0, /* tp_as_buffer */
180 #if PY_VERSION_HEX >= 0x03000000
181 Py_TPFLAGS_DEFAULT |
182 Py_TPFLAGS_BASETYPE, /* tp_flags */
183 #else
184 Py_TPFLAGS_DEFAULT |
185 Py_TPFLAGS_BASETYPE |
186 Py_TPFLAGS_HAVE_RICHCOMPARE, /* tp_flags */
187 #endif
188 0, /* tp_doc */
189 0, /* tp_traverse */
190 0, /* tp_clear */
191 reinterpret_cast<richcmpfunc>(endpointCompare), /* tp_richcompare */
192 0, /* tp_weaklistoffset */
193 0, /* tp_iter */
194 0, /* tp_iternext */
195 EndpointMethods, /* tp_methods */
196 0, /* tp_members */
197 0, /* tp_getset */
198 0, /* tp_base */
199 0, /* tp_dict */
200 0, /* tp_descr_get */
201 0, /* tp_descr_set */
202 0, /* tp_dictoffset */
203 0, /* tp_init */
204 0, /* tp_alloc */
205 reinterpret_cast<newfunc>(endpointNew), /* tp_new */
206 0, /* tp_free */
207 0, /* tp_is_gc */
208 };
209
210 };
211
212 bool
initEndpoint(PyObject * module)213 IcePy::initEndpoint(PyObject* module)
214 {
215 if(PyType_Ready(&EndpointType) < 0)
216 {
217 return false;
218 }
219 PyTypeObject* type = &EndpointType; // Necessary to prevent GCC's strict-alias warnings.
220 if(PyModule_AddObject(module, STRCAST("Endpoint"), reinterpret_cast<PyObject*>(type)) < 0)
221 {
222 return false;
223 }
224
225 return true;
226 }
227
228 Ice::EndpointPtr
getEndpoint(PyObject * obj)229 IcePy::getEndpoint(PyObject* obj)
230 {
231 assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&EndpointType)));
232 EndpointObject* eobj = reinterpret_cast<EndpointObject*>(obj);
233 return *eobj->endpoint;
234 }
235
236 PyObject*
createEndpoint(const Ice::EndpointPtr & endpoint)237 IcePy::createEndpoint(const Ice::EndpointPtr& endpoint)
238 {
239 EndpointObject* obj = reinterpret_cast<EndpointObject*>(EndpointType.tp_alloc(&EndpointType, 0));
240 if(!obj)
241 {
242 return 0;
243 }
244 obj->endpoint = new Ice::EndpointPtr(endpoint);
245 return (PyObject*)obj;
246 }
247
248 bool
toEndpointSeq(PyObject * endpoints,Ice::EndpointSeq & seq)249 IcePy::toEndpointSeq(PyObject* endpoints, Ice::EndpointSeq& seq)
250 {
251 Py_ssize_t sz = PySequence_Fast_GET_SIZE(endpoints);
252 for(Py_ssize_t i = 0; i < sz; ++i)
253 {
254 PyObject* p = PySequence_Fast_GET_ITEM(endpoints, i);
255 PyTypeObject* type = &EndpointType; // Necessary to prevent GCC's strict-alias warnings.
256 if(!PyObject_IsInstance(p, reinterpret_cast<PyObject*>(type)))
257 {
258 PyErr_Format(PyExc_ValueError, STRCAST("expected element of type Ice.Endpoint"));
259 return false;
260 }
261 Ice::EndpointPtr endp = getEndpoint(p);
262 if(!endp)
263 {
264 return false;
265 }
266 seq.push_back(endp);
267 }
268
269 return true;
270 }
271