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 <iostream>
 32 #include <fstream>
 33 #include <sstream>
 34 #include "buffer_cursor.h"
 35 #include "fsutil.h"
 36 
 37 //https://www.json.org/json-en.html
 38 class JSonNode;
 39 
 40 class JSonObjectNode;
 41 
 42 class JSonValueNode;
 43 
 44 class JSonListNode;
 45 
 46 class JSonWriter {
 47    std::ostream &o;
 48    int indent;
 49    public:
 50    using Filter = std::function<bool(JSonNode *n)>;
 51 
 52    explicit JSonWriter(std::ostream &o);
 53      JSonWriter *put(std::string s);
 54      JSonWriter *name(std::string n);
 55      JSonWriter *comma();
 56      JSonWriter *colon();
 57      JSonWriter *oquote();
 58      JSonWriter *cquote();
 59      JSonWriter *obrace();
 60      JSonWriter *cbrace();
 61      JSonWriter *osbrace();
 62      JSonWriter *csbrace();
 63      JSonWriter *in();
 64      JSonWriter *out();
 65      JSonWriter *nl();
 66      JSonWriter *write(JSonNode *, Filter filter);
 67      JSonWriter *write(JSonNode *);
 68 };
 69 
 70 class JSonNode {
 71 public:
 72     using JSonNodeVisitor = std::function<void(JSonNode *n)>;
 73     enum Type {
 74         LIST, VALUE, OBJECT
 75     };
 76     enum ValueType {
 77         STRING, INTEGER, NUMBER, BOOLEAN
 78     };
 79     Type type;
 80     JSonObjectNode *parent;
 81     std::string name;
 82 
 83     JSonNode(Type type, JSonObjectNode *parent, std::string name);
 84 
 85     virtual bool hasNode(std::string name);
 86 
 87    virtual JSonNode *getNode(std::string name);
 88 
 89     JSonValueNode *asValue();
 90 
 91     JSonListNode *asList();
 92 
 93     JSonObjectNode *asObject();
 94 
 95    bool isList();
 96    bool isObject();
 97    bool isValue();
 98 
 99     static JSonNode *parse(char *text);
100 
101     virtual JSonNode *clone(JSonObjectNode *newParent) = 0;
102 
103     virtual ~JSonNode() = 0;
104 
105     JSonNode *get(std::string s, JSonNodeVisitor visitor);
106    JSonNode *collect(std::string s, std::vector<JSonNode *> &list);
107     static std::string parseString(BufferCursor *c);
108 
109     JSonObjectNode * remove();
110 
111     bool write(std::ostream o);
112     bool write(std::string filename);
113 };
114 
115 
116 class JSonObjectNode : public JSonNode {
117 public:
118    friend JSonNode *JSonNode::get(std::string s, JSonNodeVisitor visitor);
119    friend JSonNode *JSonNode::collect(std::string s, std::vector<JSonNode *> &list);
120    friend JSonWriter *JSonWriter::write(JSonNode *node, JSonWriter::Filter filter);
121     using JSonObjectNodeVisitor = std::function<void(JSonObjectNode *n)>;
122     using JSonListNodeVisitor = std::function<void(JSonListNode *n)>;
123    protected:
124     std::map<std::string, JSonNode *> nameToChildMap;
125     std::vector<JSonNode *> childArray;
126    public:
127 
128     JSonObjectNode * remove(JSonNode *n);
129    JSonObjectNode * remove(std::string name);
130     JSonObjectNode(Type type, JSonObjectNode *parent, std::string name);
131 
132     JSonObjectNode(JSonObjectNode *parent, std::string name);
133 
134     ~JSonObjectNode() override;
135 
136     virtual JSonNode *parse(BufferCursor *cursor);
137     void visit(JSonNodeVisitor visitor);
138     JSonObjectNode *object(std::string name, JSonObjectNodeVisitor visitor);
139 
140     JSonObjectNode *list(std::string name, JSonListNodeVisitor visitor);
141 
142     JSonObjectNode *boolean(std::string name, std::string value);
143 
144     JSonObjectNode *boolean(std::string name, bool value);
145 
146     JSonObjectNode *number(std::string name, std::string value);
147 
148     JSonObjectNode *integer(std::string name, std::string value);
149     JSonObjectNode *integer(std::string name, int value);
150     JSonObjectNode *string(std::string name, std::string value);
151     JSonNode * add( JSonNode *newOne);
152     virtual bool hasNode(std::string name) override;
153 
154     virtual JSonNode *getNode(std::string name) override;
155 
156     virtual JSonNode *clone(JSonObjectNode *newParent) override{
157        JSonObjectNode *copy = new JSonObjectNode(newParent, name);
158 
159        for (auto c:childArray){
160           copy->childArray.push_back(copy->nameToChildMap[c->name] = c->clone(copy));
161        }
162        return copy;
163     }
164 };
165 
166 
167 class JSonValueNode : public JSonNode {
168 public:
169     std::string value;
170     ValueType valueType;
171     JSonValueNode(JSonObjectNode *parent, std::string name, ValueType valueType, std::string value);
172     JSonNode *clone(JSonObjectNode *newParent) override{
173       return new JSonValueNode(newParent, name, valueType, value);
174    }
175     ~JSonValueNode() override;
176 };
177 
178 class JSonListNode : public JSonObjectNode {
179 public:
180 
181 
182     JSonListNode(JSonObjectNode *parent, std::string name);
183 
184     JSonNode *parse(BufferCursor *cursor) override;
185 
186     ~JSonListNode() override;
187 
188     JSonObjectNode *item(JSonObjectNodeVisitor visitor);
189 
190     int size();
191 
192 public:
193    JSonNode *clone(JSonObjectNode *newParent) override{
194       JSonListNode *copy = new JSonListNode(newParent, name);
195 
196       for (auto c:childArray){
197          copy->childArray.push_back(copy->nameToChildMap[c->name] = c->clone(copy));
198       }
199       return copy;
200    }
201     JSonObjectNode *boolean(std::string value);
202 
203     JSonObjectNode *boolean(bool value);
204 
205     JSonObjectNode *string(std::string value);
206 
207     JSonObjectNode *integer(std::string value);
208 
209     JSonObjectNode *integer(int value);
210 
211     JSonObjectNode *number(std::string value);
212 
213     JSonObjectNode *list(JSonListNodeVisitor visitor);
214 };
215 
216 
217 class JSon{
218    public:
219    static JSonObjectNode *create(std::function<void(JSonObjectNode *)> builder);
220    static JSonNode *parseFile(std::string filename);
221 };