From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Subject: [Qemu-devel] [PULL 09/41] qnum: add uint type
Date: Fri, 9 Jun 2017 15:46:53 +0200 [thread overview]
Message-ID: <1497016045-6009-10-git-send-email-armbru@redhat.com> (raw)
In-Reply-To: <1497016045-6009-1-git-send-email-armbru@redhat.com>
From: Marc-André Lureau <marcandre.lureau@redhat.com>
In order to store integer values between INT64_MAX and UINT64_MAX, add
a uint64_t internal representation.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20170607163635.17635-10-marcandre.lureau@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
include/qapi/qmp/qnum.h | 7 ++++++
qobject/qnum.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
tests/check-qnum.c | 48 +++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+)
diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index e42b136..09d745c 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -19,6 +19,7 @@
typedef enum {
QNUM_I64,
+ QNUM_U64,
QNUM_DOUBLE
} QNumKind;
@@ -27,15 +28,21 @@ typedef struct QNum {
QNumKind kind;
union {
int64_t i64;
+ uint64_t u64;
double dbl;
} u;
} QNum;
QNum *qnum_from_int(int64_t value);
+QNum *qnum_from_uint(uint64_t value);
QNum *qnum_from_double(double value);
bool qnum_get_try_int(const QNum *qn, int64_t *val);
int64_t qnum_get_int(const QNum *qn);
+
+bool qnum_get_try_uint(const QNum *qn, uint64_t *val);
+uint64_t qnum_get_uint(const QNum *qn);
+
double qnum_get_double(QNum *qn);
char *qnum_to_string(QNum *qn);
diff --git a/qobject/qnum.c b/qobject/qnum.c
index d88e4f7..52918ac 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -35,6 +35,22 @@ QNum *qnum_from_int(int64_t value)
}
/**
+ * qnum_from_uint(): Create a new QNum from an uint64_t
+ *
+ * Return strong reference.
+ */
+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;
+}
+
+/**
* qnum_from_double(): Create a new QNum from a double
*
* Return strong reference.
@@ -61,6 +77,12 @@ bool qnum_get_try_int(const QNum *qn, int64_t *val)
case QNUM_I64:
*val = qn->u.i64;
return true;
+ case QNUM_U64:
+ if (qn->u.u64 > INT64_MAX) {
+ return false;
+ }
+ *val = qn->u.u64;
+ return true;
case QNUM_DOUBLE:
return false;
}
@@ -83,6 +105,44 @@ int64_t qnum_get_int(const QNum *qn)
}
/**
+ * qnum_get_uint(): Get an unsigned integer from the number
+ *
+ * Return true on success.
+ */
+bool qnum_get_try_uint(const QNum *qn, uint64_t *val)
+{
+ switch (qn->kind) {
+ case QNUM_I64:
+ if (qn->u.i64 < 0) {
+ return false;
+ }
+ *val = qn->u.i64;
+ return true;
+ case QNUM_U64:
+ *val = qn->u.u64;
+ return true;
+ case QNUM_DOUBLE:
+ return false;
+ }
+
+ assert(0);
+ return false;
+}
+
+/**
+ * qnum_get_uint(): Get an unsigned integer from the number
+ *
+ * assert() on failure.
+ */
+uint64_t qnum_get_uint(const QNum *qn)
+{
+ uint64_t val;
+ bool success = qnum_get_try_uint(qn, &val);
+ assert(success);
+ return val;
+}
+
+/**
* qnum_get_double(): Get a float representation of the number
*
* qnum_get_double() loses precision for integers beyond 53 bits.
@@ -92,6 +152,8 @@ double qnum_get_double(QNum *qn)
switch (qn->kind) {
case QNUM_I64:
return qn->u.i64;
+ case QNUM_U64:
+ return qn->u.u64;
case QNUM_DOUBLE:
return qn->u.dbl;
}
@@ -107,6 +169,8 @@ char *qnum_to_string(QNum *qn)
switch (qn->kind) {
case QNUM_I64:
return g_strdup_printf("%" PRId64, qn->u.i64);
+ case QNUM_U64:
+ return g_strdup_printf("%" PRIu64, qn->u.u64);
case QNUM_DOUBLE:
/* FIXME: snprintf() is locale dependent; but JSON requires
* numbers to be formatted as if in the C locale. Dependence
diff --git a/tests/check-qnum.c b/tests/check-qnum.c
index da7e0b0..d702d5d 100644
--- a/tests/check-qnum.c
+++ b/tests/check-qnum.c
@@ -39,6 +39,21 @@ static void qnum_from_int_test(void)
QDECREF(qn);
}
+static void qnum_from_uint_test(void)
+{
+ QNum *qn;
+ const uint64_t value = UINT64_MAX;
+
+ qn = qnum_from_uint(value);
+ g_assert(qn != NULL);
+ g_assert_cmpint(qn->kind, ==, QNUM_U64);
+ g_assert(qn->u.u64 == value);
+ g_assert(qn->base.refcnt == 1);
+ g_assert(qobject_type(QOBJECT(qn)) == QTYPE_QNUM);
+
+ QDECREF(qn);
+}
+
static void qnum_from_double_test(void)
{
QNum *qn;
@@ -76,6 +91,37 @@ static void qnum_get_int_test(void)
QDECREF(qn);
}
+static void qnum_get_uint_test(void)
+{
+ QNum *qn;
+ const int value = 123456;
+ uint64_t val;
+ int64_t ival;
+
+ qn = qnum_from_uint(value);
+ g_assert(qnum_get_try_uint(qn, &val));
+ g_assert_cmpuint(val, ==, value);
+ QDECREF(qn);
+
+ qn = qnum_from_int(value);
+ g_assert(qnum_get_try_uint(qn, &val));
+ g_assert_cmpuint(val, ==, value);
+ QDECREF(qn);
+
+ /* invalid cases */
+ qn = qnum_from_int(-1);
+ g_assert(!qnum_get_try_uint(qn, &val));
+ QDECREF(qn);
+
+ qn = qnum_from_uint(-1ULL);
+ g_assert(!qnum_get_try_int(qn, &ival));
+ QDECREF(qn);
+
+ qn = qnum_from_double(0.42);
+ g_assert(!qnum_get_try_uint(qn, &val));
+ QDECREF(qn);
+}
+
static void qobject_to_qnum_test(void)
{
QNum *qn;
@@ -112,9 +158,11 @@ int main(int argc, char **argv)
g_test_init(&argc, &argv, NULL);
g_test_add_func("/qnum/from_int", qnum_from_int_test);
+ g_test_add_func("/qnum/from_uint", qnum_from_uint_test);
g_test_add_func("/qnum/from_double", qnum_from_double_test);
g_test_add_func("/qnum/from_int64", qnum_from_int64_test);
g_test_add_func("/qnum/get_int", qnum_get_int_test);
+ g_test_add_func("/qnum/get_uint", qnum_get_uint_test);
g_test_add_func("/qnum/to_qnum", qobject_to_qnum_test);
g_test_add_func("/qnum/to_string", qnum_to_string_test);
--
2.7.5
next prev parent reply other threads:[~2017-06-09 13:47 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-09 13:46 [Qemu-devel] [PULL 00/41] QAPI patches for 2017-06-09 Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 01/41] qdev: remove PropertyInfo.qtype field Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 02/41] object: fix potential leak in getters Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 03/41] tests: Remove test cases for alternates of 'number' and 'int' Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 04/41] tests: add more int/number ranges checks Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 05/41] qapi: Clean up qobject_input_type_number() control flow Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 06/41] qapi: merge QInt and QFloat in QNum Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 07/41] qapi: Remove visit_start_alternate() parameter promote_int Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 08/41] tests: remove /{qnum, qlist, dict}/destroy test Markus Armbruster
2017-06-09 13:46 ` Markus Armbruster [this message]
2017-06-09 13:46 ` [Qemu-devel] [PULL 10/41] json: learn to parse uint64 numbers Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 11/41] qapi: update the qobject visitor to use QNUM_U64 Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 12/41] object: add uint property setter/getter Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 13/41] q35: fix get_mmcfg_size to use uint64 visitor Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 14/41] object: use more specific property type names Markus Armbruster
2017-06-09 13:46 ` [Qemu-devel] [PULL 15/41] qdev: Rename DEFINE_PROP_DEFAULT() to DEFINE_PROP_SIGNED() Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 16/41] qdev: wrap default property value in an union Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 17/41] qdev: avoid type casts between signed and unsigned Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 18/41] apic-common: make "id" property a uint32 Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 19/41] qdev: Use appropriate getter/setters type Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 20/41] isa: use get_uint() for "io-base" Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 21/41] pc-dimm: use get_uint() for dimm properties Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 22/41] pc-dimm: make "size" property uint64 Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 23/41] pcihp: use get_uint() for "bsel" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 24/41] aspeed: use {set, get}_uint() for "ram-size" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 25/41] bcm2835_fb: use {get, set}_uint() for "vcram-size" and "vcram-base" Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 26/41] platform-bus: use get_uint() for "addr" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 27/41] acpi: use get_uint() for "acpi-pcihp-io*" properties Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 28/41] acpi: use get_uint() for various acpi properties Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 29/41] acpi: use get_uint() for "pci-hole*" properties Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 30/41] pc: use get_uint() for "iobase" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 31/41] pc: use get_uint() for "apic-id" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 32/41] pc: use get_uint() for "hpet-intcap" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 33/41] xen: use get_uint() for "max-ram-below-4g" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 34/41] arm: use get_uint() for "mp-affinity" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 35/41] auxbus: use get_uint() for "addr" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 36/41] pvpanic: use get_uint() for "ioport" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 37/41] pnv-core: use get_uint() for "core-pir" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 38/41] numa: use get_uint() for "size" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 39/41] i386/cpu: use get_uint() for "min-level"/"min-xlevel" properties Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 40/41] console: use get_uint() for "head" property Markus Armbruster
2017-06-09 13:47 ` [Qemu-devel] [PULL 41/41] tests/qdict: check more get_try_int() cases Markus Armbruster
2017-06-09 15:05 ` [Qemu-devel] [PULL 00/41] QAPI patches for 2017-06-09 no-reply
2017-06-09 15:38 ` no-reply
2017-06-12 10:39 ` Peter Maydell
2017-06-12 10:52 ` Marc-André Lureau
2017-06-12 11:50 ` Peter Maydell
2017-06-20 11:59 ` Markus Armbruster
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=1497016045-6009-10-git-send-email-armbru@redhat.com \
--to=armbru@redhat.com \
--cc=marcandre.lureau@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).