Fixes for Heimdal (macOS) builds from Stefan.
[mech_eap.git] / mech_eap / util_json.h
1 /*
2  * Copyright (c) 2011, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 /*
34  * JSON object wrapper with not-entirely-toll-free DDF bridging.
35  */
36
37 #ifndef _UTIL_JSON_H_
38 #define _UTIL_JSON_H_ 1
39
40 #ifdef __cplusplus
41 #include <string>
42 #include <new>
43
44 #include <jansson.h>
45
46 #ifdef HAVE_SHIBRESOLVER
47 #include <shibsp/remoting/ddf.h>
48 using namespace shibsp;
49 #endif
50
51 namespace gss_eap_util {
52     class JSONObject;
53
54     class JSONException : public std::exception {
55     public:
56         JSONException(json_t *obj = NULL, json_type type = JSON_NULL);
57
58         ~JSONException(void) throw() {
59             json_decref(m_obj);
60         }
61
62         virtual const char *what(void) const throw() {
63             return m_reason.c_str();
64         }
65
66     private:
67         json_t *m_obj;
68         json_type m_type;
69         std::string m_reason;
70     };
71
72     class JSONIterator {
73     public:
74         JSONIterator(const JSONObject &obj);
75         ~JSONIterator(void);
76         const char *key(void) const;
77         JSONObject value(void) const;
78         bool next(void);
79
80     private:
81         json_t *m_obj;
82         void *m_iter;
83     };
84
85     class JSONObject {
86     public:
87         static JSONObject load(const char *input, size_t flags, json_error_t *error);
88         static JSONObject load(FILE *, size_t flags, json_error_t *error);
89
90         static JSONObject object(void);
91         static JSONObject array(void);
92         static JSONObject null(void);
93 #ifdef HAVE_SHIBRESOLVER
94         static JSONObject ddf(DDF &value);
95 #endif
96
97         char *dump(size_t flags = 0) const;
98         void dump(FILE *fp, size_t flags = JSON_INDENT(4)) const;
99
100         json_type type(void) const { return json_typeof(m_obj); }
101         size_t size(void) const;
102
103         JSONObject(void);
104         JSONObject(const char *value);
105         JSONObject(json_int_t value);
106         JSONObject(double value);
107         JSONObject(bool value);
108
109         void set(const char *key, JSONObject &value);
110         void set(const char *key, const char *value);
111         void set(const char *key, json_int_t value);
112         void del(const char *key);
113         void update(JSONObject &value);
114         JSONIterator iterator(void) const { return JSONIterator(*this); }
115         JSONObject get(const char *key) const;
116         JSONObject operator[](const char *key) const;
117
118         JSONObject get(size_t index) const;
119         JSONObject operator[](size_t index) const;
120         void append(JSONObject &value);
121         void insert(size_t index, JSONObject &value);
122         void remove(size_t index);
123         void clear(void);
124         void extend(JSONObject &value);
125
126         const char *string(void) const;
127         json_int_t integer(void) const;
128         double real(void) const;
129         double number(void) const;
130 #ifdef HAVE_SHIBRESOLVER
131         DDF ddf(void) const;
132 #endif
133
134         bool isObject(void) const;
135         bool isArray(void) const;
136         bool isString(void) const;
137         bool isInteger(void) const;
138         bool isNumber(void) const;
139         bool isBoolean(void) const;
140         bool isNull(void) const;
141
142         ~JSONObject(void)
143         {
144             if (m_obj != NULL)
145                 json_decref(m_obj);
146         }
147
148         JSONObject(const JSONObject &obj)
149         {
150             m_obj = json_incref(obj.m_obj);
151         }
152
153         JSONObject& operator=(const JSONObject &obj)
154         {
155             if (this != &obj)
156                 set(obj.m_obj);
157             return *this;
158         }
159
160     private:
161         friend class JSONIterator;
162
163         json_t *get(void) const {
164             return json_incref(m_obj);
165         }
166
167         void set(json_t *obj) {
168             if (m_obj != obj) {
169                 json_decref(m_obj);
170                 m_obj = json_incref(m_obj);
171             }
172         }
173
174         JSONObject(json_t *obj, bool retain = true);
175
176         json_t *m_obj;
177     };
178 }
179
180 #endif /* __cplusplus */
181
182 #endif /* _UTIL_JSON_H_ */