Port GxsTrans to new serialization system

RsItem added some comment and more verbose error reporting
RsTypeSerializer added support for RsItem derived classes as members
  added utility macros for better readability of the code and easier
  handling of RsItem derived members
  RS_REGISTER_SERIAL_MEMBER(I)
  RS_REGISTER_SERIAL_MEMBER_TYPED(I, T)
  RS_REGISTER_ITEM_TYPE(T)

RsNxsMsg::serial_process use new macros for better readability and to
 have an exemple of usage with RsTlvItem derived class
Fix undefined reference to RsNxsMsg::print
This commit is contained in:
Gioacchino Mazzurco 2017-05-08 00:19:11 +02:00
parent f7f36f697e
commit ea8f800003
11 changed files with 655 additions and 728 deletions

View file

@ -478,14 +478,16 @@ bool p3GxsTrans::dispatchDecryptedMail( const RsGxsId& authorId,
}
GxsTransSubServices rsrvc = static_cast<GxsTransSubServices>(csri);
RsNxsTransPresignedReceipt* receipt = new RsNxsTransPresignedReceipt();
uint32_t rcptsize = decrypted_data_size;
if(!receipt->deserialize(decrypted_data, rcptsize, offset))
RsNxsTransPresignedReceipt* receipt =
static_cast<RsNxsTransPresignedReceipt*>(
RsGxsTransSerializer().deserialise(
const_cast<uint8_t*>(decrypted_data), &rcptsize ) );
if(!receipt)
{
std::cerr << "p3GxsTrans::dispatchDecryptedMail(...) (EE) fatal error "
<< "deserializing presigned return receipt , something really"
<< " wrong is happening!" << std::endl;
delete receipt;
return false;
}
std::cout << "p3GxsTrans::dispatchDecryptedMail(...) dispatching receipt "
@ -541,10 +543,10 @@ void p3GxsTrans::processOutgoingRecord(OutgoingRecord& pr)
grcpt.meta = pr.mailItem.meta;
grcpt.meta.mPublishTs = time(NULL);
grcpt.mailId = pr.mailItem.mailId;
uint32_t groff = 0, grsz = grcpt.serial_size();
uint32_t grsz = RsGxsTransSerializer().size(&grcpt);
std::vector<uint8_t> grsrz;
grsrz.resize(grsz);
grcpt.serialize(&grsrz[0], grsz, groff);
RsGxsTransSerializer().serialise(&grcpt, &grsrz[0], &grsz);
pr.presignedReceipt.grpId = mPreferredGroupId;
pr.presignedReceipt.metaData = new RsGxsMsgMetaData();
@ -572,13 +574,14 @@ void p3GxsTrans::processOutgoingRecord(OutgoingRecord& pr)
case GxsTransSendStatus::PENDING_PAYLOAD_CREATE:
{
uint16_t serv = static_cast<uint16_t>(pr.clientService);
uint32_t rcptsize = pr.presignedReceipt.serial_size();
uint32_t rcptsize = RsGxsTransSerializer().size(&pr.presignedReceipt);
uint32_t datasize = pr.mailData.size();
pr.mailItem.payload.resize(2 + rcptsize + datasize);
uint32_t offset = 0;
setRawUInt16(&pr.mailItem.payload[0], 2, &offset, serv);
pr.presignedReceipt.serialise( &pr.mailItem.payload[offset],
rcptsize );
RsGxsTransSerializer().serialise(&pr.presignedReceipt,
&pr.mailItem.payload[offset],
&rcptsize);
offset += rcptsize;
memcpy(&pr.mailItem.payload[offset], &pr.mailData[0], datasize);
}
@ -781,4 +784,3 @@ bool p3GxsTrans::loadList(std::list<RsItem *>&loadList)
return true;
}

View file

