xref: /qemu/include/qobject/qnum.h (revision 407bc4bf9027f7ac4333e47cd900d773b99a23e3)
101b2ffceSMarc-André Lureau /*
201b2ffceSMarc-André Lureau  * QNum Module
301b2ffceSMarc-André Lureau  *
401b2ffceSMarc-André Lureau  * Copyright (C) 2009 Red Hat Inc.
501b2ffceSMarc-André Lureau  *
601b2ffceSMarc-André Lureau  * Authors:
701b2ffceSMarc-André Lureau  *  Luiz Capitulino <lcapitulino@redhat.com>
801b2ffceSMarc-André Lureau  *  Anthony Liguori <aliguori@us.ibm.com>
901b2ffceSMarc-André Lureau  *  Marc-André Lureau <marcandre.lureau@redhat.com>
1001b2ffceSMarc-André Lureau  *
1101b2ffceSMarc-André Lureau  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
1201b2ffceSMarc-André Lureau  * See the COPYING.LIB file in the top-level directory.
1301b2ffceSMarc-André Lureau  */
1401b2ffceSMarc-André Lureau 
1501b2ffceSMarc-André Lureau #ifndef QNUM_H
1601b2ffceSMarc-André Lureau #define QNUM_H
1701b2ffceSMarc-André Lureau 
18*407bc4bfSDaniel P. Berrangé #include "qobject/qobject.h"
1901b2ffceSMarc-André Lureau 
2001b2ffceSMarc-André Lureau typedef enum {
2101b2ffceSMarc-André Lureau     QNUM_I64,
2261a8f418SMarc-André Lureau     QNUM_U64,
2301b2ffceSMarc-André Lureau     QNUM_DOUBLE
2401b2ffceSMarc-André Lureau } QNumKind;
2501b2ffceSMarc-André Lureau 
26f90cb284SMarkus Armbruster /*
27f90cb284SMarkus Armbruster  * QNum encapsulates how our dialect of JSON fills in the blanks left
2837aded92SMarkus Armbruster  * by the JSON specification (RFC 8259) regarding numbers.
29f90cb284SMarkus Armbruster  *
30f90cb284SMarkus Armbruster  * Conceptually, we treat number as an abstract type with three
31f90cb284SMarkus Armbruster  * concrete subtypes: floating-point, signed integer, unsigned
32f90cb284SMarkus Armbruster  * integer.  QNum implements this as a discriminated union of double,
33f90cb284SMarkus Armbruster  * int64_t, uint64_t.
34f90cb284SMarkus Armbruster  *
35f90cb284SMarkus Armbruster  * The JSON parser picks the subtype as follows.  If the number has a
36f90cb284SMarkus Armbruster  * decimal point or an exponent, it is floating-point.  Else if it
37f90cb284SMarkus Armbruster  * fits into int64_t, it's signed integer.  Else if it fits into
38f90cb284SMarkus Armbruster  * uint64_t, it's unsigned integer.  Else it's floating-point.
39f90cb284SMarkus Armbruster  *
40f90cb284SMarkus Armbruster  * Any number can serve as double: qnum_get_double() converts under
41f90cb284SMarkus Armbruster  * the hood.
42f90cb284SMarkus Armbruster  *
43f90cb284SMarkus Armbruster  * An integer can serve as signed / unsigned integer as long as it is
44f90cb284SMarkus Armbruster  * in range: qnum_get_try_int() / qnum_get_try_uint() check range and
45f90cb284SMarkus Armbruster  * convert under the hood.
46f90cb284SMarkus Armbruster  */
479f5c734dSMarkus Armbruster struct QNum {
483d3eacaeSMarc-André Lureau     struct QObjectBase_ base;
4901b2ffceSMarc-André Lureau     QNumKind kind;
5001b2ffceSMarc-André Lureau     union {
5101b2ffceSMarc-André Lureau         int64_t i64;
5261a8f418SMarc-André Lureau         uint64_t u64;
5301b2ffceSMarc-André Lureau         double dbl;
5401b2ffceSMarc-André Lureau     } u;
559f5c734dSMarkus Armbruster };
5601b2ffceSMarc-André Lureau 
57d709bbf3SMarc-André Lureau void qnum_unref(QNum *q);
58d709bbf3SMarc-André Lureau 
59d709bbf3SMarc-André Lureau G_DEFINE_AUTOPTR_CLEANUP_FUNC(QNum, qnum_unref)
60d709bbf3SMarc-André Lureau 
6101b2ffceSMarc-André Lureau QNum *qnum_from_int(int64_t value);
6261a8f418SMarc-André Lureau QNum *qnum_from_uint(uint64_t value);
6301b2ffceSMarc-André Lureau QNum *qnum_from_double(double value);
6401b2ffceSMarc-André Lureau 
6501b2ffceSMarc-André Lureau bool qnum_get_try_int(const QNum *qn, int64_t *val);
6601b2ffceSMarc-André Lureau int64_t qnum_get_int(const QNum *qn);
6761a8f418SMarc-André Lureau 
6861a8f418SMarc-André Lureau bool qnum_get_try_uint(const QNum *qn, uint64_t *val);
6961a8f418SMarc-André Lureau uint64_t qnum_get_uint(const QNum *qn);
7061a8f418SMarc-André Lureau 
7101b2ffceSMarc-André Lureau double qnum_get_double(QNum *qn);
7201b2ffceSMarc-André Lureau 
7301b2ffceSMarc-André Lureau char *qnum_to_string(QNum *qn);
7401b2ffceSMarc-André Lureau 
7501b2ffceSMarc-André Lureau #endif /* QNUM_H */
76