Patchwork [45/50] qemu-option: Functions to convert to/from QDict

login
register
mail settings
Submitter Markus Armbruster
Date March 4, 2010, 3:57 p.m.
Message ID <1267718231-13303-46-git-send-email-armbru@redhat.com>
Download mbox | patch
Permalink /patch/46942/
State New
Headers show

Comments

Markus Armbruster - March 4, 2010, 3:57 p.m.
The functions are somewhat restricted.  Good enough for the job at
hand.  We'll extend them when we need more.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qemu-option.c |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-option.h |    3 ++
 2 files changed, 82 insertions(+), 0 deletions(-)
Luiz Capitulino - March 4, 2010, 8:55 p.m.
On Thu,  4 Mar 2010 16:57:06 +0100
Markus Armbruster <armbru@redhat.com> wrote:

> The functions are somewhat restricted.  Good enough for the job at
> hand.  We'll extend them when we need more.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  qemu-option.c |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  qemu-option.h |    3 ++
>  2 files changed, 82 insertions(+), 0 deletions(-)
> 
> diff --git a/qemu-option.c b/qemu-option.c
> index ab488e4..24bb19b 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -28,6 +28,7 @@
>  
>  #include "qemu-common.h"
>  #include "qemu-error.h"
> +#include "qemu-objects.h"
>  #include "qemu-option.h"
>  
>  /*
> @@ -777,6 +778,84 @@ QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *fi
>      return opts;
>  }
>  
> +static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
> +{
> +    char buf[32];
> +    const char *value;
> +    int n;
> +
> +    if (!strcmp(key, "id")) {
> +        return;
> +    }
> +
> +    switch (qobject_type(obj)) {
> +    case QTYPE_QSTRING:
> +        value = qstring_get_str(qobject_to_qstring(obj));
> +        break;
> +    case QTYPE_QINT:
> +        n = snprintf(buf, sizeof(buf), "%" PRId64,
> +                     qint_get_int(qobject_to_qint(obj)));
> +        assert(n < sizeof(buf));
> +        value = buf;
> +        break;
> +    case QTYPE_QFLOAT:
> +        n = snprintf(buf, sizeof(buf), "%.17g",
> +                     qfloat_get_double(qobject_to_qfloat(obj)));
> +        assert(n < sizeof(buf));
> +        value = buf;
> +        break;
> +    case QTYPE_QBOOL:
> +        strcpy(buf, qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
> +        value = buf;
> +        break;
> +    default:
> +        return;
> +    }
> +    qemu_opt_set(opaque, key, value);
> +}
> +
> +/*
> + * Create QemuOpts from a QDict.
> + * Use value of key "id" as ID if it exists and is a QString.
> + * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
> + * other types are silently ignored.
> + */
> +QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict)
> +{
> +    QemuOpts *opts;
> +
> +    opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1);
> +    if (opts == NULL)
> +        return NULL;
> +
> +    qdict_iter(qdict, qemu_opts_from_qdict_1, opts);
> +    return opts;
> +}
> +
> +/*
> + * Convert from QemuOpts to QDict.
> + * The QDict values are of type QString.
> + * TODO We'll want to use types appropriate for opt->desc->type, but
> + * this is enough for now.
> + */
> +QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
> +{
> +    QemuOpt *opt;
> +    QObject *val;
> +
> +    if (!qdict) {
> +        qdict = qdict_new();
> +    }
> +    if (opts->id) {
> +        qdict_put(qdict, "id", qstring_from_str(opts->id));
> +    }
> +    QTAILQ_FOREACH(opt, &opts->head, next) {
> +        val = QOBJECT(qstring_from_str(opt->str));
> +        qdict_put_obj(qdict, opt->name, val);
> +    }

 Why not just do:

qdict_put(qdict, opt->name, qstring_from_str(opt->str));

> +    return qdict;
> +}
> +
>  /* Validate parsed opts against descriptions where no
>   * descriptions were provided in the QemuOptsList.
>   */
> diff --git a/qemu-option.h b/qemu-option.h
> index f3f1de7..d735386 100644
> --- a/qemu-option.h
> +++ b/qemu-option.h
> @@ -28,6 +28,7 @@
>  
>  #include <stdint.h>
>  #include "qemu-queue.h"
> +#include "qdict.h"
>  
>  enum QEMUOptionParType {
>      OPT_FLAG,
> @@ -118,6 +119,8 @@ void qemu_opts_del(QemuOpts *opts);
>  int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc);
>  int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
>  QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname);
> +QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict);
> +QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
>  
>  typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
>  int qemu_opts_print(QemuOpts *opts, void *dummy);
Markus Armbruster - March 4, 2010, 9:12 p.m.
Luiz Capitulino <lcapitulino@redhat.com> writes:

