Many serialization and related stuff improvements

Fix bug in array-like containers serialization which could cause almost infinite
  loop on malformed input
Implement VLQ integer serialization
Unify sequence containers serialization code
Add support for VLQ serialization also for string size
Use VLQ compression for file links
Add templated function to fix endiannes for all integer types
Use bitset to print flags in binary form
Unify serialization code for integral types
Serialize 64bit integers types to JSON object with both string and integer
  representation, so it is posible to have this representation also for
  containers types like std::vetor or std::map this breaks retrocompatibility
  but is necessary to support clients written in languages which doesn't have
  64 bit integers support such as JavaScript or Dart
This commit is contained in:
Gioacchino Mazzurco 2020-03-16 16:20:06 +01:00
parent d203f31d0c
commit 39bde58c29
No known key found for this signature in database
GPG key ID: A1FBCA3872E87051
9 changed files with 985 additions and 752 deletions

View file

@ -309,10 +309,6 @@ public:
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
/* TODO: most of the time handles are smaller then 64bit use VLQ for
* binary serialization of those
* https://en.wikipedia.org/wiki/Variable-length_quantity#Zigzag_encoding
*/
RS_SERIAL_PROCESS(mFiles);
RS_SERIAL_PROCESS(mDirs);
RS_SERIAL_PROCESS(mTotalFiles);

View file

@ -24,6 +24,7 @@
#include <type_traits>
#include <ostream>
#include <bitset>
/** Check if given type is a scoped enum */
template<typename E>
@ -128,13 +129,7 @@ typename std::enable_if<Rs__BitFlagsOps<EFT>::enabled, std::ostream>::type&
operator <<(std::ostream& stream, EFT flags)
{
using u_t = typename std::underlying_type<EFT>::type;
for(int i = sizeof(u_t); i>=0; --i)
{
stream << (flags & ( 1 << i ) ? "1" : "0");
if( i % 8 == 0 ) stream << " ";
}
return stream;
return stream << std::bitset<sizeof(u_t)>(static_cast<u_t>(flags));
}
#include <cstdint>
@ -170,6 +165,7 @@ template<int n> class RS_DEPRECATED_FOR(RS_REGISTER_ENUM_FLAGS_TYPE) t_RsFlags32
inline t_RsFlags32() : _bits(0) {}
inline explicit t_RsFlags32(uint32_t N) : _bits(N) {} // allows initialization from a set of uint32_t
inline t_RsFlags32<n> operator| (const t_RsFlags32<n>& f) const { return t_RsFlags32<n>(_bits | f._bits) ; }
inline t_RsFlags32<n> operator^ (const t_RsFlags32<n>& f) const { return t_RsFlags32<n>(_bits ^ f._bits) ; }
inline t_RsFlags32<n> operator* (const t_RsFlags32<n>& f) const { return t_RsFlags32<n>(_bits & f._bits) ; }
@ -187,6 +183,19 @@ template<int n> class RS_DEPRECATED_FOR(RS_REGISTER_ENUM_FLAGS_TYPE) t_RsFlags32
//inline explicit operator bool() const { return _bits>0; }
inline uint32_t toUInt32() const { return _bits ; }
/// Easier porting to new flag system
template<typename EFT> inline
typename std::enable_if<(Rs__BitFlagsOps<EFT>::enabled &&
sizeof(EFT) >= sizeof(uint32_t) ), EFT>::type
toEFT() { return static_cast<EFT>(_bits); }
/// Easier porting to new flag system
template<typename EFT>
static inline typename std::enable_if<
Rs__BitFlagsOps<EFT>::enabled &&
sizeof(EFT) <= sizeof(uint32_t), t_RsFlags32>::type
fromEFT(EFT e) { return t_RsFlags32(static_cast<uint32_t>(e)); }
void clear() { _bits = 0 ; }
friend std::ostream& operator<<(std::ostream& o,const t_RsFlags32<n>& f) // friendly print with 0 and I
@ -199,8 +208,10 @@ template<int n> class RS_DEPRECATED_FOR(RS_REGISTER_ENUM_FLAGS_TYPE) t_RsFlags32
}
return o ;
}
private:
uint32_t _bits ;
private:
friend struct RsTypeSerializer;
uint32_t _bits;
};
#define FLAGS_TAG_TRANSFER_REQS 0x4228af
@ -230,7 +241,7 @@ typedef t_RsFlags32<FLAGS_TAG_SERVICE_PERM > ServicePermissionFlags ;
//
typedef t_RsFlags32<FLAGS_TAG_SERVICE_CHAT > ChatLobbyFlags ;
// Flags for serializer
//
/// @deprecated Flags for serializer
RS_DEPRECATED_FOR(RsSerializationFlags)
typedef t_RsFlags32<FLAGS_TAG_SERIALIZER > SerializationFlags ;