102 lines
2.2 KiB
C
Raw Normal View History

2017-03-25 19:01:32 +01:00
#pragma once
#include <stdint.h>
#include <string.h>
#include <iostream>
#include <string>
#include "serialiser/rsserial.h"
#define SERIALIZE_ERROR() std::cerr << __PRETTY_FUNCTION__ << " : "
2017-03-25 19:01:32 +01:00
class SerializeContext
{
public:
SerializeContext(uint8_t *data,uint32_t size)
: mData(data),mSize(size),mOffset(0),mOk(true) {}
unsigned char *mData ;
uint32_t mSize ;
uint32_t mOffset ;
bool mOk ;
};
class RsSerializer: public RsSerialType
2017-03-25 19:01:32 +01:00
{
public:
RsSerializer(uint16_t service_id) : RsSerialType(service_id) {}
2017-03-25 19:01:32 +01:00
/*! 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)
2017-03-25 19:01:32 +01:00
{
return NULL ;
}
RsItem *deserialise(const uint8_t *data,uint32_t size)
2017-03-25 19:01:32 +01:00
{
uint32_t rstype = getRsItemId(const_cast<void*>((const void*)data)) ;
RsItem *item = create_item(getRsItemService(rstype),getRsItemSubType(rstype)) ;
2017-03-25 19:01:32 +01:00
if(!item)
{
std::cerr << "(EE) cannot deserialise: unknown item type " << std::hex << rstype << std::dec << std::endl;
return NULL ;
}
SerializeContext ctx(const_cast<uint8_t*>(data),size);
ctx.mOffset = 8 ;
item->serial_process(RsItem::DESERIALIZE, ctx) ;
2017-03-25 19:01:32 +01:00
if(ctx.mOk)
return item ;
delete item ;
return NULL ;
}
bool serialise(RsItem *item,uint8_t *const data,uint32_t size)
2017-03-25 19:01:32 +01:00
{
SerializeContext ctx(data,0);
uint32_t tlvsize = this->size(item) ;
2017-03-25 19:01:32 +01:00
if(tlvsize > size)
throw std::runtime_error("Cannot serialise: not enough room.") ;
if(!setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize))
2017-03-25 19:01:32 +01:00
{
std::cerr << "RsSerializer::serialise_item(): ERROR. Not enough size!" << std::endl;
return false ;
}
ctx.mOffset = 8;
ctx.mSize = tlvsize;
item->serial_process(RsItem::SERIALIZE,ctx) ;
2017-03-25 19:01:32 +01:00
if(ctx.mSize != ctx.mOffset)
{
std::cerr << "RsSerializer::serialise_item(): ERROR. offset does not match expected size!" << std::endl;
return false ;
}
return true ;
}
uint32_t size(RsItem *item)
2017-03-25 19:01:32 +01:00
{
SerializeContext ctx(NULL,0);
ctx.mSize = 8 ; // header size
item->serial_process(RsItem::SIZE_ESTIMATE, ctx) ;
2017-03-25 19:01:32 +01:00
return ctx.mSize ;
}
};