Async 1.8.0
AsyncMsg.h
Go to the documentation of this file.
1
117#ifndef ASYNC_MSG_INCLUDED
118#define ASYNC_MSG_INCLUDED
119
120
121/****************************************************************************
122 *
123 * System Includes
124 *
125 ****************************************************************************/
126
127#include <istream>
128#include <ostream>
129#include <vector>
130#include <array>
131#include <set>
132#include <map>
133#include <limits>
134#include <endian.h>
135#include <stdint.h>
136
137
138/****************************************************************************
139 *
140 * Project Includes
141 *
142 ****************************************************************************/
143
144
145
146/****************************************************************************
147 *
148 * Local Includes
149 *
150 ****************************************************************************/
151
152
153
154/****************************************************************************
155 *
156 * Forward declarations
157 *
158 ****************************************************************************/
159
160
161
162/****************************************************************************
163 *
164 * Namespace
165 *
166 ****************************************************************************/
167
168namespace Async
169{
170
171
172/****************************************************************************
173 *
174 * Forward declarations of classes inside of the declared namespace
175 *
176 ****************************************************************************/
177
178
179
180/****************************************************************************
181 *
182 * Defines & typedefs
183 *
184 ****************************************************************************/
185
193#define ASYNC_MSG_DERIVED_FROM(BASE_CLASS) \
194 bool packParent(std::ostream& os) const \
195 { \
196 return BASE_CLASS::pack(os); \
197 } \
198 size_t packedSizeParent(void) const \
199 { \
200 return BASE_CLASS::packedSize(); \
201 } \
202 bool unpackParent(std::istream& is) \
203 { \
204 return BASE_CLASS::unpack(is); \
205 }
206
214#define ASYNC_MSG_MEMBERS(...) \
215 bool pack(std::ostream& os) const override \
216 { \
217 return packParent(os) && Msg::pack(os, __VA_ARGS__); \
218 } \
219 size_t packedSize(void) const override \
220 { \
221 return packedSizeParent() + Msg::packedSize(__VA_ARGS__); \
222 } \
223 bool unpack(std::istream& is) override \
224 { \
225 return unpackParent(is) && Msg::unpack(is, __VA_ARGS__); \
226 }
227
233#define ASYNC_MSG_NO_MEMBERS \
234 bool pack(std::ostream& os) const override \
235 { \
236 return packParent(os); \
237 } \
238 size_t packedSize(void) const override { return packedSizeParent(); } \
239 bool unpack(std::istream& is) override \
240 { \
241 return unpackParent(is); \
242 }
243
244
245/****************************************************************************
246 *
247 * Exported Global Variables
248 *
249 ****************************************************************************/
250
251
252
253/****************************************************************************
254 *
255 * Class definitions
256 *
257 ****************************************************************************/
258
259template <typename T>
261{
262 public:
263 static bool pack(std::ostream& os, const T& val) { return val.pack(os); }
264 static size_t packedSize(const T& val) { return val.packedSize(); }
265 static bool unpack(std::istream& is, T& val) { return val.unpack(is); }
266};
267
268template <>
269class MsgPacker<char>
270{
271 public:
272 static bool pack(std::ostream& os, char val)
273 {
274 //std::cout << "pack<char>("<< int(val) << ")" << std::endl;
275 return os.write(&val, 1).good();
276 }
277 static size_t packedSize(const char& val) { return sizeof(char); }
278 static bool unpack(std::istream& is, char& val)
279 {
280 is.read(&val, 1);
281 //std::cout << "unpack<char>(" << int(val) << ")" << std::endl;
282 return is.good();
283 }
284};
285
286template <typename T>
288{
289 public:
290 static bool pack(std::ostream& os, const T& val)
291 {
292 //std::cout << "pack<64>(" << val << ")" << std::endl;
293 Overlay o;
294 o.val = val;
295 o.uval = htobe64(o.uval);
296 return os.write(o.buf, sizeof(T)).good();
297 }
298 static size_t packedSize(const T& val) { return sizeof(T); }
299 static bool unpack(std::istream& is, T& val)
300 {
301 Overlay o;
302 is.read(o.buf, sizeof(T));
303 o.uval = be64toh(o.uval);
304 val = o.val;
305 //std::cout << "unpack<64>(" << val << ")" << std::endl;
306 return is.good();
307 }
308 private:
309 union Overlay
310 {
311 char buf[sizeof(T)];
312 uint64_t uval;
313 T val;
314 };
315};
316template <> class MsgPacker<uint64_t> : public Packer64<uint64_t> {};
317template <> class MsgPacker<int64_t> : public Packer64<int64_t> {};
318template <> class MsgPacker<double> : public Packer64<double> {};
319
320template <typename T>
322{
323 public:
324 static bool pack(std::ostream& os, const T& val)
325 {
326 //std::cout << "pack<32>(" << val << ")" << std::endl;
327 Overlay o;
328 o.val = val;
329 o.uval = htobe32(o.uval);
330 return os.write(o.buf, sizeof(T)).good();
331 }
332 static size_t packedSize(const T& val) { return sizeof(T); }
333 static bool unpack(std::istream& is, T& val)
334 {
335 Overlay o;
336 is.read(o.buf, sizeof(T));
337 o.uval = be32toh(o.uval);
338 val = o.val;
339 //std::cout << "unpack<32>(" << val << ")" << std::endl;
340 return is.good();
341 }
342 private:
343 union Overlay
344 {
345 char buf[sizeof(T)];
346 uint32_t uval;
347 T val;
348 };
349};
350template <> class MsgPacker<uint32_t> : public Packer32<uint32_t> {};
351template <> class MsgPacker<int32_t> : public Packer32<int32_t> {};
352template <> class MsgPacker<float> : public Packer32<float> {};
353
354template <typename T>
356{
357 public:
358 static bool pack(std::ostream& os, const T& val)
359 {
360 //std::cout << "pack<16>(" << val << ")" << std::endl;
361 Overlay o;
362 o.val = val;
363 o.uval = htobe16(o.uval);
364 return os.write(o.buf, sizeof(T)).good();
365 }
366 static size_t packedSize(const T& val) { return sizeof(T); }
367 static bool unpack(std::istream& is, T& val)
368 {
369 Overlay o;
370 is.read(o.buf, sizeof(T));
371 o.uval = be16toh(o.uval);
372 val = o.val;
373 //std::cout << "unpack<16>(" << val << ")" << std::endl;
374 return is.good();
375 }
376 private:
377 union Overlay
378 {
379 char buf[sizeof(T)];
380 uint16_t uval;
381 T val;
382 };
383};
384template <> class MsgPacker<uint16_t> : public Packer16<uint16_t> {};
385template <> class MsgPacker<int16_t> : public Packer16<int16_t> {};
386
387template <typename T>
389{
390 public:
391 static bool pack(std::ostream& os, const T& val)
392 {
393 //std::cout << "pack<8>(" << int(val) << ")" << std::endl;
394 return os.write(reinterpret_cast<const char*>(&val), sizeof(T)).good();
395 }
396 static size_t packedSize(const T& val) { return sizeof(T); }
397 static bool unpack(std::istream& is, T& val)
398 {
399 is.read(reinterpret_cast<char*>(&val), sizeof(T));
400 //std::cout << "unpack<8>(" << int(val) << ")" << std::endl;
401 return is.good();
402 }
403};
404template <> class MsgPacker<uint8_t> : public Packer8<uint8_t> {};
405template <> class MsgPacker<int8_t> : public Packer8<int8_t> {};
406
407template <>
408class MsgPacker<std::string>
409{
410 public:
411 static bool pack(std::ostream& os, const std::string& val)
412 {
413 //std::cout << "pack<string>(" << val << ")" << std::endl;
414 if (val.size() > std::numeric_limits<uint16_t>::max())
415 {
416 return false;
417 }
418 uint16_t str_len(val.size());
419 return MsgPacker<uint16_t>::pack(os, str_len) &&
420 os.write(val.c_str(), val.size());
421 }
422 static size_t packedSize(const std::string& val)
423 {
424 return sizeof(uint16_t) + val.size();
425 }
426 static bool unpack(std::istream& is, std::string& val)
427 {
428 uint16_t str_len;
429 if (MsgPacker<uint16_t>::unpack(is, str_len))
430 {
431 if (str_len > std::numeric_limits<uint16_t>::max())
432 {
433 return false;
434 }
435 char buf[str_len];
436 if (is.read(buf, str_len))
437 {
438 val.assign(buf, str_len);
439 //std::cout << "unpack<string>(" << val << ")" << std::endl;
440 return true;
441 }
442 }
443 return false;
444 }
445};
446
447template <typename I>
448class MsgPacker<std::vector<I>>
449{
450 public:
451 static bool pack(std::ostream& os, const std::vector<I>& vec)
452 {
453 //std::cout << "pack<vector>(" << vec.size() << ")" << std::endl;
454 if (vec.size() > std::numeric_limits<uint16_t>::max())
455 {
456 return false;
457 }
458 MsgPacker<uint16_t>::pack(os, vec.size());
459 for (const auto& item : vec)
460 {
461 if (!MsgPacker<I>::pack(os, item))
462 {
463 return false;
464 }
465 }
466 return true;
467 }
468 static size_t packedSize(const std::vector<I>& vec)
469 {
470 size_t size = sizeof(uint16_t);
471 for (const auto& item : vec)
472 {
473 size += MsgPacker<I>::packedSize(item);
474 }
475 return size;
476 }
477 static bool unpack(std::istream& is, std::vector<I>& vec)
478 {
479 uint16_t vec_size;
480 MsgPacker<uint16_t>::unpack(is, vec_size);
481 if (vec_size > std::numeric_limits<uint16_t>::max())
482 {
483 return false;
484 }
485 //std::cout << "unpack<vector>(" << vec_size << ")" << std::endl;
486 vec.resize(vec_size);
487 for (auto& item : vec)
488 {
489 if (!MsgPacker<I>::unpack(is, item))
490 {
491 return false;
492 }
493 }
494 return true;
495 }
496};
497
498template <typename I>
499class MsgPacker<std::set<I>>
500{
501 public:
502 static bool pack(std::ostream& os, const std::set<I>& s)
503 {
504 //std::cout << "pack<set>(" << s.size() << ")" << std::endl;
505 if (s.size() > std::numeric_limits<uint16_t>::max())
506 {
507 return false;
508 }
509 if (!MsgPacker<uint16_t>::pack(os, s.size()))
510 {
511 return false;
512 }
513 for (const auto& item : s)
514 {
515 if (!MsgPacker<I>::pack(os, item))
516 {
517 return false;
518 }
519 }
520 return true;
521 }
522 static size_t packedSize(const std::set<I>& s)
523 {
524 size_t size = sizeof(uint16_t);
525 for (const auto& item : s)
526 {
527 size += MsgPacker<I>::packedSize(item);
528 }
529 return size;
530 }
531 static bool unpack(std::istream& is, std::set<I>& s)
532 {
533 uint16_t set_size;
534 if (!MsgPacker<uint16_t>::unpack(is, set_size))
535 {
536 return false;
537 }
538 if (set_size > std::numeric_limits<uint16_t>::max())
539 {
540 return false;
541 }
542 //std::cout << "unpack<set>(" << set_size << ")" << std::endl;
543 s.clear();
544 for (int i=0; i<set_size; ++i)
545 {
546 I val;
547 if (!MsgPacker<I>::unpack(is, val))
548 {
549 return false;
550 }
551 s.insert(val);
552 }
553 return true;
554 }
555};
556
557template <typename Tag, typename Value>
558class MsgPacker<std::map<Tag,Value>>
559{
560 public:
561 static bool pack(std::ostream& os, const std::map<Tag, Value>& m)
562 {
563 //std::cout << "pack<map>(" << m.size() << ")" << std::endl;
564 if (m.size() > std::numeric_limits<uint16_t>::max())
565 {
566 return false;
567 }
568 MsgPacker<uint16_t>::pack(os, m.size());
569 for (const auto& item : m)
570 {
571 MsgPacker<Tag>::pack(os, item.first);
572 MsgPacker<Value>::pack(os, item.second);
573 }
574 return true;
575 }
576 static size_t packedSize(const std::map<Tag, Value>& m)
577 {
578 size_t size = sizeof(uint16_t);
579 for (const auto& item : m)
580 {
581 size += (MsgPacker<Tag>::packedSize(item.first) +
582 MsgPacker<Value>::packedSize(item.second));
583 }
584 return size;
585 }
586 static bool unpack(std::istream& is, std::map<Tag,Value>& m)
587 {
588 uint16_t map_size;
589 MsgPacker<uint16_t>::unpack(is, map_size);
590 if (map_size > std::numeric_limits<uint16_t>::max())
591 {
592 return false;
593 }
594 //std::cout << "unpack<map>(" << map_size << ")" << std::endl;
595 m.clear();
596 for (int i=0; i<map_size; ++i)
597 {
598 Tag tag;
599 Value val;
600 MsgPacker<Tag>::unpack(is, tag);
602 m[tag] = val;
603 }
604 return true;
605 }
606};
607
608template <typename T, size_t N>
609class MsgPacker<std::array<T, N>>
610{
611 public:
612 static bool pack(std::ostream& os, const std::array<T, N>& vec)
613 {
614 for (const auto& item : vec)
615 {
616 if (!MsgPacker<T>::pack(os, item))
617 {
618 return false;
619 }
620 }
621 return true;
622 }
623 static size_t packedSize(const std::array<T, N>& vec)
624 {
625 size_t size = 0;
626 for (const auto& item : vec)
627 {
628 size += MsgPacker<T>::packedSize(item);
629 }
630 return size;
631 }
632 static bool unpack(std::istream& is, std::array<T, N>& vec)
633 {
634 for (auto& item : vec)
635 {
636 if (!MsgPacker<T>::unpack(is, item))
637 {
638 return false;
639 }
640 }
641 return true;
642 }
643};
644
645template <typename T, size_t N> class MsgPacker<T[N]>
646{
647 public:
648 static bool pack(std::ostream& os, const T (&vec)[N])
649 {
650 for (const auto& item : vec)
651 {
652 if (!MsgPacker<T>::pack(os, item))
653 {
654 return false;
655 }
656 }
657 return true;
658 }
659 static size_t packedSize(const T (&vec)[N])
660 {
661 size_t size = 0;
662 for (const auto& item : vec)
663 {
664 size += MsgPacker<T>::packedSize(item);
665 }
666 return size;
667 }
668 static bool unpack(std::istream& is, T (&vec)[N])
669 {
670 for (auto& item : vec)
671 {
672 if (!MsgPacker<T>::unpack(is, item))
673 {
674 return false;
675 }
676 }
677 return true;
678 }
679};
680
681
687class Msg
688{
689 public:
690 virtual ~Msg(void) {}
691
692 bool packParent(std::ostream&) const { return true; }
693 size_t packedSizeParent(void) const { return 0; }
694 bool unpackParent(std::istream&) { return true; }
695
696 virtual bool pack(std::ostream&) const { return true; }
697 virtual size_t packedSize(void) const { return 0; }
698 virtual bool unpack(std::istream&) { return true; }
699
700 template <typename T>
701 bool pack(std::ostream& os, const T& val) const
702 {
703 return MsgPacker<T>::pack(os, val);
704 }
705 template <typename T>
706 size_t packedSize(const T& val) const
707 {
708 return MsgPacker<T>::packedSize(val);
709 }
710 template <typename T>
711 bool unpack(std::istream& is, T& val) const
712 {
713 return MsgPacker<T>::unpack(is, val);
714 }
715
716 template <typename T1, typename T2, typename... Args>
717 bool pack(std::ostream& os, const T1& v1, const T2& v2,
718 const Args&... args) const
719 {
720 return pack(os, v1) && pack(os, v2, args...);
721 }
722 template <typename T1, typename T2, typename... Args>
723 size_t packedSize(const T1& v1, const T2& v2, const Args&... args) const
724 {
725 return packedSize(v1) + packedSize(v2, args...);
726 }
727 template <typename T1, typename T2, typename... Args>
728 bool unpack(std::istream& is, T1& v1, T2& v2, Args&... args)
729 {
730 return unpack(is, v1) && unpack(is, v2, args...);
731 }
732}; /* class Msg */
733
734
735} /* namespace */
736
737#endif /* ASYNC_MSG_INCLUDED */
738
739
740/*
741 * This file has not been truncated
742 */
static bool pack(std::ostream &os, const T(&vec)[N])
Definition AsyncMsg.h:648
static size_t packedSize(const T(&vec)[N])
Definition AsyncMsg.h:659
static bool unpack(std::istream &is, T(&vec)[N])
Definition AsyncMsg.h:668
static bool pack(std::ostream &os, char val)
Definition AsyncMsg.h:272
static bool unpack(std::istream &is, char &val)
Definition AsyncMsg.h:278
static size_t packedSize(const char &val)
Definition AsyncMsg.h:277
static size_t packedSize(const std::array< T, N > &vec)
Definition AsyncMsg.h:623
static bool unpack(std::istream &is, std::array< T, N > &vec)
Definition AsyncMsg.h:632
static bool pack(std::ostream &os, const std::array< T, N > &vec)
Definition AsyncMsg.h:612
static bool pack(std::ostream &os, const std::map< Tag, Value > &m)
Definition AsyncMsg.h:561
static bool unpack(std::istream &is, std::map< Tag, Value > &m)
Definition AsyncMsg.h:586
static size_t packedSize(const std::map< Tag, Value > &m)
Definition AsyncMsg.h:576
static bool unpack(std::istream &is, std::set< I > &s)
Definition AsyncMsg.h:531
static size_t packedSize(const std::set< I > &s)
Definition AsyncMsg.h:522
static bool pack(std::ostream &os, const std::set< I > &s)
Definition AsyncMsg.h:502
static bool unpack(std::istream &is, std::string &val)
Definition AsyncMsg.h:426
static size_t packedSize(const std::string &val)
Definition AsyncMsg.h:422
static bool pack(std::ostream &os, const std::string &val)
Definition AsyncMsg.h:411
static bool unpack(std::istream &is, std::vector< I > &vec)
Definition AsyncMsg.h:477
static size_t packedSize(const std::vector< I > &vec)
Definition AsyncMsg.h:468
static bool pack(std::ostream &os, const std::vector< I > &vec)
Definition AsyncMsg.h:451
static bool unpack(std::istream &is, T &val)
Definition AsyncMsg.h:265
static bool pack(std::ostream &os, const T &val)
Definition AsyncMsg.h:263
static size_t packedSize(const T &val)
Definition AsyncMsg.h:264
Base class for all messages.
Definition AsyncMsg.h:688
size_t packedSize(const T1 &v1, const T2 &v2, const Args &... args) const
Definition AsyncMsg.h:723
virtual ~Msg(void)
Definition AsyncMsg.h:690
size_t packedSize(const T &val) const
Definition AsyncMsg.h:706
bool unpack(std::istream &is, T &val) const
Definition AsyncMsg.h:711
bool pack(std::ostream &os, const T1 &v1, const T2 &v2, const Args &... args) const
Definition AsyncMsg.h:717
bool unpack(std::istream &is, T1 &v1, T2 &v2, Args &... args)
Definition AsyncMsg.h:728
bool pack(std::ostream &os, const T &val) const
Definition AsyncMsg.h:701
bool packParent(std::ostream &) const
Definition AsyncMsg.h:692
size_t packedSizeParent(void) const
Definition AsyncMsg.h:693
virtual size_t packedSize(void) const
Definition AsyncMsg.h:697
virtual bool unpack(std::istream &)
Definition AsyncMsg.h:698
bool unpackParent(std::istream &)
Definition AsyncMsg.h:694
virtual bool pack(std::ostream &) const
Definition AsyncMsg.h:696
static bool unpack(std::istream &is, T &val)
Definition AsyncMsg.h:367
static size_t packedSize(const T &val)
Definition AsyncMsg.h:366
static bool pack(std::ostream &os, const T &val)
Definition AsyncMsg.h:358
static bool unpack(std::istream &is, T &val)
Definition AsyncMsg.h:333
static bool pack(std::ostream &os, const T &val)
Definition AsyncMsg.h:324
static size_t packedSize(const T &val)
Definition AsyncMsg.h:332
static bool pack(std::ostream &os, const T &val)
Definition AsyncMsg.h:290
static size_t packedSize(const T &val)
Definition AsyncMsg.h:298
static bool unpack(std::istream &is, T &val)
Definition AsyncMsg.h:299
static bool unpack(std::istream &is, T &val)
Definition AsyncMsg.h:397
static bool pack(std::ostream &os, const T &val)
Definition AsyncMsg.h:391
static size_t packedSize(const T &val)
Definition AsyncMsg.h:396
Namespace for the asynchronous programming classes.