Loading...
Searching...
No Matches
JSONParse.hpp
1#pragma once
2#include <score/serialization/JSONVisitor.hpp>
3
4#include <ossia/math/safe_math.hpp>
5
6#include <QSize>
7#include <QString>
8
9#include <cmath>
10#include <cstddef>
11#include <limits>
12#include <type_traits>
13
14namespace score
15{
16
26template <typename Obj, std::size_t N>
27bool parseJsonField(const Obj& obj, const char (&key)[N], QString& out)
28{
29 if(auto v = obj.tryGet(key); v && v->obj.IsString())
30 {
31 out = v->toString();
32 return true;
33 }
34 return false;
35}
36
37template <typename Obj, std::size_t N>
38bool parseJsonField(const Obj& obj, const char (&key)[N], bool& out)
39{
40 if(auto v = obj.tryGet(key); v && v->obj.IsBool())
41 {
42 out = v->obj.GetBool();
43 return true;
44 }
45 return false;
46}
47
50template <typename T>
51bool parseJsonNumber(double d, T& out) noexcept
52{
53 if(!ossia::safe_isfinite(d))
54 return false;
55 if constexpr(!std::is_floating_point_v<T>)
56 {
57 if(d < double(std::numeric_limits<long long>::min())
58 || d > double(std::numeric_limits<long long>::max()))
59 return false;
60 out = static_cast<T>(static_cast<long long>(d));
61 }
62 else
63 {
64 out = static_cast<T>(d);
65 }
66 return true;
67}
68
69template <typename Obj, std::size_t N, typename T>
70 requires(
71 (std::is_arithmetic_v<T> || std::is_enum_v<T>) && !std::is_same_v<T, bool>)
72bool parseJsonField(const Obj& obj, const char (&key)[N], T& out)
73{
74 auto v = obj.tryGet(key);
75 if(!v || !v->obj.IsNumber())
76 return false;
77
78 if constexpr(std::is_floating_point_v<T>)
79 {
80 out = static_cast<T>(v->obj.GetDouble());
81 return true;
82 }
83 else if constexpr(std::is_integral_v<T> && std::is_unsigned_v<T>)
84 {
85 if(v->obj.IsUint64())
86 {
87 out = static_cast<T>(v->obj.GetUint64());
88 return true;
89 }
90 if(v->obj.IsInt64())
91 {
92 out = static_cast<T>(v->obj.GetInt64());
93 return true;
94 }
95 }
96 else
97 {
98 if(v->obj.IsInt64())
99 {
100 out = static_cast<T>(v->obj.GetInt64());
101 return true;
102 }
103 if(v->obj.IsUint64())
104 {
105 const auto u = v->obj.GetUint64();
106 if(u > uint64_t(std::numeric_limits<long long>::max()))
107 return false;
108 out = static_cast<T>(static_cast<long long>(u));
109 return true;
110 }
111 }
112 return parseJsonNumber(v->obj.GetDouble(), out);
113}
114
115template <typename Obj, std::size_t N>
116bool parseJsonField(const Obj& obj, const char (&key)[N], QSize& out)
117{
118 auto v = obj.tryGet(key);
119 if(!v || !v->obj.IsArray())
120 return false;
121 const auto& arr = v->obj.GetArray();
122 if(arr.Size() < 2 || !arr[0].IsNumber() || !arr[1].IsNumber())
123 return false;
124
125 int w{}, h{};
126 if(!parseJsonNumber(arr[0].GetDouble(), w) || !parseJsonNumber(arr[1].GetDouble(), h))
127 return false;
128 out = QSize{w, h};
129 return true;
130}
131
132}
Base toolkit upon which the software is built.
Definition Application.cpp:117
bool parseJsonNumber(double d, T &out) noexcept
Definition JSONParse.hpp:51
bool parseJsonField(const Obj &obj, const char(&key)[N], QString &out)
Read one field of a JSON object, or leave out alone.
Definition JSONParse.hpp:27