RetroShare/libretroshare/src/serialiser/rsposteditems.cc
chrisparker126 325fa4f222 merging gxs_phase2 branch
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6401 b45a01b8-16f6-495d-af2f-9b41ad6348cc
2013-06-04 21:00:43 +00:00

394 lines
10 KiB
C++

/*
* libretroshare/src/gxs: rsopsteditems.cc
*
* RetroShare Serialiser.
*
* Copyright 2012-2013 by Robert Fernie, Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "serialiser/rsposteditems.h"
#include "rsbaseserial.h"
#include "rstlvbase.h"
uint32_t RsGxsPostedSerialiser::size(RsItem *item)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::size()" << std::endl;
#endif
RsGxsPostedGroupItem* pgItem = NULL;
RsGxsPostedPostItem* ppItem = NULL;
if ((pgItem = dynamic_cast<RsGxsPostedGroupItem*>(item)) != NULL)
{
return sizeGxsPostedGroupItem(pgItem);
}
else if ((ppItem = dynamic_cast<RsGxsPostedPostItem*>(item)) != NULL)
{
return sizeGxsPostedPostItem(ppItem);
}
else
{
return RsGxsCommentSerialiser::size(item);
}
return NULL;
}
bool RsGxsPostedSerialiser::serialise(RsItem *item, void *data, uint32_t *size)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::serialise()" << std::endl;
#endif
RsGxsPostedPostItem* ppItem = NULL;
RsGxsPostedGroupItem* pgItem = NULL;
if ((pgItem = dynamic_cast<RsGxsPostedGroupItem*>(item)) != NULL)
{
return serialiseGxsPostedGroupItem(pgItem, data, size);
}
else if ((ppItem = dynamic_cast<RsGxsPostedPostItem*>(item)) != NULL)
{
return serialiseGxsPostedPostItem(ppItem, data, size);
}
else
{
return RsGxsCommentSerialiser::serialise(item, data, size);
}
return false;
}
RsItem* RsGxsPostedSerialiser::deserialise(void *data, uint32_t *size)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::deserialise()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_GXSV2_TYPE_POSTED != getRsItemService(rstype)))
{
std::cerr << "RsGxsPostedSerialiser::deserialise() ERROR Wrong Type";
std::cerr << std::endl;
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_POSTED_GRP_ITEM:
return deserialiseGxsPostedGroupItem(data, size);
break;
case RS_PKT_SUBTYPE_POSTED_POST_ITEM:
return deserialiseGxsPostedPostItem(data, size);
break;
default:
return RsGxsCommentSerialiser::deserialise(data, size);
break;
}
return NULL;
}
/*****************************************************************************************/
/*****************************************************************************************/
/*****************************************************************************************/
void RsGxsPostedPostItem::clear()
{
mPost.mLink.clear();
mPost.mNotes.clear();
}
std::ostream & RsGxsPostedPostItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsPostedPostItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "Link: " << mPost.mLink << std::endl;
printIndent(out, int_Indent);
out << "Notes: " << mPost.mNotes << std::endl;
printRsItemEnd(out ,"RsGxsPostedPostItem", indent);
return out;
}
uint32_t RsGxsPostedSerialiser::sizeGxsPostedPostItem(RsGxsPostedPostItem* item)
{
RsPostedPost& p = item->mPost;
uint32_t s = 8;
s += GetTlvStringSize(p.mLink);
s += GetTlvStringSize(p.mNotes);
return s;
}
bool RsGxsPostedSerialiser::serialiseGxsPostedPostItem(RsGxsPostedPostItem* item, void* data, uint32_t *size)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedPostItem()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsPostedPostItem(item);
uint32_t offset = 0;
if(*size < tlvsize){
std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedPostItem() Size too small" << std::endl;
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* RsPostedPost */
ok &= SetTlvString(data, tlvsize, &offset, 1, item->mPost.mLink);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->mPost.mNotes);
if(offset != tlvsize)
{
std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedPostItem() FAIL Size Error! " << std::endl;
ok = false;
}
#ifdef POSTED_DEBUG
if (!ok)
{
std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedPostItem() NOK" << std::endl;
}
#endif
return ok;
}
RsGxsPostedPostItem* RsGxsPostedSerialiser::deserialiseGxsPostedPostItem(void *data, uint32_t *size)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_GXSV2_TYPE_POSTED != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_POSTED_POST_ITEM != getRsItemSubType(rstype)))
{
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem() FAIL wrong type" << std::endl;
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem() FAIL wrong size" << std::endl;
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsPostedPostItem* item = new RsGxsPostedPostItem();
/* skip the header */
offset += 8;
ok &= GetTlvString(data, rssize, &offset, 1, item->mPost.mLink);
ok &= GetTlvString(data, rssize, &offset, 1, item->mPost.mNotes);
if (offset != rssize)
{
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem() FAIL size mismatch" << std::endl;
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}
/*****************************************************************************************/
/*****************************************************************************************/
/*****************************************************************************************/
void RsGxsPostedGroupItem::clear()
{
mGroup.mDescription.clear();
return;
}
std::ostream & RsGxsPostedGroupItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsPostedGroupItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "Description: " << mGroup.mDescription << std::endl;
printRsItemEnd(out ,"RsGxsPostedGroupItem", indent);
return out;
}
uint32_t RsGxsPostedSerialiser::sizeGxsPostedGroupItem(RsGxsPostedGroupItem* item)
{
RsPostedGroup& g = item->mGroup;
uint32_t s = 8; // header
s += GetTlvStringSize(g.mDescription);
return s;
}
bool RsGxsPostedSerialiser::serialiseGxsPostedGroupItem(RsGxsPostedGroupItem* item, void* data, uint32_t *size)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedGroupItem()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsPostedGroupItem(item);
uint32_t offset = 0;
if(*size < tlvsize){
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedGroupItem()" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* PostedGroupItem */
ok &= SetTlvString(data, tlvsize, &offset, 1, item->mGroup.mDescription);
if(offset != tlvsize)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedGroupItem() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef POSTED_DEBUG
if (!ok)
{
std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedGroupItem() NOK" << std::endl;
}
#endif
return ok;
}
RsGxsPostedGroupItem* RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem(void *data, uint32_t *size)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_GXSV2_TYPE_POSTED != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_POSTED_GRP_ITEM != getRsItemSubType(rstype)))
{
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem() FAIL wrong type" << std::endl;
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem() FAIL wrong size" << std::endl;
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsPostedGroupItem* item = new RsGxsPostedGroupItem();
/* skip the header */
offset += 8;
ok &= GetTlvString(data, rssize, &offset, 1, item->mGroup.mDescription);
if (offset != rssize)
{
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem() FAIL size mismatch" << std::endl;
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef POSTED_DEBUG
std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}