> On Thu,  4 Mar 2010 16:57:06 +0100
> Markus Armbruster <armbru@redhat.com> wrote:
>
>> The functions are somewhat restricted.  Good enough for the job at
>> hand.  We'll extend them when we need more.
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  qemu-option.c |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  qemu-option.h |    3 ++
>>  2 files changed, 82 insertions(+), 0 deletions(-)
>> 
>> diff --git a/qemu-option.c b/qemu-option.c
>> index ab488e4..24bb19b 100644
>> --- a/qemu-option.c
>> +++ b/qemu-option.c
[...]
>> +/*
>> + * Convert from QemuOpts to QDict.
>> + * The QDict values are of type QString.
>> + * TODO We'll want to use types appropriate for opt->desc->type, but
>> + * this is enough for now.
>> + */
>> +QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
>> +{
>> +    QemuOpt *opt;
>> +    QObject *val;
>> +
>> +    if (!qdict) {
>> +        qdict = qdict_new();
>> +    }
>> +    if (opts->id) {
>> +        qdict_put(qdict, "id", qstring_from_str(opts->id));
>> +    }
>> +    QTAILQ_FOREACH(opt, &opts->head, next) {
>> +        val = QOBJECT(qstring_from_str(opt->str));
>> +        qdict_put_obj(qdict, opt->name, val);
>> +    }
>
>  Why not just do:
>
> qdict_put(qdict, opt->name, qstring_from_str(opt->str));

I got a version without the TODO.  Looks like this:

    QTAILQ_FOREACH(opt, &opts->head, next) {
        switch (opt->desc ? opt->desc->type : QEMU_OPT_STRING) {
        case QEMU_OPT_BOOL:
            val = QOBJECT(qbool_from_int(opt->value.boolean));
            break;
        case QEMU_OPT_NUMBER:
        case QEMU_OPT_SIZE:
            // FIXME opts only uint64_t, qint only int64_t
            val = QOBJECT(qint_from_int(opt->value.uint));
            break;
        default:
            val = QOBJECT(qstring_from_str(opt->str));
            break;
        }
        qdict_put_obj(qdict, opt->name, val);
    }

I dumbed it down to keep this series as simple as possible, and missed
the simplification opportunity.  Okay to leave it as is?

[...]
Luiz Capitulino - March 4, 2010, 9:17 p.m.
On Thu, 04 Mar 2010 22:12:01 +0100
Markus Armbruster <armbru@redhat.com> wrote:

> Luiz Capitulino <lcapitulino@redhat.com> writes:
> 
> > On Thu,  4 Mar 2010 16:57:06 +0100
> > Markus Armbruster <armbru@redhat.com> wrote:
> >
> >> The functions are somewhat restricted.  Good enough for the job at
> >> hand.  We'll extend them when we need more.
> >> 
> >> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> >> ---
> >>  qemu-option.c |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  qemu-option.h |    3 ++
> >>  2 files changed, 82 insertions(+), 0 deletions(-)
> >> 
> >> diff --git a/qemu-option.c b/qemu-option.c
> >> index ab488e4..24bb19b 100644
> >> --- a/qemu-option.c
> >> +++ b/qemu-option.c
> [...]
> >> +/*
> >> + * Convert from QemuOpts to QDict.
> >> + * The QDict values are of type QString.
> >> + * TODO We'll want to use types appropriate for opt->desc->type, but
> >> + * this is enough for now.
> >> + */
> >> +QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
> >> +{
> >> +    QemuOpt *opt;
> >> +    QObject *val;
> >> +
> >> +    if (!qdict) {
> >> +        qdict = qdict_new();
> >> +    }
> >> +    if (opts->id) {
> >> +        qdict_put(qdict, "id", qstring_from_str(opts->id));
> >> +    }
> >> +    QTAILQ_FOREACH(opt, &opts->head, next) {
> >> +        val = QOBJECT(qstring_from_str(opt->str));
> >> +        qdict_put_obj(qdict, opt->name, val);
> >> +    }
> >
> >  Why not just do:
> >
> > qdict_put(qdict, opt->name, qstring_from_str(opt->str));
> 
> I got a version without the TODO.  Looks like this:
> 
>     QTAILQ_FOREACH(opt, &opts->head, next) {
>         switch (opt->desc ? opt->desc->type : QEMU_OPT_STRING) {
>         case QEMU_OPT_BOOL:
>             val = QOBJECT(qbool_from_int(opt->value.boolean));
>             break;
>         case QEMU_OPT_NUMBER:
>         case QEMU_OPT_SIZE:
>             // FIXME opts only uint64_t, qint only int64_t
>             val = QOBJECT(qint_from_int(opt->value.uint));
>             break;
>         default:
>             val = QOBJECT(qstring_from_str(opt->str));
>             break;
>         }
>         qdict_put_obj(qdict, opt->name, val);
>     }
> 
> I dumbed it down to keep this series as simple as possible, and missed
> the simplification opportunity.  Okay to leave it as is?

 Yes, although it's worth changing in case you resend the series with
other modifications (assuming you'll cleanup soon, of course).

Patch

diff --git a/qemu-option.c b/qemu-option.c
index ab488e4..24bb19b 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -28,6 +28,7 @@ 
 
 #include "qemu-common.h"
 #include "qemu-error.h"
+#include "qemu-objects.h"
 #include "qemu-option.h"
 
 /*
@@ -777,6 +778,84 @@  QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *fi
     return opts;
 }
 
+static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
+{
+    char buf[32];
+    const char *value;
+    int n;
+
+    if (!strcmp(key, "id")) {
+        return;
+    }
+
+    switch (qobject_type(obj)) {
+    case QTYPE_QSTRING:
+        value = qstring_get_str(qobject_to_qstring(obj));
+        break;
+    case QTYPE_QINT:
+        n = snprintf(buf, sizeof(buf), "%" PRId64,
+                     qint_get_int(qobject_to_qint(obj)));
+        assert(n < sizeof(buf));
+        value = buf;
+        break;
+    case QTYPE_QFLOAT:
+        n = snprintf(buf, sizeof(buf), "%.17g",
+                     qfloat_get_double(qobject_to_qfloat(obj)));
+        assert(n < sizeof(buf));
+        value = buf;
+        break;
+    case QTYPE_QBOOL:
+        strcpy(buf, qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
+        value = buf;
+        break;
+    default:
+        return;
+    }
+    qemu_opt_set(opaque, key, value);
+}
+
+/*
+ * Create QemuOpts from a QDict.
+ * Use value of key "id" as ID if it exists and is a QString.
+ * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
+ * other types are silently ignored.
+ */
+QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict)
+{
+    QemuOpts *opts;
+
+    opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1);
+    if (opts == NULL)
+        return NULL;
+
+    qdict_iter(qdict, qemu_opts_from_qdict_1, opts);
+    return opts;
+}
+
+/*
+ * Convert from QemuOpts to QDict.
+ * The QDict values are of type QString.
+ * TODO We'll want to use types appropriate for opt->desc->type, but
+ * this is enough for now.
+ */
+QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
+{
+    QemuOpt *opt;
+    QObject *val;
+
+    if (!qdict) {
+        qdict = qdict_new();
+    }
+    if (opts->id) {
+        qdict_put(qdict, "id", qstring_from_str(opts->id));
+    }
+    QTAILQ_FOREACH(opt, &opts->head, next) {
+        val = QOBJECT(qstring_from_str(opt->str));
+        qdict_put_obj(qdict, opt->name, val);
+    }
+    return qdict;
+}
+
 /* Validate parsed opts against descriptions where no
  * descriptions were provided in the QemuOptsList.
  */
diff --git a/qemu-option.h b/qemu-option.h
index f3f1de7..d735386 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -28,6 +28,7 @@ 
 
 #include <stdint.h>
 #include "qemu-queue.h"
+#include "qdict.h"
 
 enum QEMUOptionParType {
     OPT_FLAG,
@@ -118,6 +119,8 @@  void qemu_opts_del(QemuOpts *opts);
 int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc);
 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname);
+QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict);
+QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
 
 typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
 int qemu_opts_print(QemuOpts *opts, void *dummy);