Anklang 0.3.0-460-gc4ef46ba
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
jsonapi.hh
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#ifndef __ASE_JSONAPI_HH__
3#define __ASE_JSONAPI_HH__
4
5#include <ase/websocket.hh>
6#include <ase/value.hh>
7
8#define JSONIPC_CUSTOM_SHARED_BASE ::Ase::SharedBase
9#include <jsonipc/jsonipc.hh>
10JSONIPC_MAP_TO_TYPESCRIPT (::Ase::Value, "any");
11JSONIPC_MAP_TO_TYPESCRIPT (::Ase::ValueS, "any[]");
12JSONIPC_MAP_TO_TYPESCRIPT (::Ase::ValueR, "{ [key: string]: any }");
13JSONIPC_MAP_TO_TYPESCRIPT (::Ase::JsTrigger, "any");
14
15namespace Ase {
16
17using JsonapiBinarySender = std::function<bool(const String&)>;
18
19void jsonapi_set_subprotocol (const String &subprotocol);
20WebSocketConnectionP jsonapi_make_connection (WebSocketConnection::Internals&, int logflags);
21CustomDataContainer* jsonapi_connection_data ();
22JsonapiBinarySender jsonapi_connection_sender ();
23
26 static Value
27 from_json (const Jsonipc::JsonValue &v)
28 {
29 Value val;
30 switch (v.GetType())
31 {
32 case rapidjson::kNullType:
33 val = Value{}; // NONE
34 break;
35 case rapidjson::kFalseType:
36 val = false;
37 break;
38 case rapidjson::kTrueType:
39 val = true;
40 break;
41 case rapidjson::kStringType:
42 val = Jsonipc::from_json<std::string> (v);
43 break;
44 case rapidjson::kNumberType:
45 if (v.IsInt()) val = v.GetInt();
46 else if (v.IsUint()) val = v.GetUint();
47 else if (v.IsInt64()) val = v.GetInt64();
48 else if (v.IsUint64()) val = int64 (v.GetUint64());
49 else val = v.GetDouble();
50 break;
51 case rapidjson::kArrayType:
52 sequence_from_json_array (val, v);
53 break;
54 case rapidjson::kObjectType: // RECORD + INSTANCE
55 value_from_json_object (val, v);
56 break;
57 };
58 return val;
59 }
60 static Jsonipc::JsonValue
61 to_json (const Value &val, Jsonipc::JsonAllocator &allocator)
62 {
63 using namespace Jsonipc;
64 switch (val.index())
65 {
66 case Value::BOOL: return JsonValue (std::get<bool> (val));
67 case Value::INT64: return JsonValue (std::get<int64> (val));
68 case Value::DOUBLE: return JsonValue (std::get<double> (val));
69 case Value::STRING: return Jsonipc::to_json (std::get<String> (val), allocator);
70 case Value::ARRAY: return sequence_to_json_array (std::get<ValueS> (val), allocator);
71 case Value::RECORD: return record_to_json_object (std::get<ValueR> (val), allocator);
72 case Value::INSTANCE: return Jsonipc::to_json (std::get<InstanceP> (val), allocator);
73 case Value::NONE: return JsonValue(); // null
74 }
75 return JsonValue(); // null
76 }
77 static void
78 sequence_from_json_array (Value &val, const Jsonipc::JsonValue &v)
79 {
80 const size_t l = v.Size();
81 ValueS s;
82 s.reserve (l);
83 for (size_t i = 0; i < l; ++i)
84 s.push_back (ConvertValue::from_json (v[i]));
85 val = std::move (s);
86 }
87 static Jsonipc::JsonValue
88 sequence_to_json_array (const ValueS &seq, Jsonipc::JsonAllocator &allocator)
89 {
90 const size_t l = seq.size();
91 Jsonipc::JsonValue jarray (rapidjson::kArrayType);
92 jarray.Reserve (l, allocator);
93 for (size_t i = 0; i < l; ++i)
94 if (seq[i])
95 jarray.PushBack (ConvertValue::to_json (*seq[i], allocator).Move(), allocator);
96 return jarray;
97 }
98 static void
99 value_from_json_object (Value &val, const Jsonipc::JsonValue &v)
100 {
101 ValueR rec;
102 rec.reserve (v.MemberCount());
103 for (const auto &field : v.GetObject())
104 {
105 const std::string key = field.name.GetString();
106 if (key == "$class" || key == "$id") // actually INSTANCE
107 {
108 val = Jsonipc::from_json<InstanceP> (v);
109 return;
110 }
111 rec[key] = ConvertValue::from_json (field.value);
112 }
113 val = std::move (rec);
114 }
115 static Jsonipc::JsonValue
116 record_to_json_object (const ValueR &rec, Jsonipc::JsonAllocator &allocator)
117 {
118 Jsonipc::JsonValue jobject (rapidjson::kObjectType);
119 jobject.MemberReserve (rec.size(), allocator);
120 for (auto const &field : rec)
121 if (field.value)
122 jobject.AddMember (Jsonipc::JsonValue (field.name.c_str(), allocator),
123 ConvertValue::to_json (*field.value, allocator).Move(), allocator);
124 return jobject;
125 }
126};
127
130 static ValueP
131 from_json (const Jsonipc::JsonValue &value)
132 {
133 auto val = ConvertValue::from_json (value);
134 return std::make_shared<Value> (std::move (val)); // yields NONE for kNullType
135 }
136 static Jsonipc::JsonValue
137 to_json (const ValueP &valp, Jsonipc::JsonAllocator &allocator)
138 {
139 if (!valp)
140 return Jsonipc::JsonValue(); // yields kNullType for nullptr
141 auto val = *valp;
142 return ConvertValue::to_json (val, allocator);
143 }
144};
145
148 static ValueR
149 from_json (const Jsonipc::JsonValue &v)
150 {
151 ValueR rec;
152 if (v.IsObject())
153 {
154 rec.reserve (v.MemberCount());
155 for (const auto &field : v.GetObject())
156 {
157 const std::string key = field.name.GetString();
158 rec[key] = ConvertValue::from_json (field.value);
159 }
160 }
161 return rec;
162 }
163 static Jsonipc::JsonValue
164 to_json (const ValueR &rec, Jsonipc::JsonAllocator &allocator)
165 {
166 Jsonipc::JsonValue jobject (rapidjson::kObjectType);
167 jobject.MemberReserve (rec.size(), allocator);
168 for (auto const &field : rec)
169 if (field.value)
170 jobject.AddMember (Jsonipc::JsonValue (field.name.c_str(), allocator),
171 ConvertValue::to_json (*field.value, allocator).Move(), allocator);
172 return jobject;
173 }
174};
175
179 static ValueRP
180 from_json (const Jsonipc::JsonValue &value)
181 {
182 ValueR rec = ConvertValueR::from_json (value);
183 return std::make_shared<ValueR> (std::move (rec));
184 }
185 static Jsonipc::JsonValue
186 to_json (const ValueRP &recp, Jsonipc::JsonAllocator &allocator)
187 {
188 if (!recp)
189 return Jsonipc::JsonValue(); // null
190 return ConvertValueR::to_json (*recp, allocator);
191 }
192};
193
196 static JsTrigger lookup (const String &triggerid);
197 static JsTrigger
198 from_json (const Jsonipc::JsonValue &v)
199 {
200 if (v.IsString())
201 return lookup (Jsonipc::from_json<std::string> (v));
202 return {};
203 }
204 static Jsonipc::JsonValue
205 to_json (const JsTrigger&, Jsonipc::JsonAllocator &allocator)
206 {
207 return {}; // null
208 }
209};
210
211} // Ase
212
213namespace Jsonipc {
214template<> struct Convert<Ase::Value> : Ase::ConvertValue {};
215template<> struct Convert<Ase::ValueP> : Ase::ConvertValueP {};
216template<> struct Convert<Ase::ValueR> : Ase::ConvertValueR {};
217template<> struct Convert<std::shared_ptr<Ase::ValueR>> : Ase::ConvertValueRP {};
218template<> struct Convert<Ase::JsTrigger> : Ase::ConvertJsTrigger {};
219} // Jsonipc
220
221#endif // __ASE_JSONAPI_HH__
Callback mechanism for Jsonapi/Jsonipc.
Definition value.hh:123
The Anklang C++ API namespace.
Definition api.hh:9
int64_t int64
A 64-bit unsigned integer, use PRI*64 in format strings.
Definition cxxaux.hh:29
std::string String
Convenience alias for std::string.
Definition cxxaux.hh:35
T reserve(T... args)
T size(T... args)
Convert between Jsonipc::JsonValue to JsTrigger.
Definition jsonapi.hh:195
Convert between ValueP and Jsonipc::JsonValue.
Definition jsonapi.hh:129
Convert between std::shared_ptr<ValueR> and Jsonipc::JsonValue.
Definition jsonapi.hh:177
Convert between ValueR and Jsonipc::JsonValue.
Definition jsonapi.hh:147
Convert between Value and Jsonipc::JsonValue.
Definition jsonapi.hh:25
Value type used to interface with various property types.
Definition value.hh:54
Template class providing C++ <-> JsonValue conversions for various types.
Definition jsonipc.hh:213