WebCFace 3.1.1
Web-based Communication Framework & Dashboard-like UI
Loading...
Searching...
No Matches
pack.h
Go to the documentation of this file.
1#pragma once
2#ifdef MSGPACK_DEFINE_MAP
3#error "webcface/common/internal/pack.h must be included first"
4#endif
5
6#include <msgpack.hpp>
7#include <string>
8#include <cstdint>
9#include <utf8.h>
12#include "./base.h"
13
14#if defined(__GNUC__) && !defined(__clang__)
15#pragma GCC diagnostic push
16#pragma GCC diagnostic ignored "-Wabi"
17#endif
18#include <spdlog/logger.h>
19#if defined(__GNUC__) && !defined(__clang__)
20#pragma GCC diagnostic pop
21#endif
22
23MSGPACK_ADD_ENUM(webcface::ValType)
24
26namespace message {
27struct Ping;
28struct PingStatusReq;
29
34std::string messageTrace(const std::string &message);
35
40std::vector<std::pair<int, std::shared_ptr<void>>>
41unpack(const std::string &message,
42 const std::shared_ptr<spdlog::logger> &logger);
43
48template <typename T>
49std::string packSingle(const T &obj) {
50 msgpack::type::tuple<int, T> src(static_cast<int>(T::kind), obj);
51 std::stringstream buffer;
52 msgpack::pack(buffer, src);
53 return buffer.str();
54}
55
60template <typename T>
61void pack(std::stringstream &buffer, int &len, const T &obj) {
62 msgpack::pack(buffer, static_cast<int>(T::kind));
63 msgpack::pack(buffer, obj);
64 len += 2;
65}
66
67inline std::string packDone(std::stringstream &buffer, int len) {
68 std::stringstream buffer2;
69 msgpack::packer packer(buffer2);
70 packer.pack_array(len);
71 buffer2 << buffer.rdbuf();
72 return buffer2.str();
73}
74
75} // namespace message
77
78namespace msgpack {
79MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
80 namespace adaptor {
81
90 template <>
91 struct pack<double> {
92 template <typename Stream>
93 packer<Stream> &operator()(msgpack::packer<Stream> &o, double v) const {
94 if (v == v) { // check for nan
95 // compare d to limits to avoid undefined behaviour
96 if (v >= 0 &&
97 v <= double(std::numeric_limits<uint64_t>::max()) &&
98 v == static_cast<double>(static_cast<uint64_t>(v))) {
99 o.pack_uint64(static_cast<std::uint64_t>(v));
100 return o;
101 } else if (v < 0 &&
102 v >= double(std::numeric_limits<int64_t>::min()) &&
103 v == static_cast<double>(static_cast<int64_t>(v))) {
104 o.pack_int64(static_cast<std::int64_t>(v));
105 return o;
106 } else if (std::abs(v) <= std::numeric_limits<float>::max() &&
107 v == static_cast<double>(static_cast<float>(v))) {
108 o.pack_float(static_cast<float>(v));
109 return o;
110 }
111 }
112 o.pack_double(v);
113 return o;
114 }
115 };
116
117 template <>
118 struct convert<webcface::SharedString> {
119 msgpack::object const &operator()(msgpack::object const &o,
120 webcface::SharedString &v) const {
121 v = webcface::SharedString::fromU8String(utf8::replace_invalid(
122 std::string(o.via.bin.ptr, o.via.bin.size)));
123 return o;
124 }
125 };
126 template <>
127 struct pack<webcface::SharedString> {
128 template <typename Stream>
129 msgpack::packer<Stream> &operator()(msgpack::packer<Stream> &o,
130 const webcface::SharedString &v) {
131 o.pack(std::string_view(v.u8StringView()));
132 return o;
133 }
134 };
135
136 template <>
137 struct convert<webcface::ValAdaptor> {
138 msgpack::object const &operator()(msgpack::object const &o,
139 webcface::ValAdaptor &v) const {
140 switch (o.type) {
141 case msgpack::type::FLOAT32:
142 case msgpack::type::FLOAT64:
143 v = o.via.f64;
144 break;
145 case msgpack::type::POSITIVE_INTEGER:
146 v = o.via.u64;
147 break;
148 case msgpack::type::NEGATIVE_INTEGER:
149 v = o.via.i64;
150 break;
151 case msgpack::type::BOOLEAN:
152 v = o.via.boolean;
153 break;
154 case msgpack::type::BIN:
155 case msgpack::type::STR:
156 v = webcface::SharedString::fromU8String(utf8::replace_invalid(
157 std::string(o.via.bin.ptr, o.via.bin.size)));
158 break;
159 default:
160 throw msgpack::type_error();
161 }
162 return o;
163 }
164 };
165 template <>
166 struct pack<webcface::ValAdaptor> {
167 template <typename Stream>
168 msgpack::packer<Stream> &operator()(msgpack::packer<Stream> &o,
169 const webcface::ValAdaptor &v) {
170 switch (v.valType()) {
172 o.pack(static_cast<bool>(v));
173 break;
175 o.pack(static_cast<std::int64_t>(v));
176 break;
178 o.pack(static_cast<double>(v));
179 break;
181 default:
182 o.pack(std::string_view(v.asU8StringView()));
183 break;
184 }
185 return o;
186 }
187 };
188
189 template <>
190 struct convert<webcface::ValAdaptorVector> {
191 msgpack::object const &operator()(msgpack::object const &o,
193 switch (o.type) {
194 case msgpack::type::ARRAY: {
195 std::vector<webcface::ValAdaptor> vec;
196 vec.reserve(o.via.array.size);
197 for (std::size_t i = 0; i < o.via.array.size; i++) {
198 vec.push_back(
199 o.via.array.ptr[i].as<webcface::ValAdaptor>());
200 }
201 v = std::move(vec);
202 break;
203 }
204 default:
205 v = o.as<webcface::ValAdaptor>();
206 break;
207 }
208 return o;
209 }
210 };
211 template <>
212 struct pack<webcface::ValAdaptorVector> {
213 template <typename Stream>
214 msgpack::packer<Stream> &
215 operator()(msgpack::packer<Stream> &o,
217 if (v.size() == 1) {
218 o.pack(v.at(0));
219 } else {
220 o.pack_array(static_cast<std::uint32_t>(v.size()));
221 for (auto val : v) {
222 o.pack(val);
223 }
224 }
225 return o;
226 }
227 };
228
229 template <>
230 struct convert<webcface::MutableNumVector> {
231 msgpack::object const &operator()(msgpack::object const &o,
233 if (o.type != msgpack::type::ARRAY) {
234 throw msgpack::type_error();
235 }
236 if (o.via.array.size == 0) {
237 v.assign(0);
238 } else if (o.via.array.size == 1) {
239 v.assign(o.via.array.ptr[0].as<double>());
240 } else {
241 std::vector<double> vec;
242 vec.reserve(o.via.array.size);
243 for (std::size_t i = 0; i < o.via.array.size; i++) {
244 vec.push_back(o.via.array.ptr[i].as<double>());
245 }
246 v.assign(std::move(vec));
247 }
248 return o;
249 }
250 };
251 template <>
252 struct pack<webcface::MutableNumVector> {
253 template <typename Stream>
254 msgpack::packer<Stream> &
255 operator()(msgpack::packer<Stream> &o,
257 o.pack_array(static_cast<std::uint32_t>(v.size()));
258 for (auto val : v) {
259 o.pack(val);
260 }
261 return o;
262 }
263 };
264
265 template <typename T>
266 struct EmptyConvert {
267 msgpack::object const &operator()(msgpack::object const &o, T &) const {
268 return o;
269 }
270 };
271 template <typename T>
272 struct EmptyPack {
273 template <typename Stream>
274 msgpack::packer<Stream> &operator()(msgpack::packer<Stream> &o,
275 const T &) {
276 o.pack_map(0);
277 return o;
278 }
279 };
280 template <>
281 struct convert<webcface::message::Ping>
282 : public EmptyConvert<webcface::message::Ping> {};
283 template <>
284 struct convert<webcface::message::PingStatusReq>
285 : public EmptyConvert<webcface::message::PingStatusReq> {};
286 template <>
287 struct pack<webcface::message::Ping>
288 : public EmptyPack<webcface::message::Ping> {};
289 template <>
290 struct pack<webcface::message::PingStatusReq>
291 : public EmptyPack<webcface::message::PingStatusReq> {};
292
293 } // namespace adaptor
294}
295} // namespace msgpack
shared_ptrで管理されているdoubleのvector
Definition num_vector.h:56
u8stringとstringとwstringをshared_ptrで持ち共有する
Definition encoding.h:170
static SharedString fromU8String(std::string u8s)
Definition encoding.cc:136
ValAdaptorのVector.
Definition val_adaptor_vec.h:17
数値、文字列などの値を相互変換するクラス
Definition val_adaptor.h:81
int v
Definition latency-value.cc:38
std::string packDone(std::stringstream &buffer, int len)
Definition pack.h:67
void pack(std::stringstream &buffer, int &len, const T &obj)
メッセージをシリアル化しbufferに追加
Definition pack.h:61
std::vector< std::pair< int, std::shared_ptr< void > > > unpack(const std::string &message, const std::shared_ptr< spdlog::logger > &logger)
msgpackのメッセージをパースし返す
Definition message.cc:53
std::string packSingle(const T &obj)
メッセージ1つを要素数2の配列としてシリアル化
Definition pack.h:49
std::string messageTrace(const std::string &message)
バイナリを16進数の文字列に変換
Definition message.cc:16
Definition arg.h:15
ValType
引数や戻り値の型を表すenum
Definition val_adaptor.h:21
#define WEBCFACE_NS_END
Definition webcface-config.h:113
#define WEBCFACE_NS_BEGIN
Definition webcface-config.h:112