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