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  set_type(t);
41  }
42 
43  json_type type() const {
44  return type_;
45  }
46 
48  std::string string_value() const;
49 
51  std::wstring wstring_value() const {
52  return fz::to_wstring_from_utf8(string_value());
53  }
54 
55 
57  template<typename T, std::enable_if_t<std::is_integral_v<typename std::decay_t<T>>, int> = 0>
58  T number_value() const {
59  return static_cast<T>(number_value_integer());
60  }
61 
63  template<typename T, std::enable_if_t<std::is_floating_point_v<typename std::decay_t<T>>, int> = 0>
64  T number_value() const {
65  return static_cast<T>(number_value_double());
66  }
67 
69  bool bool_value() const;
70 
72  void erase(std::string const& name);
73 
75  json const& operator[](std::string const& name) const;
76 
83  json& operator[](std::string const& name);
84 
86  json const& operator[](size_t i) const;
87 
94  json& operator[](size_t i);
95 
97  size_t children() const;
98 
100  template<typename Bool, std::enable_if_t<std::is_same_v<bool, typename std::decay_t<Bool>>, int> = 0>
101  json& operator=(Bool b) {
102  type_ = json_type::boolean;
103  value_ = b;
104  return *this;
105  }
106 
108  template<typename T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<bool, typename std::decay_t<T>>, int> = 0>
109  json& operator=(T n) {
110  type_ = json_type::number;
111  value_ = fz::to_string(n);
112  return *this;
113  }
114 
119  json& operator=(std::string_view const& v);
120 
122  json& operator=(std::wstring_view const& v) {
123  return *this = to_utf8(v);
124  }
125 
126  json& operator=(json const&) = default;
127  json& operator=(json &&) noexcept = default;
128 
129  explicit operator bool() const { return type_ != json_type::none; }
130 
136  std::string to_string(bool pretty = false, size_t depth = 0) const;
137 
142  static json parse(std::string_view const& v, size_t max_depth = 20);
143  static json parse(fz::buffer const& b, size_t max_depth = 20);
144 
145  void clear();
146 
147 private:
148  uint64_t number_value_integer() const;
149  double number_value_double() const;
150 
151  bool check_type(json_type t);
152  void set_type(json_type t);
153 
154  static json parse(char const*& p, char const* end, size_t max_depth);
155 
156  typedef std::variant<std::string, std::map<std::string, json, std::less<>>, std::vector<json>, bool> value_type;
157  value_type value_;
158  json_type type_{json_type::none};
159 };
160 
161 template <bool isconst>
162 struct json_array_iterator final {
163  using json_ref_t = std::conditional_t<isconst, json const&, json &>;
164 
165  struct sentinel final {};
166 
167  json_array_iterator(json_ref_t j)
168  // 0 if it's an array, -1 otherwise
169  : idx_((j.type() == json_type::array)-1)
170  , json_(j)
171  {}
172 
173  json_array_iterator & operator++()
174  {
175  ++idx_;
176 
177  return *this;
178  }
179 
180 
181  json_ref_t operator*() const
182  {
183  return json_[idx_];
184  }
185 
186  bool operator!=(json_array_iterator::sentinel const&) const
187  {
188  return idx_ < json_.children();
189  }
190 
191 private:
192  std::size_t idx_;
193  json_ref_t json_;
194 };
195 
196 inline json_array_iterator<false> begin(json &j) { return {j}; }
197 inline json_array_iterator<false>::sentinel end(json &) { return {}; }
198 
199 inline json_array_iterator<true> begin(json const& j) { return {j}; }
200 inline json_array_iterator<true>::sentinel end(json const&) { return {}; }
201 
202 }
203 
204 #endif
json & operator=(T n)
Sets type to number and assigns value.
Definition: json.hpp:109
std::wstring wstring_value() const
Returns string, number and boolean values as wstring.
Definition: json.hpp:51
std::string to_utf8(std::string_view const &in)
Converts from std::string in native encoding into std::string in UTF-8.
json(json_type t)
Explicitly creates a value of a specific type, mainly needed for null objects.
Definition: json.hpp:38
The explicit null value.
Definition: json.hpp:162
std::wstring to_wstring_from_utf8(std::string_view const &in)
Converts from std::string in UTF-8 into std::wstring.
Definition: json.hpp:165
String types and assorted functions.
json parser/builder
Definition: json.hpp:30
The namespace used by libfilezilla.
Definition: apply.hpp:17
json_type
Types of JSON values.
Definition: json.hpp:16
json & operator=(std::wstring_view const &v)
Sets type to string and assigns value.
Definition: json.hpp:122
The buffer class is a simple buffer where data can be appended at the end and consumed at the front...
Definition: buffer.hpp:25
Not a JSON value.
json & operator=(Bool b)
Sets type to boolean and assigns value.
Definition: json.hpp:101
T number_value() const
Returns number and string values as the passed integer type.
Definition: json.hpp:58
std::string to_string(std::wstring_view const &in)
Converts from std::wstring into std::string in system encoding.