| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| /* For UUID objects, to convert them to Python uuid.UUID objects, |
| * we'll need a reference to the uuid module. |
| */ |
| %{ |
| static PyObject* pUuidModule; |
| %} |
| |
| %init %{ |
| /* Instead of directly referencing the uuid module (which is not available |
| * on older versions of Python), reference the wrapper defined in |
| * qpid.datatypes. |
| */ |
| pUuidModule = PyImport_ImportModule("qpid.datatypes"); |
| if (pUuidModule) { |
| /* Although it is not required, we'll publish the uuid module in our |
| * module, as if this module was a python module and we called |
| * "import uuid" |
| */ |
| Py_INCREF(pUuidModule); |
| PyModule_AddObject(m, "uuid", pUuidModule); |
| } else { |
| if (!PyErr_Occurred()) PyErr_SetString(PyExc_ImportError, "Cannot import qpid.datatypes"); |
| } |
| %} |
| |
| |
| %wrapper %{ |
| |
| #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) |
| typedef int Py_ssize_t; |
| #define PY_SSIZE_T_MAX INT_MAX |
| #define PY_SSIZE_T_MIN INT_MIN |
| #endif |
| #if PY_VERSION_HEX < 0x03000000 |
| #define PyLong_AS_LONG PyInt_AS_LONG |
| #else |
| #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask |
| #endif |
| |
| PyObject* MapToPy(const qpid::types::Variant::Map*); |
| PyObject* ListToPy(const qpid::types::Variant::List*); |
| PyObject* UuidToPy(const qpid::types::Uuid*); |
| void PyToMap(PyObject*, qpid::types::Variant::Map*); |
| void PyToList(PyObject*, qpid::types::Variant::List*); |
| |
| qpid::types::Variant PyToVariant(PyObject* value) { |
| if (PyBool_Check(value)) return qpid::types::Variant(bool(PyLong_AS_LONG(value) ? true : false)); |
| if (PyFloat_Check(value)) return qpid::types::Variant(PyFloat_AS_DOUBLE(value)); |
| if (PyLong_Check(value)) return qpid::types::Variant(int64_t(PyLong_AsLongLong(value))); |
| if (PyInt_Check(value)) return qpid::types::Variant(int64_t(PyLong_AS_LONG(value))); |
| if (PyString_Check(value)) return qpid::types::Variant(std::string(PyBytes_AS_STRING(value))); |
| if (PyUnicode_Check(value)) { |
| qpid::types::Variant v(std::string(PyUnicode_AS_DATA(value))); |
| v.setEncoding("utf8"); |
| return v; |
| } |
| if (PyDict_Check(value)) { |
| qpid::types::Variant::Map map; |
| PyToMap(value, &map); |
| return qpid::types::Variant(map); |
| } |
| if (PyList_Check(value)) { |
| qpid::types::Variant::List list; |
| PyToList(value, &list); |
| return qpid::types::Variant(list); |
| } |
| return qpid::types::Variant(); |
| } |
| |
| PyObject* VariantToPy(const qpid::types::Variant* v) { |
| PyObject* result; |
| try { |
| switch (v->getType()) { |
| case qpid::types::VAR_VOID: { |
| result = Py_None; |
| Py_INCREF(result); |
| break; |
| } |
| case qpid::types::VAR_BOOL : { |
| result = v->asBool() ? Py_True : Py_False; |
| break; |
| } |
| case qpid::types::VAR_UINT8 : |
| case qpid::types::VAR_UINT16 : |
| case qpid::types::VAR_UINT32 : { |
| result = PyInt_FromLong((long) v->asUint32()); |
| break; |
| } |
| case qpid::types::VAR_UINT64 : { |
| result = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) v->asUint64()); |
| break; |
| } |
| case qpid::types::VAR_INT8 : |
| case qpid::types::VAR_INT16 : |
| case qpid::types::VAR_INT32 : { |
| result = PyInt_FromLong((long) v->asInt32()); |
| break; |
| } |
| case qpid::types::VAR_INT64 : { |
| result = PyLong_FromLongLong((PY_LONG_LONG) v->asInt64()); |
| break; |
| } |
| case qpid::types::VAR_FLOAT : { |
| result = PyFloat_FromDouble((double) v->asFloat()); |
| break; |
| } |
| case qpid::types::VAR_DOUBLE : { |
| result = PyFloat_FromDouble((double) v->asDouble()); |
| break; |
| } |
| case qpid::types::VAR_STRING : { |
| const std::string val(v->asString()); |
| if (v->getEncoding() == "utf8") |
| result = PyUnicode_DecodeUTF8(val.c_str(), val.size(), NULL); |
| else |
| result = PyBytes_FromStringAndSize(val.c_str(), val.size()); |
| break; |
| } |
| case qpid::types::VAR_MAP : { |
| result = MapToPy(&(v->asMap())); |
| break; |
| } |
| case qpid::types::VAR_LIST : { |
| result = ListToPy(&(v->asList())); |
| break; |
| } |
| case qpid::types::VAR_UUID : { |
| qpid::types::Uuid uuid = v->asUuid(); |
| result = UuidToPy(&uuid); |
| break; |
| } |
| } |
| } catch (qpid::types::Exception& ex) { |
| PyErr_SetString(PyExc_RuntimeError, ex.what()); |
| result = 0; |
| } |
| |
| return result; |
| } |
| |
| PyObject* MapToPy(const qpid::types::Variant::Map* map) { |
| PyObject* result = PyDict_New(); |
| qpid::types::Variant::Map::const_iterator iter; |
| for (iter = map->begin(); iter != map->end(); iter++) { |
| const std::string key(iter->first); |
| PyObject* pyval = VariantToPy(&(iter->second)); |
| if (pyval == 0) |
| return 0; |
| PyDict_SetItem(result, PyBytes_FromStringAndSize(key.c_str(), key.size()), pyval); |
| } |
| return result; |
| } |
| |
| PyObject* ListToPy(const qpid::types::Variant::List* list) { |
| PyObject* result = PyList_New(list->size()); |
| qpid::types::Variant::List::const_iterator iter; |
| Py_ssize_t idx(0); |
| for (iter = list->begin(); iter != list->end(); iter++) { |
| PyObject* pyval = VariantToPy(&(*iter)); |
| if (pyval == 0) |
| return 0; |
| PyList_SetItem(result, idx, pyval); |
| idx++; |
| } |
| return result; |
| } |
| |
| PyObject* UuidToPy(const qpid::types::Uuid * uuid) { |
| PyObject* pUuidClass = PyObject_GetAttrString(pUuidModule, "UUID"); |
| if (!pUuidClass) { |
| // Failed to get UUID class |
| return 0; |
| } |
| |
| PyObject* pArgs = PyTuple_New(0); |
| PyObject* pKw = PyDict_New(); |
| PyObject* pData = PyBytes_FromStringAndSize( |
| (const char*)(uuid->data()), 16); |
| PyDict_SetItemString(pKw, "bytes", pData); |
| |
| PyObject* result = PyObject_Call(pUuidClass, pArgs, pKw); |
| |
| Py_DECREF(pData); |
| Py_DECREF(pKw); |
| Py_DECREF(pArgs); |
| Py_DECREF(pUuidClass); |
| |
| return result; |
| } |
| |
| |
| void PyToMap(PyObject* obj, qpid::types::Variant::Map* map) { |
| map->clear(); |
| Py_ssize_t iter(0); |
| PyObject *key; |
| PyObject *val; |
| while (PyDict_Next(obj, &iter, &key, &val)) |
| (*map)[std::string(PyBytes_AS_STRING(key))] = PyToVariant(val); |
| } |
| |
| void PyToList(PyObject* obj, qpid::types::Variant::List* list) { |
| list->clear(); |
| Py_ssize_t count(PyList_Size(obj)); |
| for (Py_ssize_t idx = 0; idx < count; idx++) |
| list->push_back(PyToVariant(PyList_GetItem(obj, idx))); |
| } |
| |
| %} |
| |
| |
| /* unsigned32 Convert from Python --> C */ |
| %typemap(in) uint32_t { |
| if (PyInt_Check($input)) { |
| $1 = (uint32_t) PyInt_AsUnsignedLongMask($input); |
| } else if (PyLong_Check($input)) { |
| $1 = (uint32_t) PyLong_AsUnsignedLong($input); |
| } else { |
| SWIG_exception_fail(SWIG_ValueError, "unknown integer type"); |
| } |
| } |
| |
| /* unsinged32 Convert from C --> Python */ |
| %typemap(out) uint32_t { |
| $result = PyInt_FromLong((long)$1); |
| } |
| |
| |
| /* unsigned16 Convert from Python --> C */ |
| %typemap(in) uint16_t { |
| if (PyLong_Check($input)) { |
| $1 = (uint16_t) PyLong_AsUnsignedLong($input); |
| } else if (PyInt_Check($input)) { |
| $1 = (uint16_t) PyInt_AsUnsignedLongMask($input); |
| } else { |
| SWIG_exception_fail(SWIG_ValueError, "unknown integer type"); |
| } |
| } |
| |
| /* unsigned16 Convert from C --> Python */ |
| %typemap(out) uint16_t { |
| $result = PyInt_FromLong((long)$1); |
| } |
| |
| |
| /* signed32 Convert from Python --> C */ |
| %typemap(in) int32_t { |
| if (PyLong_Check($input)) { |
| $1 = (int32_t) PyLong_AsLong($input); |
| } else if (PyInt_Check($input)) { |
| $1 = (int32_t) PyInt_AsLong($input); |
| } else { |
| SWIG_exception_fail(SWIG_ValueError, "unknown integer type"); |
| } |
| } |
| |
| /* signed32 Convert from C --> Python */ |
| %typemap(out) int32_t { |
| $result = PyInt_FromLong((long)$1); |
| } |
| |
| |
| /* unsigned64 Convert from Python --> C */ |
| %typemap(in) uint64_t { |
| %#ifdef HAVE_LONG_LONG |
| if (PyLong_Check($input)) { |
| $1 = (uint64_t)PyLong_AsUnsignedLongLong($input); |
| } else if (PyInt_Check($input)) { |
| $1 = (uint64_t)PyLong_AS_LONG($input); |
| } else |
| %#endif |
| { |
| SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - uint64_t input too large"); |
| } |
| } |
| |
| /* unsigned64 Convert from C --> Python */ |
| %typemap(out) uint64_t { |
| %#ifdef HAVE_LONG_LONG |
| $result = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)$1); |
| %#else |
| SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - uint64_t output too large"); |
| %#endif |
| } |
| |
| /* signed64 Convert from Python --> C */ |
| %typemap(in) int64_t { |
| %#ifdef HAVE_LONG_LONG |
| if (PyLong_Check($input)) { |
| $1 = (int64_t)PyLong_AsLongLong($input); |
| } else if (PyInt_Check($input)) { |
| $1 = (int64_t)PyInt_AsLong($input); |
| } else |
| %#endif |
| { |
| SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - int64_t input too large"); |
| } |
| } |
| |
| /* signed64 Convert from C --> Python */ |
| %typemap(out) int64_t { |
| %#ifdef HAVE_LONG_LONG |
| $result = PyLong_FromLongLong((PY_LONG_LONG)$1); |
| %#else |
| SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - int64_t output too large"); |
| %#endif |
| } |
| |
| |
| /* Convert from Python --> C */ |
| %typemap(in) void * { |
| $1 = (void *)$input; |
| } |
| |
| /* Convert from C --> Python */ |
| %typemap(out) void * { |
| $result = (PyObject *) $1; |
| Py_INCREF($result); |
| } |
| |
| /* |
| * Variant types: C++ --> Python |
| */ |
| %typemap(out) qpid::types::Variant::Map { |
| $result = MapToPy(&$1); |
| } |
| |
| %typemap(out) qpid::types::Variant::Map& { |
| $result = MapToPy($1); |
| } |
| |
| %typemap(out) qpid::types::Variant::List { |
| $result = ListToPy(&$1); |
| } |
| |
| %typemap(out) qpid::types::Variant::List& { |
| $result = ListToPy($1); |
| } |
| |
| %typemap(out) qpid::types::Variant& { |
| $result = VariantToPy($1); |
| } |
| |
| /* |
| * UUID type: C++ --> Python |
| */ |
| %typemap(out) qpid::types::UUID & { |
| $result = UuidToPy($1); |
| } |
| |
| |
| /* |
| * Variant types: Ruby --> C++ |
| */ |
| %typemap(in) qpid::types::Variant& { |
| $1 = new qpid::types::Variant(PyToVariant($input)); |
| } |
| |
| %typemap(in) qpid::types::Variant::Map& { |
| $1 = new qpid::types::Variant::Map(); |
| PyToMap($input, $1); |
| } |
| |
| %typemap(in) qpid::types::Variant::List& { |
| $1 = new qpid::types::Variant::List(); |
| PyToList($input, $1); |
| } |
| |
| %typemap(in) const qpid::types::Variant::Map const & { |
| $1 = new qpid::types::Variant::Map(); |
| PyToMap($input, $1); |
| } |
| |
| %typemap(in) const qpid::types::Variant::List const & { |
| $1 = new qpid::types::Variant::List(); |
| PyToList($input, $1); |
| } |
| |
| %typemap(freearg) qpid::types::Variant& { |
| delete $1; |
| } |
| |
| %typemap(freearg) qpid::types::Variant::Map& { |
| delete $1; |
| } |
| |
| %typemap(freearg) qpid::types::Variant::List& { |
| delete $1; |
| } |
| |
| |
| /* |
| * Variant types: typecheck maps |
| */ |
| %typemap(typecheck) qpid::types::Variant::Map& { |
| $1 = PyDict_Check($input) ? 1 : 0; |
| } |
| |
| %typemap(typecheck) qpid::types::Variant::List& { |
| $1 = PyList_Check($input) ? 1 : 0; |
| } |
| |
| %typemap(typecheck) qpid::types::Variant& { |
| $1 = (PyFloat_Check($input) || |
| PyString_Check($input) || |
| PyInt_Check($input) || |
| PyLong_Check($input) || |
| PyDict_Check($input) || |
| PyList_Check($input) || |
| PyBool_Check($input)) ? 1 : 0; |
| } |
| |
| %typemap(typecheck) const qpid::types::Variant::Map const & { |
| $1 = PyDict_Check($input) ? 1 : 0; |
| } |
| |
| %typemap(typecheck) const qpid::types::Variant::List const & { |
| $1 = PyList_Check($input) ? 1 : 0; |
| } |
| |
| %typemap(typecheck) const qpid::types::Variant const & { |
| $1 = (PyFloat_Check($input) || |
| PyString_Check($input) || |
| PyInt_Check($input) || |
| PyLong_Check($input) || |
| PyDict_Check($input) || |
| PyList_Check($input) || |
| PyBool_Check($input)) ? 1 : 0; |
| } |
| |
| %typemap(typecheck) bool { |
| $1 = PyBool_Check($input) ? 1 : 0; |
| } |
| |
| |
| |
| %typemap (typecheck, precedence=SWIG_TYPECHECK_UINT64) uint64_t { |
| $1 = PyLong_Check($input) ? 1 : 0; |
| } |
| |
| %typemap (typecheck, precedence=SWIG_TYPECHECK_UINT32) uint32_t { |
| $1 = PyInt_Check($input) ? 1 : 0; |
| } |
| |
| |
| /** |
| * argc,argv as python list |
| */ |
| |
| %include <argcargv.i> |
| %apply (int ARGC, char **ARGV) { (int argc, const char *argv[]) } |