xref: /openbmc/qemu/include/qobject/qnum.h (revision 54e91d1523b412b4cff7cb36c898fa9dc133e886)
1*407bc4bfSDaniel P. Berrangé /*
2*407bc4bfSDaniel P. Berrangé  * QNum Module
3*407bc4bfSDaniel P. Berrangé  *
4*407bc4bfSDaniel P. Berrangé  * Copyright (C) 2009 Red Hat Inc.
5*407bc4bfSDaniel P. Berrangé  *
6*407bc4bfSDaniel P. Berrangé  * Authors:
7*407bc4bfSDaniel P. Berrangé  *  Luiz Capitulino <lcapitulino@redhat.com>
8*407bc4bfSDaniel P. Berrangé  *  Anthony Liguori <aliguori@us.ibm.com>
9*407bc4bfSDaniel P. Berrangé  *  Marc-André Lureau <marcandre.lureau@redhat.com>
10*407bc4bfSDaniel P. Berrangé  *
11*407bc4bfSDaniel P. Berrangé  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
12*407bc4bfSDaniel P. Berrangé  * See the COPYING.LIB file in the top-level directory.
13*407bc4bfSDaniel P. Berrangé  */
14*407bc4bfSDaniel P. Berrangé 
15*407bc4bfSDaniel P. Berrangé #ifndef QNUM_H
16*407bc4bfSDaniel P. Berrangé #define QNUM_H
17*407bc4bfSDaniel P. Berrangé 
18*407bc4bfSDaniel P. Berrangé #include "qobject/qobject.h"
19*407bc4bfSDaniel P. Berrangé 
20*407bc4bfSDaniel P. Berrangé typedef enum {
21*407bc4bfSDaniel P. Berrangé     QNUM_I64,
22*407bc4bfSDaniel P. Berrangé     QNUM_U64,
23*407bc4bfSDaniel P. Berrangé     QNUM_DOUBLE
24*407bc4bfSDaniel P. Berrangé } QNumKind;
25*407bc4bfSDaniel P. Berrangé 
26*407bc4bfSDaniel P. Berrangé /*
27*407bc4bfSDaniel P. Berrangé  * QNum encapsulates how our dialect of JSON fills in the blanks left
28*407bc4bfSDaniel P. Berrangé  * by the JSON specification (RFC 8259) regarding numbers.
29*407bc4bfSDaniel P. Berrangé  *
30*407bc4bfSDaniel P. Berrangé  * Conceptually, we treat number as an abstract type with three
31*407bc4bfSDaniel P. Berrangé  * concrete subtypes: floating-point, signed integer, unsigned
32*407bc4bfSDaniel P. Berrangé  * integer.  QNum implements this as a discriminated union of double,
33*407bc4bfSDaniel P. Berrangé  * int64_t, uint64_t.
34*407bc4bfSDaniel P. Berrangé  *
35*407bc4bfSDaniel P. Berrangé  * The JSON parser picks the subtype as follows.  If the number has a
36*407bc4bfSDaniel P. Berrangé  * decimal point or an exponent, it is floating-point.  Else if it
37*407bc4bfSDaniel P. Berrangé  * fits into int64_t, it's signed integer.  Else if it fits into
38*407bc4bfSDaniel P. Berrangé  * uint64_t, it's unsigned integer.  Else it's floating-point.
39*407bc4bfSDaniel P. Berrangé  *
40*407bc4bfSDaniel P. Berrangé  * Any number can serve as double: qnum_get_double() converts under
41*407bc4bfSDaniel P. Berrangé  * the hood.
42*407bc4bfSDaniel P. Berrangé  *
43*407bc4bfSDaniel P. Berrangé  * An integer can serve as signed / unsigned integer as long as it is
44*407bc4bfSDaniel P. Berrangé  * in range: qnum_get_try_int() / qnum_get_try_uint() check range and
45*407bc4bfSDaniel P. Berrangé  * convert under the hood.
46*407bc4bfSDaniel P. Berrangé  */
47*407bc4bfSDaniel P. Berrangé struct QNum {
48*407bc4bfSDaniel P. Berrangé     struct QObjectBase_ base;
49*407bc4bfSDaniel P. Berrangé     QNumKind kind;
50*407bc4bfSDaniel P. Berrangé     union {
51*407bc4bfSDaniel P. Berrangé         int64_t i64;
52*407bc4bfSDaniel P. Berrangé         uint64_t u64;
53*407bc4bfSDaniel P. Berrangé         double dbl;
54*407bc4bfSDaniel P. Berrangé     } u;
55*407bc4bfSDaniel P. Berrangé };
56*407bc4bfSDaniel P. Berrangé 
57*407bc4bfSDaniel P. Berrangé void qnum_unref(QNum *q);
58*407bc4bfSDaniel P. Berrangé 
59*407bc4bfSDaniel P. Berrangé G_DEFINE_AUTOPTR_CLEANUP_FUNC(QNum, qnum_unref)
60*407bc4bfSDaniel P. Berrangé 
61*407bc4bfSDaniel P. Berrangé QNum *qnum_from_int(int64_t value);
62*407bc4bfSDaniel P. Berrangé QNum *qnum_from_uint(uint64_t value);
63*407bc4bfSDaniel P. Berrangé QNum *qnum_from_double(double value);
64*407bc4bfSDaniel P. Berrangé 
65*407bc4bfSDaniel P. Berrangé bool qnum_get_try_int(const QNum *qn, int64_t *val);
66*407bc4bfSDaniel P. Berrangé int64_t qnum_get_int(const QNum *qn);
67*407bc4bfSDaniel P. Berrangé 
68*407bc4bfSDaniel P. Berrangé bool qnum_get_try_uint(const QNum *qn, uint64_t *val);
69*407bc4bfSDaniel P. Berrangé uint64_t qnum_get_uint(const QNum *qn);
70*407bc4bfSDaniel P. Berrangé 
71*407bc4bfSDaniel P. Berrangé double qnum_get_double(QNum *qn);
72*407bc4bfSDaniel P. Berrangé 
73*407bc4bfSDaniel P. Berrangé char *qnum_to_string(QNum *qn);
74*407bc4bfSDaniel P. Berrangé 
75*407bc4bfSDaniel P. Berrangé #endif /* QNUM_H */
76