mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-06 08:05:18 -04:00
moved rsserializer and rstypeserializer to serialiser/
This commit is contained in:
parent
4f92f483fa
commit
e401b90e02
50 changed files with 52 additions and 248 deletions
142
libretroshare/src/serialiser/rsserializer.cc
Normal file
142
libretroshare/src/serialiser/rsserializer.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
112
libretroshare/src/serialiser/rsserializer.h
Normal file
112
libretroshare/src/serialiser/rsserializer.h
Normal 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) ;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
268
libretroshare/src/serialiser/rstypeserializer.cc
Normal file
268
libretroshare/src/serialiser/rstypeserializer.cc
Normal 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;
|
||||
}
|
417
libretroshare/src/serialiser/rstypeserializer.h
Normal file
417
libretroshare/src/serialiser/rstypeserializer.h
Normal 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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue