ICE 3.4.2
[php5-ice-freebsdport.git] / py / modules / IcePy / Current.cpp
blob860be1a5100124b3fd68d207bccb33bca6aa41be
1 // **********************************************************************
2 //
3 // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
4 //
5 // This copy of Ice is licensed to you under the terms described in the
6 // ICE_LICENSE file included in this distribution.
7 //
8 // **********************************************************************
10 #ifdef _WIN32
11 # include <IceUtil/Config.h>
12 #endif
13 #include <Current.h>
14 #include <structmember.h>
15 #include <Connection.h>
16 #include <ObjectAdapter.h>
17 #include <Util.h>
18 #include <Ice/ObjectAdapter.h>
20 using namespace std;
21 using namespace IcePy;
23 namespace IcePy
26 struct CurrentObject
28 PyObject_HEAD
29 Ice::Current* current;
30 PyObject* adapter;
31 PyObject* con;
32 PyObject* id;
33 PyObject* facet;
34 PyObject* operation;
35 PyObject* mode;
36 PyObject* ctx;
37 PyObject* requestId;
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;
54 #ifdef WIN32
55 extern "C"
56 #endif
57 static CurrentObject*
58 currentNew(PyObject* /*arg*/)
60 CurrentObject* self = PyObject_New(CurrentObject, &CurrentType);
61 if(!self)
63 return 0;
66 self->current = new Ice::Current;
67 self->adapter = 0;
68 self->con = 0;
69 self->id = 0;
70 self->facet = 0;
71 self->operation = 0;
72 self->mode = 0;
73 self->ctx = 0;
74 self->requestId = 0;
76 return self;
79 #ifdef WIN32
80 extern "C"
81 #endif
82 static void
83 currentDealloc(CurrentObject* self)
85 Py_XDECREF(self->adapter);
86 Py_XDECREF(self->con);
87 Py_XDECREF(self->id);
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);
93 delete self->current;
94 PyObject_Del(self);
97 #ifdef WIN32
98 extern "C"
99 #endif
100 static PyObject*
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);
113 switch(field)
115 case CURRENT_ADAPTER:
117 if(!self->adapter)
119 self->adapter = wrapObjectAdapter(self->current->adapter);
120 if(!self->adapter)
122 return 0;
125 Py_INCREF(self->adapter);
126 result = self->adapter;
127 break;
129 case CURRENT_CONNECTION:
131 if(!self->con)
133 self->con = createConnection(self->current->con, self->current->adapter->getCommunicator());
134 if(!self->con)
136 return 0;
139 Py_INCREF(self->con);
140 result = self->con;
141 break;
143 case CURRENT_ID:
145 if(!self->id)
147 self->id = createIdentity(self->current->id);
149 Py_INCREF(self->id);
150 result = self->id;
151 break;
153 case CURRENT_FACET:
155 if(!self->facet)
157 self->facet = createString(self->current->facet);
159 Py_INCREF(self->facet);
160 result = self->facet;
161 break;
163 case CURRENT_OPERATION:
165 if(!self->operation)
167 self->operation = createString(self->current->operation);
169 Py_INCREF(self->operation);
170 result = self->operation;
171 break;
173 case CURRENT_MODE:
175 if(!self->mode)
177 PyObject* type = lookupType("Ice.OperationMode");
178 assert(type);
179 const char* enumerator = 0;
180 switch(self->current->mode)
182 case Ice::Normal:
183 enumerator = "Normal";
184 break;
185 case Ice::Nonmutating:
186 enumerator = "Nonmutating";
187 break;
188 case Ice::Idempotent:
189 enumerator = "Idempotent";
190 break;
192 self->mode = PyObject_GetAttrString(type, STRCAST(enumerator));
193 assert(self->mode);
195 Py_INCREF(self->mode);
196 result = self->mode;
197 break;
199 case CURRENT_CTX:
201 if(!self->ctx)
203 self->ctx = PyDict_New();
204 if(self->ctx && !contextToDictionary(self->current->ctx, self->ctx))
206 Py_DECREF(self->ctx);
207 self->ctx = 0;
208 break;
211 Py_INCREF(self->ctx);
212 result = self->ctx;
213 break;
215 case CURRENT_REQUEST_ID:
217 if(!self->requestId)
219 self->requestId = PyInt_FromLong(self->current->requestId);
220 assert(self->requestId);
222 Py_INCREF(self->requestId);
223 result = self->requestId;
224 break;
228 return result;
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) },
249 { 0 } /* Sentinel */
252 namespace IcePy
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)
260 0, /* ob_size */
261 STRCAST("IcePy.Current"), /* tp_name */
262 sizeof(CurrentObject), /* tp_basicsize */
263 0, /* tp_itemsize */
264 /* methods */
265 reinterpret_cast<destructor>(currentDealloc), /* tp_dealloc */
266 0, /* tp_print */
267 0, /* tp_getattr */
268 0, /* tp_setattr */
269 0, /* tp_compare */
270 0, /* tp_repr */
271 0, /* tp_as_number */
272 0, /* tp_as_sequence */
273 0, /* tp_as_mapping */
274 0, /* tp_hash */
275 0, /* tp_call */
276 0, /* tp_str */
277 0, /* tp_getattro */
278 0, /* tp_setattro */
279 0, /* tp_as_buffer */
280 Py_TPFLAGS_DEFAULT, /* tp_flags */
281 0, /* tp_doc */
282 0, /* tp_traverse */
283 0, /* tp_clear */
284 0, /* tp_richcompare */
285 0, /* tp_weaklistoffset */
286 0, /* tp_iter */
287 0, /* tp_iternext */
288 0, /* tp_methods */
289 0, /* tp_members */
290 CurrentGetSetters, /* tp_getset */
291 0, /* tp_base */
292 0, /* tp_dict */
293 0, /* tp_descr_get */
294 0, /* tp_descr_set */
295 0, /* tp_dictoffset */
296 0, /* tp_init */
297 0, /* tp_alloc */
298 reinterpret_cast<newfunc>(currentNew), /* tp_new */
299 0, /* tp_free */
300 0, /* tp_is_gc */
305 bool
306 IcePy::initCurrent(PyObject* module)
308 if(PyType_Ready(&CurrentType) < 0)
310 return false;
312 PyTypeObject* type = &CurrentType; // Necessary to prevent GCC's strict-alias warnings.
313 if(PyModule_AddObject(module, STRCAST("Current"), reinterpret_cast<PyObject*>(type)) < 0)
315 return false;
318 return true;
321 PyObject*
322 IcePy::createCurrent(const Ice::Current& current)
325 // Return an instance of IcePy.Current to hold the current information.
327 CurrentObject* obj = currentNew(0);
328 if(obj)
330 *obj->current = current;
332 return reinterpret_cast<PyObject*>(obj);