qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v6 04/15] qapi: Factor out JSON number formatting


From: Eric Blake
Subject: [Qemu-devel] [PATCH v6 04/15] qapi: Factor out JSON number formatting
Date: Mon, 10 Oct 2016 08:23:46 -0500

Pull out a new qstring_append_json_number() helper, so that all
JSON output producers can use a consistent style for printing
floating point without duplicating code (since we are doing more
data massaging than a simple printf format can handle).  (For
now, there is only one client, but later patches will use it.)

Unlike qstring_append_json_string() which has a return value to
allow callers to detect when output was munged to produce valid
JSON, this code either succeeds or triggers an assertion failure.

Signed-off-by: Eric Blake <address@hidden>

---
v6: drop return value, now that we assert finite floats on any
QObject converted to JSON
[no v5 due to series split]
v4: keep helper in qobject-json.[ch], don't use Error **errp for
inf/NaN handling, drop R-b
v3: rebase to latest; even though the patch differs quite a bit
from v2, the changes are due to prior comment changes that are
just moving between files, so R-b kept
v2: minor wording tweaks
---
 include/qapi/qmp/qjson.h |  1 +
 qobject/qjson.c          | 57 +++++++++++++++++++++++++++++-------------------
 2 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/include/qapi/qmp/qjson.h b/include/qapi/qmp/qjson.h
index aa8ddd7..6fb912e 100644
--- a/include/qapi/qmp/qjson.h
+++ b/include/qapi/qmp/qjson.h
@@ -25,5 +25,6 @@ QString *qobject_to_json(const QObject *obj);
 QString *qobject_to_json_pretty(const QObject *obj);

 int qstring_append_json_string(QString *qstring, const char *str);
+void qstring_append_json_number(QString *qstring, double number);

 #endif /* QJSON_H */
diff --git a/qobject/qjson.c b/qobject/qjson.c
index 6810726..b47a361 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -181,29 +181,8 @@ static void to_json(const QObject *obj, QString *str, int 
pretty, int indent)
     }
     case QTYPE_QFLOAT: {
         double val = qfloat_get_double(qobject_to_qfloat(obj));
-        char buffer[1024];
-        int len;

-        assert(isfinite(val));
-        /* FIXME: snprintf() is locale dependent; but JSON requires
-         * numbers to be formatted as if in the C locale. Dependence
-         * on C locale is a pervasive issue in QEMU. */
-        /* FIXME: the default precision of 6 for %f often causes
-         * 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.  */
-        len = snprintf(buffer, sizeof(buffer), "%f", val);
-        while (len > 0 && buffer[len - 1] == '0') {
-            len--;
-        }
-
-        if (len && buffer[len - 1] == '.') {
-            buffer[len - 1] = 0;
-        } else {
-            buffer[len] = 0;
-        }
-
-        qstring_append(str, buffer);
+        qstring_append_json_number(str, val);
         break;
     }
     case QTYPE_QBOOL: {
@@ -304,3 +283,37 @@ int qstring_append_json_string(QString *qstring, const 
char *str)
     qstring_append(qstring, "\"");
     return result;
 }
+
+/**
+ * Append a JSON representation of @number to @qstring.
+ *
+ * Requires @number to be finite, per RFC 7159.
+ */
+void qstring_append_json_number(QString *qstring, double number)
+{
+    char buffer[1024];
+    int len;
+
+    assert(isfinite(number));
+
+    /* FIXME: snprintf() is locale dependent; but JSON requires
+     * numbers to be formatted as if in the C locale. Dependence
+     * on C locale is a pervasive issue in QEMU. */
+    /* FIXME: the default precision of 6 for %f often causes
+     * 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.  */
+    len = snprintf(buffer, sizeof(buffer), "%f", number);
+    assert(len > 0 && len < sizeof(buffer));
+    while (len > 0 && buffer[len - 1] == '0') {
+        len--;
+    }
+
+    if (len && buffer[len - 1] == '.') {
+        buffer[len - 1] = 0;
+    } else {
+        buffer[len] = 0;
+    }
+
+    qstring_append(qstring, buffer);
+}
-- 
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]