moved rsserializer and rstypeserializer to serialiser/

This commit is contained in:
csoler 2017-04-30 16:05:37 +02:00
parent 4f92f483fa
commit e401b90e02
50 changed files with 52 additions and 248 deletions

View file

@ -0,0 +1,142 @@
#include <typeinfo>
#include "rsitems/rsitem.h"
#include "util/rsprint.h"
#include "serialiser/rsserializer.h"
#include "serialiser/rstypeserializer.h"
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_NONE ( 0x0000 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_CONFIG ( 0x0001 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE ( 0x0002 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER ( 0x0004 );
RsItem *RsServiceSerializer::deserialise(void *data, uint32_t *size)
{
if(mFlags & SERIALIZATION_FLAG_SKIP_HEADER)
{
std::cerr << "(EE) Cannot deserialise item with flags SERIALIZATION_FLAG_SKIP_HEADER. Check your code!" << std::endl;
return NULL ;
}
uint32_t rstype = getRsItemId(const_cast<void*>((const void*)data)) ;
RsItem *item = create_item(getRsItemService(rstype),getRsItemSubType(rstype)) ;
if(!item)
{
std::cerr << "(EE) " << typeid(*this).name() << ": cannot deserialise unknown item subtype " << std::hex << (int)getRsItemSubType(rstype) << std::dec << std::endl;
std::cerr << "(EE) Data is: " << RsUtil::BinToHex(static_cast<uint8_t*>(data),std::min(50u,*size)) << ((*size>50)?"...":"") << std::endl;
return NULL ;
}
SerializeContext ctx(const_cast<uint8_t*>(static_cast<uint8_t*>(data)),*size,mFormat,mFlags);
ctx.mOffset = 8 ;
item->serial_process(RsGenericSerializer::DESERIALIZE, ctx) ;
if(ctx.mSize != ctx.mOffset)
{
std::cerr << "RsSerializer::deserialise(): ERROR. offset does not match expected size!" << std::endl;
delete item ;
return NULL ;
}
if(ctx.mOk)
return item ;
delete item ;
return NULL ;
}
RsItem *RsConfigSerializer::deserialise(void *data, uint32_t *size)
{
if(mFlags & SERIALIZATION_FLAG_SKIP_HEADER)
{
std::cerr << "(EE) Cannot deserialise item with flags SERIALIZATION_FLAG_SKIP_HEADER. Check your code!" << std::endl;
return NULL ;
}
uint32_t rstype = getRsItemId(const_cast<void*>((const void*)data)) ;
RsItem *item = create_item(getRsItemType(rstype),getRsItemSubType(rstype)) ;
if(!item)
{
std::cerr << "(EE) " << typeid(*this).name() << ": cannot deserialise unknown item subtype " << std::hex << (int)getRsItemSubType(rstype) << std::dec << std::endl;
std::cerr << "(EE) Data is: " << RsUtil::BinToHex(static_cast<uint8_t*>(data),std::min(50u,*size)) << ((*size>50)?"...":"") << std::endl;
return NULL ;
}
SerializeContext ctx(const_cast<uint8_t*>(static_cast<uint8_t*>(data)),*size,mFormat,mFlags);
ctx.mOffset = 8 ;
item->serial_process(DESERIALIZE, ctx) ;
if(ctx.mSize != ctx.mOffset)
{
std::cerr << "RsSerializer::deserialise(): ERROR. offset does not match expected size!" << std::endl;
delete item ;
return NULL ;
}
if(ctx.mOk)
return item ;
delete item ;
return NULL ;
}
bool RsGenericSerializer::serialise(RsItem *item,void *data,uint32_t *size)
{
SerializeContext ctx(static_cast<uint8_t*>(data),0,mFormat,mFlags);
uint32_t tlvsize = this->size(item) ;
if(tlvsize > *size)
throw std::runtime_error("Cannot serialise: not enough room.") ;
if(mFlags & SERIALIZATION_FLAG_SKIP_HEADER)
ctx.mOffset = 0;
else
{
if(!setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize))
{
std::cerr << "RsSerializer::serialise_item(): ERROR. Not enough size!" << std::endl;
return false ;
}
ctx.mOffset = 8;
}
ctx.mSize = tlvsize;
item->serial_process(RsGenericSerializer::SERIALIZE,ctx) ;
if(ctx.mSize != ctx.mOffset)
{
std::cerr << "RsSerializer::serialise(): ERROR. offset does not match expected size!" << std::endl;
return false ;
}
return true ;
}
uint32_t RsGenericSerializer::size(RsItem *item)
{
SerializeContext ctx(NULL,0,mFormat,mFlags);
if(mFlags & SERIALIZATION_FLAG_SKIP_HEADER)
ctx.mOffset = 0;
else
ctx.mOffset = 8 ; // header size
item->serial_process(SIZE_ESTIMATE, ctx) ;
return ctx.mOffset ;
}
void RsGenericSerializer::print(RsItem *item)
{
SerializeContext ctx(NULL,0,mFormat,mFlags);
std::cerr << "***** RsItem class: \"" << typeid(*item).name() << "\" *****" << std::endl;
item->serial_process(PRINT, ctx) ;
std::cerr << "******************************" << std::endl;
}

View file

@ -0,0 +1,112 @@
#pragma once
#include <stdint.h>
#include <string.h>
#include <iostream>
#include <string>
#include "retroshare/rsflags.h"
#include "serialiser/rsserial.h"
class RsItem ;
#define SERIALIZE_ERROR() std::cerr << __PRETTY_FUNCTION__ << " : "
class RsGenericSerializer: public RsSerialType
{
public:
typedef enum { SIZE_ESTIMATE = 0x01, SERIALIZE = 0x02, DESERIALIZE = 0x03, PRINT=0x04 } SerializeJob ;
typedef enum { FORMAT_BINARY = 0x01, FORMAT_JSON = 0x02 } SerializationFormat ;
class SerializeContext
{
public:
SerializeContext(uint8_t *data,uint32_t size,SerializationFormat format,SerializationFlags flags)
: mData(data),mSize(size),mOffset(0),mOk(true),mFormat(format),mFlags(flags) {}
unsigned char *mData ;
uint32_t mSize ;
uint32_t mOffset ;
bool mOk ;
SerializationFormat mFormat ;
SerializationFlags mFlags ;
};
// These are convenience flags to be used by the items when processing the data. The names of the flags
// are not very important. What matters is that the serial_process() method of each item correctly
// deals with the data when it sees the flags, if the serialiser sets them. By default the flags are not
// set and shouldn't be handled.
// When deriving a new serializer, the user can set his own flags, using compatible values
static const SerializationFlags SERIALIZATION_FLAG_NONE ; // 0x0000
static const SerializationFlags SERIALIZATION_FLAG_CONFIG ; // 0x0001
static const SerializationFlags SERIALIZATION_FLAG_SIGNATURE ; // 0x0002
static const SerializationFlags SERIALIZATION_FLAG_SKIP_HEADER ; // 0x0004
// The following functions overload RsSerialType. They *should not* need to be further overloaded.
RsItem *deserialise(void *data,uint32_t *size) =0;
bool serialise(RsItem *item,void *data,uint32_t *size) ;
uint32_t size(RsItem *item) ;
void print(RsItem *item) ;
protected:
RsGenericSerializer(uint8_t serial_class,
uint8_t serial_type,
SerializationFormat format,
SerializationFlags flags )
: RsSerialType(RS_PKT_VERSION1,serial_class,serial_type), mFormat(format),mFlags(flags)
{}
RsGenericSerializer(uint16_t service,
SerializationFormat format,
SerializationFlags flags )
: RsSerialType(RS_PKT_VERSION_SERVICE,service), mFormat(format),mFlags(flags)
{}
SerializationFormat mFormat ;
SerializationFlags mFlags ;
};
class RsServiceSerializer: public RsGenericSerializer
{
public:
RsServiceSerializer(uint16_t service_id,
SerializationFormat format = FORMAT_BINARY,
SerializationFlags flags = SERIALIZATION_FLAG_NONE)
: RsGenericSerializer(service_id,format,flags) {}
/*! create_item
* should be overloaded to create the correct type of item depending on the data
*/
virtual RsItem *create_item(uint16_t /* service */, uint8_t /* item_sub_id */) const=0;
RsItem *deserialise(void *data,uint32_t *size) ;
};
class RsConfigSerializer: public RsGenericSerializer
{
public:
RsConfigSerializer(uint8_t config_class,
uint8_t config_type,
SerializationFormat format = FORMAT_BINARY,
SerializationFlags flags = SERIALIZATION_FLAG_NONE)
: RsGenericSerializer(config_class,config_type,format,flags) {}
/*! create_item
* should be overloaded to create the correct type of item depending on the data
*/
virtual RsItem *create_item(uint8_t /* class */, uint8_t /* item_type */) const=0;
RsItem *deserialise(void *data,uint32_t *size) ;
};

View file

@ -0,0 +1,268 @@
#include "serialization/rsserializer.h"
#include "serialization/rstypeserializer.h"
#include "serialiser/rsbaseserial.h"
#include "serialiser/rstlvkeys.h"
#include "util/rsprint.h"
#include <iomanip>
static const uint32_t MAX_SERIALIZED_ARRAY_SIZE = 500 ;
//=================================================================================================//
// Integer types //
//=================================================================================================//
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const bool& member)
{
return setRawUInt8(data,size,&offset,member);
}
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const uint8_t& member)
{
return setRawUInt8(data,size,&offset,member);
}
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const uint16_t& member)
{
return setRawUInt16(data,size,&offset,member);
}
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const uint32_t& member)
{
return setRawUInt32(data,size,&offset,member);
}
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const uint64_t& member)
{
return setRawUInt64(data,size,&offset,member);
}
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const time_t& member)
{
return setRawTimeT(data,size,&offset,member);
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, bool& member)
{
uint8_t m ;
bool ok = getRawUInt8(data,size,&offset,&m);
member = m ;
return ok;
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, uint8_t& member)
{
return getRawUInt8(data,size,&offset,&member);
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, uint16_t& member)
{
return getRawUInt16(data,size,&offset,&member);
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, uint32_t& member)
{
return getRawUInt32(data,size,&offset,&member);
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, uint64_t& member)
{
return getRawUInt64(data,size,&offset,&member);
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, time_t& member)
{
return getRawTimeT(data,size,&offset,member);
}
template<> uint32_t RsTypeSerializer::serial_size(const bool& /* member*/)
{
return 1;
}
template<> uint32_t RsTypeSerializer::serial_size(const uint8_t& /* member*/)
{
return 1;
}
template<> uint32_t RsTypeSerializer::serial_size(const uint16_t& /* member*/)
{
return 2;
}
template<> uint32_t RsTypeSerializer::serial_size(const uint32_t& /* member*/)
{
return 4;
}
template<> uint32_t RsTypeSerializer::serial_size(const uint64_t& /* member*/)
{
return 8;
}
template<> uint32_t RsTypeSerializer::serial_size(const time_t& /* member*/)
{
return 8;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const bool & V)
{
std::cerr << " [bool ] " << n << ": " << V << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const uint8_t & V)
{
std::cerr << " [uint8_t ] " << n << ": " << V << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const uint16_t& V)
{
std::cerr << " [uint16_t ] " << n << ": " << V << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const uint32_t& V)
{
std::cerr << " [uint32_t ] " << n << ": " << V << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const uint64_t& V)
{
std::cerr << " [uint64_t ] " << n << ": " << V << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const time_t& V)
{
std::cerr << " [time_t ] " << n << ": " << V << " (" << time(NULL)-V << " secs ago)" << std::endl;
}
//=================================================================================================//
// FLoats //
//=================================================================================================//
template<> uint32_t RsTypeSerializer::serial_size(const float&){ return 4; }
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t& offset, const float& f)
{
return setRawUFloat32(data,size,&offset,f) ;
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, float& f)
{
return getRawUFloat32(data,size,&offset,f) ;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const float& V)
{
std::cerr << " [float ] " << n << ": " << V << std::endl;
}
//=================================================================================================//
// TlvString with subtype //
//=================================================================================================//
template<> uint32_t RsTypeSerializer::serial_size(uint16_t /* type_subtype */,const std::string& s)
{
return GetTlvStringSize(s) ;
}
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset,uint16_t type_substring,const std::string& s)
{
return SetTlvString(data,size,&offset,type_substring,s) ;
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size,uint32_t& offset,uint16_t type_substring,std::string& s)
{
return GetTlvString((void*)data,size,&offset,type_substring,s) ;
}
template<> void RsTypeSerializer::print_data(const std::string& n, uint16_t type_substring,const std::string& V)
{
std::cerr << " [TlvString ] " << n << ": type=" << std::hex <<std::setw(4)<<std::setfill('0') << type_substring << std::dec << " s=\"" << V<< "\"" << std::endl;
}
//=================================================================================================//
// TlvInt with subtype //
//=================================================================================================//
template<> uint32_t RsTypeSerializer::serial_size(uint16_t /* type_subtype */,const uint32_t& s)
{
return GetTlvUInt32Size() ;
}
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset,uint16_t sub_type,const uint32_t& s)
{
return SetTlvUInt32(data,size,&offset,sub_type,s) ;
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size,uint32_t& offset,uint16_t sub_type,uint32_t& s)
{
return GetTlvUInt32((void*)data,size,&offset,sub_type,&s) ;
}
template<> void RsTypeSerializer::print_data(const std::string& n, uint16_t sub_type,const uint32_t& V)
{
std::cerr << " [TlvUInt32 ] " << n << ": type=" << std::hex <<std::setw(4)<<std::setfill('0') << sub_type << std::dec << " s=\"" << V<< "\"" << std::endl;
}
//=================================================================================================//
// std::string //
//=================================================================================================//
template<> void RsTypeSerializer::print_data(const std::string& n, const std::string& V)
{
std::cerr << " [std::string] " << n << ": " << V << std::endl;
}
//=================================================================================================//
// Binary blocks //
//=================================================================================================//
template<> uint32_t RsTypeSerializer::serial_size(const RsTypeSerializer::TlvMemBlock_proxy& r) { return 4 + r.second ; }
template<> bool RsTypeSerializer::deserialize(const uint8_t data[],uint32_t size,uint32_t& offset,RsTypeSerializer::TlvMemBlock_proxy& r)
{
uint32_t saved_offset = offset ;
bool ok = deserialize<uint32_t>(data,size,offset,r.second) ;
r.first = (uint8_t*)rs_malloc(r.second) ;
ok = ok && NULL != r.first;
memcpy(r.first,&data[offset],r.second) ;
offset += r.second ;
if(!ok)
offset = saved_offset ;
return ok;
}
template<> bool RsTypeSerializer::serialize(uint8_t data[],uint32_t size,uint32_t& offset,const RsTypeSerializer::TlvMemBlock_proxy& r)
{
uint32_t saved_offset = offset ;
bool ok = serialize<uint32_t>(data,size,offset,r.second) ;
memcpy(&data[offset],r.first,r.second) ;
offset += r.second ;
if(!ok)
offset = saved_offset ;
return ok;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const RsTypeSerializer::TlvMemBlock_proxy& s)
{
std::cerr << " [Binary data] " << n << ", length=" << s.second << " data=" << RsUtil::BinToHex((uint8_t*)s.first,std::min(50u,s.second)) << ((s.second>50)?"...":"") << std::endl;
}
//=================================================================================================//
// TlvItems //
//=================================================================================================//
template<> uint32_t RsTypeSerializer::serial_size(const RsTlvItem& s)
{
return s.TlvSize() ;
}
template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset,const RsTlvItem& s)
{
return s.SetTlv(data,size,&offset) ;
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size,uint32_t& offset,RsTlvItem& s)
{
return s.GetTlv((void*)data,size,&offset) ;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const RsTlvItem& s)
{
// can we call TlvPrint inside this?
std::cerr << " [" << typeid(s).name() << "] " << n << std::endl;
}