@ -17,88 +17,14 @@
*/
#include "gxstrans/p3gxstransitems.h"
#include "serialiser/rstypeserializer.h"
const RsGxsId RsGxsTransMailItem::allRecipientsHint("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
bool RsGxsTransBaseItem::serialize(uint8_t* data, uint32_t size,
uint32_t& offset) const
{
bool ok = setRsItemHeader(data+offset, size, PacketId(), size);
ok = ok && (offset += 8); // Take header in account
ok = ok && setRawUInt64(data, size, &offset, mailId);
return ok;
}
bool RsGxsTransBaseItem::deserialize( const uint8_t* data, uint32_t& size,
uint32_t& offset)
{
void* hdrPtr = const_cast<uint8_t*>(data+offset);
uint32_t rssize = getRsItemSize(hdrPtr);
uint32_t roffset = offset + 8; // Take header in account
void* dataPtr = const_cast<uint8_t*>(data);
bool ok = rssize <= size;
ok = ok && getRawUInt64(dataPtr, rssize, &roffset, &mailId);
if(ok) { size = rssize; offset = roffset; }
else size = 0;
return ok;
}
std::ostream& RsGxsTransBaseItem::print(std::ostream &out, uint16_t)
{ return out << __PRETTY_FUNCTION__ << " mailId: " << mailId; }
bool RsGxsTransSerializer::serialise(RsItem* item, void* data, uint32_t* size)
{
uint32_t itemSize = RsGxsTransSerializer::size(item);
if(*size < itemSize)
{
std::cout << __PRETTY_FUNCTION__ << " failed due to wrong size: "
<< size << " < " << itemSize << std::endl;
return false;
}
uint8_t* dataPtr = reinterpret_cast<uint8_t*>(data);
bool ok = false;
switch(static_cast<GxsTransItemsSubtypes>(item->PacketSubType()))
{
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL:
{
uint32_t offset = 0;
RsGxsTransMailItem* i = dynamic_cast<RsGxsTransMailItem*>(item);
ok = i && i->serialize(dataPtr, itemSize, offset);
break;
}
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT:
{
RsGxsTransPresignedReceipt* i =
dynamic_cast<RsGxsTransPresignedReceipt*>(item);
uint32_t offset = 0;
ok = i && i->serialize(dataPtr, itemSize, offset);
break;
}
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_GROUP:
ok = setRsItemHeader(data, itemSize, item->PacketId(), itemSize);
break;
case GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM:
{
uint32_t offset = 0;
OutgoingRecord* i = dynamic_cast<OutgoingRecord*>(item);
ok = i && i->serialize(dataPtr, itemSize, offset);
break;
}
default: ok = false; break;
}
if(ok)
{
*size = itemSize;
return true;
}
std::cout << __PRETTY_FUNCTION__ << " failed!" << std::endl;
return false;
}
OutgoingRecord::OutgoingRecord() :
RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TRANS,
static_cast<uint8_t>(GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM) )
{ clear();}
OutgoingRecord::OutgoingRecord( RsGxsId rec, GxsTransSubServices cs,
const uint8_t* data, uint32_t size ) :
@ -111,102 +37,17 @@ OutgoingRecord::OutgoingRecord( RsGxsId rec, GxsTransSubServices cs,
memcpy(&mailData[0], data, size);
}
void OutgoingRecord::clear()
RS_REGISTER_ITEM_TYPE(RsGxsTransMailItem) // for mailItem
RS_REGISTER_ITEM_TYPE(RsNxsTransPresignedReceipt) // for presignedReceipt
void OutgoingRecord::serial_process(RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx)
{
status = GxsTransSendStatus::UNKNOWN;
recipient.clear();
mailItem.clear();
mailData.clear();
clientService = GxsTransSubServices::UNKNOWN;
presignedReceipt.clear();
RS_REGISTER_SERIAL_MEMBER_TYPED(status, uint8_t);
RS_REGISTER_SERIAL_MEMBER(recipient);
RS_REGISTER_SERIAL_MEMBER(mailItem);
RS_REGISTER_SERIAL_MEMBER(mailData);
RS_REGISTER_SERIAL_MEMBER_TYPED(clientService, uint16_t);
RS_REGISTER_SERIAL_MEMBER(presignedReceipt);
}
std::ostream& OutgoingRecord::print(std::ostream& out, uint16_t)
{ return out << "TODO: OutgoingRecordItem::print(...)"; }
OutgoingRecord::OutgoingRecord() :
RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TRANS,
static_cast<uint8_t>(GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM) )
{ clear();}
uint32_t OutgoingRecord::serial_size() const
{
return 8 + // Header
1 + // status
recipient.serial_size() +
mailItem.serial_size() +
4 + // sizeof(mailData.size())
mailData.size() +
2 + // clientService
presignedReceipt.serial_size();
}
bool OutgoingRecord::serialize( uint8_t* data, uint32_t size,
uint32_t& offset) const
{
bool ok = true;
ok = ok && setRsItemHeader(data+offset, size, PacketId(), size)
&& (offset += 8); // Take header in account
ok = ok && setRawUInt8(data, size, &offset, static_cast<uint8_t>(status));
ok = ok && recipient.serialise(data, size, offset);
uint32_t tmpOffset = 0;
uint32_t tmpSize = mailItem.serial_size();
ok = ok && mailItem.serialize(data+offset, tmpSize, tmpOffset)
&& (offset += tmpOffset);
uint32_t dSize = mailData.size();
ok = ok && setRawUInt32(data, size, &offset, dSize)
&& memcpy(data+offset, &mailData[0], dSize) && (offset += dSize);
ok = ok && setRawUInt16( data, size, &offset,
static_cast<uint16_t>(clientService) );
dSize = presignedReceipt.serial_size();
ok = ok && presignedReceipt.serialise(data+offset, dSize)
&& (offset += dSize);
return ok;
}
bool OutgoingRecord::deserialize(
const uint8_t* data, uint32_t& size, uint32_t& offset)
{
bool ok = true;
void* dataPtr = const_cast<uint8_t*>(data);
offset += 8; // Header
uint8_t tmpStatus = 0;
ok = ok && getRawUInt8(dataPtr, size, &offset, &tmpStatus);
status = static_cast<GxsTransSendStatus>(tmpStatus);
uint32_t tmpSize = size;
ok = ok && recipient.deserialise(dataPtr, tmpSize, offset);
void* hdrPtr = const_cast<uint8_t*>(data+offset);
tmpSize = getRsItemSize(hdrPtr);
uint32_t tmpOffset = 0;
ok = ok && mailItem.deserialize(static_cast<uint8_t*>(hdrPtr), tmpSize, tmpOffset);
ok = ok && (offset += tmpOffset);
tmpSize = size;
ok = getRawUInt32(dataPtr, tmpSize, &offset, &tmpSize);
ok = ok && (tmpSize+offset < size);
ok = ok && (mailData.resize(tmpSize), memcpy(&mailData[0], data, tmpSize));
ok = ok && (offset += tmpSize);
uint16_t cs = 0;
ok = ok && getRawUInt16(dataPtr, offset+2, &offset, &cs);
clientService = static_cast<GxsTransSubServices>(cs);
tmpSize = size;
ok = ok && presignedReceipt.deserialize(data, tmpSize, offset);
return ok;
}

