From: Eduardo Habkost <ehabkost@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
"Daniel P. Berrangé" <berrange@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Eduardo Habkost" <ehabkost@redhat.com>
Subject: [PATCH 3/8] qnum: QNumValue type for QNum value literals
Date: Mon, 9 Nov 2020 16:25:51 -0500 [thread overview]
Message-ID: <20201109212556.3934583-4-ehabkost@redhat.com> (raw)
In-Reply-To: <20201109212556.3934583-1-ehabkost@redhat.com>
Provide a separate QNumValue type that can be used for QNum value
literals without the referencing counting and memory allocation
features provided by QObject.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
include/qapi/qmp/qnum.h | 40 +++++++++++++++++++--
qobject/qnum.c | 78 ++++++++++++++++++++---------------------
2 files changed, 77 insertions(+), 41 deletions(-)
diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index 55c27b1c24..62fbdfda68 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -46,20 +46,56 @@ typedef enum {
* in range: qnum_get_try_int() / qnum_get_try_uint() check range and
* convert under the hood.
*/
-struct QNum {
- struct QObjectBase_ base;
+
+/**
+ * struct QNumValue: the value of a QNum
+ *
+ * QNumValue literals can be constructed using the `QNUM_VAL_INT`,
+ * `QNUM_VAL_UINT`, and `QNUM_VAL_DOUBLE` macros.
+ */
+typedef struct QNumValue {
+ /* private: */
QNumKind kind;
union {
int64_t i64;
uint64_t u64;
double dbl;
} u;
+} QNumValue;
+
+#define QNUM_VAL_INT(value) \
+ { .kind = QNUM_I64, .u.i64 = value }
+#define QNUM_VAL_UINT(value) \
+ { .kind = QNUM_U64, .u.u64 = value }
+#define QNUM_VAL_DOUBLE(value) \
+ { .kind = QNUM_DOUBLE, .u.dbl = value }
+
+struct QNum {
+ struct QObjectBase_ base;
+ QNumValue value;
};
+/**
+ * qnum_from_int(): Create a new QNum from a QNumValue
+ * @value: QNumValue
+ *
+ * Return strong reference.
+ */
+QNum *qnum_from_value(QNumValue value);
+
QNum *qnum_from_int(int64_t value);
QNum *qnum_from_uint(uint64_t value);
QNum *qnum_from_double(double value);
+/**
+ * qnum_get_value(): Get QNumValue from QNum
+ * @qn: QNum object
+ */
+static inline const QNumValue *qnum_get_value(const QNum *qn)
+{
+ return &qn->value;
+}
+
bool qnum_get_try_int(const QNum *qn, int64_t *val);
int64_t qnum_get_int(const QNum *qn);
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 69fd9a82d9..f80d4efd76 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -15,6 +15,15 @@
#include "qemu/osdep.h"
#include "qapi/qmp/qnum.h"
+QNum *qnum_from_value(QNumValue value)
+{
+ QNum *qn = g_new(QNum, 1);
+
+ qobject_init(QOBJECT(qn), QTYPE_QNUM);
+ qn->value = value;
+ return qn;
+}
+
/**
* qnum_from_int(): Create a new QNum from an int64_t
* @value: int64_t value
@@ -23,13 +32,7 @@
*/
QNum *qnum_from_int(int64_t value)
{
- QNum *qn = g_new(QNum, 1);
-
- qobject_init(QOBJECT(qn), QTYPE_QNUM);
- qn->kind = QNUM_I64;
- qn->u.i64 = value;
-
- return qn;
+ return qnum_from_value((QNumValue) QNUM_VAL_INT(value));
}
/**
@@ -40,13 +43,7 @@ QNum *qnum_from_int(int64_t value)
*/
QNum *qnum_from_uint(uint64_t value)
{
- QNum *qn = g_new(QNum, 1);
-
- qobject_init(QOBJECT(qn), QTYPE_QNUM);
- qn->kind = QNUM_U64;
- qn->u.u64 = value;
-
- return qn;
+ return qnum_from_value((QNumValue) QNUM_VAL_UINT(value));
}
/**
@@ -57,13 +54,7 @@ QNum *qnum_from_uint(uint64_t value)
*/
QNum *qnum_from_double(double value)
{
- QNum *qn = g_new(QNum, 1);
-
- qobject_init(QOBJECT(qn), QTYPE_QNUM);
- qn->kind = QNUM_DOUBLE;
- qn->u.dbl = value;
-
- return qn;
+ return qnum_from_value((QNumValue) QNUM_VAL_DOUBLE(value));
}
/**
@@ -75,15 +66,17 @@ QNum *qnum_from_double(double value)
*/
bool qnum_get_try_int(const QNum *qn, int64_t *val)
{
- switch (qn->kind) {
+ const QNumValue *qv = &qn->value;
+
+ switch (qv->kind) {
case QNUM_I64:
- *val = qn->u.i64;
+ *val = qv->u.i64;
return true;
case QNUM_U64:
- if (qn->u.u64 > INT64_MAX) {
+ if (qv->u.u64 > INT64_MAX) {
return false;
}
- *val = qn->u.u64;
+ *val = qv->u.u64;
return true;
case QNUM_DOUBLE:
return false;
@@ -116,15 +109,17 @@ int64_t qnum_get_int(const QNum *qn)
*/
bool qnum_get_try_uint(const QNum *qn, uint64_t *val)
{
- switch (qn->kind) {
+ const QNumValue *qv = &qn->value;
+
+ switch (qv->kind) {
case QNUM_I64:
- if (qn->u.i64 < 0) {
+ if (qv->u.i64 < 0) {
return false;
}
- *val = qn->u.i64;
+ *val = qv->u.i64;
return true;
case QNUM_U64:
- *val = qn->u.u64;
+ *val = qv->u.u64;
return true;
case QNUM_DOUBLE:
return false;
@@ -156,13 +151,15 @@ uint64_t qnum_get_uint(const QNum *qn)
*/
double qnum_get_double(const QNum *qn)
{
- switch (qn->kind) {
+ const QNumValue *qv = &qn->value;
+
+ switch (qv->kind) {
case QNUM_I64:
- return qn->u.i64;
+ return qv->u.i64;
case QNUM_U64:
- return qn->u.u64;
+ return qv->u.u64;
case QNUM_DOUBLE:
- return qn->u.dbl;
+ return qv->u.dbl;
}
assert(0);
@@ -171,14 +168,15 @@ double qnum_get_double(const QNum *qn)
char *qnum_to_string(QNum *qn)
{
+ const QNumValue *qv = &qn->value;
char *buffer;
int len;
- switch (qn->kind) {
+ switch (qv->kind) {
case QNUM_I64:
- return g_strdup_printf("%" PRId64, qn->u.i64);
+ return g_strdup_printf("%" PRId64, qv->u.i64);
case QNUM_U64:
- return g_strdup_printf("%" PRIu64, qn->u.u64);
+ return g_strdup_printf("%" PRIu64, qv->u.u64);
case QNUM_DOUBLE:
/* FIXME: snprintf() is locale dependent; but JSON requires
* numbers to be formatted as if in the C locale. Dependence
@@ -189,7 +187,7 @@ char *qnum_to_string(QNum *qn)
* rounding errors; we should be using DBL_DECIMAL_DIG (17),
* and only rounding to a shorter number if the result would
* still produce the same floating point value. */
- buffer = g_strdup_printf("%f" , qn->u.dbl);
+ buffer = g_strdup_printf("%f" , qv->u.dbl);
len = strlen(buffer);
while (len > 0 && buffer[len - 1] == '0') {
len--;
@@ -221,8 +219,10 @@ char *qnum_to_string(QNum *qn)
*/
bool qnum_is_equal(const QObject *x, const QObject *y)
{
- QNum *num_x = qobject_to(QNum, x);
- QNum *num_y = qobject_to(QNum, y);
+ const QNum *qnum_x = qobject_to(QNum, x);
+ const QNum *qnum_y = qobject_to(QNum, y);
+ const QNumValue *num_x = &qnum_x->value;
+ const QNumValue *num_y = &qnum_y->value;
switch (num_x->kind) {
case QNUM_I64:
--
2.28.0
next prev parent reply other threads:[~2020-11-09 21:27 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
2020-11-09 21:25 ` [PATCH 1/8] qobject: Include API docs in docs/devel/qobject.html Eduardo Habkost
2020-11-09 21:25 ` [PATCH 2/8] qnum: Make qnum_get_double() get const pointer Eduardo Habkost
2020-11-09 21:25 ` Eduardo Habkost [this message]
2020-11-09 21:25 ` [PATCH 4/8] qnum: qnum_value_is_equal() function Eduardo Habkost
2020-11-09 21:25 ` [PATCH 5/8] qlit: Support all types of QNums Eduardo Habkost
2020-11-09 21:25 ` [PATCH 6/8] qlit: qlit_type() function Eduardo Habkost
2020-11-09 21:25 ` [PATCH 7/8] qom: Make object_property_set_default() public Eduardo Habkost
2020-11-09 21:25 ` [PATCH 8/8] qom: Use qlit to represent property defaults Eduardo Habkost
2020-11-09 21:39 ` [PATCH 0/8] " no-reply
2020-11-10 16:39 ` Paolo Bonzini
2020-11-10 18:16 ` Eduardo Habkost
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201109212556.3934583-4-ehabkost@redhat.com \
--to=ehabkost@redhat.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).