diff options
| author | Darryl L. Pierce <mcpierce@apache.org> | 2013-02-19 19:19:02 +0000 |
|---|---|---|
| committer | Darryl L. Pierce <mcpierce@apache.org> | 2013-02-19 19:19:02 +0000 |
| commit | 307c456b6a381602e4cb807fe15597f5aa5aef00 (patch) | |
| tree | e5b5e69741632ca81ae01a9bfed9ffdc100b4099 /qpid/cpp/include | |
| parent | 9b1a58d85495f217680aac3f79d56e6fb6e5ba0b (diff) | |
| download | qpid-python-307c456b6a381602e4cb807fe15597f5aa5aef00.tar.gz | |
QPID-4588: Moved the swig descriptors to the include/qpid directory.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1447877 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/include')
| -rw-r--r-- | qpid/cpp/include/qpid/swig_perl_typemaps.i | 335 | ||||
| -rw-r--r-- | qpid/cpp/include/qpid/swig_python_typemaps.i | 446 | ||||
| -rw-r--r-- | qpid/cpp/include/qpid/swig_ruby_typemaps.i | 368 |
3 files changed, 1149 insertions, 0 deletions
diff --git a/qpid/cpp/include/qpid/swig_perl_typemaps.i b/qpid/cpp/include/qpid/swig_perl_typemaps.i new file mode 100644 index 0000000000..7730b69ce7 --- /dev/null +++ b/qpid/cpp/include/qpid/swig_perl_typemaps.i @@ -0,0 +1,335 @@ +/* + * 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. + */ + +%wrapper %{ + +#include <stdarg.h> + + SV* MapToPerl(const qpid::types::Variant::Map*); + SV* ListToPerl(const qpid::types::Variant::List*); + void PerlToMap(SV*, qpid::types::Variant::Map*); + void PerlToList(SV*, qpid::types::Variant::List*); + + qpid::types::Variant PerlToVariant(SV* value) { + if (SvROK(value)) { + if (SvTYPE(SvRV(value)) == SVt_PVHV) { + qpid::types::Variant::Map map; + PerlToMap(value, &map); + return qpid::types::Variant(map); + } + else if (SvTYPE(SvRV(value)) == SVt_PVAV) { + qpid::types::Variant::List list; + PerlToList(value, &list); + return qpid::types::Variant(list); + } + } + else { + if (SvIOK(value)) { + return qpid::types::Variant((int64_t) SvIV(value)); + } + else if (SvNOK(value)) { + return qpid::types::Variant((float)SvNV(value)); + } + else if (SvPOK(value)) { + STRLEN len; + char *ptr = SvPV(value, len); + qpid::types::Variant v = qpid::types::Variant(std::string(ptr,len)); + if (SvUTF8(value)) { + v.setEncoding("utf8"); + } + return v; + } + } + return qpid::types::Variant(); + } + + SV* VariantToPerl(const qpid::types::Variant* v) { + SV* result = newSV(0); + try { + switch (v->getType()) { + case qpid::types::VAR_VOID: { + sv_setiv(result, (IV)0); + break; + } + case qpid::types::VAR_BOOL : { + result = boolSV(v->asBool()); + break; + } + case qpid::types::VAR_UINT8 : + case qpid::types::VAR_UINT16 : + case qpid::types::VAR_UINT32 : { + sv_setuv(result, (UV)v->asUint32()); + break; + } + case qpid::types::VAR_UINT64 : { + sv_setuv(result, (UV)v->asUint64()); + break; + } + case qpid::types::VAR_INT8 : + case qpid::types::VAR_INT16 : + case qpid::types::VAR_INT32 : { + sv_setiv(result, (IV)v->asInt32()); + break; + } + case qpid::types::VAR_INT64 : { + sv_setiv(result, (IV)v->asInt64()); + break; + } + case qpid::types::VAR_FLOAT : { + sv_setnv(result, (double)v->asFloat()); + break; + } + case qpid::types::VAR_DOUBLE : { + sv_setnv(result, (double)v->asDouble()); + break; + } + case qpid::types::VAR_STRING : { + const std::string val(v->asString()); + result = newSVpvn(val.c_str(), val.size()); + if( v->getEncoding() == "utf8" ) { + SvUTF8_on(result); + } + break; + } + case qpid::types::VAR_MAP : { + result = MapToPerl(&(v->asMap())); + break; + } + case qpid::types::VAR_LIST : { + result = ListToPerl(&(v->asList())); + break; + } + case qpid::types::VAR_UUID : { + } + } + } catch (qpid::types::Exception& ex) { + Perl_croak(aTHX_ ex.what()); + } + + return result; + } + + SV* MapToPerl(const qpid::types::Variant::Map* map) { + HV *hv = newHV(); + qpid::types::Variant::Map::const_iterator iter; + for (iter = map->begin(); iter != map->end(); iter++) { + const std::string key(iter->first); + SV* perlval = VariantToPerl(&(iter->second)); + hv_store(hv, key.c_str(), key.size(), perlval, 0); + } + return sv_2mortal(newRV_noinc((SV *)hv)); + } + + SV* ListToPerl(const qpid::types::Variant::List* list) { + AV* av = newAV(); + qpid::types::Variant::List::const_iterator iter; + for (iter = list->begin(); iter != list->end(); iter++) { + SV* perlval = VariantToPerl(&(*iter)); + av_push(av, perlval); + } + return sv_2mortal(newRV_noinc((SV *)av)); + } + + void PerlToMap(SV* hash, qpid::types::Variant::Map* map) { + map->clear(); + HV* hv = (HV *)SvRV(hash); + HE* he; + while((he = hv_iternext(hv)) != NULL) { + SV* svkey = HeSVKEY_force(he); + SV* svval = HeVAL(he); + (*map)[std::string(SvPV_nolen(svkey))] = PerlToVariant(svval); + } + } + + void PerlToList(SV* ary, qpid::types::Variant::List* list) { + list->clear(); + AV * av = (AV *)SvRV(ary); + I32 len = av_len(av) + 1; + if (len > 0) { + for (I32 i = 0; i < len; i++) { + list->push_back(PerlToVariant(*av_fetch(av, i, 0))); + } + } + } +%} + +%typemap (in) void * { + $1 = (void *)SvIV($input); +} + +%typemap (out) void * { + sv_setiv($result, (IV)$1); + argvi++; +} + +%typemap (in) uint8_t, uint16_t, uint32_t, uint64_t { + if (SvIOK($input)) { + $1 = ($1_ltype)SvUV($input); + } + else { + SWIG_exception_fail(SWIG_ValueError, "not an integer"); + } +} + +%typemap (out) uint8_t, uint16_t, uint32_t, uint64_t { + sv_setuv($result, (UV)$1); + argvi++; +} + +%typemap (in) int8_t, int16_t, int32_t, int64_t { + if (SvIOK($input)) { + $1 = ($1_ltype)SvIV($input); + } + else { + SWIG_exception_fail(SWIG_ValueError, "not an integer"); + } +} + +%typemap (out) int8_t, int16_t, int32_t, int64_t { + sv_setiv($result, (IV)$1); + argvi++; +} + +%typemap(in) bool { + $1 = (bool)SvTRUE($input); +} + +%typemap (out) bool { + $result = boolSV($1); + argvi++; +} + + +%typemap (typecheck, precedence=SWIG_TYPECHECK_UINT64) uint64_t { + $1 = SvIOK($input) ? 1 : 0; +} + +%typemap (typecheck, precedence=SWIG_TYPECHECK_UINT32) uint32_t { + $1 = SvIOK($input) ? 1 : 0; +} + + +/* + * Variant types: C++ --> Perl + */ +%typemap(out) qpid::types::Variant::Map { + $result = MapToPerl(&$1); + argvi++; +} + +%typemap(out) qpid::types::Variant::Map& { + $result = MapToPerl($1); + argvi++; +} + +%typemap(out) qpid::types::Variant::List { + $result = ListToPerl(&$1); + argvi++; +} + +%typemap(out) qpid::types::Variant::List& { + $result = ListToPerl($1); + argvi++; +} + +%typemap(out) qpid::types::Variant& { + $result = VariantToPerl($1); + argvi++; +} + + +/* + * Variant types: Perl --> C++ + */ +%typemap(in) qpid::types::Variant& { + $1 = new qpid::types::Variant(PerlToVariant($input)); +} + +%typemap(in) qpid::types::Variant::Map& { + $1 = new qpid::types::Variant::Map(); + PerlToMap($input, $1); + +} + +%typemap(in) qpid::types::Variant::List& { + $1 = new qpid::types::Variant::List(); + PerlToList($input, $1); + +} + +%typemap(in) const qpid::types::Variant::Map const & { + $1 = new qpid::types::Variant::Map(); + PerlToMap($input, $1); +} + +%typemap(in) const qpid::types::Variant::List const & { + $1 = new qpid::types::Variant::List(); + PerlToList($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 = (SvTYPE(SvRV($input)) == SVt_PVHV) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant::List& { + $1 = (SvTYPE(SvRV($input)) == SVt_PVAV) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant& { + $1 = (SvIOK($input) || + SvNOK($input) || + SvPOK($input) ) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant::Map const & { + $1 = (SvTYPE(SvRV($input)) == SVt_PVHV) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant::List const & { + $1 = (SvTYPE(SvRV($input)) == SVt_PVAV) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant const & { + $1 = (SvIOK($input) || + SvNOK($input) || + SvPOK($input) ) ? 1 : 0; +} + +/* No boolean type for perl. + Boolean is simply and integer in perl +*/ +%typecheck(SWIG_TYPECHECK_BOOL) bool { + $1 = (SvIOK($input)) ? 1 : 0; +} diff --git a/qpid/cpp/include/qpid/swig_python_typemaps.i b/qpid/cpp/include/qpid/swig_python_typemaps.i new file mode 100644 index 0000000000..25a4e46b18 --- /dev/null +++ b/qpid/cpp/include/qpid/swig_python_typemaps.i @@ -0,0 +1,446 @@ +/* + * 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"); + + /* 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); +%} + + +%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 + + + 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(PyInt_AS_LONG(value) ? true : false)); + if (PyFloat_Check(value)) return qpid::types::Variant(PyFloat_AS_DOUBLE(value)); + if (PyInt_Check(value)) return qpid::types::Variant(int64_t(PyInt_AS_LONG(value))); + if (PyLong_Check(value)) return qpid::types::Variant(int64_t(PyLong_AsLongLong(value))); + if (PyString_Check(value)) return qpid::types::Variant(std::string(PyString_AS_STRING(value))); + 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; + 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()); + result = PyString_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, PyString_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 = PyString_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(PyString_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 (PyInt_Check($input)) { + $1 = (uint16_t) PyInt_AsUnsignedLongMask($input); + } else if (PyLong_Check($input)) { + $1 = (uint16_t) PyLong_AsUnsignedLong($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 (PyInt_Check($input)) { + $1 = (int32_t) PyInt_AsLong($input); + } else if (PyLong_Check($input)) { + $1 = (int32_t) PyLong_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)PyInt_AsUnsignedLongLongMask($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; +} + diff --git a/qpid/cpp/include/qpid/swig_ruby_typemaps.i b/qpid/cpp/include/qpid/swig_ruby_typemaps.i new file mode 100644 index 0000000000..1a07cc86b0 --- /dev/null +++ b/qpid/cpp/include/qpid/swig_ruby_typemaps.i @@ -0,0 +1,368 @@ +/* + * 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. + */ + +%wrapper %{ + +#include <stdarg.h> + + VALUE MapToRb(const qpid::types::Variant::Map*); + VALUE ListToRb(const qpid::types::Variant::List*); + void RbToMap(VALUE, qpid::types::Variant::Map*); + void RbToList(VALUE, qpid::types::Variant::List*); + + qpid::types::Variant RbToVariant(VALUE value) { + switch (TYPE(value)) { + case T_FLOAT: return qpid::types::Variant(NUM2DBL(value)); + case T_STRING: return qpid::types::Variant(StringValuePtr(value)); + case T_FIXNUM: return qpid::types::Variant((int64_t) FIX2LONG(value)); + case T_BIGNUM: return qpid::types::Variant((int64_t) NUM2LL(value)); + case T_TRUE: return qpid::types::Variant(true); + case T_FALSE: return qpid::types::Variant(false); + case T_HASH: { + qpid::types::Variant::Map map; + RbToMap(value, &map); + return qpid::types::Variant(map); + } + case T_ARRAY: { + qpid::types::Variant::List list; + RbToList(value, &list); + return qpid::types::Variant(list); + } + default: return qpid::types::Variant(); + } + } + + VALUE VariantToRb(const qpid::types::Variant* v) { + VALUE result = Qnil; + try { + switch (v->getType()) { + case qpid::types::VAR_VOID: { + result = Qnil; + break; + } + case qpid::types::VAR_BOOL : { + result = v->asBool() ? Qtrue : Qfalse; + break; + } + case qpid::types::VAR_UINT8 : + case qpid::types::VAR_UINT16 : + case qpid::types::VAR_UINT32 : { + result = UINT2NUM(v->asUint32()); + break; + } + case qpid::types::VAR_UINT64 : { + result = ULL2NUM(v->asUint64()); + break; + } + case qpid::types::VAR_INT8 : + case qpid::types::VAR_INT16 : + case qpid::types::VAR_INT32 : { + result = INT2NUM(v->asInt32()); + break; + } + case qpid::types::VAR_INT64 : { + result = LL2NUM(v->asInt64()); + break; + } + case qpid::types::VAR_FLOAT : { + result = rb_float_new((double) v->asFloat()); + break; + } + case qpid::types::VAR_DOUBLE : { + result = rb_float_new(v->asDouble()); + break; + } + case qpid::types::VAR_STRING : { + const std::string val(v->asString()); + result = rb_str_new(val.c_str(), val.size()); + break; + } + case qpid::types::VAR_MAP : { + result = MapToRb(&(v->asMap())); + break; + } + case qpid::types::VAR_LIST : { + result = ListToRb(&(v->asList())); + break; + } + case qpid::types::VAR_UUID : { + } + } + } catch (qpid::types::Exception& ex) { + static VALUE error = rb_define_class("Error", rb_eStandardError); + rb_raise(error, ex.what()); + } + + return result; + } + + VALUE MapToRb(const qpid::types::Variant::Map* map) { + VALUE result = rb_hash_new(); + qpid::types::Variant::Map::const_iterator iter; + for (iter = map->begin(); iter != map->end(); iter++) { + const std::string key(iter->first); + VALUE rbval = VariantToRb(&(iter->second)); + rb_hash_aset(result, rb_str_new(key.c_str(), key.size()), rbval); + } + return result; + } + + VALUE ListToRb(const qpid::types::Variant::List* list) { + VALUE result = rb_ary_new2(list->size()); + qpid::types::Variant::List::const_iterator iter; + for (iter = list->begin(); iter != list->end(); iter++) { + VALUE rbval = VariantToRb(&(*iter)); + rb_ary_push(result, rbval); + } + return result; + } + + VALUE HashIter(VALUE data_ary, VALUE context) { + VALUE key = rb_ary_entry(data_ary, 0); + VALUE val = rb_ary_entry(data_ary, 1); + qpid::types::Variant::Map* map((qpid::types::Variant::Map*) context); + (*map)[std::string(StringValuePtr(key))] = RbToVariant(val); + return data_ary; + } + + VALUE AryIter(VALUE data, VALUE context) { + qpid::types::Variant::List* list((qpid::types::Variant::List*) context); + list->push_back(RbToVariant(data)); + return data; + } + + void RbToMap(VALUE hash, qpid::types::Variant::Map* map) { + map->clear(); + rb_iterate(rb_each, hash, (VALUE(*)(ANYARGS))HashIter, (VALUE) map); + } + + void RbToList(VALUE ary, qpid::types::Variant::List* list) { + list->clear(); + rb_iterate(rb_each, ary, (VALUE(*)(ANYARGS))AryIter, (VALUE) list); + } +%} + +%typemap (in) void * +{ + $1 = (void *) $input; +} + +%typemap (out) void * +{ + $result = (VALUE) $1; +} + +%typemap (in) uint8_t +{ + $1 = NUM2UINT ($input); +} + +%typemap (out) uint8_t +{ + $result = UINT2NUM((uint8_t) $1); +} + +%typemap (in) int8_t +{ + $1 = NUM2INT ($input); +} + +%typemap (out) int8_t +{ + $result = INT2NUM((int8_t) $1); +} + +%typemap (in) uint16_t +{ + $1 = NUM2UINT ($input); +} + +%typemap (out) uint16_t +{ + $result = UINT2NUM((uint16_t) $1); +} + +%typemap (in) uint32_t +{ + if (TYPE($input) == T_BIGNUM) + $1 = NUM2UINT($input); + else + $1 = FIX2UINT($input); +} + +%typemap (out) uint32_t +{ + $result = UINT2NUM((uint32_t) $1); +} + +%typemap (in) int32_t +{ + if (TYPE($input) == T_BIGNUM) + $1 = NUM2INT($input); + else + $1 = FIX2INT($input); +} + +%typemap (out) int32_t +{ + $result = INT2NUM((int32_t) $1); +} + +%typemap (typecheck, precedence=SWIG_TYPECHECK_INTEGER) uint32_t { + $1 = FIXNUM_P($input); +} + +%typemap (in) uint64_t +{ + if (TYPE($input) == T_BIGNUM) + $1 = NUM2ULL($input); + else + $1 = (uint64_t) FIX2ULONG($input); +} + +%typemap (out) uint64_t +{ + $result = ULL2NUM((uint64_t) $1); +} + +%typemap (in) int64_t +{ + if (TYPE($input) == T_BIGNUM) + $1 = NUM2LL($input); + else + $1 = (int64_t) FIX2LONG($input); +} + +%typemap (out) int64_t +{ + $result = LL2NUM((int64_t) $1); +} + +/* + * Variant types: C++ --> Ruby + */ +%typemap(out) qpid::types::Variant::Map { + $result = MapToRb(&$1); +} + +%typemap(out) qpid::types::Variant::Map& { + $result = MapToRb($1); +} + +%typemap(out) qpid::types::Variant::List { + $result = ListToRb(&$1); +} + +%typemap(out) qpid::types::Variant::List& { + $result = ListToRb($1); +} + +%typemap(out) qpid::types::Variant& { + $result = VariantToRb($1); +} + + +/* + * Variant types: Ruby --> C++ + */ +%typemap(in) qpid::types::Variant& { + $1 = new qpid::types::Variant(RbToVariant($input)); +} + +%typemap(in) qpid::types::Variant::Map& { + $1 = new qpid::types::Variant::Map(); + RbToMap($input, $1); +} + +%typemap(in) qpid::types::Variant::List& { + $1 = new qpid::types::Variant::List(); + RbToList($input, $1); +} + +%typemap(in) const qpid::types::Variant::Map const & { + $1 = new qpid::types::Variant::Map(); + RbToMap($input, $1); +} + +%typemap(in) const qpid::types::Variant::List const & { + $1 = new qpid::types::Variant::List(); + RbToList($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 = (TYPE($input) == T_HASH) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant::List& { + $1 = (TYPE($input) == T_ARRAY) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant& { + $1 = (TYPE($input) == T_FLOAT || + TYPE($input) == T_STRING || + TYPE($input) == T_FIXNUM || + TYPE($input) == T_BIGNUM || + TYPE($input) == T_TRUE || + TYPE($input) == T_FALSE) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant::Map const & { + $1 = (TYPE($input) == T_HASH) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant::List const & { + $1 = (TYPE($input) == T_ARRAY) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant const & { + $1 = (TYPE($input) == T_FLOAT || + TYPE($input) == T_STRING || + TYPE($input) == T_FIXNUM || + TYPE($input) == T_BIGNUM || + TYPE($input) == T_TRUE || + TYPE($input) == T_FALSE) ? 1 : 0; +} + +%typemap(typecheck) bool { + $1 = (TYPE($input) == T_TRUE || + TYPE($input) == T_FALSE) ? 1 : 0; +} + + + +%typemap (typecheck, precedence=SWIG_TYPECHECK_INTEGER) uint64_t { + $1 = FIXNUM_P($input); +} + |
