mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-17 21:34:10 -05:00
simplified new serialization prototype
This commit is contained in:
parent
4f24b95b16
commit
369621f4a4
@ -2,6 +2,8 @@
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
#include "util/rsmemory.h"
|
#include "util/rsmemory.h"
|
||||||
#include "util/rsprint.h"
|
#include "util/rsprint.h"
|
||||||
@ -10,18 +12,79 @@
|
|||||||
static const uint16_t RS_SERVICE_TYPE_TEST = 0xffff;
|
static const uint16_t RS_SERVICE_TYPE_TEST = 0xffff;
|
||||||
static const uint8_t RS_ITEM_SUBTYPE_TEST1 = 0x01 ;
|
static const uint8_t RS_ITEM_SUBTYPE_TEST1 = 0x01 ;
|
||||||
|
|
||||||
|
// Template serialization of RsTypeSerialiser::serial_process() for unknown/new types
|
||||||
|
//
|
||||||
|
//
|
||||||
|
template<> uint32_t RsTypeSerializer::serial_size(const std::set<uint32_t>& s)
|
||||||
|
{
|
||||||
|
return s.size() * 4 + 4 ;
|
||||||
|
}
|
||||||
|
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const std::set<uint32_t>& member)
|
||||||
|
{
|
||||||
|
uint32_t tlvsize = serial_size(member) ;
|
||||||
|
bool ok = true ;
|
||||||
|
uint32_t offset_save = offset ;
|
||||||
|
|
||||||
|
if(tlvsize + offset >= size)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
ok = ok && RsTypeSerializer::serialize(data,size,offset,member.size()) ;
|
||||||
|
|
||||||
|
for(std::set<uint32_t>::const_iterator it(member.begin());it!=member.end();++it)
|
||||||
|
ok = ok && RsTypeSerializer::serialize(data,size,offset,*it) ;
|
||||||
|
|
||||||
|
if(!ok)
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) Cannot serialize std::set<uint32_t>" << std::endl;
|
||||||
|
offset = offset_save ; // return the data in the same condition
|
||||||
|
}
|
||||||
|
return ok ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, std::set<uint32_t>& member)
|
||||||
|
{
|
||||||
|
bool ok = true ;
|
||||||
|
uint32_t n = 0 ;
|
||||||
|
uint32_t offset_save = offset ;
|
||||||
|
member.clear();
|
||||||
|
|
||||||
|
ok = ok && RsTypeSerializer::deserialize(data,size,offset,n);
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<n;++i)
|
||||||
|
{
|
||||||
|
uint32_t x;
|
||||||
|
ok = ok && RsTypeSerializer::deserialize(data,size,offset,x) ;
|
||||||
|
|
||||||
|
member.insert(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ok)
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) Cannot deserialize std::set<uint32_t>" << std::endl;
|
||||||
|
offset = offset_save ; // return the data in the same condition
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
// New item class. This class needs to define:
|
||||||
|
// - a serial_process method that tells which members to serialize
|
||||||
|
// - overload the clear() and print() methods of RsItem
|
||||||
|
//
|
||||||
class RsTestItem: public RsSerializable
|
class RsTestItem: public RsSerializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsTestItem() : RsSerializable(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_TEST,RS_ITEM_SUBTYPE_TEST1) {}
|
RsTestItem() : RsSerializable(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_TEST,RS_ITEM_SUBTYPE_TEST1) {}
|
||||||
|
|
||||||
|
// Derived from RsSerializable
|
||||||
|
//
|
||||||
virtual void serial_process(RsSerializable::SerializeJob j, SerializeContext& ctx)
|
virtual void serial_process(RsSerializable::SerializeJob j, SerializeContext& ctx)
|
||||||
{
|
{
|
||||||
RsTypeSerializer<uint64_t> ().serial_process(j,ctx,ts) ;
|
RsTypeSerializer::serial_process(j,ctx,ts ) ;
|
||||||
RsTypeSerializer<std::string>().serial_process(j,ctx,str) ;
|
RsTypeSerializer::serial_process(j,ctx,str) ;
|
||||||
|
RsTypeSerializer::serial_process(j,ctx,int_set ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// derived from RsItem
|
// Derived from RsItem
|
||||||
//
|
//
|
||||||
virtual void clear() {}
|
virtual void clear() {}
|
||||||
virtual std::ostream& print(std::ostream&,uint16_t indent) {}
|
virtual std::ostream& print(std::ostream&,uint16_t indent) {}
|
||||||
@ -30,8 +93,13 @@ class RsTestItem: public RsSerializable
|
|||||||
private:
|
private:
|
||||||
std::string str ;
|
std::string str ;
|
||||||
uint64_t ts ;
|
uint64_t ts ;
|
||||||
|
std::set<uint32_t> int_set ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// New user-defined serializer class.
|
||||||
|
// The only required member is the create_item() method, which creates the correct RsSerializable
|
||||||
|
// that corresponds to a specific (service,subtype) couple.
|
||||||
|
//
|
||||||
class RsTestSerializer: public RsSerializer
|
class RsTestSerializer: public RsSerializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -51,6 +51,7 @@ class SerializeContext
|
|||||||
};
|
};
|
||||||
template<typename T> T ntoh(T t)
|
template<typename T> T ntoh(T t)
|
||||||
{
|
{
|
||||||
|
if(sizeof(T) == 8) return t;
|
||||||
if(sizeof(T) == 4) return ntohl(t) ;
|
if(sizeof(T) == 4) return ntohl(t) ;
|
||||||
if(sizeof(T) == 2) return ntohs(t) ;
|
if(sizeof(T) == 2) return ntohs(t) ;
|
||||||
|
|
||||||
@ -59,6 +60,7 @@ template<typename T> T ntoh(T t)
|
|||||||
}
|
}
|
||||||
template<typename T> T hton(T t)
|
template<typename T> T hton(T t)
|
||||||
{
|
{
|
||||||
|
if(sizeof(T) == 8) return t;
|
||||||
if(sizeof(T) == 4) return htonl(t) ;
|
if(sizeof(T) == 4) return htonl(t) ;
|
||||||
if(sizeof(T) == 2) return htons(t) ;
|
if(sizeof(T) == 2) return htons(t) ;
|
||||||
|
|
||||||
@ -66,10 +68,11 @@ template<typename T> T hton(T t)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> class RsTypeSerializerBase
|
class RsTypeSerializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void serial_process(RsSerializable::SerializeJob j,SerializeContext& ctx,T& member)
|
template<typename T>
|
||||||
|
static void serial_process(RsSerializable::SerializeJob j,SerializeContext& ctx,T& member)
|
||||||
{
|
{
|
||||||
switch(j)
|
switch(j)
|
||||||
{
|
{
|
||||||
@ -88,16 +91,22 @@ template<typename T> class RsTypeSerializerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool serialize(uint8_t data[], uint32_t size, uint32_t &offset, const T& member)const=0;
|
template<typename T>
|
||||||
virtual bool deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, T& member) const=0;
|
static bool serialize(uint8_t data[], uint32_t size, uint32_t &offset, const T& member);
|
||||||
virtual uint32_t serial_size(const T& /* member */)const=0;
|
|
||||||
|
template<typename T>
|
||||||
|
static bool deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, T& member);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static uint32_t serial_size(const T& /* member */);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Templates to generate RsSerializer for standard integral types
|
/// Templates to generate RsSerializer for standard integral types
|
||||||
template<typename N, uint32_t SIZE> class t_SerializerNType : public RsTypeSerializerBase<N>
|
//
|
||||||
|
template<typename N,uint32_t SIZE> class t_SerializerNType
|
||||||
{
|
{
|
||||||
protected:
|
public:
|
||||||
bool serialize(uint8_t data[], uint32_t size, uint32_t &offset, const N& member)const
|
static bool serialize(uint8_t data[], uint32_t size, uint32_t &offset, const N& member)
|
||||||
{
|
{
|
||||||
if (size <= offset || size - offset < SIZE)
|
if (size <= offset || size - offset < SIZE)
|
||||||
return false;
|
return false;
|
||||||
@ -107,7 +116,7 @@ protected:
|
|||||||
offset += SIZE;
|
offset += SIZE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, N& member)const
|
static bool deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, N& member)
|
||||||
{
|
{
|
||||||
if (size <= offset || size - offset < SIZE)
|
if (size <= offset || size - offset < SIZE)
|
||||||
return false;
|
return false;
|
||||||
@ -119,34 +128,56 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t serial_size(const N& /* member */)const
|
static uint32_t serial_size(const N& /* member */)
|
||||||
{
|
{
|
||||||
return SIZE;
|
return SIZE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> class RsTypeSerializer
|
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const uint8_t& member)
|
||||||
{
|
{
|
||||||
// public:
|
return t_SerializerNType<uint8_t,1>::serialize(data,size,offset,member);
|
||||||
// virtual void serial_process(RsSerializable::SerializeJob j,SerializeContext& ctx,const T& member)=0;
|
}
|
||||||
|
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const uint32_t& member)
|
||||||
|
{
|
||||||
|
return t_SerializerNType<uint64_t,8>::serialize(data,size,offset,member);
|
||||||
|
}
|
||||||
|
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const uint64_t& member)
|
||||||
|
{
|
||||||
|
return t_SerializerNType<uint64_t,8>::serialize(data,size,offset,member);
|
||||||
|
}
|
||||||
|
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, uint8_t& member)
|
||||||
|
{
|
||||||
|
return t_SerializerNType<uint8_t,1>::deserialize(data,size,offset,member);
|
||||||
|
}
|
||||||
|
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, uint32_t& member)
|
||||||
|
{
|
||||||
|
return t_SerializerNType<uint32_t,4>::deserialize(data,size,offset,member);
|
||||||
|
}
|
||||||
|
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, uint64_t& member)
|
||||||
|
{
|
||||||
|
return t_SerializerNType<uint64_t,8>::deserialize(data,size,offset,member);
|
||||||
|
}
|
||||||
|
template<> uint32_t RsTypeSerializer::serial_size(const uint8_t& member)
|
||||||
|
{
|
||||||
|
return t_SerializerNType<uint8_t,1>::serial_size(member);
|
||||||
|
}
|
||||||
|
template<> uint32_t RsTypeSerializer::serial_size(const uint32_t& member)
|
||||||
|
{
|
||||||
|
return t_SerializerNType<uint32_t,4>::serial_size(member);
|
||||||
|
}
|
||||||
|
template<> uint32_t RsTypeSerializer::serial_size(const uint64_t& member)
|
||||||
|
{
|
||||||
|
return t_SerializerNType<uint64_t,8>::serial_size(member);
|
||||||
|
}
|
||||||
|
//// Float
|
||||||
//
|
//
|
||||||
// protected:
|
template<>
|
||||||
// virtual bool serialize(uint8_t data[], uint32_t size, uint32_t &offset, const T& member)const=0;
|
uint32_t RsTypeSerializer::serial_size(const float&){ return 4; }
|
||||||
// virtual bool deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, T& member)=0;
|
|
||||||
// virtual uint32_t serial_size(const T& /* member */)const=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> class RsTypeSerializer<uint8_t> : public t_SerializerNType<uint8_t, 1>{};
|
|
||||||
template<> class RsTypeSerializer<uint16_t> : public t_SerializerNType<uint16_t, 2>{};
|
|
||||||
template<> class RsTypeSerializer<uint32_t> : public t_SerializerNType<uint32_t, 4>{};
|
|
||||||
template<> class RsTypeSerializer<uint64_t> : public t_SerializerNType<uint64_t, 8>{};
|
|
||||||
template<> class RsTypeSerializer<time_t> : public t_SerializerNType<uint64_t, 8>{};
|
|
||||||
|
|
||||||
/// Serializer for <b>non negative</b> float
|
template<>
|
||||||
template<> class RsTypeSerializer<float> : public RsTypeSerializerBase<float>
|
bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const float& f)
|
||||||
{
|
|
||||||
protected:
|
|
||||||
bool serialize(uint8_t data[], uint32_t size, uint32_t &offset, const float& f)const
|
|
||||||
{
|
{
|
||||||
uint32_t sz = serial_size(f);
|
uint32_t sz = serial_size(f);
|
||||||
if ( !data || size <= offset || size - offset < sz )
|
if ( !data || size <= offset || size - offset < sz )
|
||||||
@ -172,7 +203,14 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, float& f)const
|
template<> uint32_t RsTypeSerializer::serial_size<std::string>(const std::string& s)
|
||||||
|
{
|
||||||
|
return s.length() + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, float& f)
|
||||||
{
|
{
|
||||||
uint32_t sz = serial_size(f);
|
uint32_t sz = serial_size(f);
|
||||||
if ( !data || size <= offset ||
|
if ( !data || size <= offset ||
|
||||||
@ -185,14 +223,11 @@ protected:
|
|||||||
f = 1.0f/ ( n/(float)(~(uint32_t)0)) - 1.0f;
|
f = 1.0f/ ( n/(float)(~(uint32_t)0)) - 1.0f;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
inline uint32_t serial_size(const float&)const { return 4; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Serializer for std::string
|
/// Serializer for std::string
|
||||||
template<> class RsTypeSerializer<std::string> : public RsTypeSerializerBase<std::string>
|
template<>
|
||||||
{
|
bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset,const std::string& s)
|
||||||
protected:
|
|
||||||
bool serialize(uint8_t data[], uint32_t size, uint32_t &offset,const std::string& s)const
|
|
||||||
{
|
{
|
||||||
if ( !data || size <= offset || size - offset < serial_size(s))
|
if ( !data || size <= offset || size - offset < serial_size(s))
|
||||||
return false;
|
return false;
|
||||||
@ -203,7 +238,8 @@ template<> class RsTypeSerializer<std::string> : public RsTypeSerializerBase<std
|
|||||||
memcpy(data+offset, s.c_str(), charsLen); offset += charsLen;
|
memcpy(data+offset, s.c_str(), charsLen); offset += charsLen;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool deserialize(const uint8_t data[], uint32_t size,uint32_t& offset,std::string& s)const
|
template<>
|
||||||
|
bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size,uint32_t& offset,std::string& s)
|
||||||
{
|
{
|
||||||
if ( !data || size <= offset || size - offset < 4 ) return false;
|
if ( !data || size <= offset || size - offset < 4 ) return false;
|
||||||
uint32_t charsLen;
|
uint32_t charsLen;
|
||||||
@ -216,13 +252,6 @@ template<> class RsTypeSerializer<std::string> : public RsTypeSerializerBase<std
|
|||||||
offset += charsLen;
|
offset += charsLen;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
inline uint32_t serial_size(const std::string& s)const
|
|
||||||
{
|
|
||||||
return s.length() + 4;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RsSerializer
|
class RsSerializer
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user