View file

@ -0,0 +1,417 @@
#pragma once
#include "serialiser/rsserial.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvlist.h"
#include "retroshare/rsflags.h"
#include "retroshare/rsids.h"
#include "serialiser/rsserializer.h"
class RsTypeSerializer
{
public:
// This type should be used to pass a parameter to drive the serialisation if needed.
struct TlvMemBlock_proxy: public std::pair<void*& ,uint32_t&>
{
TlvMemBlock_proxy(void *& p,uint32_t& s) : std::pair<void*&,uint32_t&>(p,s) {}
TlvMemBlock_proxy(uint8_t*& p,uint32_t& s) : std::pair<void*&,uint32_t&>(*(void**)&p,s) {}
};
//=================================================================================================//
// Generic types //
//=================================================================================================//
template<typename T>
static void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,T& member,const std::string& member_name)
{
switch(j)
{
case RsGenericSerializer::SIZE_ESTIMATE: ctx.mOffset += serial_size(member) ;
break ;
case RsGenericSerializer::DESERIALIZE: ctx.mOk = ctx.mOk && deserialize(ctx.mData,ctx.mSize,ctx.mOffset,member) ;
break ;
case RsGenericSerializer::SERIALIZE: ctx.mOk = ctx.mOk && serialize(ctx.mData,ctx.mSize,ctx.mOffset,member) ;
break ;
case RsGenericSerializer::PRINT:
print_data(member_name,member);
break;
default:
ctx.mOk = false ;
throw std::runtime_error("Unknown serial job") ;
}
}
//=================================================================================================//
// Generic types + type_id //
//=================================================================================================//
template<typename T>
static void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,uint16_t type_id,T& member,const std::string& member_name)
{
switch(j)
{
case RsGenericSerializer::SIZE_ESTIMATE: ctx.mOffset += serial_size(type_id,member) ;
break ;
case RsGenericSerializer::DESERIALIZE: ctx.mOk = ctx.mOk && deserialize(ctx.mData,ctx.mSize,ctx.mOffset,type_id,member) ;
break ;
case RsGenericSerializer::SERIALIZE: ctx.mOk = ctx.mOk && serialize(ctx.mData,ctx.mSize,ctx.mOffset,type_id,member) ;
break ;
case RsGenericSerializer::PRINT:
print_data(member_name,type_id,member);
break;
default:
ctx.mOk = false ;
throw std::runtime_error("Unknown serial job") ;
}
}
//=================================================================================================//
// std::map<T,U> //
//=================================================================================================//
template<typename T,typename U>
static void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,std::map<T,U>& v,const std::string& member_name)
{
switch(j)
{
case RsGenericSerializer::SIZE_ESTIMATE:
{
ctx.mOffset += 4 ;
for(typename std::map<T,U>::iterator it(v.begin());it!=v.end();++it)
{
serial_process(j,ctx,const_cast<T&>(it->first),"map::*it->first") ;
serial_process(j,ctx,const_cast<U&>(it->second),"map::*it->second") ;
}
}
break ;
case RsGenericSerializer::DESERIALIZE:
{
uint32_t n=0 ;
serial_process(j,ctx,n,"temporary size");
for(uint32_t i=0;i<n;++i)
{
T t ;
U u ;
serial_process(j,ctx,t,"map::*it->first") ;
serial_process(j,ctx,u,"map::*it->second") ;
v[t] = u ;
}
}
break ;
case RsGenericSerializer::SERIALIZE:
{
uint32_t n=v.size();
serial_process(j,ctx,n,"temporary size");
for(typename std::map<T,U>::iterator it(v.begin());it!=v.end();++it)
{
serial_process(j,ctx,const_cast<T&>(it->first),"map::*it->first") ;
serial_process(j,ctx,const_cast<U&>(it->second),"map::*it->second") ;
}
}
break ;
case RsGenericSerializer::PRINT:
{
if(v.empty())
std::cerr << " Empty map \"" << member_name << "\"" << std::endl;
else
std::cerr << " std::map of " << v.size() << " elements: \"" << member_name << "\"" << std::endl;
for(typename std::map<T,U>::iterator it(v.begin());it!=v.end();++it)
{
std::cerr << " " ;
serial_process(j,ctx,const_cast<T&>(it->first),"map::*it->first") ;
serial_process(j,ctx,const_cast<U&>(it->second),"map::*it->second") ;
}
}
break;
default:
break;
}
}
//=================================================================================================//
// std::vector<T> //
//=================================================================================================//
template<typename T>
static void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,std::vector<T>& v,const std::string& member_name)
{
switch(j)
{
case RsGenericSerializer::SIZE_ESTIMATE:
{
ctx.mOffset += 4 ;
for(uint32_t i=0;i<v.size();++i)
serial_process(j,ctx,v[i],member_name) ;
}
break ;
case RsGenericSerializer::DESERIALIZE:
{ uint32_t n=0 ;
serial_process(j,ctx,n,"temporary size") ;
v.resize(n) ;
for(uint32_t i=0;i<v.size();++i)
serial_process(j,ctx,v[i],member_name) ;
}
break ;
case RsGenericSerializer::SERIALIZE:
{
uint32_t n=v.size();
serial_process(j,ctx,n,"temporary size") ;
for(uint32_t i=0;i<v.size();++i)
serial_process(j,ctx,v[i],member_name) ;
}
break ;
case RsGenericSerializer::PRINT:
{
if(v.empty())
std::cerr << " Empty array"<< std::endl;
else
std::cerr << " Array of " << v.size() << " elements:" << std::endl;
for(uint32_t i=0;i<v.size();++i)
{
std::cerr << " " ;
serial_process(j,ctx,v[i],member_name) ;
}
}
break;
default:
break;
}
}
//=================================================================================================//
// std::set<T> //
//=================================================================================================//
template<typename T>
static void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,std::set<T>& v,const std::string& member_name)
{
switch(j)
{
case RsGenericSerializer::SIZE_ESTIMATE:
{
ctx.mOffset += 4 ;
for(typename std::set<T>::iterator it(v.begin());it!=v.end();++it)
serial_process(j,ctx,const_cast<T&>(*it) ,member_name) ; // the const cast here is a hack to avoid serial_process to instantiate serialise(const T&)
}
break ;
case RsGenericSerializer::DESERIALIZE:
{ uint32_t n=0 ;
serial_process(j,ctx,n,"temporary size") ;
for(uint32_t i=0;i<n;++i)
{
T tmp;
serial_process<T>(j,ctx,tmp,member_name) ;
v.insert(tmp);
}
}
break ;
case RsGenericSerializer::SERIALIZE:
{
uint32_t n=v.size();
serial_process(j,ctx,n,"temporary size") ;
for(typename std::set<T>::iterator it(v.begin());it!=v.end();++it)
serial_process(j,ctx,const_cast<T&>(*it) ,member_name) ; // the const cast here is a hack to avoid serial_process to instantiate serialise(const T&)
}
break ;
case RsGenericSerializer::PRINT:
{
if(v.empty())
std::cerr << " Empty set"<< std::endl;
else
std::cerr << " Set of " << v.size() << " elements:" << std::endl;
}
break;
default:
break;
}
}
//=================================================================================================//
// std::list<T> //
//=================================================================================================//
template<typename T>
static void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,std::list<T>& v,const std::string& member_name)
{
switch(j)
{
case RsGenericSerializer::SIZE_ESTIMATE:
{
ctx.mOffset += 4 ;
for(typename std::list<T>::iterator it(v.begin());it!=v.end();++it)
serial_process(j,ctx,*it ,member_name) ;
}
break ;
case RsGenericSerializer::DESERIALIZE:
{ uint32_t n=0 ;
serial_process(j,ctx,n,"temporary size") ;
for(uint32_t i=0;i<n;++i)
{
T tmp;
serial_process<T>(j,ctx,tmp,member_name) ;
v.push_back(tmp);
}
}
break ;
case RsGenericSerializer::SERIALIZE:
{
uint32_t n=v.size();
serial_process(j,ctx,n,"temporary size") ;
for(typename std::list<T>::iterator it(v.begin());it!=v.end();++it)
serial_process(j,ctx,*it ,member_name) ;
}
break ;
case RsGenericSerializer::PRINT:
{
if(v.empty())
std::cerr << " Empty list"<< std::endl;
else
std::cerr << " List of " << v.size() << " elements:" << std::endl;
}
break;
default:
break;
}
}
//=================================================================================================//
// t_RsFlags32<> types //
//=================================================================================================//
template<int N>
static void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,t_RsFlags32<N>& v,const std::string& member_name)
{
switch(j)
{
case RsGenericSerializer::SIZE_ESTIMATE: ctx.mOffset += 4 ;
break ;
case RsGenericSerializer::DESERIALIZE:
{
uint32_t n=0 ;
deserialize<uint32_t>(ctx.mData,ctx.mSize,ctx.mOffset,n) ;
v = t_RsFlags32<N>(n) ;
}
break ;
case RsGenericSerializer::SERIALIZE:
{
uint32_t n=v.toUInt32() ;
serialize<uint32_t>(ctx.mData,ctx.mSize,ctx.mOffset,n) ;
}
break ;
case RsGenericSerializer::PRINT:
std::cerr << " Flags of type " << std::hex << N << " : " << v.toUInt32() << std::endl;
break ;
}
}
protected:
template<typename T> static bool serialize (uint8_t data[], uint32_t size, uint32_t &offset, const T& member);
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 */);
template<typename T> static void print_data(const std::string& name,const T& /* member */);
template<typename T> static bool serialize (uint8_t data[], uint32_t size, uint32_t &offset, uint16_t type_id,const T& member);
template<typename T> static bool deserialize(const uint8_t data[], uint32_t size, uint32_t &offset,uint16_t type_id, T& member);
template<typename T> static uint32_t serial_size(uint16_t type_id,const T& /* member */);
template<typename T> static void print_data(const std::string& name,uint16_t type_id,const T& /* member */);
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> static bool serialize (uint8_t data[], uint32_t size, uint32_t &offset, const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member);
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> static bool deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member);
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> static uint32_t serial_size(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& /* member */);
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> static void print_data(const std::string& name,const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& /* member */);
template<class TLV_CLASS,uint32_t TLV_TYPE> static bool serialize (uint8_t data[], uint32_t size, uint32_t &offset, const t_RsTlvList<TLV_CLASS,TLV_TYPE>& member);
template<class TLV_CLASS,uint32_t TLV_TYPE> static bool deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, t_RsTlvList<TLV_CLASS,TLV_TYPE>& member);
template<class TLV_CLASS,uint32_t TLV_TYPE> static uint32_t serial_size(const t_RsTlvList<TLV_CLASS,TLV_TYPE>& /* member */);
template<class TLV_CLASS,uint32_t TLV_TYPE> static void print_data(const std::string& name,const t_RsTlvList<TLV_CLASS,TLV_TYPE>& /* member */);
};
//=================================================================================================//
// t_RsGenericId<> //
//=================================================================================================//
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
bool RsTypeSerializer::serialize (uint8_t data[], uint32_t size, uint32_t &offset, const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member)
{
return (*const_cast<const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> *>(&member)).serialise(data,size,offset) ;
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member)
{
return member.deserialise(data,size,offset) ;
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
uint32_t RsTypeSerializer::serial_size(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member)
{
return member.serial_size();
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
void RsTypeSerializer::print_data(const std::string& /* name */,const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member)
{
std::cerr << " [RsGenericId<" << std::hex << UNIQUE_IDENTIFIER << ">] : " << member << std::endl;
}
//=================================================================================================//
// t_RsTlvList<> //
//=================================================================================================//
template<class TLV_CLASS,uint32_t TLV_TYPE>
bool RsTypeSerializer::serialize (uint8_t data[], uint32_t size, uint32_t &offset, const t_RsTlvList<TLV_CLASS,TLV_TYPE>& member)
{
return (*const_cast<const t_RsTlvList<TLV_CLASS,TLV_TYPE> *>(&member)).SetTlv(data,size,&offset) ;
}
template<class TLV_CLASS,uint32_t TLV_TYPE>
bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, t_RsTlvList<TLV_CLASS,TLV_TYPE>& member)
{
return member.GetTlv(const_cast<uint8_t*>(data),size,&offset) ;
}
template<class TLV_CLASS,uint32_t TLV_TYPE>
uint32_t RsTypeSerializer::serial_size(const t_RsTlvList<TLV_CLASS,TLV_TYPE>& member)
{
return member.TlvSize();
}
template<class TLV_CLASS,uint32_t TLV_TYPE>
void RsTypeSerializer::print_data(const std::string& /* name */,const t_RsTlvList<TLV_CLASS,TLV_TYPE>& member)
{
std::cerr << " [t_RsTlvString<" << std::hex << TLV_TYPE << ">] : size=" << member.mList.size() << std::endl;
}