29#error no JSON library available
40#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 13
41#define DISABLE_DANGLING_WARNINGS() \
42 _Pragma("GCC diagnostic push") \
43 _Pragma("GCC diagnostic ignored \"-Wdangling-reference\"")
45#define REENABLE_DANGLING_WARNINGS() \
46 _Pragma("GCC diagnostic pop")
48#define DISABLE_DANGLING_WARNINGS()
49#define REENABLE_DANGLING_WARNINGS()
53template <
typename TITLE>
54inline Json::Value
parse(
const std::string &
str,
const TITLE &title)
59 Json::CharReaderBuilder builder;
60 builder[
"collectComments"] =
false;
63 std::istringstream instr(
str);
65 if (!Json::parseFromStream(builder, instr, &root, &errors))
71inline Json::Value
parse(
const std::string &
str)
81template <
typename BUFFER,
typename TITLE>
87 Json::CharReaderBuilder builder;
88 builder[
"collectComments"] =
false;
92 std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
93 if (!reader->parse(
reinterpret_cast<const char *
>(buf.c_data()),
reinterpret_cast<const char *
>(buf.c_data()) + buf.size(), &root, &errors))
99#ifdef OPENVPN_JSON_INTERNAL
101template <typename NAME, typename TITLE>
102inline const Json::Value &cast(const Json::ValueType target_type,
103 const Json::Value &value,
112 throw json_parse(Json::Value::type_string(target_type) +
" cast " +
fmt_name(name, title) +
" is null");
114 if (!value.isConvertibleTo(target_type))
115 throw json_parse(Json::Value::type_string(target_type) +
" cast " +
fmt_name(name, title) +
" is of incorrect type (" + value.type_string() +
')');
120template <typename NAME>
121inline const Json::Value &cast(const Json::ValueType target_type,
122 const Json::Value &value,
126 return cast(target_type, value, name, optional,
nullptr);
129template <
typename NAME,
typename TITLE>
130inline Json::Value
cast(
const Json::ValueType target_type,
136 Json::Value
ret = std::move(value);
137 cast(target_type,
ret, name, optional, title);
141template <
typename NAME>
142inline Json::Value
cast(
const Json::ValueType target_type,
147 return cast(target_type, std::move(value), name, optional,
nullptr);
152template <
typename T,
typename NAME>
153inline void from_vector(Json::Value &root,
const T &vec,
const NAME &name)
155 Json::Value array(Json::arrayValue);
157 array.append(e.to_json());
159 root[name] = std::move(array);
162template <
typename TITLE>
163inline void assert_dict(
const Json::Value &obj,
const TITLE &title)
166 throw json_parse(
fmt_name_cast(title) +
" is not a JSON dictionary");
169template <
typename TITLE>
170inline bool is_dict(
const Json::Value &obj,
const TITLE &title)
178template <
typename NAME>
179inline bool exists(
const Json::Value &root,
const NAME &name)
181 if (!root.isObject())
183 return !root[name].isNull();
186template <
typename NAME>
189 if (!root.isObject())
191 return root[name].isString();
194template <
typename T,
typename NAME,
typename TITLE>
195inline void to_vector(
const Json::Value &root, T &vec,
const NAME &name,
const TITLE &title)
197 const Json::Value &array = root[name];
200 if (!array.isArray())
201 throw json_parse(
"array " +
fmt_name(name, title) +
" is of incorrect type");
202 for (
unsigned int i = 0; i < array.size(); ++i)
205 vec.back().from_json(array[i],
fmt_name(name, title));
209template <
typename NAME,
typename TITLE>
214 const Json::Value &value = root[name];
216 throw json_parse(
"string " +
fmt_name(name, title) +
" is missing");
217 if (!value.isString())
218 throw json_parse(
"string " +
fmt_name(name, title) +
" is of incorrect type");
219 return value.asString();
222template <
typename NAME>
223inline std::string
get_string(
const Json::Value &root,
const NAME &name)
228#ifdef OPENVPN_JSON_INTERNAL
229template <
typename NAME,
typename TITLE>
230inline const std::string &get_string_ref(
const Json::Value &root,
234 const Json::Value &value = root[name];
236 throw json_parse(
"string " +
fmt_name(name, title) +
" is missing");
237 if (!value.isString())
238 throw json_parse(
"string " +
fmt_name(name, title) +
" is of incorrect type");
239 return value.asStringRef();
242template <
typename NAME>
243inline const std::string &get_string_ref(
const Json::Value &root,
const NAME &name)
245 return get_string_ref(root, name,
nullptr);
249template <
typename NAME,
typename TITLE>
250inline std::string get_string_ref(Json::Value &&root,
257template <
typename NAME,
typename TITLE>
258inline const std::string *get_string_ptr(
const Json::Value &root,
262 const Json::Value &value =
root[
name];
265 if (!value.isString())
266 throw json_parse(
"string " +
fmt_name(name, title) +
" is of incorrect type");
267 return value.asStringPtr();
270template <
typename NAME>
271inline const std::string *get_string_ptr(
const Json::Value &root,
const NAME &name)
273 return get_string_ptr(root, name,
nullptr);
277template <
typename NAME,
typename TITLE>
280 const std::string &default_value,
283 const Json::Value &value = root[name];
285 return default_value;
286 if (!value.isString())
287 throw json_parse(
"string " +
fmt_name(name, title) +
" is of incorrect type");
288 return value.asString();
291template <
typename NAME>
294 const std::string &default_value)
299template <
typename TITLE>
301 const Json::ArrayIndex index,
304 const Json::Value &value = root[index];
306 throw json_parse(
"string " +
fmt_name(index, title) +
" is missing");
307 if (!value.isString())
308 throw json_parse(
"string " +
fmt_name(index, title) +
" is of incorrect type");
309 return value.asString();
313 const Json::ArrayIndex index)
318template <
typename NAME,
typename TITLE>
323 const Json::Value &value = root[name];
325 throw json_parse(
"int " +
fmt_name(name, title) +
" is missing");
327 throw json_parse(
"int " +
fmt_name(name, title) +
" is of incorrect type");
328 return value.asInt();
331template <
typename NAME>
332inline int get_int(
const Json::Value &root,
const NAME &name)
334 return get_int(root, name,
nullptr);
337template <
typename NAME,
typename TITLE>
340 const int default_value,
343 const Json::Value &value = root[name];
345 return default_value;
347 throw json_parse(
"int " +
fmt_name(name, title) +
" is of incorrect type");
348 return value.asInt();
351template <
typename NAME>
354 const int default_value)
359template <
typename NAME,
typename TITLE>
360inline unsigned int get_uint(
const Json::Value &root,
364 const Json::Value &value = root[name];
366 throw json_parse(
"uint " +
fmt_name(name, title) +
" is missing");
368 throw json_parse(
"uint " +
fmt_name(name, title) +
" is of incorrect type");
369 return value.asUInt();
372template <
typename NAME>
373inline unsigned int get_uint(
const Json::Value &root,
const NAME &name)
375 return get_uint(root, name,
nullptr);
378template <
typename NAME,
typename TITLE>
381 const unsigned int default_value,
384 const Json::Value &value = root[name];
386 return default_value;
388 throw json_parse(
"uint " +
fmt_name(name, title) +
" is of incorrect type");
389 return value.asUInt();
392template <
typename NAME>
395 const unsigned int default_value)
400template <
typename NAME,
typename TITLE>
405 const Json::Value &value = root[name];
407 throw json_parse(
"uint-via-string " +
fmt_name(name, title) +
" is missing");
408 if (!value.isString())
409 throw json_parse(
"uint-via-string " +
fmt_name(name, title) +
" is of incorrect type");
413 throw json_parse(
"uint-via-string " +
fmt_name(name, title) +
" failed to parse");
417template <
typename NAME>
424template <
typename NAME,
typename TITLE>
427 const unsigned int default_value,
430 const Json::Value &value = root[name];
432 return default_value;
433 if (!value.isString())
434 throw json_parse(
"uint-via-string " +
fmt_name(name, title) +
" is of incorrect type");
438 throw json_parse(
"uint-via-string " +
fmt_name(name, title) +
" failed to parse");
442template <
typename NAME>
445 const unsigned int default_value)
450template <
typename NAME,
typename TITLE>
455 const Json::Value &value = root[name];
457 throw json_parse(
"uint64 " +
fmt_name(name, title) +
" is missing");
458 if (!value.isUInt64())
459 throw json_parse(
"uint64 " +
fmt_name(name, title) +
" is of incorrect type");
460 return value.asUInt64();
463template <
typename NAME>
464inline std::uint64_t
get_uint64(
const Json::Value &root,
const NAME &name)
469template <
typename NAME,
typename TITLE>
472 const std::uint64_t default_value,
475 const Json::Value &value = root[name];
477 return default_value;
478 if (!value.isUInt64())
479 throw json_parse(
"uint64 " +
fmt_name(name, title) +
" is of incorrect type");
480 return value.asUInt64();
483template <
typename NAME,
typename TITLE>
486 const std::uint64_t default_value,
489 const Json::Value &value = root[name];
491 return default_value;
492 if (!value.isInt64())
493 throw json_parse(
"int64 " +
fmt_name(name, title) +
" is of incorrect type");
494 return value.asInt64();
497template <
typename NAME>
500 const std::uint64_t default_value)
510template <
typename NAME,
typename TITLE>
513 const std::uint64_t default_value,
519template <
typename NAME,
typename TITLE>
522 const std::int64_t default_value,
528template <
typename NAME,
typename TITLE>
531 const unsigned int default_value,
537template <
typename NAME,
typename TITLE>
540 const int default_value,
546template <
typename NAME,
typename TITLE>
551 const Json::Value &value = root[name];
553 throw json_parse(
"uint64-via-string " +
fmt_name(name, title) +
" is missing");
554 if (!value.isString())
555 throw json_parse(
"uint64-via-string " +
fmt_name(name, title) +
" is of incorrect type");
559 throw json_parse(
"uint64-via-string " +
fmt_name(name, title) +
" failed to parse");
563template <
typename NAME>
570template <
typename NAME,
typename TITLE>
573 const std::uint64_t default_value,
576 const Json::Value &value = root[name];
578 return default_value;
579 if (!value.isString())
580 throw json_parse(
"uint64-via-string " +
fmt_name(name, title) +
" is of incorrect type");
584 throw json_parse(
"uint64-via-string " +
fmt_name(name, title) +
" failed to parse");
588template <
typename NAME>
591 const std::uint64_t default_value)
595template <
typename NAME,
typename TITLE>
600 const Json::Value &value = root[name];
602 throw json_parse(
"bool " +
fmt_name(name, title) +
" is missing");
604 throw json_parse(
"bool " +
fmt_name(name, title) +
" is of incorrect type");
605 return value.asBool();
608template <
typename NAME>
609inline bool get_bool(
const Json::Value &root,
const NAME &name)
611 return get_bool(root, name,
nullptr);
614template <
typename NAME>
617 const bool default_value =
false)
619 const Json::Value &jv = root[name];
620 if (jv.isConvertibleTo(Json::booleanValue))
623 return default_value;
626template <
typename NAME>
630 const Json::Value &jv = root[name];
631 if (jv.isConvertibleTo(Json::booleanValue))
632 return jv.asBool() ? 1 : 0;
638template <typename NAME, typename TITLE>
639inline const Json::Value &
get_dict(const Json::Value &root,
644 const Json::Value &value = root[name];
649 throw json_parse(
"dictionary " +
fmt_name(name, title) +
" is missing");
651 if (!value.isObject())
652 throw json_parse(
"dictionary " +
fmt_name(name, title) +
" is of incorrect type");
657template <typename NAME>
658inline const Json::Value &
get_dict(const Json::Value &root,
662 return get_dict(root, name, optional,
nullptr);
665template <
typename NAME,
typename TITLE>
671 Json::Value r = std::move(root);
672 return get_dict(r, name, optional, title);
675template <
typename NAME>
680 return get_dict(std::move(root), name, optional,
nullptr);
684template <typename TITLE>
685inline const Json::Value &
cast_dict(const Json::Value &value,
693 throw json_parse(
"dictionary cast " +
fmt_name_cast(title) +
" is null");
695 if (!value.isObject())
696 throw json_parse(
"dictionary cast " +
fmt_name_cast(title) +
" is of incorrect type");
701inline const Json::Value &
cast_dict(const Json::Value &value,
704 return cast_dict(value, optional,
nullptr);
707template <
typename TITLE>
712 Json::Value
ret = std::move(value);
720 return cast_dict(std::move(value), optional,
nullptr);
724template <typename NAME, typename TITLE>
725inline const Json::Value &
get_array(const Json::Value &root,
730 const Json::Value &value = root[name];
735 throw json_parse(
"array " +
fmt_name(name, title) +
" is missing");
737 if (!value.isArray())
738 throw json_parse(
"array " +
fmt_name(name, title) +
" is of incorrect type");
743template <typename NAME>
744inline const Json::Value &
get_array(const Json::Value &root,
748 return get_array(root, name, optional,
nullptr);
751template <
typename NAME,
typename TITLE>
757 Json::Value r = std::move(root);
758 return get_array(r, name, optional, title);
761template <
typename NAME>
766 return get_array(std::move(root), name, optional,
nullptr);
770template <typename TITLE>
771inline const Json::Value &
cast_array(const Json::Value &value,
779 throw json_parse(
"array cast " +
fmt_name_cast(title) +
" is null");
781 if (!value.isArray())
782 throw json_parse(
"array cast " +
fmt_name_cast(title) +
" is of incorrect type");
787inline const Json::Value &
cast_array(const Json::Value &value,
793template <
typename TITLE>
798 Json::Value
ret = std::move(value);
806 return cast_array(std::move(value), optional,
nullptr);
809template <
typename NAME,
typename TITLE>
818template <
typename NAME,
typename TITLE>
822 const std::string &default_value,
828template <
typename NAME,
typename TITLE>
829inline void to_int(
const Json::Value &root,
834 dest =
get_int(root, name, title);
837template <
typename NAME,
typename TITLE>
843 auto temp =
get_int(root, name, title);
844 dest = clamp_notify<unsigned char>(temp,
845 [](
decltype(temp) temp) ->
unsigned char
847 auto why = std::string(
"Conversion error [" + std::to_string(temp) +
"] to unsigned char");
848 throw json_parse(std::move(why)); });
851template <
typename NAME,
typename TITLE>
860template <
typename NAME,
typename TITLE>
864 const unsigned int default_value,
870template <
typename NAME,
typename TITLE>
879template <
typename NAME,
typename TITLE>
891 root.toCompactString(buf);
893 Json::StreamWriterBuilder json_builder;
894 json_builder.settings_[
"indentation"] =
"";
896 std::unique_ptr<Json::StreamWriter> sw(json_builder.newStreamWriter());
897 sw->write(root, &
os);
902 const size_t size_hint = 256)
912 root.toStyledString(buf);
914 Json::StreamWriterBuilder json_builder;
915 json_builder.settings_[
"indentation"] =
" ";
917 std::unique_ptr<Json::StreamWriter> sw(json_builder.newStreamWriter());
918 sw->write(root, &
os);
922inline std::string
format(
const Json::Value &root)
924 return root.toStyledString();
927inline std::string
error(
const Json::Value &root)
929 const Json::Value &je = root[
"error"];
931 return je.asString();
933 return std::string();
945 Json::Value jret(Json::objectValue);
946 jret[
"result"] = std::move(jr);
#define OPENVPN_EXCEPTION(C)
#define REENABLE_DANGLING_WARNINGS()
#define DISABLE_DANGLING_WARNINGS()
constexpr BufferFlags GROW(1u<< 2)
if enabled, buffer will grow (otherwise buffer_full exception will be thrown)
const auto cast(const C &container)
Provide an instance of C2os::Container<C> from the underlying container.
const char * name(const KeyDerivation kd)
std::string to_string(std::nullptr_t)
void assert_dict(const Json::Value &obj, const TITLE &title)
int get_bool_tristate(const Json::Value &root, const NAME &name)
std::string fmt_name_cast(const TITLE &title)
void to_string_optional(const Json::Value &root, std::string &dest, const NAME &name, const std::string &default_value, const TITLE &title)
std::uint64_t get_integer_optional(const Json::Value &root, const NAME &name, const std::uint64_t default_value, const TITLE &title)
void format(const Json::Value &root, Buffer &buf)
std::string fmt_name(const NAME &name, const TITLE &title)
int get_int(const Json::Value &root, const NAME &name, const TITLE &title)
void to_uint64(const Json::Value &root, std::uint64_t &dest, const NAME &name, const TITLE &title)
std::uint64_t get_uint64(const Json::Value &root, const NAME &name, const TITLE &title)
void to_string(const Json::Value &root, std::string &dest, const NAME &name, const TITLE &title)
void to_uint(const Json::Value &root, unsigned int &dest, const NAME &name, const TITLE &title)
unsigned int get_uint_optional_via_string(const Json::Value &root, const NAME &name, const unsigned int default_value, const TITLE &title)
Json::Value parse_from_file(const std::string &fn)
const Json::Value & get_array(const Json::Value &root, const NAME &name, const bool optional, const TITLE &title)
bool string_exists(const Json::Value &root, const NAME &name)
std::int64_t get_int64_optional(const Json::Value &root, const NAME &name, const std::uint64_t default_value, const TITLE &title)
void to_int(const Json::Value &root, int &dest, const NAME &name, const TITLE &title)
bool get_bool_optional(const Json::Value &root, const NAME &name, const bool default_value=false)
bool get_bool(const Json::Value &root, const NAME &name, const TITLE &title)
unsigned int get_uint(const Json::Value &root, const NAME &name, const TITLE &title)
void to_uchar(const Json::Value &root, unsigned char &dest, const NAME &name, const TITLE &title)
std::uint64_t get_uint64_optional_via_string(const Json::Value &root, const NAME &name, const std::uint64_t default_value, const TITLE &title)
unsigned int get_uint_optional(const Json::Value &root, const NAME &name, const unsigned int default_value, const TITLE &title)
const Json::Value & get_dict(const Json::Value &root, const NAME &name, const bool optional, const TITLE &title)
const Json::Value & cast_array(const Json::Value &value, const bool optional, const TITLE &title)
bool is_dict(const Json::Value &obj, const TITLE &title)
void to_vector(const Json::Value &root, T &vec, const NAME &name, const TITLE &title)
bool exists(const Json::Value &root, const NAME &name)
int get_int_optional(const Json::Value &root, const NAME &name, const int default_value, const TITLE &title)
std::string error(const Json::Value &root)
std::string get_string_optional(const Json::Value &root, const NAME &name, const std::string &default_value, const TITLE &title)
std::uint64_t get_uint64_via_string(const Json::Value &root, const NAME &name, const TITLE &title)
void to_bool(const Json::Value &root, bool &dest, const NAME &name, const TITLE &title)
std::string get_string_from_array(const Json::Value &root, const Json::ArrayIndex index, const TITLE &title)
Json::Value parse(const std::string &str, const TITLE &title)
void from_vector(Json::Value &root, const T &vec, const NAME &name)
Json::Value dict_result(Json::Value jr)
const Json::Value & cast_dict(const Json::Value &value, const bool optional, const TITLE &title)
void format_compact(const Json::Value &root, Buffer &buf)
unsigned int get_uint_via_string(const Json::Value &root, const NAME &name, const TITLE &title)
std::uint64_t get_uint64_optional(const Json::Value &root, const NAME &name, const std::uint64_t default_value, const TITLE &title)
std::string get_string(const Json::Value &root, const NAME &name, const TITLE &title)
Json::Value parse_from_buffer(const BUFFER &buf, const TITLE &title)
void to_uint_optional(const Json::Value &root, unsigned int &dest, const NAME &name, const unsigned int default_value, const TITLE &title)
std::string root(const std::string &basename)
std::string read_text_utf8(const std::string &filename, const std::uint64_t max_size=0)
BufferAllocatedType< unsigned char > BufferAllocated
bool parse_number(const char *str, T &retval, const bool nondigit_term=false)
std::string buf_to_string(const Buffer &buf)
os<< "Session Name: "<< tbc-> session_name<< '\n';os<< "Layer: "<< tbc-> layer str()<< '\n'