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