summaryrefslogtreecommitdiff
path: root/qobject
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2017-06-07 20:36:01 +0400
committerMarkus Armbruster <armbru@redhat.com>2017-06-20 14:31:31 +0200
commit61a8f418b26a2d974e38e4ae55020aca8d402d88 (patch)
tree3d0247aa5282793a911b8c699ae7c2da5772e50c /qobject
parent36aeb6094f04bed036c43c5e0eb675ca78bf72fe (diff)
downloadqemu-61a8f418b26a2d974e38e4ae55020aca8d402d88.tar.gz
qnum: add uint type
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>
Diffstat (limited to 'qobject')
-rw-r--r--qobject/qnum.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 7bb9006763..476e81c93b 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;
}
@@ -108,6 +170,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