// ********************************************************************** // // Copyright (c) 2003-2006 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 #endif #include #include #include #include #include #include using namespace std; using namespace IcePy; namespace IcePy { struct CurrentObject { PyObject_HEAD Ice::Current* current; PyObject* adapter; PyObject* con; PyObject* id; PyObject* facet; PyObject* operation; PyObject* mode; PyObject* ctx; }; // // Member identifiers. // const int CURRENT_ADAPTER = 0; const int CURRENT_CONNECTION = 1; const int CURRENT_ID = 2; const int CURRENT_FACET = 3; const int CURRENT_OPERATION = 4; const int CURRENT_MODE = 5; const int CURRENT_CTX = 6; } #ifdef WIN32 extern "C" #endif static CurrentObject* currentNew(PyObject* /*arg*/) { CurrentObject* self = PyObject_New(CurrentObject, &CurrentType); if(self == NULL) { return NULL; } self->current = new Ice::Current; self->adapter = NULL; self->con = NULL; self->id = NULL; self->facet = NULL; self->operation = NULL; self->mode = NULL; self->ctx = NULL; return self; } #ifdef WIN32 extern "C" #endif static void currentDealloc(CurrentObject* self) { Py_XDECREF(self->adapter); Py_XDECREF(self->con); Py_XDECREF(self->id); Py_XDECREF(self->facet); Py_XDECREF(self->operation); Py_XDECREF(self->mode); Py_XDECREF(self->ctx); delete self->current; PyObject_Del(self); } #ifdef WIN32 extern "C" #endif static PyObject* currentGetter(CurrentObject* self, void* closure) { // // This function intercepts requests for attributes of a Current object. We use this // lazy initialization in order to minimize the cost of translating Ice::Current into a // Python object for every upcall. // PyObject* result = NULL; assert(self->current); long field = reinterpret_cast(closure); switch(field) { case CURRENT_ADAPTER: { if(self->adapter == NULL) { self->adapter = wrapObjectAdapter(self->current->adapter); if(self->adapter == NULL) { return NULL; } } Py_INCREF(self->adapter); result = self->adapter; break; } case CURRENT_CONNECTION: { if(self->con == NULL) { self->con = createConnection(self->current->con, self->current->adapter->getCommunicator()); if(self->con == NULL) { return NULL; } } Py_INCREF(self->con); result = self->con; break; } case CURRENT_ID: { if(self->id == NULL) { self->id = createIdentity(self->current->id); } Py_INCREF(self->id); result = self->id; break; } case CURRENT_FACET: { if(self->facet == NULL) { self->facet = PyString_FromString(const_cast(self->current->facet.c_str())); } Py_INCREF(self->facet); result = self->facet; break; } case CURRENT_OPERATION: { if(self->operation == NULL) { self->operation = PyString_FromString(const_cast(self->current->operation.c_str())); } Py_INCREF(self->operation); result = self->operation; break; } case CURRENT_MODE: { if(self->mode == NULL) { PyObject* type = lookupType("Ice.OperationMode"); assert(type != NULL); const char* enumerator = 0; switch(self->current->mode) { case Ice::Normal: enumerator = "Normal"; break; case Ice::Nonmutating: enumerator = "Nonmutating"; break; case Ice::Idempotent: enumerator = "Idempotent"; break; } self->mode = PyObject_GetAttrString(type, STRCAST(enumerator)); assert(self->mode != NULL); } Py_INCREF(self->mode); result = self->mode; break; } case CURRENT_CTX: { if(self->ctx == NULL) { self->ctx = PyDict_New(); if(self->ctx != NULL && !contextToDictionary(self->current->ctx, self->ctx)) { Py_DECREF(self->ctx); self->ctx = NULL; break; } } Py_INCREF(self->ctx); result = self->ctx; break; } } return result; } static PyGetSetDef CurrentGetSetters[] = { {STRCAST("adapter"), (getter)currentGetter, NULL, STRCAST("object adapter"), (void*)CURRENT_ADAPTER}, {STRCAST("con"), (getter)currentGetter, NULL, STRCAST("connection info"), (void*)CURRENT_CONNECTION}, {STRCAST("id"), (getter)currentGetter, NULL, STRCAST("identity"), (void*)CURRENT_ID}, {STRCAST("facet"), (getter)currentGetter, NULL, STRCAST("facet name"), (void*)CURRENT_FACET}, {STRCAST("operation"), (getter)currentGetter, NULL, STRCAST("operation name"), (void*)CURRENT_OPERATION}, {STRCAST("mode"), (getter)currentGetter, NULL, STRCAST("operation mode"), (void*)CURRENT_MODE}, {STRCAST("ctx"), (getter)currentGetter, NULL, STRCAST("context"), (void*)CURRENT_CTX}, {NULL} /* Sentinel */ }; namespace IcePy { PyTypeObject CurrentType = { /* The ob_type field must be initialized in the module init function * to be portable to Windows without using C++. */ PyObject_HEAD_INIT(NULL) 0, /* ob_size */ STRCAST("IcePy.Current"), /* tp_name */ sizeof(CurrentObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)currentDealloc, /* 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, /* 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 */ 0, /* tp_members */ CurrentGetSetters, /* 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)currentNew, /* tp_new */ 0, /* tp_free */ 0, /* tp_is_gc */ }; } bool IcePy::initCurrent(PyObject* module) { if(PyType_Ready(&CurrentType) < 0) { return false; } if(PyModule_AddObject(module, STRCAST("Current"), (PyObject*)&CurrentType) < 0) { return false; } return true; } PyObject* IcePy::createCurrent(const Ice::Current& current) { // // Return an instance of IcePy.Current to hold the current information. // CurrentObject* obj = currentNew(NULL); if(obj != NULL) { *obj->current = current; } return (PyObject*)obj; }