1 // **********************************************************************
3 // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
5 // This copy of Ice is licensed to you under the terms described in the
6 // ICE_LICENSE file included in this distribution.
8 // **********************************************************************
11 # include <IceUtil/Config.h>
14 #include <structmember.h>
15 #include <Connection.h>
16 #include <ObjectAdapter.h>
18 #include <Ice/ObjectAdapter.h>
21 using namespace IcePy
;
29 Ice::Current
* current
;
41 // Member identifiers.
43 const Py_ssize_t CURRENT_ADAPTER
= 0;
44 const Py_ssize_t CURRENT_CONNECTION
= 1;
45 const Py_ssize_t CURRENT_ID
= 2;
46 const Py_ssize_t CURRENT_FACET
= 3;
47 const Py_ssize_t CURRENT_OPERATION
= 4;
48 const Py_ssize_t CURRENT_MODE
= 5;
49 const Py_ssize_t CURRENT_CTX
= 6;
50 const Py_ssize_t CURRENT_REQUEST_ID
= 7;
58 currentNew(PyObject
* /*arg*/)
60 CurrentObject
* self
= PyObject_New(CurrentObject
, &CurrentType
);
66 self
->current
= new Ice::Current
;
83 currentDealloc(CurrentObject
* self
)
85 Py_XDECREF(self
->adapter
);
86 Py_XDECREF(self
->con
);
88 Py_XDECREF(self
->facet
);
89 Py_XDECREF(self
->operation
);
90 Py_XDECREF(self
->mode
);
91 Py_XDECREF(self
->ctx
);
92 Py_XDECREF(self
->requestId
);
101 currentGetter(CurrentObject
* self
, void* closure
)
104 // This function intercepts requests for attributes of a Current object. We use this
105 // lazy initialization in order to minimize the cost of translating Ice::Current into a
106 // Python object for every upcall.
108 PyObject
* result
= 0;
110 assert(self
->current
);
112 long field
= reinterpret_cast<long>(closure
);
115 case CURRENT_ADAPTER
:
119 self
->adapter
= wrapObjectAdapter(self
->current
->adapter
);
125 Py_INCREF(self
->adapter
);
126 result
= self
->adapter
;
129 case CURRENT_CONNECTION
:
133 self
->con
= createConnection(self
->current
->con
, self
->current
->adapter
->getCommunicator());
139 Py_INCREF(self
->con
);
147 self
->id
= createIdentity(self
->current
->id
);
157 self
->facet
= createString(self
->current
->facet
);
159 Py_INCREF(self
->facet
);
160 result
= self
->facet
;
163 case CURRENT_OPERATION
:
167 self
->operation
= createString(self
->current
->operation
);
169 Py_INCREF(self
->operation
);
170 result
= self
->operation
;
177 PyObject
* type
= lookupType("Ice.OperationMode");
179 const char* enumerator
= 0;
180 switch(self
->current
->mode
)
183 enumerator
= "Normal";
185 case Ice::Nonmutating
:
186 enumerator
= "Nonmutating";
188 case Ice::Idempotent
:
189 enumerator
= "Idempotent";
192 self
->mode
= PyObject_GetAttrString(type
, STRCAST(enumerator
));
195 Py_INCREF(self
->mode
);
203 self
->ctx
= PyDict_New();
204 if(self
->ctx
&& !contextToDictionary(self
->current
->ctx
, self
->ctx
))
206 Py_DECREF(self
->ctx
);
211 Py_INCREF(self
->ctx
);
215 case CURRENT_REQUEST_ID
:
219 self
->requestId
= PyInt_FromLong(self
->current
->requestId
);
220 assert(self
->requestId
);
222 Py_INCREF(self
->requestId
);
223 result
= self
->requestId
;
231 static PyGetSetDef CurrentGetSetters
[] =
233 { STRCAST("adapter"), reinterpret_cast<getter
>(currentGetter
), 0, STRCAST("object adapter"),
234 reinterpret_cast<void*>(CURRENT_ADAPTER
) },
235 { STRCAST("con"), reinterpret_cast<getter
>(currentGetter
), 0, STRCAST("connection info"),
236 reinterpret_cast<void*>(CURRENT_CONNECTION
) },
237 { STRCAST("id"), reinterpret_cast<getter
>(currentGetter
), 0, STRCAST("identity"),
238 reinterpret_cast<void*>(CURRENT_ID
) },
239 { STRCAST("facet"), reinterpret_cast<getter
>(currentGetter
), 0, STRCAST("facet name"),
240 reinterpret_cast<void*>(CURRENT_FACET
) },
241 { STRCAST("operation"), reinterpret_cast<getter
>(currentGetter
), 0, STRCAST("operation name"),
242 reinterpret_cast<void*>(CURRENT_OPERATION
) },
243 { STRCAST("mode"), reinterpret_cast<getter
>(currentGetter
), 0, STRCAST("operation mode"),
244 reinterpret_cast<void*>(CURRENT_MODE
) },
245 { STRCAST("ctx"), reinterpret_cast<getter
>(currentGetter
), 0, STRCAST("context"),
246 reinterpret_cast<void*>(CURRENT_CTX
) },
247 { STRCAST("requestId"), reinterpret_cast<getter
>(currentGetter
), 0, STRCAST("requestId"),
248 reinterpret_cast<void*>(CURRENT_REQUEST_ID
) },
255 PyTypeObject CurrentType
=
257 /* The ob_type field must be initialized in the module init function
258 * to be portable to Windows without using C++. */
259 PyObject_HEAD_INIT(0)
261 STRCAST("IcePy.Current"), /* tp_name */
262 sizeof(CurrentObject
), /* tp_basicsize */
265 reinterpret_cast<destructor
>(currentDealloc
), /* tp_dealloc */
271 0, /* tp_as_number */
272 0, /* tp_as_sequence */
273 0, /* tp_as_mapping */
279 0, /* tp_as_buffer */
280 Py_TPFLAGS_DEFAULT
, /* tp_flags */
284 0, /* tp_richcompare */
285 0, /* tp_weaklistoffset */
290 CurrentGetSetters
, /* tp_getset */
293 0, /* tp_descr_get */
294 0, /* tp_descr_set */
295 0, /* tp_dictoffset */
298 reinterpret_cast<newfunc
>(currentNew
), /* tp_new */
306 IcePy::initCurrent(PyObject
* module
)
308 if(PyType_Ready(&CurrentType
) < 0)
312 PyTypeObject
* type
= &CurrentType
; // Necessary to prevent GCC's strict-alias warnings.
313 if(PyModule_AddObject(module
, STRCAST("Current"), reinterpret_cast<PyObject
*>(type
)) < 0)
322 IcePy::createCurrent(const Ice::Current
& current
)
325 // Return an instance of IcePy.Current to hold the current information.
327 CurrentObject
* obj
= currentNew(0);
330 *obj
->current
= current
;
332 return reinterpret_cast<PyObject
*>(obj
);