libfilezilla
json.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_JSON_HEADER
2 #define LIBFILEZILLA_JSON_HEADER
3 
7 #include "string.hpp"
8 
9 #include <map>
10 #include <type_traits>
11 #include <variant>
12 
13 namespace fz {
14 
16 enum class json_type {
17  none,
18  null,
19  object,
20  array,
21  string,
22  number,
23  boolean
24 };
25 
26 class buffer;
27 
30 class FZ_PUBLIC_SYMBOL json final
31 {
32 public:
33  json() noexcept = default;
34  json(json const&) = default;
35  json(json &&) noexcept = default;
36 
38  explicit json(json_type t);
39 
40  json_type type() const {
41  return static_cast<json_type>(value_.index());
42  }
43 
45  std::string string_value() const;
46 
48  std::wstring wstring_value() const {
49  return fz::to_wstring_from_utf8(string_value());
50  }
51 
52 
54  template<typename T, std::enable_if_t<std::is_integral_v<typename std::decay_t<T>>, int> = 0>
55  T number_value() const {
56  return static_cast<T>(number_value_integer());
57  }
58 
60  template<typename T, std::enable_if_t<std::is_floating_point_v<typename std::decay_t<T>>, int> = 0>
61  T number_value() const {
62  return static_cast<T>(number_value_double());
63  }
64 
66  bool bool_value() const;
67 
69  void erase(std::string const& name);
70 
72  json const& operator[](std::string const& name) const;
73 
80  json& operator[](std::string const& name);
81 
83  json const& operator[](size_t i) const;
84 
91  json& operator[](size_t i);
92 
94  size_t children() const;
95 
97  template<typename Bool, std::enable_if_t<std::is_same_v<bool, typename std::decay_t<Bool>>, int> = 0>
98  json& operator=(Bool b) {
99  value_ = b;
100  return *this;
101  }
102 
104  template<typename T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<bool, typename std::decay_t<T>>, int> = 0>
105  json& operator=(T n) {
106  value_.emplace<std::size_t(json_type::number)>(fz::to_string(n));
107  return *this;
108  }
109 
114  json& operator=(std::string_view const& v);
115 
117  json& operator=(std::wstring_view const& v) {
118  return *this = to_utf8(v);
119  }
120 
121  json& operator=(json const&);
122  json& operator=(json &&) noexcept;
123 
124  explicit operator bool() const { return type() != json_type::none; }
125 
126  bool has_non_null_value() const {
127  return type() != fz::json_type::none && type() != fz::json_type::null;
128  }
129 
130  bool is_null() const { return type() == fz::json_type::null; }
131  bool is_object() const { return type() == fz::json_type::object; }
132  bool is_array() const { return type() == fz::json_type::array; }
133  bool is_number() const { return type() == fz::json_type::number; }
134  bool is_boolean() const { return type() == fz::json_type::boolean; }
135 
141  std::string to_string(bool pretty = false, size_t depth = 0) const;
142 
150  void to_string(std::string & ret, bool pretty = false, size_t depth = 0) const;
151 
156  static json parse(std::string_view const& v, size_t max_depth = 20);
157  static json parse(fz::buffer const& b, size_t max_depth = 20);
158 
159  void clear();
160 
161 private:
162  uint64_t number_value_integer() const;
163  double number_value_double() const;
164 
165  bool FZ_PRIVATE_SYMBOL check_type(json_type t);
166  void FZ_PRIVATE_SYMBOL set_type(json_type t);
167 
168  static json FZ_PRIVATE_SYMBOL parse(char const*& p, char const* end, size_t max_depth);
169 
170  typedef std::variant<
171  std::monostate, // json_type::none
172  std::nullptr_t, // json_type::null
173  std::map<std::string, json, std::less<>>, // json_type::object
174  std::vector<json>, // json_type::array
175  std::string, // json_type::string,
176  std::string, // json_type::number,
177  bool // json_type::boolean
178  > value_type;
179  value_type value_;
180 };
181 
182 template <bool isconst>
183 struct json_array_iterator final {
184  using json_ref_t = std::conditional_t<isconst, json const&, json &>;
185 
186  struct sentinel final {};
187 
188  json_array_iterator(json_ref_t j)
189  // 0 if it's an array, -1 otherwise
190  : idx_((j.type() == json_type::array)-1)
191  , json_(j)
192  {}
193 
194  json_array_iterator & operator++()
195  {
196  ++idx_;
197 
198  return *this;
199  }
200 
201  json_ref_t operator*() const
202  {
203  return json_[idx_];
204  }
205 
206  bool operator!=(json_array_iterator::sentinel const&) const
207  {
208  return idx_ < json_.children();
209  }
210 
211 private:
212  std::size_t idx_;
213  json_ref_t json_;
214 };
215 
216 inline json_array_iterator<false> begin(json &j) { return {j}; }
217 inline json_array_iterator<false>::sentinel end(json &) { return {}; }
218 
219 inline json_array_iterator<true> begin(json const& j) { return {j}; }
220 inline json_array_iterator<true>::sentinel end(json const&) { return {}; }
221 
222 }
223 
224 #endif
The buffer class is a simple buffer where data can be appended at the end and consumed at the front....
Definition: buffer.hpp:27
json parser/builder
Definition: json.hpp:31
static json parse(std::string_view const &v, size_t max_depth=20)
Parses JSON structure from input.
std::string to_string(bool pretty=false, size_t depth=0) const
Serializes JSON structure.
json & operator=(std::wstring_view const &v)
Sets type to string and assigns value.
Definition: json.hpp:117
json & operator=(Bool b)
Sets type to boolean and assigns value.
Definition: json.hpp:98
json const & operator[](std::string const &name) const
If object, get the value with the given name. Returns none if not object or name doesn't exist.
std::string string_value() const
Returns string, number and boolean values as string.
void erase(std::string const &name)
If object value, deletes child value with given name.
json & operator[](size_t i)
Returns reference to the child value with the given index.
json const & operator[](size_t i) const
If array, get the value with the given index. Returns none if not array or index doesn't exist.
size_t children() const
For arrays and objects, returns the number of elements.
void to_string(std::string &ret, bool pretty=false, size_t depth=0) const
Serializes JSON structure.
json & operator=(std::string_view const &v)
Sets type to string and assigns value.
T number_value() const
Returns number and string values as the passed integer type.
Definition: json.hpp:55
json & operator=(T n)
Sets type to number and assigns value.
Definition: json.hpp:105
std::wstring wstring_value() const
Returns string, number and boolean values as wstring.
Definition: json.hpp:48
json(json_type t)
Explicitly creates a value of a specific type, mainly needed for null objects.
bool bool_value() const
Returns boolean and string values as bool.
json & operator[](std::string const &name)
Returns reference to the child value with the given name.
type
Definition: logger.hpp:16
The namespace used by libfilezilla.
Definition: apply.hpp:17
std::wstring to_wstring_from_utf8(std::string_view const &in)
Converts from std::string in UTF-8 into std::wstring.
std::string to_string(std::wstring_view const &in)
Converts from std::wstring into std::string in system encoding.
std::string to_utf8(std::string_view const &in)
Converts from std::string in native encoding into std::string in UTF-8.
json_type
Types of JSON values.
Definition: json.hpp:16
@ null
Not a JSON value.
@ object
The explicit null value.
String types and assorted functions.
Definition: json.hpp:186
Definition: json.hpp:183