Branch data Line data Source code
1 : : /* JSON trees
2 : : Copyright (C) 2017-2024 Free Software Foundation, Inc.
3 : : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #ifndef GCC_JSON_H
22 : : #define GCC_JSON_H
23 : :
24 : : /* Implementation of JSON, a lightweight data-interchange format.
25 : :
26 : : See http://www.json.org/
27 : : and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
28 : : and https://tools.ietf.org/html/rfc7159
29 : :
30 : : Supports creating a DOM-like tree of json::value *, and then dumping
31 : : json::value * to text. */
32 : :
33 : : /* TODO: `libcpp/mkdeps.cc` wants JSON writing support for p1689r5 output;
34 : : extract this code and move to libiberty. */
35 : :
36 : : namespace json
37 : : {
38 : :
39 : : /* Forward decls of json::value and its subclasses (using indentation
40 : : to denote inheritance. */
41 : :
42 : : class value;
43 : : class object;
44 : : class array;
45 : : class float_number;
46 : : class integer_number;
47 : : class string;
48 : : class literal;
49 : :
50 : : /* An enum for discriminating the subclasses of json::value. */
51 : :
52 : : enum kind
53 : : {
54 : : /* class json::object. */
55 : : JSON_OBJECT,
56 : :
57 : : /* class json::array. */
58 : : JSON_ARRAY,
59 : :
60 : : /* class json::integer_number. */
61 : : JSON_INTEGER,
62 : :
63 : : /* class json::float_number. */
64 : : JSON_FLOAT,
65 : :
66 : : /* class json::string. */
67 : : JSON_STRING,
68 : :
69 : : /* class json::literal uses these three values to identify the
70 : : particular literal. */
71 : : JSON_TRUE,
72 : : JSON_FALSE,
73 : : JSON_NULL
74 : : };
75 : :
76 : : /* Base class of JSON value. */
77 : :
78 : 2481855 : class value
79 : : {
80 : : public:
81 : 672432 : virtual ~value () {}
82 : : virtual enum kind get_kind () const = 0;
83 : : virtual void print (pretty_printer *pp, bool formatted) const = 0;
84 : :
85 : : void dump (FILE *, bool formatted) const;
86 : : };
87 : :
88 : : /* Subclass of value for objects: a collection of key/value pairs
89 : : preserving the ordering in which keys were inserted.
90 : :
91 : : Preserving the order eliminates non-determinism in the output,
92 : : making it easier for the user to compare repeated invocations. */
93 : :
94 : : class object : public value
95 : : {
96 : : public:
97 : : ~object ();
98 : :
99 : 25 : enum kind get_kind () const final override { return JSON_OBJECT; }
100 : : void print (pretty_printer *pp, bool formatted) const final override;
101 : :
102 : : void set (const char *key, value *v);
103 : : value *get (const char *key) const;
104 : :
105 : : void set_string (const char *key, const char *utf8_value);
106 : : void set_integer (const char *key, long v);
107 : : void set_float (const char *key, double v);
108 : :
109 : : /* Set to literal true/false. */
110 : : void set_bool (const char *key, bool v);
111 : :
112 : : private:
113 : : typedef hash_map <char *, value *,
114 : : simple_hashmap_traits<nofree_string_hash, value *> > map_t;
115 : : map_t m_map;
116 : :
117 : : /* Keep track of order in which keys were inserted. */
118 : : auto_vec <const char *> m_keys;
119 : : };
120 : :
121 : : /* Subclass of value for arrays. */
122 : :
123 : 577417 : class array : public value
124 : : {
125 : : public:
126 : : ~array ();
127 : :
128 : 0 : enum kind get_kind () const final override { return JSON_ARRAY; }
129 : : void print (pretty_printer *pp, bool formatted) const final override;
130 : :
131 : : void append (value *v);
132 : :
133 : : private:
134 : : auto_vec<value *> m_elements;
135 : : };
136 : :
137 : : /* Subclass of value for floating-point numbers. */
138 : :
139 : 4 : class float_number : public value
140 : : {
141 : : public:
142 : 88 : float_number (double value) : m_value (value) {}
143 : :
144 : 0 : enum kind get_kind () const final override { return JSON_FLOAT; }
145 : : void print (pretty_printer *pp, bool formatted) const final override;
146 : :
147 : : double get () const { return m_value; }
148 : :
149 : : private:
150 : : double m_value;
151 : : };
152 : :
153 : : /* Subclass of value for integer-valued numbers. */
154 : :
155 : 4 : class integer_number : public value
156 : : {
157 : : public:
158 : 613676 : integer_number (long value) : m_value (value) {}
159 : :
160 : 0 : enum kind get_kind () const final override { return JSON_INTEGER; }
161 : : void print (pretty_printer *pp, bool formatted) const final override;
162 : :
163 : : long get () const { return m_value; }
164 : :
165 : : private:
166 : : long m_value;
167 : : };
168 : :
169 : :
170 : : /* Subclass of value for strings. */
171 : :
172 : : class string : public value
173 : : {
174 : : public:
175 : : explicit string (const char *utf8);
176 : : string (const char *utf8, size_t len);
177 : 1903564 : ~string () { free (m_utf8); }
178 : :
179 : 0 : enum kind get_kind () const final override { return JSON_STRING; }
180 : : void print (pretty_printer *pp, bool formatted) const final override;
181 : :
182 : : const char *get_string () const { return m_utf8; }
183 : : size_t get_length () const { return m_len; }
184 : :
185 : : private:
186 : : char *m_utf8;
187 : : size_t m_len;
188 : : };
189 : :
190 : : /* Subclass of value for the three JSON literals "true", "false",
191 : : and "null". */
192 : :
193 : 4 : class literal : public value
194 : : {
195 : : public:
196 : 4 : literal (enum kind kind) : m_kind (kind) {}
197 : :
198 : : /* Construct literal for a boolean value. */
199 : 351 : literal (bool value): m_kind (value ? JSON_TRUE : JSON_FALSE) {}
200 : :
201 : 0 : enum kind get_kind () const final override { return m_kind; }
202 : : void print (pretty_printer *pp, bool formatted) const final override;
203 : :
204 : : private:
205 : : enum kind m_kind;
206 : : };
207 : :
208 : : } // namespace json
209 : :
210 : : #endif /* GCC_JSON_H */
|