mirror of
https://gitlab.com/libvirt/libvirt-python.git
synced 2025-12-03 16:23:46 +03:00
Move utils and shared code into libvirt-utils
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
@@ -47,13 +47,6 @@ extern void initcygvirtmod_lxc(void);
|
||||
do {} while (0)
|
||||
#endif
|
||||
|
||||
/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;"
|
||||
is so common that we encapsulate it here. Now, each use is simply
|
||||
return VIR_PY_NONE; */
|
||||
#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None)
|
||||
#define VIR_PY_INT_FAIL (libvirt_intWrap(-1))
|
||||
#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0))
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Statistics *
|
||||
|
||||
@@ -51,419 +51,6 @@ extern void initcygvirtmod(void);
|
||||
do {} while (0)
|
||||
#endif
|
||||
|
||||
/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;"
|
||||
is so common that we encapsulate it here. Now, each use is simply
|
||||
return VIR_PY_NONE; */
|
||||
#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None)
|
||||
#define VIR_PY_INT_FAIL (libvirt_intWrap(-1))
|
||||
#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0))
|
||||
|
||||
static char *py_str(PyObject *obj)
|
||||
{
|
||||
PyObject *str = PyObject_Str(obj);
|
||||
char *ret;
|
||||
if (!str) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
return NULL;
|
||||
};
|
||||
libvirt_charPtrUnwrap(str, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Helper function to convert a virTypedParameter output array into a
|
||||
* Python dictionary for return to the user. Return NULL on failure,
|
||||
* after raising a python exception. */
|
||||
static PyObject *
|
||||
getPyVirTypedParameter(const virTypedParameter *params, int nparams)
|
||||
{
|
||||
PyObject *key, *val, *info;
|
||||
size_t i;
|
||||
|
||||
if ((info = PyDict_New()) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < nparams; i++) {
|
||||
switch (params[i].type) {
|
||||
case VIR_TYPED_PARAM_INT:
|
||||
val = libvirt_intWrap(params[i].value.i);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_UINT:
|
||||
val = libvirt_intWrap(params[i].value.ui);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_LLONG:
|
||||
val = libvirt_longlongWrap(params[i].value.l);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_ULLONG:
|
||||
val = libvirt_ulonglongWrap(params[i].value.ul);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_DOUBLE:
|
||||
val = PyFloat_FromDouble(params[i].value.d);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_BOOLEAN:
|
||||
val = PyBool_FromLong(params[i].value.b);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_STRING:
|
||||
val = libvirt_constcharPtrWrap(params[i].value.s);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Possible if a newer server has a bug and sent stuff we
|
||||
* don't recognize. */
|
||||
PyErr_Format(PyExc_LookupError,
|
||||
"Type value \"%d\" not recognized",
|
||||
params[i].type);
|
||||
val = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
key = libvirt_constcharPtrWrap(params[i].field);
|
||||
if (!key || !val)
|
||||
goto cleanup;
|
||||
|
||||
if (PyDict_SetItem(info, key, val) < 0) {
|
||||
Py_DECREF(info);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
Py_DECREF(key);
|
||||
Py_DECREF(val);
|
||||
}
|
||||
return info;
|
||||
|
||||
cleanup:
|
||||
Py_XDECREF(key);
|
||||
Py_XDECREF(val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate a new typed parameter array with the same contents and
|
||||
* length as info, and using the array params of length nparams as
|
||||
* hints on what types to use when creating the new array. The caller
|
||||
* must clear the array before freeing it. Return NULL on failure,
|
||||
* after raising a python exception. */
|
||||
static virTypedParameterPtr ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
|
||||
setPyVirTypedParameter(PyObject *info,
|
||||
const virTypedParameter *params, int nparams)
|
||||
{
|
||||
PyObject *key, *value;
|
||||
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4
|
||||
int pos = 0;
|
||||
#else
|
||||
Py_ssize_t pos = 0;
|
||||
#endif
|
||||
virTypedParameterPtr temp = NULL, ret = NULL;
|
||||
Py_ssize_t size;
|
||||
size_t i;
|
||||
|
||||
if ((size = PyDict_Size(info)) < 0)
|
||||
return NULL;
|
||||
|
||||
/* Libvirt APIs use NULL array and 0 size as a special case;
|
||||
* setting should have at least one parameter. */
|
||||
if (size == 0) {
|
||||
PyErr_Format(PyExc_LookupError, "Dictionary must not be empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC_N(ret, size) < 0) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
temp = &ret[0];
|
||||
while (PyDict_Next(info, &pos, &key, &value)) {
|
||||
char *keystr = NULL;
|
||||
|
||||
if (libvirt_charPtrUnwrap(key, &keystr) < 0 ||
|
||||
keystr == NULL)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < nparams; i++) {
|
||||
if (STREQ(params[i].field, keystr))
|
||||
break;
|
||||
}
|
||||
if (i == nparams) {
|
||||
PyErr_Format(PyExc_LookupError,
|
||||
"Attribute name \"%s\" could not be recognized",
|
||||
keystr);
|
||||
VIR_FREE(keystr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
strncpy(temp->field, keystr, VIR_TYPED_PARAM_FIELD_LENGTH - 1);
|
||||
temp->type = params[i].type;
|
||||
VIR_FREE(keystr);
|
||||
|
||||
switch (params[i].type) {
|
||||
case VIR_TYPED_PARAM_INT:
|
||||
if (libvirt_intUnwrap(value, &temp->value.i) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_UINT:
|
||||
if (libvirt_uintUnwrap(value, &temp->value.ui) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_LLONG:
|
||||
if (libvirt_longlongUnwrap(value, &temp->value.l) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_ULLONG:
|
||||
if (libvirt_ulonglongUnwrap(value, &temp->value.ul) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_DOUBLE:
|
||||
if (libvirt_doubleUnwrap(value, &temp->value.d) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_BOOLEAN:
|
||||
{
|
||||
bool b;
|
||||
if (libvirt_boolUnwrap(value, &b) < 0)
|
||||
goto cleanup;
|
||||
temp->value.b = b;
|
||||
break;
|
||||
}
|
||||
case VIR_TYPED_PARAM_STRING:
|
||||
{
|
||||
char *string_val;
|
||||
if (libvirt_charPtrUnwrap(value, &string_val) < 0 ||
|
||||
!string_val)
|
||||
goto cleanup;
|
||||
temp->value.s = string_val;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/* Possible if a newer server has a bug and sent stuff we
|
||||
* don't recognize. */
|
||||
PyErr_Format(PyExc_LookupError,
|
||||
"Type value \"%d\" not recognized",
|
||||
params[i].type);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
temp++;
|
||||
}
|
||||
return ret;
|
||||
|
||||
cleanup:
|
||||
virTypedParamsFree(ret, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* While these appeared in libvirt in 1.0.2, we only
|
||||
* need them in the python from 1.1.0 onwards */
|
||||
#if LIBVIR_CHECK_VERSION(1, 1, 0)
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int type;
|
||||
} virPyTypedParamsHint;
|
||||
typedef virPyTypedParamsHint *virPyTypedParamsHintPtr;
|
||||
|
||||
# if PY_MAJOR_VERSION > 2
|
||||
# define libvirt_PyString_Check PyUnicode_Check
|
||||
# else
|
||||
# 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
|
||||
* handling, use @hints to explicitly specify what types should be used for
|
||||
* specific parameters.
|
||||
*/
|
||||
static int
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
|
||||
virPyDictToTypedParams(PyObject *dict,
|
||||
virTypedParameterPtr *ret_params,
|
||||
int *ret_nparams,
|
||||
virPyTypedParamsHintPtr hints,
|
||||
int nhints)
|
||||
{
|
||||
PyObject *key;
|
||||
PyObject *value;
|
||||
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4
|
||||
int pos = 0;
|
||||
#else
|
||||
Py_ssize_t pos = 0;
|
||||
#endif
|
||||
virTypedParameterPtr params = NULL;
|
||||
int n = 0;
|
||||
int max = 0;
|
||||
int ret = -1;
|
||||
char *keystr = NULL;
|
||||
|
||||
*ret_params = NULL;
|
||||
*ret_nparams = 0;
|
||||
|
||||
if (PyDict_Size(dict) < 0)
|
||||
return -1;
|
||||
|
||||
while (PyDict_Next(dict, &pos, &key, &value)) {
|
||||
if (libvirt_charPtrUnwrap(key, &keystr) < 0 ||
|
||||
!keystr)
|
||||
goto cleanup;
|
||||
|
||||
if (PyList_Check(value) || PyTuple_Check(value)) {
|
||||
Py_ssize_t i, size = PySequence_Size(value);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
PyObject *v = PySequence_ITEM(value, i);
|
||||
if (virPyDictToTypedParamOne(¶ms, &n, &max,
|
||||
hints, nhints, keystr, v) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (virPyDictToTypedParamOne(¶ms, &n, &max,
|
||||
hints, nhints, keystr, value) < 0)
|
||||
goto cleanup;
|
||||
|
||||
VIR_FREE(keystr);
|
||||
}
|
||||
|
||||
*ret_params = params;
|
||||
*ret_nparams = n;
|
||||
params = NULL;
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(keystr);
|
||||
virTypedParamsFree(params, n);
|
||||
return ret;
|
||||
}
|
||||
#endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */
|
||||
|
||||
|
||||
/*
|
||||
* Utility function to retrieve the number of node CPUs present.
|
||||
|
||||
@@ -47,13 +47,6 @@ extern void initcygvirtmod_qemu(void);
|
||||
do {} while (0)
|
||||
#endif
|
||||
|
||||
/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;"
|
||||
is so common that we encapsulate it here. Now, each use is simply
|
||||
return VIR_PY_NONE; */
|
||||
#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None)
|
||||
#define VIR_PY_INT_FAIL (libvirt_intWrap(-1))
|
||||
#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0))
|
||||
|
||||
/*******************************************
|
||||
* Helper functions to avoid importing modules
|
||||
* for every callback
|
||||
|
||||
406
libvirt-utils.c
406
libvirt-utils.c
@@ -19,12 +19,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
/* Ugly python defines that, which is also defined in errno.h */
|
||||
#undef _POSIC_C_SOURCE
|
||||
|
||||
/* We want to see *_LAST enums. */
|
||||
#define VIR_ENUM_SENTINELS
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <libvirt/libvirt.h>
|
||||
#include "libvirt-utils.h"
|
||||
#include "typewrappers.h"
|
||||
|
||||
/**
|
||||
* virAlloc:
|
||||
@@ -184,3 +193,400 @@ virTypedParamsFree(virTypedParameterPtr params,
|
||||
VIR_FREE(params);
|
||||
}
|
||||
#endif /* ! LIBVIR_CHECK_VERSION(1, 0, 2) */
|
||||
|
||||
char *
|
||||
py_str(PyObject *obj)
|
||||
{
|
||||
PyObject *str = PyObject_Str(obj);
|
||||
char *ret;
|
||||
if (!str) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
return NULL;
|
||||
};
|
||||
libvirt_charPtrUnwrap(str, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Helper function to convert a virTypedParameter output array into a
|
||||
* Python dictionary for return to the user. Return NULL on failure,
|
||||
* after raising a python exception. */
|
||||
PyObject *
|
||||
getPyVirTypedParameter(const virTypedParameter *params,
|
||||
int nparams)
|
||||
{
|
||||
PyObject *key, *val, *info;
|
||||
size_t i;
|
||||
|
||||
if ((info = PyDict_New()) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < nparams; i++) {
|
||||
switch (params[i].type) {
|
||||
case VIR_TYPED_PARAM_INT:
|
||||
val = libvirt_intWrap(params[i].value.i);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_UINT:
|
||||
val = libvirt_intWrap(params[i].value.ui);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_LLONG:
|
||||
val = libvirt_longlongWrap(params[i].value.l);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_ULLONG:
|
||||
val = libvirt_ulonglongWrap(params[i].value.ul);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_DOUBLE:
|
||||
val = PyFloat_FromDouble(params[i].value.d);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_BOOLEAN:
|
||||
val = PyBool_FromLong(params[i].value.b);
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_STRING:
|
||||
val = libvirt_constcharPtrWrap(params[i].value.s);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Possible if a newer server has a bug and sent stuff we
|
||||
* don't recognize. */
|
||||
PyErr_Format(PyExc_LookupError,
|
||||
"Type value \"%d\" not recognized",
|
||||
params[i].type);
|
||||
val = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
key = libvirt_constcharPtrWrap(params[i].field);
|
||||
if (!key || !val)
|
||||
goto cleanup;
|
||||
|
||||
if (PyDict_SetItem(info, key, val) < 0) {
|
||||
Py_DECREF(info);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
Py_DECREF(key);
|
||||
Py_DECREF(val);
|
||||
}
|
||||
return info;
|
||||
|
||||
cleanup:
|
||||
Py_XDECREF(key);
|
||||
Py_XDECREF(val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate a new typed parameter array with the same contents and
|
||||
* length as info, and using the array params of length nparams as
|
||||
* hints on what types to use when creating the new array. The caller
|
||||
* must clear the array before freeing it. Return NULL on failure,
|
||||
* after raising a python exception. */
|
||||
virTypedParameterPtr
|
||||
setPyVirTypedParameter(PyObject *info,
|
||||
const virTypedParameter *params,
|
||||
int nparams)
|
||||
{
|
||||
PyObject *key, *value;
|
||||
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4
|
||||
int pos = 0;
|
||||
#else
|
||||
Py_ssize_t pos = 0;
|
||||
#endif
|
||||
virTypedParameterPtr temp = NULL, ret = NULL;
|
||||
Py_ssize_t size;
|
||||
size_t i;
|
||||
|
||||
if ((size = PyDict_Size(info)) < 0)
|
||||
return NULL;
|
||||
|
||||
/* Libvirt APIs use NULL array and 0 size as a special case;
|
||||
* setting should have at least one parameter. */
|
||||
if (size == 0) {
|
||||
PyErr_Format(PyExc_LookupError, "Dictionary must not be empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC_N(ret, size) < 0) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
temp = &ret[0];
|
||||
while (PyDict_Next(info, &pos, &key, &value)) {
|
||||
char *keystr = NULL;
|
||||
|
||||
if (libvirt_charPtrUnwrap(key, &keystr) < 0 ||
|
||||
keystr == NULL)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < nparams; i++) {
|
||||
if (STREQ(params[i].field, keystr))
|
||||
break;
|
||||
}
|
||||
if (i == nparams) {
|
||||
PyErr_Format(PyExc_LookupError,
|
||||
"Attribute name \"%s\" could not be recognized",
|
||||
keystr);
|
||||
VIR_FREE(keystr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
strncpy(temp->field, keystr, VIR_TYPED_PARAM_FIELD_LENGTH - 1);
|
||||
temp->type = params[i].type;
|
||||
VIR_FREE(keystr);
|
||||
|
||||
switch (params[i].type) {
|
||||
case VIR_TYPED_PARAM_INT:
|
||||
if (libvirt_intUnwrap(value, &temp->value.i) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_UINT:
|
||||
if (libvirt_uintUnwrap(value, &temp->value.ui) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_LLONG:
|
||||
if (libvirt_longlongUnwrap(value, &temp->value.l) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_ULLONG:
|
||||
if (libvirt_ulonglongUnwrap(value, &temp->value.ul) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_DOUBLE:
|
||||
if (libvirt_doubleUnwrap(value, &temp->value.d) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_TYPED_PARAM_BOOLEAN:
|
||||
{
|
||||
bool b;
|
||||
if (libvirt_boolUnwrap(value, &b) < 0)
|
||||
goto cleanup;
|
||||
temp->value.b = b;
|
||||
break;
|
||||
}
|
||||
case VIR_TYPED_PARAM_STRING:
|
||||
{
|
||||
char *string_val;
|
||||
if (libvirt_charPtrUnwrap(value, &string_val) < 0 ||
|
||||
!string_val)
|
||||
goto cleanup;
|
||||
temp->value.s = string_val;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/* Possible if a newer server has a bug and sent stuff we
|
||||
* don't recognize. */
|
||||
PyErr_Format(PyExc_LookupError,
|
||||
"Type value \"%d\" not recognized",
|
||||
params[i].type);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
temp++;
|
||||
}
|
||||
return ret;
|
||||
|
||||
cleanup:
|
||||
virTypedParamsFree(ret, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* While these appeared in libvirt in 1.0.2, we only
|
||||
* need them in the python from 1.1.0 onwards */
|
||||
#if LIBVIR_CHECK_VERSION(1, 1, 0)
|
||||
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
|
||||
* handling, use @hints to explicitly specify what types should be used for
|
||||
* specific parameters.
|
||||
*/
|
||||
int
|
||||
virPyDictToTypedParams(PyObject *dict,
|
||||
virTypedParameterPtr *ret_params,
|
||||
int *ret_nparams,
|
||||
virPyTypedParamsHintPtr hints,
|
||||
int nhints)
|
||||
{
|
||||
PyObject *key;
|
||||
PyObject *value;
|
||||
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4
|
||||
int pos = 0;
|
||||
#else
|
||||
Py_ssize_t pos = 0;
|
||||
#endif
|
||||
virTypedParameterPtr params = NULL;
|
||||
int n = 0;
|
||||
int max = 0;
|
||||
int ret = -1;
|
||||
char *keystr = NULL;
|
||||
|
||||
*ret_params = NULL;
|
||||
*ret_nparams = 0;
|
||||
|
||||
if (PyDict_Size(dict) < 0)
|
||||
return -1;
|
||||
|
||||
while (PyDict_Next(dict, &pos, &key, &value)) {
|
||||
if (libvirt_charPtrUnwrap(key, &keystr) < 0 ||
|
||||
!keystr)
|
||||
goto cleanup;
|
||||
|
||||
if (PyList_Check(value) || PyTuple_Check(value)) {
|
||||
Py_ssize_t i, size = PySequence_Size(value);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
PyObject *v = PySequence_ITEM(value, i);
|
||||
if (virPyDictToTypedParamOne(¶ms, &n, &max,
|
||||
hints, nhints, keystr, v) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (virPyDictToTypedParamOne(¶ms, &n, &max,
|
||||
hints, nhints, keystr, value) < 0)
|
||||
goto cleanup;
|
||||
|
||||
VIR_FREE(keystr);
|
||||
}
|
||||
|
||||
*ret_params = params;
|
||||
*ret_nparams = n;
|
||||
params = NULL;
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(keystr);
|
||||
virTypedParamsFree(params, n);
|
||||
return ret;
|
||||
}
|
||||
#endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#ifndef __LIBVIRT_UTILS_H__
|
||||
# define __LIBVIRT_UTILS_H__
|
||||
|
||||
# include <Python.h>
|
||||
# include <libvirt/libvirt.h>
|
||||
|
||||
# define STREQ(a,b) (strcmp(a,b) == 0)
|
||||
|
||||
# ifndef MIN
|
||||
@@ -135,6 +138,22 @@ int virReallocN(void *ptrptr, size_t size, size_t count)
|
||||
ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
|
||||
void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
|
||||
|
||||
|
||||
# if PY_MAJOR_VERSION > 2
|
||||
# define libvirt_PyString_Check PyUnicode_Check
|
||||
# else
|
||||
# define libvirt_PyString_Check PyString_Check
|
||||
# endif
|
||||
|
||||
|
||||
/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;"
|
||||
is so common that we encapsulate it here. Now, each use is simply
|
||||
return VIR_PY_NONE; */
|
||||
#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None)
|
||||
#define VIR_PY_INT_FAIL (libvirt_intWrap(-1))
|
||||
#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0))
|
||||
|
||||
|
||||
/**
|
||||
* VIR_ALLOC:
|
||||
* @ptr: pointer to hold address of allocated memory
|
||||
@@ -216,4 +235,36 @@ void virTypedParamsClear(virTypedParameterPtr params, int nparams);
|
||||
void virTypedParamsFree(virTypedParameterPtr params, int nparams);
|
||||
# endif /* ! LIBVIR_CHECK_VERSION(1, 0, 2) */
|
||||
|
||||
char * py_str(PyObject *obj);
|
||||
PyObject * getPyVirTypedParameter(const virTypedParameter *params,
|
||||
int nparams);
|
||||
virTypedParameterPtr setPyVirTypedParameter(PyObject *info,
|
||||
const virTypedParameter *params,
|
||||
int nparams)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
|
||||
|
||||
# if LIBVIR_CHECK_VERSION(1, 1, 0)
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int type;
|
||||
} virPyTypedParamsHint;
|
||||
typedef virPyTypedParamsHint *virPyTypedParamsHintPtr;
|
||||
|
||||
|
||||
int virPyDictToTypedPramaOne(virTypedParameterPtr *params,
|
||||
int *n,
|
||||
int *max,
|
||||
virPyTypedParamsHintPtr hints,
|
||||
int nhints,
|
||||
const char *keystr,
|
||||
PyObject *value);
|
||||
int virPyDictToTypedParams(PyObject *dict,
|
||||
virTypedParameterPtr *ret_params,
|
||||
int *ret_nparams,
|
||||
virPyTypedParamsHintPtr hints,
|
||||
int nhints)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
||||
# endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */
|
||||
|
||||
#endif /* __LIBVIRT_UTILS_H__ */
|
||||
|
||||
Reference in New Issue
Block a user