Ocean
Loading...
Searching...
No Matches
JSONConfig.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_IO_JSON_CONFIG_H
9#define META_OCEAN_IO_JSON_CONFIG_H
10
11#include "ocean/io/IO.h"
12#include "ocean/io/Scanner.h"
13
14#include "ocean/base/Config.h"
15
16namespace Ocean
17{
18
19namespace IO
20{
21
22/**
23 * This class implements a configuration toolkit based on JSON.
24 * @ingroup io
25 */
26class OCEAN_IO_EXPORT JSONConfig final : public Config
27{
28 public:
29
30 // Forward declaration
31 class JSONValue;
32
33 /**
34 * Definition of a map mapping value names to value objects.
35 */
36 typedef std::unordered_map<std::string, std::vector<JSONValue>> JSONValues;
37
38 /**
39 * Definition of a JSON value object.
40 */
41 class OCEAN_IO_EXPORT JSONValue final : public Value
42 {
43 friend class JSONConfig;
44
45 public:
46
47 /**
48 * Creates a new value object.
49 */
51
52 /**
53 * Default copy constructor.
54 * @param value The value to copy
55 */
56 JSONValue(const JSONValue& value) = default;
57
58 /**
59 * Creates a new value object by a single value as string and the real value type.
60 * @param value String value
61 * @param type Value type
62 */
63 JSONValue(const std::string& value, const ValueType type);
64
65 /**
66 * Creates a new value object holding sub values.
67 * @param values Sub values
68 */
69 explicit JSONValue(const JSONValues& values);
70
71 /**
72 * Destructs a value object.
73 */
74 ~JSONValue() override;
75
76 /**
77 * Returns the number of sub values.
78 * @see Config::Value::values().
79 */
80 unsigned int values() const override;
81
82 /**
83 * Returns the number of sub values with a given name.
84 * @param name The name of the JSON node
85 * @see Config::Value::values().
86 */
87 unsigned int values(const std::string& name) const override;
88
89 /**
90 * Returns whether this value holds at least one specified sub value.
91 * @param name The name of the JSON node
92 * @see Config::Value::exist().
93 */
94 bool exist(const std::string& name) const override;
95
96 /**
97 * Returns a sub value specified by it's name and it's index if more than one value exists with the same name.
98 * @param name The name of the JSON node
99 * @param index The index of the specific node in case multiple nodes with the same name exist, range: [0, infinity)
100 * @return A reference to the node with the specified name, will be an empty node if the name doesn't exist
101 * @see Config::Value::value().
102 */
103 JSONValue& value(const std::string& name, const unsigned int index) override;
104
105 /**
106 * Returns a sub value specified by it's name and it's index if more than one value exists with the same name.
107 * @param name The name of the JSON node, must be valid
108 * @param index The index of the specific node in case multiple nodes with the same name exist, range: [0, infinity)
109 * @param value Pointer to the memory where the value of the selected node will be copied to
110 * @return True if the node with the specified name exists, otherwise false
111 * @see Config::Value::value().
112 */
113 bool value(const std::string& name, const unsigned int index, Value** value) override;
114
115 /**
116 * Returns a sub value specified by it's index.
117 * @param index The index of the specific node , range: [0, N), where N = number of nodes
118 * @param name The name of the JSON node at index @c index, will be unchanged if that node doesn't exist
119 * @return A reference to the node with the specified name, will be an empty node if the name doesn't exist
120 * @see Config::Value::value().
121 */
122 JSONValue& value(const unsigned int index, std::string& name) override;
123
124 /**
125 * Returns a sub value specified by it's index.
126 * @param index The index of the specific node , range: [0, N), where N = number of nodes
127 * @param name The name of the JSON node, must be valid
128 * @param value Pointer to the memory where the value of the selected node will be copied to
129 * @return True if the node with the specified name exists, otherwise false
130 * @see Config::Value::value().
131 */
132 bool value(const unsigned int index, std::string& name, Value** value) override;
133
134 /**
135 * Adds a new sub value specified by it's name.
136 * @param name The name of the sub value to create
137 * @return New sub value
138 */
139 JSONValue& add(const std::string& name) override;
140
141 /**
142 * Returns this value as boolean.
143 * @param value The value that is returned in case the type of the internal value doesn't match (or cannot be cast into) the type of this parameter/return type of this function
144 * @return The internal value of this node
145 * @see Config::Value::operator().
146 */
147 bool operator()(const bool value) const override;
148
149 /**
150 * Returns this value as integer.
151 * @param value The value that is returned in case the type of the internal value doesn't match (or cannot be cast into) the type of this parameter/return type of this function
152 * @return The internal value of this node
153 * @see Config::Value::operator().
154 */
155 int operator()(const int value) const override;
156
157 /**
158 * Returns this value as number.
159 * @param value The value that is returned in case the type of the internal value doesn't match (or cannot be cast into) the type of this parameter/return type of this function
160 * @return The internal value of this node
161 * @see Config::Value::operator().
162 */
163 double operator()(const double value) const override;
164
165 /**
166 * Returns this value as string.
167 * @param value The value that is returned in case the type of the internal value doesn't match (or cannot be cast into) the type of this parameter/return type of this function
168 * @return The internal value of this node
169 * @see Config::Value::operator().
170 */
171 std::string operator()(const std::string& value) const override;
172
173 /**
174 * Returns this value as multi boolean.
175 * @param value The value that is returned in case the type of the internal value doesn't match (or cannot be cast into) the type of this parameter/return type of this function
176 * @return The internal value of this node
177 * @see Config::Value::operator().
178 */
179 std::vector<bool> operator()(const std::vector<bool>& value) const override;
180
181 /**
182 * Returns this value as multi integer.
183 * @param value The value that is returned in case the type of the internal value doesn't match (or cannot be cast into) the type of this parameter/return type of this function
184 * @return The internal value of this node
185 * @see Config::Value::operator().
186 */
187 std::vector<int> operator()(const std::vector<int>& value) const override;
188
189 /**
190 * Returns this value as multi number.
191 * @param value The value that is returned in case the type of the internal value doesn't match (or cannot be cast into) the type of this parameter/return type of this function
192 * @return The internal value of this node
193 * @see Config::Value::operator().
194 */
195 std::vector<double> operator()(const std::vector<double>& value) const override;
196
197 /**
198 * Returns this value as multi string.
199 * @param value The value that is returned in case the type of the internal value doesn't match (or cannot be cast into) the type of this parameter/return type of this function
200 * @return The internal value of this node
201 * @see Config::Value::operator().
202 */
203 std::vector<std::string> operator()(const std::vector<std::string>& value) const override;
204
205 /**
206 * Sets this value as boolean.
207 * @param value Will set the internal value and value type of this node, node must be valid and not a group
208 * @return True if the value could be set, otherwise false
209 * @see Config::Value::operator=().
210 */
211 bool operator=(const bool value) override;
212
213 /**
214 * Sets this value as integer.
215 * @param value Will set the internal value and value type of this node, node must be valid and not a group
216 * @return True if the value could be set, otherwise false
217 * @see Config::Value::operator=().
218 */
219 bool operator=(const int value) override;
220
221 /**
222 * Sets this value as number.
223 * @param value Will set the internal value and value type of this node, node must be valid and not a group. Up to 10 decimals of the value will be stored.
224 * @return True if the value could be set, otherwise false
225 * @see Config::Value::operator=().
226 */
227 bool operator=(const double value) override;
228
229 /**
230 * Sets this value as string.
231 * @param value Will set the internal value and value type of this node, node must be valid and not a group
232 * @return True if the value could be set, otherwise false
233 * @see Config::Value::operator=().
234 */
235 bool operator=(const std::string& value) override;
236
237 /**
238 * Sets this value as multi boolean.
239 * @param values Will set the internal value and value type of this node, node must be valid and not a group
240 * @return True if the value could be set, otherwise false
241 * @see Config::Value::operator=().
242 */
243 bool operator=(const std::vector<bool>& values) override;
244
245 /**
246 * Sets this value as multi integer.
247 * @param values Will set the internal value and value type of this node, node must be valid and not a group
248 * @return True if the value could be set, otherwise false
249 * @see Config::Value::operator=().
250 */
251 bool operator=(const std::vector<int>& values) override;
252
253 /**
254 * Sets this value as multi number.
255 * @param values Will set the internal value and value type of this node, node must be valid and not a group
256 * @return True if the value could be set, otherwise false
257 * @see Config::Value::operator=().
258 */
259 bool operator=(const std::vector<double>& values) override;
260
261 /**
262 * Sets this value as multi string.
263 * @param values Will set the internal value and value type of this node, node must be valid and not a group
264 * @return True if the value could be set, otherwise false
265 * @see Config::Value::operator=().
266 */
267 bool operator=(const std::vector<std::string>& values) override;
268
269 /**
270 * Returns a sub value specified by it's name
271 * @param name The name of the JSON node to retrieve
272 * @return A reference to the node with the specified name; will be an empty node if the name doesn't exist
273 * @see Config::Value::operator[]().
274 */
275 JSONValue& operator[](const std::string& name) override;
276
277 /**
278 * Returns a sub value specified by it's name
279 * @param name The name of the JSON node to retrieve
280 * @return A constant reference to the node with the specified name; will be an empty node if the name doesn't exist
281 * @see Config::Value::operator[]().
282 */
283 const JSONValue& operator[](const std::string& name) const;
284
285 private:
286
287 /**
288 * Returns the boolean value of this object.
289 * @return Parsed boolean value
290 */
291 bool boolValue() const;
292
293 /**
294 * Returns the integer value of this object.
295 * @return Parsed integer value
296 */
297 int integerValue() const;
298
299 /**
300 * Returns the number value of this object.
301 * @return Parsed number value
302 */
303 double numberValue() const;
304
305 /**
306 * Returns the boolean value of this object.
307 * @return Parsed boolean value
308 */
309 std::vector<bool> boolValues() const;
310
311 /**
312 * Returns the integer values of this object.
313 * @return Parsed integer value
314 */
315 std::vector<int> integerValues() const;
316
317 /**
318 * Returns the number values of this object.
319 * @return Parsed number value
320 */
321 std::vector<double> numberValues() const;
322
323 /**
324 * Returns the string values of this object.
325 * @return Parsed number value
326 */
327 std::vector<std::string> stringValues() const;
328
329 private:
330
331 /// Value as string.
332 std::string valueString_;
333
334 /// Sub values if this value is a group.
336 };
337
338 protected:
339
340 /**
341 * This class implements a scanner for JSON files.
342 */
343 class JSONScanner : public Scanner
344 {
345 public:
346
347 /**
348 * Definition of individual JSON symbols.
349 */
351 {
352 /// Node begin symbol: '{'.
354 /// Node end symbol: '}'.
356 /// Array begin symbol: '['.
358 /// Node end symbol: ']'.
360 /// Colon symbol: '.'
362 /// Comma symbol: ','
363 JS_COMMA
364 };
365
366 /**
367 * Definition of individual JSON keywords.
368 */
370 {
371 /// Keyword true.
373 /// Keyword false.
375 /// Keyword null.
376 JK_NULL
377 };
378
379 public:
380
381 /**
382 * Creates a new scanner by a given filename.
383 * @param stream The input stream from which the JSON data is read, must be valid
384 * @param progress Optional scanner progress value
385 * @param cancel Optional scanner cancel state
386 * @see Scanner::Scanner().
387 */
388 explicit JSONScanner(const std::shared_ptr<std::istream>& stream, float* progress = nullptr, bool* cancel = nullptr);
389 };
390
391 public:
392
393 /**
394 * Creates a new config object.
395 */
397
398 /**
399 * Creates a new config object with a specified configuration file.
400 * @param filename The name of the file associated with the new config object
401 * @param read True, to load the data from the file directly
402 * @see read().
403 */
404 explicit JSONConfig(const std::string& filename, const bool read = true);
405
406 /**
407 * Creates a new config object with a specified input stream.
408 * @param stream The input stream from which the JSON data is read immediately, must be valid
409 */
410 explicit JSONConfig(const std::shared_ptr<std::istream>& stream);
411
412 /**
413 * Returns the config file.
414 * @return Config file
415 */
416 inline const std::string& filename() const;
417
418 /**
419 * Sets the filename of the new config objects.
420 * All old config objects will be released before.
421 * @param filename to set
422 * @param read True, to load the file directly
423 * @return True, if the file could be loaded
424 */
425 bool setFilename(const std::string& filename, const bool read = true);
426
427 /**
428 * Reads / loads all values of this configuration.
429 * @see Config::read().
430 */
431 bool read() override;
432
433 /**
434 * Writes / saves all values of this configuration.
435 * @see Config::write().
436 */
437 bool write() override;
438
439 /**
440 * Returns the number of sub values.
441 * @see Config::values().
442 */
443 unsigned int values() const override;
444
445 /**
446 * Returns the number of sub values with a given name.
447 * @see Config::values().
448 */
449 unsigned int values(const std::string& name) const override;
450
451 /**
452 * Returns whether this value holds at least one specified sub value.
453 * @see Config::exist().
454 */
455 bool exist(const std::string& name) const override;
456
457 /**
458 * Returns a sub value specified by it's index.
459 * @see Config::value().
460 */
461 JSONValue& value(const unsigned int index, std::string& name) override;
462
463 /**
464 * Returns a sub value specified by it's index.
465 * @see Config::value().
466 */
467 bool value(const unsigned int index, std::string& name, Value** value) override;
468
469 /**
470 * Returns a sub value specified by it's name and it's index if more than one value exists with the same name.
471 * @see Config::value().
472 */
473 JSONValue& value(const std::string& name, const unsigned int index) override;
474
475 /**
476 * Returns a sub value specified by it's name and it's index if more than one value exists with the same name.
477 * @see Config::value().
478 */
479 bool value(const std::string& name, const unsigned int index, Value** value) override;
480
481 /**
482 * Adds a new sub value specified by it's name.
483 * @param name The name of the sub value to create
484 * @return New sub value
485 */
486 JSONValue& add(const std::string& name) override;
487
488 /**
489 * Returns a sub value specified by it's name
490 * @see Config::operator[]().
491 */
492 JSONValue& operator[](const std::string& name) override;
493
494 protected:
495
496 /**
497 * Parses a JSON node.
498 * @param node The node receiving the parse data
499 * @param scanner The scanner from which the information is parsed, while the node begin symbol has been popped already
500 * @return True, if succeeded
501 */
502 bool parseNode(JSONValue& node, JSONScanner& scanner);
503
504 /**
505 * Parses a JSON array.
506 * @param node The node receiving the parse data
507 * @param fieldName The name of the array
508 * @param scanner The scanner from which the information is parsed, while the array begin symbol has been popped already
509 * @return True, if succeeded
510 */
511 bool parseArray(JSONValue& node, const std::string& fieldName, JSONScanner& scanner);
512
513 /**
514 * Writes a JSON node.
515 * @param node The node to be written
516 * @param stream The output stream receiving the node's information
517 * @param indentation The indentation of the node (the number of empty space characters in front of the node), with range [0, infinity)
518 * @return True, if succeeded
519 */
520 static bool writeNode(JSONValue& node, std::ostream& stream, const unsigned int indentation);
521
522 /**
523 * Writes a line (with indentation) to an output stream.
524 * @param string The string to be written
525 * @param stream The output stream in which the string will be written
526 * @param indentation The number of empty space characters to be written in front of the string, with range [0, infinity)
527 * @return True, if succeeded
528 */
529 static bool writeLine(const std::string& string, std::ostream& stream, const unsigned int indentation);
530
531 /**
532 * Returns the default value holding no data.
533 * @return The default value holding no data.
534 */
536
537 protected:
538
539 /// Filename of this config object.
540 std::string filename_;
541
542 /// The root value.
544};
545
546inline const std::string& JSONConfig::filename() const
547{
548 return filename_;
549}
550
551} // namespace IO
552
553} // namespace Ocean
554
555#endif // META_OCEAN_IO_JSON_CONFIG_H
This class implements a configuration value.
Definition Config.h:77
This class implements an application or module configuration toolkit.
Definition Config.h:38
ValueType
Definition of different value types.
Definition Config.h:45
This class implements a scanner for JSON files.
Definition JSONConfig.h:344
JSONScanner(const std::shared_ptr< std::istream > &stream, float *progress=nullptr, bool *cancel=nullptr)
Creates a new scanner by a given filename.
JSONKeyword
Definition of individual JSON keywords.
Definition JSONConfig.h:370
@ JK_FALSE
Keyword false.
Definition JSONConfig.h:374
@ JK_TRUE
Keyword true.
Definition JSONConfig.h:372
JSONSymbol
Definition of individual JSON symbols.
Definition JSONConfig.h:351
@ JS_NODE_BEGIN
Node begin symbol: '{'.
Definition JSONConfig.h:353
@ JS_ARRAY_END
Node end symbol: ']'.
Definition JSONConfig.h:359
@ JS_COLON
Colon symbol: '.'.
Definition JSONConfig.h:361
@ JS_NODE_END
Node end symbol: '}'.
Definition JSONConfig.h:355
@ JS_ARRAY_BEGIN
Array begin symbol: '['.
Definition JSONConfig.h:357
Definition of a JSON value object.
Definition JSONConfig.h:42
JSONValues subValues_
Sub values if this value is a group.
Definition JSONConfig.h:335
JSONValue & add(const std::string &name) override
Adds a new sub value specified by it's name.
bool value(const std::string &name, const unsigned int index, Value **value) override
Returns a sub value specified by it's name and it's index if more than one value exists with the same...
std::string operator()(const std::string &value) const override
Returns this value as string.
std::vector< bool > boolValues() const
Returns the boolean value of this object.
double operator()(const double value) const override
Returns this value as number.
std::vector< bool > operator()(const std::vector< bool > &value) const override
Returns this value as multi boolean.
std::vector< std::string > stringValues() const
Returns the string values of this object.
JSONValue & operator[](const std::string &name) override
Returns a sub value specified by it's name.
int operator()(const int value) const override
Returns this value as integer.
bool operator=(const std::vector< bool > &values) override
Sets this value as multi boolean.
bool boolValue() const
Returns the boolean value of this object.
JSONValue()
Creates a new value object.
bool exist(const std::string &name) const override
Returns whether this value holds at least one specified sub value.
int integerValue() const
Returns the integer value of this object.
JSONValue & value(const std::string &name, const unsigned int index) override
Returns a sub value specified by it's name and it's index if more than one value exists with the same...
bool operator=(const double value) override
Sets this value as number.
JSONValue(const JSONValues &values)
Creates a new value object holding sub values.
std::vector< int > integerValues() const
Returns the integer values of this object.
JSONValue(const JSONValue &value)=default
Default copy constructor.
unsigned int values() const override
Returns the number of sub values.
bool value(const unsigned int index, std::string &name, Value **value) override
Returns a sub value specified by it's index.
JSONValue & value(const unsigned int index, std::string &name) override
Returns a sub value specified by it's index.
bool operator=(const std::vector< int > &values) override
Sets this value as multi integer.
~JSONValue() override
Destructs a value object.
std::string valueString_
Value as string.
Definition JSONConfig.h:332
const JSONValue & operator[](const std::string &name) const
Returns a sub value specified by it's name.
std::vector< std::string > operator()(const std::vector< std::string > &value) const override
Returns this value as multi string.
std::vector< double > numberValues() const
Returns the number values of this object.
bool operator=(const std::vector< std::string > &values) override
Sets this value as multi string.
bool operator()(const bool value) const override
Returns this value as boolean.
bool operator=(const bool value) override
Sets this value as boolean.
bool operator=(const std::string &value) override
Sets this value as string.
JSONValue(const std::string &value, const ValueType type)
Creates a new value object by a single value as string and the real value type.
std::vector< double > operator()(const std::vector< double > &value) const override
Returns this value as multi number.
bool operator=(const int value) override
Sets this value as integer.
double numberValue() const
Returns the number value of this object.
unsigned int values(const std::string &name) const override
Returns the number of sub values with a given name.
std::vector< int > operator()(const std::vector< int > &value) const override
Returns this value as multi integer.
bool operator=(const std::vector< double > &values) override
Sets this value as multi number.
This class implements a configuration toolkit based on JSON.
Definition JSONConfig.h:27
JSONValue root_
The root value.
Definition JSONConfig.h:543
JSONValue & value(const std::string &name, const unsigned int index) override
Returns a sub value specified by it's name and it's index if more than one value exists with the same...
static bool writeNode(JSONValue &node, std::ostream &stream, const unsigned int indentation)
Writes a JSON node.
bool value(const unsigned int index, std::string &name, Value **value) override
Returns a sub value specified by it's index.
JSONConfig(const std::string &filename, const bool read=true)
Creates a new config object with a specified configuration file.
const std::string & filename() const
Returns the config file.
Definition JSONConfig.h:546
std::string filename_
Filename of this config object.
Definition JSONConfig.h:540
JSONConfig()
Creates a new config object.
bool read() override
Reads / loads all values of this configuration.
JSONValue & add(const std::string &name) override
Adds a new sub value specified by it's name.
bool parseArray(JSONValue &node, const std::string &fieldName, JSONScanner &scanner)
Parses a JSON array.
bool parseNode(JSONValue &node, JSONScanner &scanner)
Parses a JSON node.
unsigned int values() const override
Returns the number of sub values.
bool setFilename(const std::string &filename, const bool read=true)
Sets the filename of the new config objects.
bool write() override
Writes / saves all values of this configuration.
JSONValue & value(const unsigned int index, std::string &name) override
Returns a sub value specified by it's index.
bool value(const std::string &name, const unsigned int index, Value **value) override
Returns a sub value specified by it's name and it's index if more than one value exists with the same...
JSONValue & operator[](const std::string &name) override
Returns a sub value specified by it's name.
JSONConfig(const std::shared_ptr< std::istream > &stream)
Creates a new config object with a specified input stream.
unsigned int values(const std::string &name) const override
Returns the number of sub values with a given name.
bool exist(const std::string &name) const override
Returns whether this value holds at least one specified sub value.
static bool writeLine(const std::string &string, std::ostream &stream, const unsigned int indentation)
Writes a line (with indentation) to an output stream.
std::unordered_map< std::string, std::vector< JSONValue > > JSONValues
Definition of a map mapping value names to value objects.
Definition JSONConfig.h:36
static JSONValue & nullValue()
Returns the default value holding no data.
This class implements a simple scanner.
Definition Scanner.h:31
The namespace covering the entire Ocean framework.
Definition Accessor.h:15