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