diff --git a/src/vasingletonmethods.hpp b/src/vasingletonmethods.hpp index 67506bc8f9c7ddbc48a168956d2082ed35668fa3..b10c9f3d91aaa9d638495864d1170a8fd20a1e97 100644 --- a/src/vasingletonmethods.hpp +++ b/src/vasingletonmethods.hpp @@ -42,7 +42,63 @@ PyObject* ConvertVAStructToPythonDict( const CVAStruct& oInStruct ) //! Helper to convert recursively from Python dict to VAStruct CVAStruct ConvertPythonDictToVAStruct( PyObject* pInDict ) { - return CVAStruct(); + CVAStruct oReturn; + + PyObject* pKeyList = PyDict_Keys(pInDict); + PyObject* pValueList = PyDict_Values(pInDict); + + for (Py_ssize_t i = 0; i < PyList_Size(pKeyList); i++) + { + PyObject* pKey = PyList_GetItem(pKeyList, i); + PyObject* pValue = PyList_GetItem(pValueList, i); + char* pcKeyName = nullptr; + if (!PyArg_Parse(pKey, "s", &pcKeyName)) + VA_EXCEPT2(CVAException::INVALID_PARAMETER, "Invalid key '" + std::string( pcKeyName ) + "'"); + + if (Py_None == pValue) + { + oReturn[pcKeyName] = false; + } + else if (PyBool_Check(pValue)) + { + oReturn[pcKeyName] = bool(PyLong_AsLong(pValue)); + } + else if (PyLong_Check(pValue)) + { + oReturn[pcKeyName] = PyLong_AsLong(pValue); + } + else if (PyFloat_Check(pValue)) + { + oReturn[pcKeyName] = PyFloat_AsDouble(pValue); + } + else if (PyUnicode_Check(pValue)) + { + char* pcStringValue = nullptr; + if (!PyArg_Parse(pValue, "s", &pcStringValue)) + VA_EXCEPT2(CVAException::INVALID_PARAMETER, "Invalid string value at key '" + std::string(pcKeyName) + "': " + std::string(pcStringValue)); + oReturn[pcKeyName] = std::string(pcStringValue); + } + else if (PyDict_Check(pValue)) + { + oReturn[pcKeyName] = ConvertPythonDictToVAStruct( pValue); + } + else if (PyList_Check(pValue)) + { + // Sample buffer + VA_EXCEPT_NOT_IMPLEMENTED; + } + else if (PyByteArray_Check(pValue)) + { + // Data blob + VA_EXCEPT_NOT_IMPLEMENTED; + } + else + { + VA_EXCEPT2( INVALID_PARAMETER, "Could not interpret value of key '" + std::string(pcKeyName) + "' as a supported VAStruct type.") + } + } + + return oReturn; }; @@ -126,21 +182,21 @@ static PyObject* va_call_module(PyObject* pSelf, PyObject** ppArgs, Py_ssize_t n { VAPY_REQUIRE_CONN_TRY; - static const char * const _keywords[] = { "module_name", "arguments", NULL }; - static _PyArg_Parser _parser = { "so:call_module", _keywords, 0 }; + static const char * const _keywords[] = { "module_name", "arguments_dict", NULL }; + static _PyArg_Parser _parser = { "sO!:call_module", _keywords, 0 }; char* pcModuleName = nullptr; - PyObject* pArguments = nullptr; + PyObject* pArgumentsDict = nullptr; - if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcModuleName, &pArguments ) ) + if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcModuleName, &PyDict_Type, &pArgumentsDict ) ) return NULL; std::string sModuleName = std::string( pcModuleName ); - CVAStruct oArgs = ConvertPythonDictToVAStruct( pArguments ); - CVAStruct oReturn; + CVAStruct oInArgs = ConvertPythonDictToVAStruct( pArgumentsDict ); + CVAStruct oOutArgs; - g_pVANetClient->GetCoreInstance()->CallModule( sModuleName, oArgs, oReturn ); + g_pVANetClient->GetCoreInstance()->CallModule( sModuleName, oInArgs, oOutArgs ); - return ConvertVAStructToPythonDict( oReturn ); + return ConvertVAStructToPythonDict( oOutArgs ); VAPY_CATCH_RETURN; };