35#ifndef _MSG_SERIALIZE_H
36#define _MSG_SERIALIZE_H
64#define CHECK_UNSUPPORTED_CONTAINER
65#ifdef CHECK_UNSUPPORTED_CONTAINER
68#include <forward_list>
71#include <unordered_set>
72#include <unordered_map>
77 template <
typename U,
typename V>
80 template <
typename T,
typename Alloc>
83 template <
typename T,
typename Alloc>
86 template <
typename T,
typename Alloc>
89 template <
typename T,
typename Alloc>
92 template <
typename T,
typename Alloc>
95 template <
typename T,
typename Hash,
typename KeyEqual,
typename Alloc>
98 template <
typename Key,
typename T,
typename Hash,
typename KeyEqual,
typename Alloc>
101 template <
typename Key,
typename T,
typename Hash,
typename KeyEqual,
typename Alloc>
192 const static int n = 1;
193 const static bool le= (* (
char *)&n == 1);
200 std::istream&
readEndian(std::istream& is,
bool& littleEndian)
204 is.read((
char*) &littleEndian,
sizeof(littleEndian));
213 bool littleEndian =
LE();
215 os.write((
const char*) &littleEndian,
sizeof(littleEndian));
225 std::istream&
read (std::istream& is,
I* t_)
227 if (check_stop_parse(is))
230 if (check_pointer(is, t_))
235 std::streampos startPos = is.tellg();
237 read(is, size,
false);
240 push_stop_parse_pos(startPos + std::streampos(size));
244 pop_stop_parse_pos();
248 std::streampos endPos = is.tellg();
249 uint16_t rcvdSize =
static_cast<uint16_t
>(endPos - startPos);
255 uint16_t seekOffset = size - rcvdSize;
256 is.seekg(seekOffset, std::ios_base::cur);
269 std::istream&
read (std::istream& is, std::string& s)
271 if (check_stop_parse(is))
277 read(is, size,
false);
278 if (check_stream(is) && check_slength(is, size))
281 parseStatus(
typeid(s), s.size());
282 read_internal(is,
const_cast<char*
>(s.c_str()), size,
true);
292 std::istream&
read (std::istream& is, std::wstring& s)
294 if (check_stop_parse(is))
300 read(is, size,
false);
301 if (check_stream(is) && check_slength(is, size))
304 parseStatus(
typeid(s), s.size());
305 for (uint16_t ii = 0; ii < size; ii++)
308 int offset =
sizeof(wchar_t) - WCHAR_SIZE;
309 read_internal(is,
reinterpret_cast<char*
>(&c) + offset, WCHAR_SIZE);
321 std::istream&
read (std::istream& is,
char* str)
323 if (check_stop_parse(is))
329 read(is, size,
false);
330 if (check_stream(is) && check_slength(is, size))
332 if (check_pointer(is, str))
334 parseStatus(
typeid(str), size);
335 read_internal(is, str, size,
true);
350 std::istream&
read (std::istream& is, std::vector<bool>& container)
352 if (check_stop_parse(is))
359 read(is, size,
false);
360 if (check_stream(is) && check_container_size(is, size))
362 parseStatus(
typeid(container), size);
363 for (uint16_t i = 0; i < size; ++i)
367 container.push_back(t);
379 std::ostream&
write (std::ostream& os,
I* t_)
381 if (check_pointer(os, t_))
383 uint16_t elementSize = 0;
386 std::streampos elementSizePos = os.tellp();
387 write(os, elementSize,
false);
390 t_->
write(*
this, os);
395 std::streampos currentPos = os.tellp();
396 os.seekp(elementSizePos);
397 elementSize =
static_cast<uint16_t
>(currentPos - elementSizePos);
398 write(os, elementSize,
false);
399 os.seekp(currentPos);
410 std::ostream&
write(std::ostream& os,
const std::string& s)
412 uint16_t size =
static_cast<uint16_t
>(s.size());
414 write(os, size,
false);
415 if (check_stream(os) && check_slength(os, size))
417 write_internal(os, s.c_str(), size,
true);
426 std::ostream&
write(std::ostream& os, std::string& s)
428 return write(os,
static_cast<const std::string&
>(s));
435 std::ostream&
write (std::ostream& os,
const std::wstring& s)
437 uint16_t size =
static_cast<uint16_t
>(s.size());
439 write(os, size,
false);
440 if (check_stream(os) && check_slength(os, size))
442 for (uint16_t ii = 0; ii < size; ii++)
445 int offset =
sizeof(wchar_t) - WCHAR_SIZE;
446 write_internal(os,
reinterpret_cast<char*
>(&c) + offset, WCHAR_SIZE);
456 std::ostream&
write (std::ostream& os, std::wstring& s)
458 return write(os,
static_cast<const std::wstring&
>(s));
465 std::ostream&
write(std::ostream& os,
char* str)
467 return write(os,
static_cast<const char*
>(str));
474 std::ostream&
write (std::ostream& os,
const char* str)
476 if (check_pointer(os, str))
478 uint16_t size =
static_cast<uint16_t
>(strlen(str)) + 1;
480 write(os, size,
false);
481 if (check_stream(os) && check_slength(os, size))
483 write_internal (os, str, size,
true);
497 std::ostream&
write (std::ostream& os, std::vector<bool>& container)
499 uint16_t size =
static_cast<uint16_t
>(container.size());
501 write(os, size,
false);
502 if (check_stream(os) && check_container_size(os, size))
504 for (
const bool& c : container)
517 std::istream&
read(std::istream& is, T &t_,
bool readPrependedType =
true)
521 static_assert(!(std::is_pointer<T>::value &&
522 (std::is_arithmetic<typename std::remove_pointer<T>::type>::value ||
523 std::is_class<typename std::remove_pointer<T>::type>::value)),
524 "T cannot be a pointer to a built-in or custom data type");
526 if (check_stop_parse(is))
530 if (std::is_class<T>::value ==
false)
533 if (std::is_pointer<T>::value ==
false)
535 if (readPrependedType)
543 if (readPrependedType)
544 parseStatus(
typeid(t_));
545 read_internal(is, (
char*)&t_,
sizeof (t_));
552 is.setstate(std::ios::failbit);
559 parseStatus(
typeid(t_));
570 std::ostream&
write(std::ostream& os, T &t_,
bool prependType =
true)
574 static_assert(!(std::is_pointer<T>::value &&
575 (std::is_arithmetic<typename std::remove_pointer<T>::type>::value ||
576 std::is_class<typename std::remove_pointer<T>::type>::value)),
577 "T cannot be a pointer to a built-in or custom data type");
580#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L
582 if constexpr (std::is_class<T>::value)
585 static_assert(std::is_base_of<serialize::I, T>::value,
"T must inherit from serialize::I");
593 if (std::is_pointer<T>::value ==
false)
599 return write_internal(os, (
const char*)&t_,
sizeof(t_));
605 os.setstate(std::ios::failbit);
611 if (std::is_class<T>::value ==
false)
614 if (std::is_pointer<T>::value ==
false)
620 return write_internal(os, (
const char*)&t_,
sizeof(t_));
626 os.setstate(std::ios::failbit);
644 std::ostream&
write(std::ostream& os, std::vector<T>& container)
648 uint16_t size =
static_cast<uint16_t
>(container.size());
650 write(os, size,
false);
651 if (check_stream(os) && check_container_size(os, size))
653 for (
const auto& item : container)
655 write(os, item,
false);
667 std::istream&
read(std::istream& is, std::vector<T>& container)
671 if (check_stop_parse(is))
678 read(is, size,
false);
679 if (check_stream(is) && check_container_size(is, size))
681 parseStatus(
typeid(container), size);
682 for (uint16_t i = 0; i < size; ++i)
686 container.push_back(t);
699 std::ostream&
write(std::ostream& os, std::vector<T*>& container)
701 static_assert(std::is_base_of<serialize::I, T>::value,
"Type T must be derived from serialize::I");
703 uint16_t size =
static_cast<uint16_t
>(container.size());
705 write(os, size,
false);
707 if (check_stream(os) && check_container_size(os, size))
709 for (
auto* ptr : container)
714 write(os, notNULL,
false);
716 auto* i =
static_cast<I*
>(ptr);
721 bool notNULL =
false;
722 write(os, notNULL,
false);
736 std::istream&
read(std::istream& is, std::vector<T*>& container)
738 static_assert(std::is_base_of<serialize::I, T>::value,
"Type T must be derived from serialize::I");
740 if (check_stop_parse(is))
747 read(is, size,
false);
748 if (check_stream(is) && check_container_size(is, size))
750 parseStatus(
typeid(container), size);
751 for (uint16_t i = 0; i < size; ++i)
753 bool notNULL =
false;
754 read(is, notNULL,
false);
759 auto *i =
static_cast<I*
>(object);
761 container.push_back(
object);
765 container.push_back(
nullptr);
778 template <
class K,
class V,
class P>
779 std::ostream&
write(std::ostream& os, std::map<K, V, P>& container)
783 uint16_t size =
static_cast<uint16_t
>(container.size());
785 write(os, size,
false);
786 if (check_stream(os) && check_container_size(os, size))
788 for (
const auto& entry : container)
790 write(os, entry.first,
false);
791 write(os, entry.second,
false);
802 template <
class K,
class V,
class P>
803 std::istream&
read(std::istream& is, std::map<K, V, P>& container)
807 if (check_stop_parse(is))
814 read(is, size,
false);
815 if (check_stream(is) && check_container_size(is, size))
817 parseStatus(
typeid(container), size);
818 for (uint16_t i = 0; i < size; ++i)
822 read(is, key,
false);
824 read(is, value,
false);
825 container[key] = value;
837 template <
class K,
class V,
class P>
838 std::ostream&
write(std::ostream& os, std::map<K, V*, P>& container)
840 static_assert(std::is_base_of<serialize::I, V>::value,
"Type V must be derived from serialize::I");
842 uint16_t size =
static_cast<uint16_t
>(container.size());
844 write(os, size,
false);
846 if (check_stream(os) && check_container_size(os, size))
848 for (
auto& entry : container)
850 write(os, entry.first,
false);
852 if (entry.second !=
nullptr)
855 write(os, notNULL,
false);
857 auto* i =
static_cast<I*
>(entry.second);
862 bool notNULL =
false;
863 write(os, notNULL,
false);
875 template <
class K,
class V,
class P>
876 std::istream&
read(std::istream& is, std::map<K, V*, P>& container)
878 static_assert(std::is_base_of<serialize::I, V>::value,
"Type V must be derived from serialize::I");
880 if (check_stop_parse(is))
887 read(is, size,
false);
888 if (check_stream(is) && check_container_size(is, size))
890 parseStatus(
typeid(container), size);
891 for (uint16_t i = 0; i < size; ++i)
894 read(is, key,
false);
896 read(is, notNULL,
false);
900 auto *i =
static_cast<I*
>(object);
902 container[key] = (V*)
object;
906 container[key] =
nullptr;
919 template <
class T,
class P>
920 std::ostream&
write(std::ostream& os, std::set<T, P>& container)
924 uint16_t size =
static_cast<uint16_t
>(container.size());
926 write(os, size,
false);
928 if (check_stream(os) && check_container_size(os, size))
930 for (
const auto& item : container)
932 write(os, item,
false);
943 template <
class T,
class P>
944 std::istream&
read(std::istream& is, std::set<T, P>& container)
948 if (check_stop_parse(is))
955 read(is, size,
false);
956 if (check_stream(is) && check_container_size(is, size))
958 parseStatus(
typeid(container), size);
959 for (uint16_t i = 0; i < size; ++i)
975 template <
class T,
class P>
976 std::ostream&
write(std::ostream& os, std::set<T*, P>& container)
978 static_assert(std::is_base_of<serialize::I, T>::value,
"Type T must be derived from serialize::I");
980 uint16_t size =
static_cast<uint16_t
>(container.size());
982 write(os, size,
false);
983 if (check_stream(os) && check_container_size(os, size))
985 for (
auto ptr : container)
990 write(os, notNULL,
false);
992 auto* i =
static_cast<I*
>(ptr);
997 bool notNULL =
false;
998 write(os, notNULL,
false);
1010 template <
class T,
class P>
1011 std::istream&
read(std::istream& is, std::set<T*, P>& container)
1013 static_assert(std::is_base_of<serialize::I, T>::value,
"Type T must be derived from serialize::I");
1015 if (check_stop_parse(is))
1022 read(is, size,
false);
1023 if (check_stream(is) && check_container_size(is, size))
1025 parseStatus(
typeid(container), size);
1026 for (uint16_t i = 0; i < size; ++i)
1028 bool notNULL =
false;
1029 read(is, notNULL,
false);
1033 auto *i =
static_cast<I*
>(object);
1035 container.insert(
object);
1039 container.insert(
nullptr);
1053 std::ostream&
write(std::ostream& os, std::list<T>& container)
1057 uint16_t size =
static_cast<uint16_t
>(container.size());
1059 write(os, size,
false);
1061 if (check_stream(os) && check_container_size(os, size))
1063 for (
const auto& item : container)
1065 write(os, item,
false);
1077 std::istream&
read(std::istream& is, std::list<T>& container)
1081 if (check_stop_parse(is))
1088 read(is, size,
false);
1089 if (check_stream(is) && check_container_size(is, size))
1091 parseStatus(
typeid(container), size);
1092 for (uint16_t i = 0; i < size; ++i)
1096 container.push_back(t);
1109 std::ostream&
write(std::ostream& os, std::list<T*>& container)
1111 static_assert(std::is_base_of<serialize::I, T>::value,
"Type T must be derived from serialize::I");
1113 uint16_t size =
static_cast<uint16_t
>(container.size());
1115 write(os, size,
false);
1117 if (check_stream(os) && check_container_size(os, size))
1119 for (
auto* ptr : container)
1123 bool notNULL =
true;
1124 write(os, notNULL,
false);
1126 auto* i =
static_cast<I*
>(ptr);
1131 bool notNULL =
false;
1132 write(os, notNULL,
false);
1145 std::istream&
read(std::istream& is, std::list<T*>& container)
1147 static_assert(std::is_base_of<serialize::I, T>::value,
"Type T must be derived from serialize::I");
1149 if (check_stop_parse(is))
1156 read(is, size,
false);
1157 if (check_stream(is) && check_container_size(is, size))
1159 parseStatus(
typeid(container), size);
1160 for (uint16_t i = 0; i < size; ++i)
1162 bool notNULL =
false;
1163 read(is, notNULL,
false);
1167 auto *i =
static_cast<I*
>(object);
1169 container.push_back(
object);
1173 container.push_back(
nullptr);
1184 error_handler = error_handler_;
1193 parse_handler = parse_handler_;
1204 std::istream& read_internal(std::istream& is,
char* p, uint32_t size,
bool no_swap =
false)
1206 if (check_stop_parse(is))
1211 if (!check_pointer(is, p))
1215 if (
LE() && !no_swap)
1218 for (
int i = size - 1; i >= 0; --i)
1239 std::ostream& write_internal(std::ostream& os,
const char* p, uint32_t size,
bool no_swap =
false)
1241 if (!check_pointer(os, p))
1245 if (
LE() && !no_swap)
1248 for (
int i = size - 1; i >= 0; --i)
1262 static const uint16_t MAX_STRING_SIZE = 256;
1263 static const uint16_t MAX_CONTAINER_SIZE = 200;
1266 static const size_t WCHAR_SIZE = 2;
1269 std::list<std::streampos> stopParsePosStack;
1273 void raiseError(
ParsingError error,
int line,
const char* file)
1277 error_handler(error, line, file);
1281 void parseStatus(
const std::type_info& typeId,
size_t size = 0)
1284 parse_handler(typeId, size);
1287 void write_type(std::ostream& os,
Type type_)
1289 uint8_t type =
static_cast<uint8_t
>(type_);
1290 write_internal(os, (
const char*) &type,
sizeof(type));
1293 bool read_type(std::istream& is,
Type type_)
1295 Type type =
static_cast<Type>(is.peek());
1298 uint8_t typeByte = 0;
1299 read_internal(is, (
char*) &typeByte,
sizeof(typeByte));
1305 is.setstate(std::ios::failbit);
1310 bool check_stream(std::ios& stream)
1315 stream.setstate(std::ios::failbit);
1317 return stream.good();
1320 bool check_slength(std::ios& stream,
int stringSize)
1322 bool sizeOk = stringSize <= MAX_STRING_SIZE;
1326 stream.setstate(std::ios::failbit);
1328 if (stringSize == 0)
1333 bool check_container_size(std::ios& stream,
int containerSize)
1335 bool sizeOk = containerSize <= MAX_CONTAINER_SIZE;
1339 stream.setstate(std::ios::failbit);
1344 bool check_pointer(std::ios& stream,
const void* ptr)
1349 stream.setstate(std::ios::failbit);
1354 void push_stop_parse_pos(std::streampos stopParsePos)
1356 stopParsePosStack.push_front(stopParsePos);
1359 std::streampos pop_stop_parse_pos()
1361 std::streampos stopParsePos = stopParsePosStack.front();
1362 stopParsePosStack.pop_front();
1363 return stopParsePos;
1366 bool check_stop_parse(std::istream& is)
1373 if (stopParsePosStack.size() > 0)
1375 std::streampos stopParsePos = stopParsePosStack.front();
1376 if (is.tellg() >= stopParsePos)
Abstract interface that all serialized user defined classes inherit.
Definition msg_serialize.h:139
virtual std::ostream & write(serialize &ms, std::ostream &os)=0
virtual std::istream & read(serialize &ms, std::istream &is)=0
The serialize class binary serializes and deserializes C++ objects.
Definition msg_serialize.h:135
std::ostream & write(std::ostream &os, char *str)
Definition msg_serialize.h:465
void writeEndian(std::ostream &os)
Definition msg_serialize.h:211
std::ostream & write(std::ostream &os, std::set< T, P > &container)
Definition msg_serialize.h:920
bool LE()
Definition msg_serialize.h:190
std::istream & read(std::istream &is, std::vector< bool > &container)
Definition msg_serialize.h:350
std::istream & read(std::istream &is, std::wstring &s)
Definition msg_serialize.h:292
std::istream & read(std::istream &is, std::map< K, V *, P > &container)
Definition msg_serialize.h:876
std::istream & read(std::istream &is, char *str)
Definition msg_serialize.h:321
std::ostream & write(std::ostream &os, const std::wstring &s)
Definition msg_serialize.h:435
std::ostream & write(std::ostream &os, std::map< K, V *, P > &container)
Definition msg_serialize.h:838
void setParseHandler(ParseHandler parse_handler_)
Definition msg_serialize.h:1191
std::ostream & write(std::ostream &os, const std::string &s)
Definition msg_serialize.h:410
void clearLastError()
Definition msg_serialize.h:1188
std::ostream & write(std::ostream &os, std::wstring &s)
Definition msg_serialize.h:456
std::ostream & write(std::ostream &os, std::vector< T * > &container)
Definition msg_serialize.h:699
std::istream & read(std::istream &is, std::set< T, P > &container)
Definition msg_serialize.h:944
std::ostream & write(std::ostream &os, T &t_, bool prependType=true)
Definition msg_serialize.h:570
std::istream & read(std::istream &is, std::list< T * > &container)
Definition msg_serialize.h:1145
std::ostream & write(std::ostream &os, std::vector< T > &container)
Definition msg_serialize.h:644
std::ostream & write(std::ostream &os, std::list< T > &container)
Definition msg_serialize.h:1053
std::ostream & write(std::ostream &os, std::set< T *, P > &container)
Definition msg_serialize.h:976
Type
Definition msg_serialize.h:161
std::ostream & write(std::ostream &os, std::map< K, V, P > &container)
Definition msg_serialize.h:779
void setErrorHandler(ErrorHandler error_handler_)
Definition msg_serialize.h:1182
std::ostream & write(std::ostream &os, std::vector< bool > &container)
Definition msg_serialize.h:497
std::istream & read(std::istream &is, T &t_, bool readPrependedType=true)
Definition msg_serialize.h:517
std::ostream & write(std::ostream &os, std::string &s)
Definition msg_serialize.h:426
std::istream & read(std::istream &is, std::set< T *, P > &container)
Definition msg_serialize.h:1011
std::istream & read(std::istream &is, std::vector< T > &container)
Definition msg_serialize.h:667
std::ostream & write(std::ostream &os, std::list< T * > &container)
Definition msg_serialize.h:1109
void(*) ParseHandler(const std::type_info &typeId, size_t size)
Definition msg_serialize.h:1190
ParsingError getLastError() const
Definition msg_serialize.h:1187
std::istream & read(std::istream &is, std::string &s)
Definition msg_serialize.h:269
std::istream & read(std::istream &is, I *t_)
Definition msg_serialize.h:225
std::istream & readEndian(std::istream &is, bool &littleEndian)
Definition msg_serialize.h:200
std::ostream & write(std::ostream &os, I *t_)
Definition msg_serialize.h:379
void(*) ErrorHandler(ParsingError error, int line, const char *file)
Definition msg_serialize.h:1181
ParsingError
Definition msg_serialize.h:175
std::istream & read(std::istream &is, std::vector< T * > &container)
Definition msg_serialize.h:736
std::istream & read(std::istream &is, std::map< K, V, P > &container)
Definition msg_serialize.h:803
std::istream & read(std::istream &is, std::list< T > &container)
Definition msg_serialize.h:1077
std::ostream & write(std::ostream &os, const char *str)
Definition msg_serialize.h:474
Definition msg_serialize.h:51
Definition msg_serialize.h:53
Definition msg_serialize.h:59