13 #ifndef __STOUT_JSON__ 14 #define __STOUT_JSON__ 21 #undef __STDC_FORMAT_MACROS 25 #define PICOJSON_USE_INT64 27 #define __STDC_FORMAT_MACROS 34 #include <type_traits> 37 #include <boost/variant.hpp> 100 typename std::enable_if<std::is_floating_point<T>::value,
int>::
type = 0)
103 template <
typename T>
106 typename std::enable_if<
107 std::is_integral<T>::value && std::is_signed<T>::value,
109 :
type(SIGNED_INTEGER), signed_integer(_value) {}
111 template <
typename T>
114 typename std::enable_if<
115 std::is_integral<T>::value && std::is_unsigned<T>::value,
117 :
type(UNSIGNED_INTEGER), unsigned_integer(_value) {}
119 template <
typename T>
124 return static_cast<T
>(
value);
126 return static_cast<T
>(signed_integer);
127 case UNSIGNED_INTEGER:
128 return static_cast<T
>(unsigned_integer);
162 Object(std::initializer_list<std::pair<const std::string, Value>> values_)
182 template <
typename T>
191 template <
typename T>
192 Result<T> at(
const std::string& key)
const;
201 Array(std::initializer_list<Value> values_) : values(values_) {}
237 typedef boost::variant<
Null,
240 boost::recursive_wrapper<Object>,
241 boost::recursive_wrapper<Array>,
260 template <
typename T>
263 typename std::enable_if<std::is_arithmetic<T>::value,
int>::
type = 0)
268 template <
typename T>
271 typename std::enable_if<!std::is_arithmetic<T>::value,
int>::
type = 0)
274 template <
typename T>
277 template <
typename T>
278 const T& as()
const &;
280 template <
typename T>
283 template <
typename T>
286 template <
typename T>
287 const T&& as()
const &&;
319 struct ContainmentComparator :
public boost::static_visitor<bool>
321 explicit ContainmentComparator(
const Value& _self)
324 bool operator()(
const Object& other)
const;
325 bool operator()(
const Array& other)
const;
326 bool operator()(
const String& other)
const;
327 bool operator()(
const Number& other)
const;
328 bool operator()(
const Boolean& other)
const;
329 bool operator()(
const Null&)
const;
337 template <
typename T>
340 const T* t = boost::get<T>(
this);
346 inline bool Value::is<Value>()
const 352 template <
typename T>
355 return boost::get<T>(*this);
359 template <
typename T>
362 return boost::get<T>(*this);
366 template <
typename T>
369 return std::move(boost::get<T>(*
this));
373 template <
typename T>
376 return std::move(boost::get<T>(*
this));
381 inline const Value& Value::as<Value>()
const &
394 template <
typename T>
397 const std::vector<std::string> names =
strings::split(path,
".", 2);
403 std::string
name = names[0];
408 size_t index = name.find(
'[');
409 if (index != std::string::npos) {
411 if (name.at(name.length() - 1) !=
']') {
412 return Error(
"Malformed array subscript, expecting ']'");
417 std::string s = name.substr(index + 1, name.length() - index - 2);
423 return Error(
"Failed to numify array subscript '" + s +
"'");
424 }
else if (i.
get() < 0) {
425 return Error(
"Array subscript '" + s +
"' must be >= 0");
431 name = name.substr(0, index);
434 std::map<std::string, Value>::const_iterator entry = values.find(name);
436 if (entry == values.end()) {
445 if (subscript.
get() >= array.
values.size()) {
449 }
else if (value.
is<
Null>()) {
453 return Error(
"Intermediate JSON value not an array");
457 if (names.size() == 1) {
459 return value.
as<T>();
460 }
else if (value.
is<
Null>()) {
464 return Error(
"Found JSON value of wrong type");
470 return Error(
"Intermediate JSON value not an object");
473 return value.
as<
Object>().find<T>(names[1]);
477 template <
typename T>
484 std::map<std::string, Value>::const_iterator entry = values.find(key);
486 if (entry == values.end()) {
492 if (!value.
is<T>()) {
494 return Error(
"Found JSON value of wrong type");
497 return value.
as<T>();
503 return boost::apply_visitor(Value::ContainmentComparator(*
this), other);
507 inline bool Value::ContainmentComparator::operator()(
const Object& other)
const 509 if (!
self.is<Object>()) {
514 if (other.
values.empty()) {
527 auto _selfIterator = _self.
values.find(key);
529 if (_selfIterator == _self.
values.end()) {
533 if (!_selfIterator->second.contains(value)) {
542 inline bool Value::ContainmentComparator::operator()(
const String& other)
const 544 if (!
self.is<String>()) {
551 inline bool Value::ContainmentComparator::operator()(
const Number& other)
const 553 if (!
self.is<Number>()) {
568 switch (number.
type) {
570 switch (other.
type) {
580 switch (other.
type) {
592 switch (other.
type) {
608 inline bool Value::ContainmentComparator::operator()(
const Array& other)
const 610 if (!
self.is<Array>()) {
620 for (
unsigned i = 0; i < other.
values.size(); ++i) {
630 inline bool Value::ContainmentComparator::operator()(
const Boolean& other)
const 632 if (!
self.is<Boolean>()) {
639 inline bool Value::ContainmentComparator::operator()(
const Null&)
const 641 return self.is<
Null>();
670 return Value::ContainmentComparator(
value)(other);
701 return boost::apply_visitor(
Comparator(lhs), rhs);
707 return !(lhs == rhs);
749 switch (number.
type) {
765 json(writer,
object.values);
817 typename std::enable_if<std::is_same<T, Value>::value,
int>
::type = 0>
822 using result_type = void;
824 void operator()(
const Boolean& value)
const 826 json(std::move(writer_), value);
828 void operator()(
const String& value)
const 830 json(std::move(writer_), value);
832 void operator()(
const Number& value)
const 834 json(std::move(writer_), value);
836 void operator()(
const Object& value)
const 838 json(std::move(writer_), value);
840 void operator()(
const Array& value)
const 842 json(std::move(writer_), value);
844 void operator()(
const Null& value)
const 846 json(std::move(writer_), value);
850 } visitor{std::move(writer)};
851 boost::apply_visitor(visitor, value);
857 return stream <<
jsonify(
boolean);
863 return stream <<
jsonify(
string);
869 return stream <<
jsonify(number);
875 return stream <<
jsonify(
object);
881 return stream <<
jsonify(array);
887 return stream <<
jsonify(null);
903 :
value(_value), depth(_depth) {}
917 picojson::value v(f);
922 template <
typename Iter>
937 template <
typename Iter>
942 return picojson::_parse(
context, in);
959 template <
typename Iter>
963 return picojson::_parse(context, in);
980 const char* parseBegin = s.c_str();
990 const char* lastVisibleChar =
998 const char* parseEnd;
1002 picojson::_parse(context, parseBegin, parseBegin + s.size(), &
error);
1003 }
catch (
const std::overflow_error&) {
1004 return Error(
"Value out of range");
1006 return Error(
"Unknown JSON parse error");
1009 if (!error.empty()) {
1010 return Error(error);
1011 }
else if (parseEnd != lastVisibleChar + 1) {
1013 "Parsed JSON included non-whitespace trailing characters: " 1014 + s.substr(parseEnd - parseBegin, lastVisibleChar + 1 - parseEnd));
1021 return std::move(value);
1025 template <
typename T>
1034 if (!value->is<T>()) {
1035 return Error(
"Unexpected JSON type parsed");
1038 return std::move(value->as<T>());
1050 #endif // __STOUT_JSON__ T as() const
Definition: json.hpp:120
bool parse_array_item(picojson::input< Iter > &in, size_t)
Definition: json.hpp:938
int64_t signed_integer
Definition: json.hpp:152
Value(const T &value, typename std::enable_if< std::is_arithmetic< T >::value, int >::type=0)
Definition: json.hpp:261
constexpr size_t STOUT_JSON_MAX_DEPTH
Definition: json.hpp:894
bool operator()(const Null &) const
Definition: json.hpp:689
bool value
Definition: json.hpp:211
Definition: errorbase.hpp:36
bool operator()(const Number &other) const
Definition: json.hpp:666
F && f
Definition: defer.hpp:270
T & get()&
Definition: try.hpp:80
Boolean()
Definition: json.hpp:209
Value(char *value)
Definition: json.hpp:254
Definition: jsonify.hpp:364
Definition: jsonify.hpp:137
bool parse_string(picojson::input< Iter > &in)
Definition: json.hpp:923
Type
Definition: json.hpp:138
std::map< std::string, Value > values
Definition: json.hpp:194
Definition: jsonify.hpp:255
Value()
Definition: json.hpp:250
bool isSome() const
Definition: option.hpp:116
size_t depth
Definition: json.hpp:972
Value(bool value)
Definition: json.hpp:252
bool is() const
Definition: json.hpp:338
bool set_int64(int64_t i)
Definition: json.hpp:910
Result< T > at(const std::string &key) const
Definition: json.hpp:478
double value
Definition: json.hpp:151
void json(BooleanWriter *writer, const Boolean &boolean)
Definition: json.hpp:735
Result< int > index(const std::string &link)
Number(T _value, typename std::enable_if< std::is_integral< T >::value &&std::is_signed< T >::value, int >::type=0)
Definition: json.hpp:104
Value * value
Definition: json.hpp:971
bool parse_array_stop(size_t)
Definition: json.hpp:945
String(const char *_value)
Definition: json.hpp:82
Array(std::initializer_list< Value > values_)
Definition: json.hpp:201
Number(T _value, typename std::enable_if< std::is_floating_point< T >::value, int >::type=0)
Definition: json.hpp:98
bool operator!=(const Value &lhs, const Value &rhs)
Definition: json.hpp:705
String()
Definition: json.hpp:81
const T & as() const &
Definition: json.hpp:353
Definition: variant.hpp:47
const std::string WHITESPACE
Definition: strings.hpp:30
Definition: jsonify.hpp:326
const T & get() const &
Definition: option.hpp:119
#define foreachpair(KEY, VALUE, ELEMS)
Definition: foreach.hpp:51
String(const std::string &_value)
Definition: json.hpp:83
Try< Value > parse(const std::string &s)
Returns the OCI v1 descriptor, image index, image manifest and image configuration from the given str...
Definition: json.hpp:978
std::vector< Value > values
Definition: json.hpp:203
Definition: jsonify.hpp:161
std::ostream & operator<<(std::ostream &stream, const Boolean &boolean)
Definition: json.hpp:855
static Try error(const E &e)
Definition: try.hpp:43
bool operator()(const Object &object) const
Definition: json.hpp:650
JSON::Proxy jsonify(const T &)
Definition: jsonify.hpp:702
#define UNREACHABLE()
Definition: unreachable.hpp:22
Value(const T &value, typename std::enable_if<!std::is_arithmetic< T >::value, int >::type=0)
Definition: json.hpp:269
bool operator==(const Value &lhs, const Value &rhs)
Definition: json.hpp:699
Definition: attributes.hpp:24
bool isError() const
Definition: try.hpp:78
bool parse_object_start()
Definition: json.hpp:950
bool parse_array_start()
Definition: json.hpp:928
Number(T _value, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value, int >::type=0)
Definition: json.hpp:112
std::string error(const std::string &msg, uint32_t code)
bool contains(const Value &other) const
Definition: json.hpp:501
Value(const char *value)
Definition: json.hpp:255
False()
Definition: json.hpp:227
Try< uint32_t > type(const std::string &path)
Comparator(const Value &_value)
Definition: json.hpp:647
std::vector< std::string > split(const std::string &s, const std::string &delims, const Option< size_t > &maxTokens=None())
Definition: strings.hpp:184
bool operator()(const Array &array) const
Definition: json.hpp:673
bool set_bool(bool b)
Definition: json.hpp:909
bool operator()(const Boolean &boolean) const
Definition: json.hpp:681
bool operator()(const String &string) const
Definition: json.hpp:658
boost::variant< Null, String, Number, boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, Boolean > Variant
Definition: json.hpp:242
Number()
Definition: json.hpp:95
bool parse_object_item(picojson::input< Iter > &in, const std::string &key)
Definition: json.hpp:960
uint64_t unsigned_integer
Definition: json.hpp:153
bool set_null()
Definition: json.hpp:908
enum JSON::Number::Type type
Result< T > find(const std::string &path) const
Definition: json.hpp:395
ParseContext(Value *_value, size_t _depth=STOUT_JSON_MAX_DEPTH)
Definition: json.hpp:902
constexpr const char * name
Definition: shell.hpp:41
bool contains(const Resource &left, const Resource &right)
Boolean(bool _value)
Definition: json.hpp:210
Definition: jsonify.hpp:557
bool parse_object_stop()
Definition: json.hpp:966
std::string value
Definition: json.hpp:84
True()
Definition: json.hpp:219
Try< std::list< std::string > > find(const std::string &directory, const std::string &pattern)
Definition: find.hpp:37
Definition: jsonify.hpp:296
Object(std::initializer_list< std::pair< const std::string, Value >> values_)
Definition: json.hpp:162
bool set_number(double f)
Definition: json.hpp:912