qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH v4 17/28] qapi: Factor out JSON number formatting


From: Eric Blake
Subject: [Qemu-devel] [PATCH v4 17/28] qapi: Factor out JSON number formatting
Date: Wed, 18 May 2016 22:41:03 -0600

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.)

Adding a return value will let callers that care diagnose the
situation where an attempt was made to output invalid JSON (which
does not specify Infinity or NaN). None of the current callers
care, but a future patch wants to make it possible to turn this
situation into an error.

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

---
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/qobject-json.h |  1 +
 qobject/qobject-json.c          | 63 +++++++++++++++++++++++++----------------
 2 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/include/qapi/qmp/qobject-json.h b/include/qapi/qmp/qobject-json.h
index aa8ddd7..0749e7e 100644
--- a/include/qapi/qmp/qobject-json.h
+++ b/include/qapi/qmp/qobject-json.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);
+int qstring_append_json_number(QString *qstring, double number);

 #endif /* QJSON_H */
diff --git a/qobject/qobject-json.c b/qobject/qobject-json.c
index bc3634f..08daeed 100644
--- a/qobject/qobject-json.c
+++ b/qobject/qobject-json.c
@@ -18,6 +18,7 @@
 #include "qapi/qmp/qobject-json.h"
 #include "qemu/unicode.h"
 #include "qapi/qmp/types.h"
+#include <math.h>

 typedef struct JSONParsingState
 {
@@ -180,30 +181,8 @@ static void to_json(const QObject *obj, QString *str, int 
pretty, int indent)
     }
     case QTYPE_QFLOAT: {
         QFloat *val = qobject_to_qfloat(obj);
-        char buffer[1024];
-        int len;
-
-        /* 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: This risks printing Inf or NaN, which are not valid
-         * JSON values. */
-        /* 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", qfloat_get_double(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);
+        /* FIXME: no way inform user if we generated invalid JSON */
+        qstring_append_json_number(str, qfloat_get_double(val));
         break;
     }
     case QTYPE_QBOOL: {
@@ -303,3 +282,39 @@ int qstring_append_json_string(QString *qstring, const 
char *str)
     qstring_append(qstring, "\"");
     return result;
 }
+
+/**
+ * Append a JSON representation of @number to @qstring.
+ *
+ * Returns -1 if the added text is not strict JSON, or 0 if the number
+ * was finite.
+ */
+int qstring_append_json_number(QString *qstring, double number)
+{
+    char buffer[1024];
+    int len;
+
+    /* 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: This risks printing Inf or NaN, which are not valid
+     * JSON values. */
+    /* 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);
+    return isfinite(number) ? 0 : -1;
+}
-- 
2.5.5




reply via email to

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