[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
- [Qemu-devel] [PATCH v4 08/28] qmp-input-visitor: Favor new visit_free() function, (continued)
- [Qemu-devel] [PATCH v4 08/28] qmp-input-visitor: Favor new visit_free() function, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 07/28] string-input-visitor: Favor new visit_free() function, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 01/28] qapi: Rename (one) qjson.h to qobject-json.h, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 09/28] string-output-visitor: Favor new visit_free() function, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 04/28] qapi: Add parameter to visit_end_*, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 15/28] replay: Use new QAPI cloning, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 11/28] tests: Factor out common code in qapi output tests, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 10/28] qmp-output-visitor: Favor new visit_free() function, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 14/28] sockets: Use new QAPI cloning, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 16/28] qapi: Factor out JSON string escaping, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 17/28] qapi: Factor out JSON number formatting,
Eric Blake <=
- [Qemu-devel] [PATCH v4 23/28] tests: Test qobject_to_json() pretty formatting, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 13/28] qapi: Add new clone visitor, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 18/28] qapi: Add qstring_append_printf(), Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 25/28] qapi: Support pretty printing in JSON output visitor, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 26/28] qobject: Implement qobject_to_json() atop JSON visitor, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 27/28] qapi: Add 'any' support to JSON output, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 20/28] qstring: Add qstring_consume_str(), Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 24/28] qapi: Add JSON output visitor, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 22/28] qobject: Consolidate qobject_to_json() calls, Eric Blake, 2016/05/19
- [Qemu-devel] [PATCH v4 28/28] qemu-img: Use new JSON output formatter, Eric Blake, 2016/05/19