1 /*
2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #pragma once
27
28 #include <map>
29 #include <vector>
30 #include <functional>
31 #include <fstream>
32 #include "buffer_cursor.h"
33 #include "fsutil.h"
34
35 //https://www.json.org/json-en.html
36 class JSonNode;
37
38 class JSonObjectNode;
39
40 class JSonValueNode;
41
42 class JSonListNode;
43
44 class JSonWriter {
45 std::ostream &o;
46 int indent;
47
48 public:
49 using Filter = std::function<bool(JSonNode *n)>;
50
51 explicit JSonWriter(std::ostream &o);
52
53 JSonWriter *put(std::string s);
54
55 JSonWriter *name(std::string n);
56
57 JSonWriter *comma();
58
59 JSonWriter *colon();
60
61 JSonWriter *oquote();
62
63 JSonWriter *cquote();
64
65 JSonWriter *obrace();
66
67 JSonWriter *cbrace();
68
69 JSonWriter *osbrace();
70
71 JSonWriter *csbrace();
72
73 JSonWriter *in();
74
75 JSonWriter *out();
76
77 JSonWriter *nl();
78
79 JSonWriter *write(JSonNode *, Filter filter);
80
81 JSonWriter *write(JSonNode *);
82 };
83
84 class JSonNode {
85 public:
86 using JSonNodeVisitor = std::function<void(JSonNode *n)>;
87
88 enum Type {
89 LIST, VALUE, OBJECT
90 };
91
92 enum ValueType {
93 STRING, INTEGER, NUMBER, BOOLEAN
94 };
95
96 Type type;
97 JSonObjectNode *parent;
98 std::string name;
99
100 JSonNode(Type type, JSonObjectNode *parent, std::string name);
101
102 virtual bool hasNode(std::string name);
103
104 virtual JSonNode *getNode(std::string name);
105
106 JSonValueNode *asValue();
107
108 JSonListNode *asList();
109
110 JSonObjectNode *asObject();
111
112 bool isList();
113
114 bool isObject();
115
116 bool isValue();
117
118 static JSonNode *parse(char *text);
119
120 virtual JSonNode *clone(JSonObjectNode *newParent) = 0;
121
122 virtual ~JSonNode() = 0;
123
124 JSonNode *get(std::string s, JSonNodeVisitor visitor);
125
126 JSonNode *collect(std::string s, std::vector<JSonNode *> &list);
127
128 static std::string parseString(BufferCursor *c);
129
130 JSonObjectNode *remove();
131
132 bool write(std::ostream o);
133
134 bool write(std::string filename);
135 };
136
137
138 class JSonObjectNode : public JSonNode {
139 public:
140 friend JSonNode *JSonNode::get(std::string s, JSonNodeVisitor visitor);
141
142 friend JSonNode *JSonNode::collect(std::string s, std::vector<JSonNode *> &list);
143
144 friend JSonWriter *JSonWriter::write(JSonNode *node, JSonWriter::Filter filter);
145
146 using JSonObjectNodeVisitor = std::function<void(JSonObjectNode *n)>;
147 using JSonListNodeVisitor = std::function<void(JSonListNode *n)>;
148
149 protected:
150 std::map<std::string, JSonNode *> nameToChildMap;
151 std::vector<JSonNode *> childArray;
152
153 public:
154 JSonObjectNode *remove(JSonNode *n);
155
156 JSonObjectNode *remove(std::string name);
157
158 JSonObjectNode(Type type, JSonObjectNode *parent, const std::string &name);
159
160 JSonObjectNode(JSonObjectNode *parent, const std::string &name);
161
162 ~JSonObjectNode() override;
163
164 virtual JSonNode *parse(BufferCursor *cursor);
165
166 void visit(const JSonNodeVisitor& visitor);
167
168 JSonObjectNode *object(std::string name, JSonObjectNodeVisitor visitor);
169
170 JSonObjectNode *list(std::string name, JSonListNodeVisitor visitor);
171
172 JSonObjectNode *boolean(std::string name, std::string value);
173
174 JSonObjectNode *boolean(std::string name, bool value);
175
176 JSonObjectNode *number(std::string name, std::string value);
177
178 JSonObjectNode *integer(std::string name, std::string value);
179
180 JSonObjectNode *integer(std::string name, int value);
181
182 JSonObjectNode *string(std::string name, std::string value);
183
184 JSonNode *add(JSonNode *newOne);
185
186 bool hasNode(std::string name) override;
187
188 JSonNode *getNode(std::string name) override;
189
190 JSonNode *clone(JSonObjectNode *newParent) override {
191 auto *copy = new JSonObjectNode(newParent, name);
192
193 for (const auto c: childArray) {
194 copy->childArray.push_back(copy->nameToChildMap[c->name] = c->clone(copy));
195 }
196 return copy;
197 }
198 };
199
200
201 class JSonValueNode final : public JSonNode {
202 public:
203 std::string value;
204 ValueType valueType;
205
206 JSonValueNode(JSonObjectNode *parent, std::string name, ValueType valueType, std::string value);
207
208 JSonNode *clone(JSonObjectNode *newParent) override {
209 return new JSonValueNode(newParent, name, valueType, value);
210 }
211
212 ~JSonValueNode() override;
213 };
214
215 class JSonListNode final : public JSonObjectNode {
216 public:
217 JSonListNode(JSonObjectNode *parent, std::string name);
218
219 JSonNode *parse(BufferCursor *cursor) override;
220
221 ~JSonListNode() override;
222
223 JSonObjectNode *item(JSonObjectNodeVisitor visitor);
224
225 int size() const;
226
227 public:
228 JSonNode *clone(JSonObjectNode *newParent) override {
229 auto *copy = new JSonListNode(newParent, name);
230
231 for (const auto c: childArray) {
232 copy->childArray.push_back(copy->nameToChildMap[c->name] = c->clone(copy));
233 }
234 return copy;
235 }
236
237 JSonObjectNode *boolean(std::string value);
238
239 JSonObjectNode *boolean(bool value);
240
241 JSonObjectNode *string(std::string value);
242
243 JSonObjectNode *integer(std::string value);
244
245 JSonObjectNode *integer(int value);
246
247 JSonObjectNode *number(std::string value);
248
249 JSonObjectNode *list(JSonListNodeVisitor visitor);
250 };
251
252
253 class JSon {
254 public:
255 static JSonObjectNode *create(std::function<void(JSonObjectNode *)> builder);
256
257 static JSonNode *parseFile(std::string filename);
258 };