P4C
The P4 Compiler
 
Loading...
Searching...
No Matches
json.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef LIB_JSON_H_
18#define LIB_JSON_H_
19
20#include <iostream>
21#include <stdexcept>
22#include <type_traits>
23#include <vector>
24
25#ifdef P4C_GTEST_ENABLED
26#include "gtest/gtest_prod.h"
27#endif
28#include "lib/big_int_util.h"
29#include "lib/castable.h"
30#include "lib/cstring.h"
31#include "lib/map.h"
32#include "lib/ordered_map.h"
33
34namespace Test {
35class TestJson;
36}
37
38namespace Util {
39
40class IJson : public ICastable {
41 public:
42 virtual ~IJson() {}
43 virtual void serialize(std::ostream &out) const = 0;
44 cstring toString() const;
45 void dump() const;
46
47 DECLARE_TYPEINFO(IJson);
48};
49
50class JsonValue final : public IJson {
51#ifdef P4C_GTEST_ENABLED
52 FRIEND_TEST(Util, Json);
53#endif
54
55 public:
56 enum Kind { String, Number, True, False, Null };
57 JsonValue() : tag(Kind::Null) {}
58 JsonValue(bool b) : tag(b ? Kind::True : Kind::False) {} // NOLINT
59 JsonValue(big_int v) : tag(Kind::Number), value(v) {} // NOLINT
60 JsonValue(int v) : tag(Kind::Number), value(v) {} // NOLINT
61 JsonValue(long v) : tag(Kind::Number), value(v) {} // NOLINT
62 JsonValue(long long v); // NOLINT
63 JsonValue(unsigned v) : tag(Kind::Number), value(v) {} // NOLINT
64 JsonValue(unsigned long v) : tag(Kind::Number), value(v) {} // NOLINT
65 JsonValue(unsigned long long v); // NOLINT
66 JsonValue(double v) : tag(Kind::Number), value(v) {} // NOLINT
67 JsonValue(float v) : tag(Kind::Number), value(v) {} // NOLINT
68 JsonValue(cstring s) : tag(Kind::String), str(s) {} // NOLINT
69 JsonValue(const std::string &s) : tag(Kind::String), str(s) {} // NOLINT
70 JsonValue(const char *s) : tag(Kind::String), str(s) {} // NOLINT
71 void serialize(std::ostream &out) const override;
72
73 bool operator==(const big_int &v) const;
74 // is_integral is true for bool
75 template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
76 bool operator==(const T &v) const {
77 return (tag == Kind::Number) && (v == value);
78 }
79 bool operator==(const double &v) const;
80 bool operator==(const float &v) const;
81 bool operator==(const cstring &s) const;
82 bool operator==(const std::string &s) const;
83 bool operator==(const char *s) const;
84 bool operator==(const JsonValue &other) const;
85
86 bool isNumber() const { return tag == Kind::Number; }
87 bool isBool() const { return tag == Kind::True || tag == Kind::False; }
88 bool isString() const { return tag == Kind::String; }
89 bool isNull() const { return tag == Kind::Null; }
90
91 bool getBool() const;
92 cstring getString() const;
93 big_int getValue() const;
94 int getInt() const;
95
96 static JsonValue *null;
97
98 private:
99 JsonValue(Kind kind) : tag(kind) { // NOLINT
100 if (kind == Kind::String || kind == Kind::Number)
101 throw std::logic_error("Incorrect constructor called");
102 }
103
104 const Kind tag;
105 const big_int value = 0;
106 const cstring str = nullptr;
107
108 DECLARE_TYPEINFO(JsonValue, IJson);
109};
110
111class JsonArray final : public IJson, public std::vector<IJson *> {
112 friend class Test::TestJson;
113
114 public:
115 void serialize(std::ostream &out) const override;
116 JsonArray *clone() const { return new JsonArray(*this); }
117 JsonArray *append(IJson *value);
118 JsonArray *append(big_int v) {
119 append(new JsonValue(v));
120 return this;
121 }
122 template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
123 JsonArray *append(T v) {
124 append(new JsonValue(v));
125 return this;
126 }
127 JsonArray *append(double v) {
128 append(new JsonValue(v));
129 return this;
130 }
131 JsonArray *append(float v) {
132 append(new JsonValue(v));
133 return this;
134 }
135 JsonArray *append(cstring s) {
136 append(new JsonValue(s));
137 return this;
138 }
139 JsonArray *append(const std::string &s) {
140 append(new JsonValue(s));
141 return this;
142 }
143 JsonArray *append(const char *s) {
144 append(new JsonValue(s));
145 return this;
146 }
147 JsonArray *concatenate(const Util::JsonArray *other) {
148 for (auto v : *other) append(v);
149 return this;
150 }
151 JsonArray(std::initializer_list<IJson *> data) : std::vector<IJson *>(data) {} // NOLINT
152 JsonArray() = default;
153 JsonArray(std::vector<IJson *> &data) : std::vector<IJson *>(data) {} // NOLINT
154
155 DECLARE_TYPEINFO(JsonArray, IJson);
156};
157
158class JsonObject final : public IJson, public ordered_map<cstring, IJson *> {
159 friend class Test::TestJson;
160
161 public:
162 JsonObject() = default;
163 void serialize(std::ostream &out) const override;
164 JsonObject *emplace(cstring label, IJson *value);
165 JsonObject *emplace_non_null(cstring label, IJson *value);
166 JsonObject *emplace(cstring label, big_int v) {
167 emplace(label, new JsonValue(v));
168 return this;
169 }
170 template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
171 JsonObject *emplace(cstring label, T v) {
172 emplace(label, new JsonValue(v));
173 return this;
174 }
175 JsonObject *emplace(cstring label, float v) {
176 emplace(label, new JsonValue(v));
177 return this;
178 }
179 JsonObject *emplace(cstring label, cstring s) {
180 emplace(label, new JsonValue(s));
181 return this;
182 }
183 JsonObject *emplace(cstring label, std::string s) {
184 emplace(label, new JsonValue(s));
185 return this;
186 }
187 JsonObject *emplace(cstring label, const char *s) {
188 emplace(label, new JsonValue(s));
189 return this;
190 }
191 IJson *get(cstring label) const { return ::get(*this, label); }
192
193 DECLARE_TYPEINFO(JsonObject, IJson);
194};
195
196} // namespace Util
197
198#endif /* LIB_JSON_H_ */
Definition castable.h:34
Definition json.h:40
Definition json.h:111
Definition json.h:158
Definition json.h:50
Definition cstring.h:72
Definition ordered_map.h:30