View file

@ -19,12 +19,13 @@
#include <string>
#include "serialiser/rsgxsitems.h"
#include "rsitems/rsgxsitems.h"
#include "serialiser/rsbaseserial.h"
#include "serialiser/rstlvidset.h"
#include "retroshare/rsgxsflags.h"
#include "retroshare/rsgxscircles.h" // For: GXS_CIRCLE_TYPE_PUBLIC
#include "services/p3idservice.h"
#include "serialiser/rstypeserializer.h"
/// Subservices identifiers (like port for TCP)
enum class GxsTransSubServices : uint16_t
@ -65,14 +66,9 @@ struct RsGxsTransBaseItem : RsGxsMsgItem
meta = RsMsgMetaData();
}
static uint32_t inline serial_size()
{
return 8 + // Header
8; // mailId
}
bool serialize(uint8_t* data, uint32_t size, uint32_t& offset) const;
bool deserialize(const uint8_t* data, uint32_t& size, uint32_t& offset);
std::ostream &print(std::ostream &out, uint16_t /*indent = 0*/);
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{ RS_REGISTER_SERIAL_MEMBER_TYPED(mailId, uint64_t); }
};
struct RsGxsTransPresignedReceipt : RsGxsTransBaseItem
@ -149,46 +145,15 @@ struct RsGxsTransMailItem : RsGxsTransBaseItem
* is specified */
std::vector<uint8_t> payload;
uint32_t serial_size() const
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
return RsGxsTransBaseItem::serial_size() +
1 + // cryptoType
recipientHint.serial_size() +
payload.size();
RsGxsTransBaseItem::serial_process(j, ctx);
RS_REGISTER_SERIAL_MEMBER_TYPED(cryptoType, uint8_t);
RS_REGISTER_SERIAL_MEMBER(recipientHint);
RS_REGISTER_SERIAL_MEMBER(payload);
}
bool serialize(uint8_t* data, uint32_t size, uint32_t& offset) const
{
bool ok = size < MAX_SIZE;
ok = ok && RsGxsTransBaseItem::serialize(data, size, offset);
ok = ok && setRawUInt8( data, size, &offset,
static_cast<uint8_t>(cryptoType) );
ok = ok && recipientHint.serialise(data, size, offset);
uint32_t psz = payload.size();
ok = ok && memcpy(data+offset, &payload[0], psz);
offset += psz;
return ok;
}
bool deserialize(const uint8_t* data, uint32_t& size, uint32_t& offset)
{
void* sizePtr = const_cast<uint8_t*>(data+offset);
uint32_t rssize = getRsItemSize(sizePtr);
uint32_t roffset = offset;
bool ok = rssize <= size && size < MAX_SIZE;
ok = ok && RsGxsTransBaseItem::deserialize(data, rssize, roffset);
void* dataPtr = const_cast<uint8_t*>(data);
uint8_t crType;
ok = ok && getRawUInt8(dataPtr, rssize, &roffset, &crType);
cryptoType = static_cast<RsGxsTransEncryptionMode>(crType);
ok = ok && recipientHint.deserialise(dataPtr, rssize, roffset);
uint32_t psz = rssize - roffset;
ok = ok && (payload.resize(psz), memcpy(&payload[0], data+roffset, psz));
ok = ok && (roffset += psz);
if(ok) { size = rssize; offset = roffset; }
else size = 0;
return ok;
}
void clear()
{
RsGxsTransBaseItem::clear();
@ -213,6 +178,11 @@ struct RsGxsTransGroupItem : RsGxsGrpItem
meta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC;
}
// TODO: Talk with Cyril why there is no RsGxsGrpItem::serial_process
virtual void serial_process(RsGenericSerializer::SerializeJob /*j*/,
RsGenericSerializer::SerializeContext& /*ctx*/)
{}
void clear() {}
std::ostream &print(std::ostream &out, uint16_t /*indent = 0*/)
{ return out; }
@ -253,12 +223,10 @@ struct OutgoingRecord : RsItem
GxsTransSubServices clientService;
RsNxsTransPresignedReceipt presignedReceipt;
uint32_t serial_size() const;
bool serialize(uint8_t* data, uint32_t size, uint32_t& offset) const;
bool deserialize(const uint8_t* data, uint32_t& size, uint32_t& offset);
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx );
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0);
void clear() {}
private:
friend class RsGxsTransSerializer;
@ -266,100 +234,23 @@ private:
};
struct RsGxsTransSerializer : RsSerialType
struct RsGxsTransSerializer : public RsServiceSerializer
{
RsGxsTransSerializer() : RsSerialType( RS_PKT_VERSION_SERVICE,
RS_SERVICE_TYPE_GXS_TRANS ) {}
RsGxsTransSerializer() : RsServiceSerializer(RS_SERVICE_TYPE_GXS_TRANS) {}
~RsGxsTransSerializer() {}
uint32_t size(RsItem* item)
RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const
{
uint32_t sz = 0;
switch(static_cast<GxsTransItemsSubtypes>(item->PacketSubType()))
{
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL:
{
RsGxsTransMailItem* i = dynamic_cast<RsGxsTransMailItem*>(item);
if(i) sz = i->serial_size();
break;
}
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT:
sz = RsGxsTransPresignedReceipt::serial_size(); break;
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_GROUP: sz = 8; break;
case GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM:
{
OutgoingRecord* ci = dynamic_cast<OutgoingRecord*>(item);
if(ci) sz = ci->serial_size();
break;
}
default: break;
}
if(service_id != RS_SERVICE_TYPE_GXS_TRANS) return NULL;
return sz;
}
bool serialise(RsItem* item, void* data, uint32_t* size);
RsItem* deserialise(void* data, uint32_t* size)
{
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint8_t pktv = getRsItemVersion(rstype);
uint16_t srvc = getRsItemService(rstype);
const uint8_t* dataPtr = reinterpret_cast<uint8_t*>(data);
if ( (RS_PKT_VERSION_SERVICE != pktv) || // 0x02
(RS_SERVICE_TYPE_GXS_TRANS != srvc) || // 0x0230 = 560
(*size < rssize) )
switch(static_cast<GxsTransItemsSubtypes>(item_sub_id))
{
print_stacktrace();
return NULL;
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL: return new RsGxsTransMailItem();
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT: return new RsGxsTransPresignedReceipt();
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_GROUP: return new RsGxsTransGroupItem();
case GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM: return new OutgoingRecord();
default: return NULL;
}
*size = rssize;
bool ok = true;
RsItem* ret = NULL;
switch (static_cast<GxsTransItemsSubtypes>(getRsItemSubType(rstype)))
{
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL:
{
RsGxsTransMailItem* i = new RsGxsTransMailItem();
uint32_t offset = 0;
ok = ok && i->deserialize(dataPtr, *size, offset);
ret = i;
break;
}
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT:
{
RsGxsTransPresignedReceipt* i = new RsGxsTransPresignedReceipt();
uint32_t offset = 0;
ok &= i->deserialize(dataPtr, *size, offset);
ret = i;
break;
}
case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_GROUP:
{
ret = new RsGxsTransGroupItem();
break;
}
case GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM:
{
OutgoingRecord* i = new OutgoingRecord();
uint32_t offset = 0;
ok = ok && i->deserialize(dataPtr, *size, offset);
ret = i;
break;
}
default:
ok = false;
break;
}
if(ok) return ret;
delete ret;
return NULL;
}
};