summaryrefslogtreecommitdiffstats
path: root/libshiboken
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-11-04 20:01:33 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2011-12-09 20:28:08 -0300
commitd25db2975162f592892313e10938531d8505e6c4 (patch)
tree4c52028ada45453ec98d25e15b497a7921dd34f0 /libshiboken
parent741142d29716de26b1630aca70d93227811ab579 (diff)
downloadshiboken-d25db2975162f592892313e10938531d8505e6c4.tar.gz
shiboken-d25db2975162f592892313e10938531d8505e6c4.tar.xz
shiboken-d25db2975162f592892313e10938531d8505e6c4.zip
Added adapter class SpecificConverter to provide type conversion based on a given string.
Also added code to register a couple of type conversions by name, a bunch of related tests, and some fixes to the converter functions.
Diffstat (limited to 'libshiboken')
-rw-r--r--libshiboken/sbkconverter.cpp63
-rw-r--r--libshiboken/sbkconverter.h33
2 files changed, 84 insertions, 12 deletions
diff --git a/libshiboken/sbkconverter.cpp b/libshiboken/sbkconverter.cpp
index ef332831..edd7097d 100644
--- a/libshiboken/sbkconverter.cpp
+++ b/libshiboken/sbkconverter.cpp
@@ -172,17 +172,12 @@ PyObject* referenceToPython(SbkConverter* converter, const void* cppIn)
{
assert(cppIn);
- // If it is a Object Type, produce a wrapper for it.
- if (!converter->copyToPython)
- return converter->pointerToPython(cppIn);
-
- // If it is a Value Type, try to find an existing wrapper, otherwise copy it as value to Python.
PyObject* pyOut = (PyObject*)BindingManager::instance().retrieveWrapper(cppIn);
if (pyOut) {
Py_INCREF(pyOut);
return pyOut;
}
- return converter->copyToPython(cppIn);
+ return converter->pointerToPython(cppIn);
}
static inline PyObject* CopyCppToPython(SbkConverter* converter, const void* cppIn)
@@ -245,6 +240,8 @@ void nonePythonToCppNullPtr(PyObject*, void* cppOut)
void* cppPointer(PyTypeObject* desiredType, SbkObject* pyIn)
{
assert(pyIn);
+ if (!ObjectType::checkType(desiredType))
+ return pyIn;
SbkObjectType* inType = (SbkObjectType*)Py_TYPE(pyIn);
if (ObjectType::hasCast(inType))
return ObjectType::cast(inType, pyIn, desiredType);
@@ -314,15 +311,12 @@ bool isImplicitConversion(SbkObjectType* type, PythonToCppFunc toCppFunc)
void registerConverterName(SbkConverter* converter , const char* typeName)
{
ConvertersMap::iterator iter = converters.find(typeName);
- if (iter == converters.end()) {
- //SbkDbg() << "Registering " << typeName;
+ if (iter == converters.end())
converters.insert(std::make_pair(typeName, converter));
- }
}
SbkConverter* getConverter(const char* typeName)
{
- //SbkDbg() << "Looking for converter for type " << typeName;
ConvertersMap::const_iterator it = converters.find(typeName);
if (it != converters.end())
return it->second;
@@ -480,4 +474,53 @@ bool pythonTypeIsObjectType(SbkConverter* converter)
return converter->pointerToPython && !converter->copyToPython;
}
+SpecificConverter::SpecificConverter(const char* typeName)
+ : m_type(InvalidConversion)
+{
+ m_converter = getConverter(typeName);
+ if (!m_converter)
+ return;
+ int len = strlen(typeName);
+ char lastChar = typeName[len -1];
+ if (lastChar == '&') {
+ m_type = ReferenceConversion;
+ } else if (lastChar == '*' || pythonTypeIsObjectType(m_converter)) {
+ m_type = PointerConversion;
+ } else {
+ m_type = CopyConversion;
+ }
+}
+
+PyObject* SpecificConverter::toPython(const void* cppIn)
+{
+ switch (m_type) {
+ case CopyConversion:
+ return copyToPython(m_converter, cppIn);
+ case PointerConversion:
+ return pointerToPython(m_converter, *((const void**)cppIn));
+ case ReferenceConversion:
+ return referenceToPython(m_converter, cppIn);
+ default:
+ PyErr_SetString(PyExc_RuntimeError, "tried to use invalid converter in 'C++ to Python' conversion");
+ }
+ return 0;
+}
+
+void SpecificConverter::toCpp(PyObject* pyIn, void* cppOut)
+{
+ switch (m_type) {
+ case CopyConversion:
+ pythonToCppCopy(m_converter, pyIn, cppOut);
+ break;
+ case PointerConversion:
+ pythonToCppPointer(m_converter, pyIn, cppOut);
+ break;
+ case ReferenceConversion:
+ pythonToCppPointer(m_converter, pyIn, &cppOut);
+ break;
+ default:
+ PyErr_SetString(PyExc_RuntimeError, "tried to use invalid converter in 'Python to C++' conversion");
+ }
+}
+
} } // namespace Shiboken::Conversions
diff --git a/libshiboken/sbkconverter.h b/libshiboken/sbkconverter.h
index a5b8d113..41126786 100644
--- a/libshiboken/sbkconverter.h
+++ b/libshiboken/sbkconverter.h
@@ -36,8 +36,6 @@
#define SbkObject_TypeCheck(tp, ob) \
(Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp)))
-#define SbkString_Check(pyObj) (pyObj == Py_None || PyString_Check(pyObj))
-
extern "C"
{
@@ -88,6 +86,36 @@ typedef PythonToCppFunc (*IsConvertibleToCppFunc)(PyObject*);
namespace Shiboken {
namespace Conversions {
+
+class LIBSHIBOKEN_API SpecificConverter
+{
+public:
+ enum Type
+ {
+ InvalidConversion,
+ CopyConversion,
+ PointerConversion,
+ ReferenceConversion
+ };
+
+ explicit SpecificConverter(const char* typeName);
+
+ inline SbkConverter* converter() { return m_converter; }
+ inline operator SbkConverter*() const { return m_converter; }
+
+ inline bool isValid() { return m_type != InvalidConversion; }
+ inline operator bool() const { return m_type != InvalidConversion; }
+
+ inline Type conversionType() { return m_type; }
+
+ PyObject* toPython(const void* cppIn);
+ void toCpp(PyObject* pyIn, void* cppOut);
+private:
+ SbkConverter* m_converter;
+ Type m_type;
+};
+
+
/**
* Creates a converter for a wrapper type.
* \param type A Shiboken.ObjectType that will receive the new converter.
@@ -306,4 +334,5 @@ template<> inline SbkConverter* PrimitiveTypeConverter<void*>() { return primiti
struct _SbkGenericType { PyHeapTypeObject super; SbkConverter** converter; };
#define SBK_CONVERTER(pyType) (*reinterpret_cast<_SbkGenericType*>(pyType)->converter)
+
#endif // SBK_CONVERTER_H