Pack a list or a tuple of values passed to a Python method to the multi-value parameter. --- libvirt-override.c | 228 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 129 insertions(+), 99 deletions(-) diff --git a/libvirt-override.c b/libvirt-override.c index 588dac1..45c8afc 100644 --- a/libvirt-override.c +++ b/libvirt-override.c @@ -278,6 +278,126 @@ typedef virPyTypedParamsHint *virPyTypedParamsHintPtr; # define libvirt_PyString_Check PyString_Check # endif +static int +virPyDictToTypedParamOne(virTypedParameterPtr *params, + int *n, + int *max, + virPyTypedParamsHintPtr hints, + int nhints, + const char *keystr, + PyObject *value) +{ + int rv = -1, type = -1; + size_t i; + + for (i = 0; i < nhints; i++) { + if (STREQ(hints[i].name, keystr)) { + type = hints[i].type; + break; + } + } + + if (type == -1) { + if (libvirt_PyString_Check(value)) { + type = VIR_TYPED_PARAM_STRING; + } else if (PyBool_Check(value)) { + type = VIR_TYPED_PARAM_BOOLEAN; + } else if (PyLong_Check(value)) { + unsigned long long ull = PyLong_AsUnsignedLongLong(value); + if (ull == (unsigned long long) -1 && PyErr_Occurred()) + type = VIR_TYPED_PARAM_LLONG; + else + type = VIR_TYPED_PARAM_ULLONG; +#if PY_MAJOR_VERSION < 3 + } else if (PyInt_Check(value)) { + if (PyInt_AS_LONG(value) < 0) + type = VIR_TYPED_PARAM_LLONG; + else + type = VIR_TYPED_PARAM_ULLONG; +#endif + } else if (PyFloat_Check(value)) { + type = VIR_TYPED_PARAM_DOUBLE; + } + } + + if (type == -1) { + PyErr_Format(PyExc_TypeError, + "Unknown type of \"%s\" field", keystr); + goto cleanup; + } + + switch ((virTypedParameterType) type) { + case VIR_TYPED_PARAM_INT: + { + int val; + if (libvirt_intUnwrap(value, &val) < 0 || + virTypedParamsAddInt(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_UINT: + { + unsigned int val; + if (libvirt_uintUnwrap(value, &val) < 0 || + virTypedParamsAddUInt(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_LLONG: + { + long long val; + if (libvirt_longlongUnwrap(value, &val) < 0 || + virTypedParamsAddLLong(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_ULLONG: + { + unsigned long long val; + if (libvirt_ulonglongUnwrap(value, &val) < 0 || + virTypedParamsAddULLong(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_DOUBLE: + { + double val; + if (libvirt_doubleUnwrap(value, &val) < 0 || + virTypedParamsAddDouble(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_BOOLEAN: + { + bool val; + if (libvirt_boolUnwrap(value, &val) < 0 || + virTypedParamsAddBoolean(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_STRING: + { + char *val;; + if (libvirt_charPtrUnwrap(value, &val) < 0 || + !val || + virTypedParamsAddString(params, n, max, keystr, val) < 0) { + VIR_FREE(val); + goto cleanup; + } + VIR_FREE(val); + break; + } + case VIR_TYPED_PARAM_LAST: + break; /* unreachable */ + } + + rv = 0; + + cleanup: + return rv; +} + + /* Automatically convert dict into type parameters based on types reported * by python. All integer types are converted into LLONG (in case of a negative * value) or ULLONG (in case of a positive value). If you need different @@ -300,7 +420,6 @@ virPyDictToTypedParams(PyObject *dict, Py_ssize_t pos = 0; #endif virTypedParameterPtr params = NULL; - size_t i; int n = 0; int max = 0; int ret = -1; @@ -313,112 +432,23 @@ virPyDictToTypedParams(PyObject *dict, return -1; while (PyDict_Next(dict, &pos, &key, &value)) { - int type = -1; - if (libvirt_charPtrUnwrap(key, &keystr) < 0 || !keystr) goto cleanup; - for (i = 0; i < nhints; i++) { - if (STREQ(hints[i].name, keystr)) { - type = hints[i].type; - break; - } - } + if (PyList_Check(value) || PyTuple_Check(value)) { + Py_ssize_t i, size = PySequence_Size(value); - if (type == -1) { - if (libvirt_PyString_Check(value)) { - type = VIR_TYPED_PARAM_STRING; - } else if (PyBool_Check(value)) { - type = VIR_TYPED_PARAM_BOOLEAN; - } else if (PyLong_Check(value)) { - unsigned long long ull = PyLong_AsUnsignedLongLong(value); - if (ull == (unsigned long long) -1 && PyErr_Occurred()) - type = VIR_TYPED_PARAM_LLONG; - else - type = VIR_TYPED_PARAM_ULLONG; -#if PY_MAJOR_VERSION < 3 - } else if (PyInt_Check(value)) { - if (PyInt_AS_LONG(value) < 0) - type = VIR_TYPED_PARAM_LLONG; - else - type = VIR_TYPED_PARAM_ULLONG; -#endif - } else if (PyFloat_Check(value)) { - type = VIR_TYPED_PARAM_DOUBLE; + for (i = 0; i < size; i++) { + PyObject *v = PySequence_ITEM(value, i); + if (virPyDictToTypedParamOne(¶ms, &n, &max, + hints, nhints, keystr, v) < 0) + goto cleanup; } - } - - if (type == -1) { - PyErr_Format(PyExc_TypeError, - "Unknown type of \"%s\" field", keystr); + } else if (virPyDictToTypedParamOne(¶ms, &n, &max, + hints, nhints, keystr, value) < 0) goto cleanup; - } - switch ((virTypedParameterType) type) { - case VIR_TYPED_PARAM_INT: - { - int val; - if (libvirt_intUnwrap(value, &val) < 0 || - virTypedParamsAddInt(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_UINT: - { - unsigned int val; - if (libvirt_uintUnwrap(value, &val) < 0 || - virTypedParamsAddUInt(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_LLONG: - { - long long val; - if (libvirt_longlongUnwrap(value, &val) < 0 || - virTypedParamsAddLLong(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_ULLONG: - { - unsigned long long val; - if (libvirt_ulonglongUnwrap(value, &val) < 0 || - virTypedParamsAddULLong(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_DOUBLE: - { - double val; - if (libvirt_doubleUnwrap(value, &val) < 0 || - virTypedParamsAddDouble(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_BOOLEAN: - { - bool val; - if (libvirt_boolUnwrap(value, &val) < 0 || - virTypedParamsAddBoolean(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_STRING: - { - char *val;; - if (libvirt_charPtrUnwrap(value, &val) < 0 || - !val || - virTypedParamsAddString(¶ms, &n, &max, keystr, val) < 0) { - VIR_FREE(val); - goto cleanup; - } - VIR_FREE(val); - break; - } - case VIR_TYPED_PARAM_LAST: - break; /* unreachable */ - } VIR_FREE(keystr); } -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list