FIMS  v0.11.0
Loading...
Searching...
No Matches
fims_json.hpp
Go to the documentation of this file.
1#ifndef FIMS_JSON_HPP
2#define FIMS_JSON_HPP
3
13#include <cctype>
14#include <cstdio>
15#include <iostream>
16#include <fstream>
17#include <map>
18#include <sstream>
19#include <string>
20#include <algorithm>
21#include <vector>
22
23namespace fims {
24class JsonValue;
25
29using JsonObject = std::map<std::string, JsonValue>;
30
34using JsonArray = std::vector<JsonValue>;
35
47
51class JsonValue {
52 public:
55
57 JsonValue(int num) : type(JsonValueType::Number), number(num) {}
58
60 JsonValue(double num) : type(JsonValueType::Number), number(num) {}
61
63 JsonValue(const std::string& str) : type(JsonValueType::String), str(str) {}
64
66 JsonValue(bool b) : type(JsonValueType::Bool), boolean(b) {}
67
69 JsonValue(const JsonObject& obj) : type(JsonValueType::Object), object(obj) {}
70
72 JsonValue(const JsonArray& arr) : type(JsonValueType::JArray), array(arr) {}
73
75 JsonValueType GetType() const { return type; }
76
78 int GetInt() const { return static_cast<int>(number); }
79
81 double GetDouble() const { return number; }
82
84 const std::string& GetString() const { return str; }
85
87 bool GetBool() const { return boolean; }
88
90 JsonObject& GetObject() { return object; }
91
93 JsonArray& GetArray() { return array; }
94
95 private:
96 JsonValueType type;
97 double number;
98 std::string str;
99 bool boolean;
100 JsonObject object;
101 JsonArray array;
102};
103
108 public:
110 JsonValue Parse(const std::string& json);
112 void WriteToFile(const std::string& filename, JsonValue jsonValue);
114 void Show(JsonValue jsonValue);
115
117 static std::string removeWhitespace(const std::string& input) {
118 std::string result;
119 result.reserve(input.size());
120 bool inQuotes = false;
121 bool escaped = false;
122 for (char current : input) {
123 if (inQuotes) {
124 result += current;
125 if (escaped) {
126 escaped = false;
127 } else if (current == '\\') {
128 escaped = true;
129 } else if (current == '"') {
130 inQuotes = false;
131 }
132 } else if (current == '"') {
133 inQuotes = true;
134 result += current;
135 } else if (!std::isspace(static_cast<unsigned char>(current))) {
136 result += current;
137 }
138 }
139 return result;
140 }
141
143 static std::string EscapeString(const std::string& input) {
144 std::string result;
145 result.reserve(input.size());
146 for (char current : input) {
147 switch (current) {
148 case '"':
149 result += "\\\"";
150 break;
151 case '\\':
152 result += "\\\\";
153 break;
154 case '\n':
155 result += "\\n";
156 break;
157 case '\r':
158 result += "\\r";
159 break;
160 case '\t':
161 result += "\\t";
162 break;
163 default:
164 if (static_cast<unsigned char>(current) < 0x20) {
165 char buffer[7];
166 std::snprintf(buffer, sizeof(buffer), "\\u%04x",
167 static_cast<unsigned char>(current));
168 result += buffer;
169 } else {
170 result += current;
171 }
172 }
173 }
174 return result;
175 }
176
182 static std::string PrettyFormatJSON(const std::string& json) {
183 std::string result;
184 std::string input = JsonParser::removeWhitespace(json);
185 int indentLevel = 0;
186 bool inQuotes = false;
187
188 for (size_t i = 0; i < input.size(); ++i) {
189 char current = input[i];
190
191 switch (current) {
192 case '{':
193 case '[':
194 result += current;
195 if (!inQuotes) {
196 result += '\n';
197 indentLevel++;
198 result += std::string(indentLevel * 4, ' ');
199 }
200 break;
201
202 case '}':
203 case ']':
204 if (!inQuotes) {
205 result += '\n';
206 indentLevel--;
207 result += std::string(indentLevel * 4, ' ');
208 }
209 result += current;
210 break;
211
212 case ',':
213 result += current;
214 if (!inQuotes) {
215 result += '\n';
216 result += std::string(indentLevel * 4, ' ');
217 }
218 break;
219
220 case ':':
221 result += current;
222 if (!inQuotes) result += " ";
223 break;
224
225 case '"': {
226 result += current;
227 // A quote is escaped only when preceded by an odd number of '\'
228 size_t backslashes = 0;
229 for (size_t j = i; j > 0 && input[j - 1] == '\\'; --j) {
230 backslashes++;
231 }
232 if (backslashes % 2 == 0) {
233 inQuotes = !inQuotes;
234 }
235 break;
236 }
237
238 default:
239 result += current;
240 break;
241 }
242 }
243 return result;
244 }
245
246 private:
248 void SkipWhitespace();
250 JsonValue ParseValue();
252 JsonValue ParseNumber();
254 JsonValue ParseString();
256 JsonValue ParseBool();
258 JsonValue ParseNull();
260 JsonValue ParseObject();
262 JsonValue ParseArray();
264 void WriteJsonValue(std::ofstream& outputFile, JsonValue jsonValue);
266 void PrintJsonValue(std::ostream& outputFile, JsonValue jsonValue);
268 void Indent(std::ostream& outputFile, int level);
270 void Indent(std::ofstream& outputFile, int level);
271
272 std::string data;
273 size_t position;
274};
275
276} // namespace fims
277#endif
Definition fims_json.hpp:107
void Show(JsonValue jsonValue)
Definition fims_json.cpp:340
void WriteToFile(const std::string &filename, JsonValue jsonValue)
Definition fims_json.cpp:268
static std::string PrettyFormatJSON(const std::string &json)
Formats a JSON string.
Definition fims_json.hpp:182
JsonValue Parse(const std::string &json)
Definition fims_json.cpp:19
static std::string removeWhitespace(const std::string &input)
Definition fims_json.hpp:117
static std::string EscapeString(const std::string &input)
Definition fims_json.hpp:143
Definition fims_json.hpp:51
JsonValue(bool b)
Definition fims_json.hpp:66
JsonValue()
Definition fims_json.hpp:54
JsonValue(const JsonArray &arr)
Definition fims_json.hpp:72
double GetDouble() const
Definition fims_json.hpp:81
JsonArray & GetArray()
Definition fims_json.hpp:93
const std::string & GetString() const
Definition fims_json.hpp:84
JsonValue(const JsonObject &obj)
Definition fims_json.hpp:69
JsonValue(double num)
Definition fims_json.hpp:60
int GetInt() const
Definition fims_json.hpp:78
JsonObject & GetObject()
Definition fims_json.hpp:90
bool GetBool() const
Definition fims_json.hpp:87
JsonValue(const std::string &str)
Definition fims_json.hpp:63
JsonValueType GetType() const
Definition fims_json.hpp:75
JsonValue(int num)
Definition fims_json.hpp:57
std::vector< JsonValue > JsonArray
Definition fims_json.hpp:34
JsonValueType
Definition fims_json.hpp:39
@ Bool
Definition fims_json.hpp:43
@ Number
Definition fims_json.hpp:41
@ String
Definition fims_json.hpp:42
@ Object
Definition fims_json.hpp:44
@ Null
Definition fims_json.hpp:40
@ JArray
Definition fims_json.hpp:45
std::map< std::string, JsonValue > JsonObject
Definition fims_json.hpp:29