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 };