From 22782e5edd582ca8871b88d282d536834415c936 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 4 Mar 2013 20:26:48 +0000 Subject: [PATCH] Adding Basics of GxsChannel Service into libretroshare. This includes a generic CommentService, which will be used by other Services. + Bugfix, gxs service threads were started before global variables were set. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6186 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.h | 5 + libretroshare/src/libretroshare.pro | 16 +- libretroshare/src/retroshare/rsgxschannels.h | 111 ++++ libretroshare/src/retroshare/rsgxscommon.h | 103 ++++ libretroshare/src/rsserver/p3face-config.cc | 2 + libretroshare/src/rsserver/p3face.h | 2 + libretroshare/src/rsserver/rsinit.cc | 79 ++- .../src/serialiser/rsgxschannelitems.cc | 405 +++++++++++++ .../src/serialiser/rsgxschannelitems.h | 98 ++++ .../src/serialiser/rsgxscommentitems.cc | 401 +++++++++++++ .../src/serialiser/rsgxscommentitems.h | 97 ++++ libretroshare/src/serialiser/rsgxsiditems.cc | 27 +- libretroshare/src/services/p3gxschannels.cc | 544 ++++++++++++++++++ libretroshare/src/services/p3gxschannels.h | 145 +++++ libretroshare/src/services/p3gxscommon.cc | 279 +++++++++ libretroshare/src/services/p3gxscommon.h | 59 ++ libretroshare/src/services/p3gxsforums.cc | 19 +- 17 files changed, 2326 insertions(+), 66 deletions(-) create mode 100644 libretroshare/src/retroshare/rsgxschannels.h create mode 100644 libretroshare/src/retroshare/rsgxscommon.h create mode 100644 libretroshare/src/serialiser/rsgxschannelitems.cc create mode 100644 libretroshare/src/serialiser/rsgxschannelitems.h create mode 100644 libretroshare/src/serialiser/rsgxscommentitems.cc create mode 100644 libretroshare/src/serialiser/rsgxscommentitems.h create mode 100644 libretroshare/src/services/p3gxschannels.cc create mode 100644 libretroshare/src/services/p3gxschannels.h create mode 100644 libretroshare/src/services/p3gxscommon.cc create mode 100644 libretroshare/src/services/p3gxscommon.h diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 164d873b1..d8374cf55 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -249,6 +249,7 @@ protected: */ bool getGroupData(const uint32_t &token, std::vector& grpItem); +public: /*! * retrieves message data associated to a request token * @param token token to be redeemed for message item retrieval @@ -263,6 +264,8 @@ protected: */ bool getMsgRelatedData(const uint32_t &token, GxsMsgRelatedDataMap& msgItems); +protected: + /*! * Convenience template function for retrieve * msg related data from @@ -391,6 +394,7 @@ protected: */ void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem); +public: /*! * Enables publication of a message item \n * Setting mOrigMsgId meta member to blank \n @@ -403,6 +407,7 @@ protected: */ void publishMsg(uint32_t& token, RsGxsMsgItem* msgItem); +protected: /*! * This represents the group before its signature is calculated * Reimplement this function if you need to access keys to further extend diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index d81b22714..de773a65c 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -7,7 +7,7 @@ CONFIG += test_voip # GXS Stuff. # This should be disabled for releases until further notice. -#CONFIG += gxs +#CONFIG += gxs debug # Beware: All data of the stripped services are lost DEFINES *= PQI_DISABLE_TUNNEL @@ -676,6 +676,18 @@ gxs { SOURCES += services/p3gxsforums.cc \ serialiser/rsgxsforumitems.cc \ + # GxsChannels Service + HEADERS += retroshare/rsgxschannels.h \ + services/p3gxschannels.h \ + services/p3gxscommon.h \ + serialiser/rsgxscommentitems.h \ + serialiser/rsgxschannelitems.h \ + + SOURCES += services/p3gxschannels.cc \ + services/p3gxscommon.cc \ + serialiser/rsgxscommentitems.cc \ + serialiser/rsgxschannelitems.cc \ + # Wiki Service HEADERS += retroshare/rswiki.h \ services/p3wiki.h \ @@ -684,7 +696,7 @@ gxs { SOURCES += services/p3wiki.cc \ serialiser/rswikiitems.cc \ - # Wiki Service + # Wire Service HEADERS += retroshare/rswire.h \ services/p3wire.h \ serialiser/rswireitems.h diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h new file mode 100644 index 000000000..edc1d816e --- /dev/null +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -0,0 +1,111 @@ +#ifndef RETROSHARE_GXS_CHANNEL_GUI_INTERFACE_H +#define RETROSHARE_GXS_CHANNEL_GUI_INTERFACE_H + +/* + * libretroshare/src/retroshare: rsgxschannel.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * 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 +#include +#include + +#include "gxs/rstokenservice.h" +#include "retroshare/rsgxsifacehelper.h" +#include "retroshare/rsgxscommon.h" + + + +/* The Main Interface Class - for information about your Peers */ +class RsGxsChannels; +extern RsGxsChannels *rsGxsChannels; + + +// These should be in rsgxscommon.h + +class RsGxsChannelGroup +{ + public: + RsGroupMetaData mMeta; + std::string mDescription; + + //RsGxsImage mChanImage; + bool mAutoDownload; + +}; + +class RsGxsChannelPost +{ + public: + RsMsgMetaData mMeta; + std::string mMsg; // UTF8 encoded. + + //std::list mFiles; + uint32_t mCount; // auto calced. + uint64_t mSize; // auto calced. + //RsGxsImage mThumbnail; +}; + + +//typedef std::map > GxsChannelMsgResult; + +std::ostream &operator<<(std::ostream &out, const RsGxsChannelGroup &group); +std::ostream &operator<<(std::ostream &out, const RsGxsChannelPost &post); + +class RsGxsChannels: public RsGxsIfaceHelper, public RsGxsCommentService +{ + public: + + RsGxsChannels(RsGxsIface *gxs) + :RsGxsIfaceHelper(gxs) { return; } +virtual ~RsGxsChannels() { return; } + + /* Specific Service Data */ +virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; +virtual bool getPostData(const uint32_t &token, std::vector &posts) = 0; + +virtual bool getRelatedPosts(const uint32_t &token, std::vector &posts) = 0; + + /* From RsGxsCommentService */ +//virtual bool getCommentData(const uint32_t &token, std::vector &comments) = 0; +//virtual bool getRelatedComments(const uint32_t &token, std::vector &comments) = 0; +//virtual bool createComment(uint32_t &token, RsGxsComment &comment) = 0; +//virtual bool createVote(uint32_t &token, RsGxsVote &vote) = 0; + + ////////////////////////////////////////////////////////////////////////////// +virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0; + +//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); +//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); + +//virtual bool groupRestoreKeys(const std::string &groupId); +//virtual bool groupShareKeys(const std::string &groupId, std::list& peers); + +virtual bool createGroup(uint32_t &token, RsGxsChannelGroup &group) = 0; +virtual bool createPost(uint32_t &token, RsGxsChannelPost &post) = 0; + +}; + + + +#endif diff --git a/libretroshare/src/retroshare/rsgxscommon.h b/libretroshare/src/retroshare/rsgxscommon.h new file mode 100644 index 000000000..cd8d574bd --- /dev/null +++ b/libretroshare/src/retroshare/rsgxscommon.h @@ -0,0 +1,103 @@ +#ifndef RETROSHARE_GXS_COMMON_OBJS_INTERFACE_H +#define RETROSHARE_GXS_COMMON_OBJS_INTERFACE_H + +/* + * libretroshare/src/retroshare: rsgxscommong.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * 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 +#include +#include + +#include "rsgxsifacetypes.h" + +class RsGxsFile +{ + public: + RsGxsFile(); + std::string mName; + std::string mHash; + uint64_t mSize; + std::string mPath; +}; + +class RsGxsImage +{ + public: + RsGxsImage(); + uint8_t *mData; + uint32_t mSize; +}; + +#define GXS_VOTE_DOWN 0x0001 +#define GXS_VOTE_UP 0x0002 + +class RsGxsVote +{ + public: + RsGxsVote(); + RsMsgMetaData mMeta; + uint32_t mVoteType; +}; + +class RsGxsComment +{ + public: + RsGxsComment(); + RsMsgMetaData mMeta; + std::string mComment; + + // below is calculated. + uint32_t mUpVotes; + uint32_t mDownVotes; + double score; + + // This is filled in if detailed Comment Data is called. + std::list votes; +}; + + +class RsGxsCommentService +{ + public: + + RsGxsCommentService() { return; } +virtual ~RsGxsCommentService() { return; } + +virtual bool getCommentData(const uint32_t &token, std::vector &comments) = 0; +virtual bool getRelatedComments(const uint32_t &token, std::vector &comments) = 0; + +//virtual bool getDetailedCommentData(const uint32_t &token, std::vector &comments); + +virtual bool createComment(uint32_t &token, RsGxsComment &comment) = 0; +virtual bool createVote(uint32_t &token, RsGxsVote &vote) = 0; + +virtual bool acknowledgeComment(const uint32_t& token, std::pair& msgId) = 0; + +}; + + + +#endif + diff --git a/libretroshare/src/rsserver/p3face-config.cc b/libretroshare/src/rsserver/p3face-config.cc index f28db3cd3..981537a85 100644 --- a/libretroshare/src/rsserver/p3face-config.cc +++ b/libretroshare/src/rsserver/p3face-config.cc @@ -51,6 +51,7 @@ const int p3facemsgzone = 11453; #include "services/p3posted.h" #include "services/p3photoservice.h" #include "services/p3gxsforums.h" +#include "services/p3gxschannels.h" #include "services/p3wire.h" #endif @@ -160,6 +161,7 @@ void RsServer::rsGlobalShutDown() #ifdef RS_ENABLE_GXS if(mGxsCircles) mGxsCircles->join(); if(mGxsForums) mGxsForums->join(); + if(mGxsChannels) mGxsChannels->join(); if(mGxsIdService) mGxsIdService->join(); if(mPosted) mPosted->join(); if(mPhoto) mPhoto->join(); diff --git a/libretroshare/src/rsserver/p3face.h b/libretroshare/src/rsserver/p3face.h index 58588fb01..443f35db4 100644 --- a/libretroshare/src/rsserver/p3face.h +++ b/libretroshare/src/rsserver/p3face.h @@ -51,6 +51,7 @@ class p3IdService; class p3GxsCircles; class p3GxsForums; +class p3GxsChannels; class p3Wiki; class p3Posted; class p3PhotoService; @@ -192,6 +193,7 @@ class RsServer: public RsControl, public RsThread p3GxsCircles *mGxsCircles; p3IdService *mGxsIdService; p3GxsForums *mGxsForums; + p3GxsChannels *mGxsChannels; p3Wire *mWire; /* Config */ diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index b0fddeeb3..9b58e1d1e 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1815,6 +1815,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3posted.h" #include "services/p3photoservice.h" #include "services/p3gxsforums.h" +#include "services/p3gxschannels.h" #include "services/p3wire.h" #endif // RS_ENABLE_GXS @@ -2261,7 +2262,7 @@ int RsServer::StartupRetroShare() // mPluginsManager->registerClientServices(pqih) ; mPluginsManager->registerCacheServices() ; -//#define RS_ENABLE_GXS + #ifdef RS_ENABLE_GXS // The idea is that if priorGxsDir is non @@ -2431,23 +2432,20 @@ int RsServer::StartupRetroShare() RS_SERVICE_GXSV1_TYPE_FORUMS, gxsforums_ds, nxsMgr, mGxsForums); - /*** start up GXS core runner ***/ - createThread(*mGxsIdService); - createThread(*mGxsCircles); - createThread(*mPhoto); - createThread(*mPosted); - createThread(*mWiki); - createThread(*mWire); - createThread(*mGxsForums); + /**** Channel GXS service ****/ - // cores ready start up GXS net servers - createThread(*gxsid_ns); - createThread(*gxscircles_ns); - createThread(*photo_ns); - createThread(*posted_ns); - createThread(*wiki_ns); - createThread(*wire_ns); - createThread(*gxsforums_ns); + RsGeneralDataService* gxschannels_ds = new RsDataService(currGxsDir + "/", "gxschannels_db", + RS_SERVICE_GXSV1_TYPE_CHANNELS); + +//#ifndef GXS_DEV_TESTNET // NO RESET, OR DUMMYDATA for TESTNET + gxschannels_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing +//#endif + + mGxsChannels = new p3GxsChannels(gxschannels_ds, NULL, mGxsIdService); + + // create GXS photo service + RsGxsNetService* gxschannels_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_CHANNELS, gxschannels_ds, nxsMgr, mGxsChannels); // now add to p3service pqih->addService(gxsid_ns); @@ -2456,6 +2454,7 @@ int RsServer::StartupRetroShare() pqih->addService(posted_ns); pqih->addService(wiki_ns); pqih->addService(gxsforums_ns); + pqih->addService(gxschannels_ns); #endif // RS_ENABLE_GXS. @@ -2676,6 +2675,41 @@ int RsServer::StartupRetroShare() /* Start up Threads */ /**************************************************************************/ +#ifdef RS_ENABLE_GXS + + // Must Set the GXS pointers before starting threads. + rsIdentity = mGxsIdService; + rsGxsCircles = mGxsCircles; + rsWiki = mWiki; + rsPosted = mPosted; + rsPhoto = mPhoto; + rsGxsForums = mGxsForums; + rsGxsChannels = mGxsChannels; + rsWire = mWire; + + /*** start up GXS core runner ***/ + createThread(*mGxsIdService); + createThread(*mGxsCircles); + createThread(*mPhoto); + createThread(*mPosted); + createThread(*mWiki); + createThread(*mWire); + createThread(*mGxsForums); + createThread(*mGxsChannels); + + // cores ready start up GXS net servers + createThread(*gxsid_ns); + createThread(*gxscircles_ns); + createThread(*photo_ns); + createThread(*posted_ns); + createThread(*wiki_ns); + createThread(*wire_ns); + createThread(*gxsforums_ns); + createThread(*gxschannels_ns); + + +#endif // RS_ENABLE_GXS + ftserver->StartupThreads(); ftserver->ResumeTransfers(); @@ -2715,17 +2749,6 @@ int RsServer::StartupRetroShare() rsForums = mForums; rsChannels = mChannels; -#ifdef RS_ENABLE_GXS - - rsIdentity = mGxsIdService; - rsGxsCircles = mGxsCircles; - rsWiki = mWiki; - rsPosted = mPosted; - rsPhoto = mPhoto; - rsGxsForums = mGxsForums; - rsWire = mWire; - -#endif // RS_ENABLE_GXS #ifdef RS_USE_BLOGS diff --git a/libretroshare/src/serialiser/rsgxschannelitems.cc b/libretroshare/src/serialiser/rsgxschannelitems.cc new file mode 100644 index 000000000..d5fb16508 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxschannelitems.cc @@ -0,0 +1,405 @@ +/* + * libretroshare/src/serialiser: rsgxschannelitems.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * 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 + +#include "rsgxschannelitems.h" +#include "serialiser/rstlvbase.h" +#include "serialiser/rsbaseserial.h" + +#define GXSCHANNEL_DEBUG 1 + + +uint32_t RsGxsChannelSerialiser::size(RsItem *item) +{ + RsGxsChannelGroupItem* grp_item = NULL; + RsGxsChannelPostItem* op_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return sizeGxsChannelGroupItem(grp_item); + } + else if((op_item = dynamic_cast(item)) != NULL) + { + return sizeGxsChannelPostItem(op_item); + } + else + { + RsGxsCommentSerialiser::size(item); + } + return 0; +} + +bool RsGxsChannelSerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + RsGxsChannelGroupItem* grp_item = NULL; + RsGxsChannelPostItem* op_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsChannelGroupItem(grp_item, data, size); + } + else if((op_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsChannelPostItem(op_item, data, size); + } + else + { + return RsGxsCommentSerialiser::serialise(item, data, size); + } + return false; +} + +RsItem* RsGxsChannelSerialiser::deserialise(void* data, uint32_t* size) +{ + +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_CHANNELS != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_GXSCHANNEL_GROUP_ITEM: + return deserialiseGxsChannelGroupItem(data, size); + break; + case RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM: + return deserialiseGxsChannelPostItem(data, size); + break; + default: + return RsGxsCommentSerialiser::deserialise(data, size); + break; + } + return NULL; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsChannelGroupItem::clear() +{ + mGroup.mDescription.clear(); +} + +std::ostream& RsGxsChannelGroupItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsChannelGroupItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Description: " << mGroup.mDescription << std::endl; + + printRsItemEnd(out ,"RsGxsChannelGroupItem", indent); + return out; +} + + +uint32_t RsGxsChannelSerialiser::sizeGxsChannelGroupItem(RsGxsChannelGroupItem *item) +{ + + const RsGxsChannelGroup& group = item->mGroup; + uint32_t s = 8; // header + + s += GetTlvStringSize(group.mDescription); + + return s; +} + +bool RsGxsChannelSerialiser::serialiseGxsChannelGroupItem(RsGxsChannelGroupItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::serialiseGxsChannelGroupItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsChannelGroupItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::serialiseGxsChannelGroupItem() Size too small" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsChannelGroupItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mGroup.mDescription); + + if(offset != tlvsize) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::serialiseGxsChannelGroupItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSCHANNEL_DEBUG + if (!ok) + { + std::cerr << "RsGxsChannelSerialiser::serialiseGxsChannelGroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsChannelGroupItem* RsGxsChannelSerialiser::deserialiseGxsChannelGroupItem(void *data, uint32_t *size) +{ + +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelGroupItem()" << 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_GXSV1_TYPE_CHANNELS != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSCHANNEL_GROUP_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelGroupItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelGroupItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsChannelGroupItem* item = new RsGxsChannelGroupItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->mGroup.mDescription); + + if (offset != rssize) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelGroupItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelGroupItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsChannelPostItem::clear() +{ + mMsg.mMsg.clear(); +} + +std::ostream& RsGxsChannelPostItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsChannelPostItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Msg: " << mMsg.mMsg << std::endl; + + printRsItemEnd(out ,"RsGxsChannelPostItem", indent); + return out; +} + + +uint32_t RsGxsChannelSerialiser::sizeGxsChannelPostItem(RsGxsChannelPostItem *item) +{ + + const RsGxsChannelPost& msg = item->mMsg; + uint32_t s = 8; // header + + s += GetTlvStringSize(msg.mMsg); // mMsg. + + return s; +} + +bool RsGxsChannelSerialiser::serialiseGxsChannelPostItem(RsGxsChannelPostItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::serialiseGxsChannelPostItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsChannelPostItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::serialiseGxsChannelPostItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsChannelPostItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mMsg.mMsg); + + if(offset != tlvsize) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::serialiseGxsChannelPostItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSCHANNEL_DEBUG + if (!ok) + { + std::cerr << "RsGxsChannelSerialiser::serialiseGxsChannelGroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsChannelPostItem* RsGxsChannelSerialiser::deserialiseGxsChannelPostItem(void *data, uint32_t *size) +{ + +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelPostItem()" << 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_GXSV1_TYPE_CHANNELS != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelPostItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelPostItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsChannelPostItem* item = new RsGxsChannelPostItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->mMsg.mMsg); + + if (offset != rssize) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelPostItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSCHANNEL_DEBUG + std::cerr << "RsGxsChannelSerialiser::deserialiseGxsChannelPostItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + diff --git a/libretroshare/src/serialiser/rsgxschannelitems.h b/libretroshare/src/serialiser/rsgxschannelitems.h new file mode 100644 index 000000000..3c5e56a9d --- /dev/null +++ b/libretroshare/src/serialiser/rsgxschannelitems.h @@ -0,0 +1,98 @@ +/* + * libretroshare/src/serialiser: rsgxschannelitems.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * 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 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". + * + */ + +#ifndef RS_GXS_CHANNEL_ITEMS_H +#define RS_GXS_CHANNEL_ITEMS_H + +#include + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "serialiser/rsgxscommentitems.h" + +#include "rsgxsitems.h" +#include "retroshare/rsgxschannels.h" + +const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_GROUP_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03; + +class RsGxsChannelGroupItem : public RsGxsGrpItem +{ + +public: + + RsGxsChannelGroupItem(): RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_CHANNELS, + RS_PKT_SUBTYPE_GXSCHANNEL_GROUP_ITEM) { return;} + virtual ~RsGxsChannelGroupItem() { return;} + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + + RsGxsChannelGroup mGroup; +}; + +class RsGxsChannelPostItem : public RsGxsMsgItem +{ +public: + + RsGxsChannelPostItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_CHANNELS, + RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM) {return; } + virtual ~RsGxsChannelPostItem() { return;} + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsGxsChannelPost mMsg; +}; + + +class RsGxsChannelSerialiser : public RsGxsCommentSerialiser +{ +public: + + RsGxsChannelSerialiser() + :RsGxsCommentSerialiser(RS_SERVICE_GXSV1_TYPE_CHANNELS) + { return; } + virtual ~RsGxsChannelSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + private: + + uint32_t sizeGxsChannelGroupItem(RsGxsChannelGroupItem *item); + bool serialiseGxsChannelGroupItem (RsGxsChannelGroupItem *item, void *data, uint32_t *size); + RsGxsChannelGroupItem * deserialiseGxsChannelGroupItem(void *data, uint32_t *size); + + uint32_t sizeGxsChannelPostItem(RsGxsChannelPostItem *item); + bool serialiseGxsChannelPostItem (RsGxsChannelPostItem *item, void *data, uint32_t *size); + RsGxsChannelPostItem * deserialiseGxsChannelPostItem(void *data, uint32_t *size); + +}; + +#endif /* RS_GXS_CHANNEL_ITEMS_H */ diff --git a/libretroshare/src/serialiser/rsgxscommentitems.cc b/libretroshare/src/serialiser/rsgxscommentitems.cc new file mode 100644 index 000000000..95bb48132 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxscommentitems.cc @@ -0,0 +1,401 @@ +/* + * libretroshare/src/serialiser: rsgxscommentitems.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2013 by Robert Fernie + * + * 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 + +#include "rsgxscommentitems.h" +#include "serialiser/rstlvbase.h" +#include "serialiser/rsbaseserial.h" + +#define GXSCOMMENT_DEBUG 1 + + +uint32_t RsGxsCommentSerialiser::size(RsItem *item) +{ + RsGxsCommentItem* com_item = NULL; + RsGxsVoteItem* vote_item = NULL; + + if((com_item = dynamic_cast(item)) != NULL) + { + return sizeGxsCommentItem(com_item); + } + else if((vote_item = dynamic_cast(item)) != NULL) + { + return sizeGxsVoteItem(vote_item); + } + std::cerr << "RsGxsCommentSerialiser::size() ERROR invalid item" << std::endl; + return 0; +} + +bool RsGxsCommentSerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + RsGxsCommentItem* com_item = NULL; + RsGxsVoteItem* vote_item = NULL; + + if((com_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsCommentItem(com_item, data, size); + } + else if((vote_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsVoteItem(vote_item, data, size); + } + std::cerr << "RsGxsCommentSerialiser::serialise() ERROR invalid item" << std::endl; + return false; +} + +RsItem* RsGxsCommentSerialiser::deserialise(void* data, uint32_t* size) +{ + +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (getRsItemService(PacketId()) != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM: + return deserialiseGxsCommentItem(data, size); + break; + case RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM: + return deserialiseGxsVoteItem(data, size); + break; + default: +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialise(): unknown subtype"; + std::cerr << std::endl; +#endif + break; + } + return NULL; +} + + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsCommentItem::clear() +{ + mMsg.mComment.clear(); +} + +std::ostream& RsGxsCommentItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsCommentItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Comment: " << mMsg.mComment << std::endl; + + printRsItemEnd(out ,"RsGxsCommentItem", indent); + return out; +} + + +uint32_t RsGxsCommentSerialiser::sizeGxsCommentItem(RsGxsCommentItem *item) +{ + + const RsGxsComment& msg = item->mMsg; + uint32_t s = 8; // header + + s += GetTlvStringSize(msg.mComment); // mMsg. + + return s; +} + +bool RsGxsCommentSerialiser::serialiseGxsCommentItem(RsGxsCommentItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::serialiseGxsCommentItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsCommentItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::serialiseGxsCommentItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsCommentItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mMsg.mComment); + + if(offset != tlvsize) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::serialiseGxsCommentItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSCOMMENT_DEBUG + if (!ok) + { + std::cerr << "RsGxsCommentSerialiser::serialiseGxsCommentItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsCommentItem* RsGxsCommentSerialiser::deserialiseGxsCommentItem(void *data, uint32_t *size) +{ + +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsCommentItem()" << 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)) || + (getRsItemService(PacketId()) != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsCommentItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsCommentItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsCommentItem* item = new RsGxsCommentItem(getRsItemService(PacketId())); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->mMsg.mComment); + + if (offset != rssize) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsCommentItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsCommentItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsVoteItem::clear() +{ + mMsg.mVoteType = 0; +} + +std::ostream& RsGxsVoteItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsVoteItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "VoteType: " << mMsg.mVoteType << std::endl; + + printRsItemEnd(out ,"RsGxsVoteItem", indent); + return out; +} + + +uint32_t RsGxsCommentSerialiser::sizeGxsVoteItem(RsGxsVoteItem *item) +{ + + const RsGxsVote& msg = item->mMsg; + uint32_t s = 8; // header + + s += 4; // vote flags. + + return s; +} + +bool RsGxsCommentSerialiser::serialiseGxsVoteItem(RsGxsVoteItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::serialiseGxsVoteItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsVoteItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::serialiseGxsVoteItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsVoteItem */ + ok &= setRawUInt32(data, tlvsize, &offset, item->mMsg.mVoteType); + + if(offset != tlvsize) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::serialiseGxsVoteItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSCOMMENT_DEBUG + if (!ok) + { + std::cerr << "RsGxsCommentSerialiser::serialiseGxsVoteItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsVoteItem* RsGxsCommentSerialiser::deserialiseGxsVoteItem(void *data, uint32_t *size) +{ + +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsVoteItem()" << 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)) || + (getRsItemService(PacketId()) != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsVoteItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsVoteItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsVoteItem* item = new RsGxsVoteItem(getRsItemService(PacketId())); + /* skip the header */ + offset += 8; + + ok &= getRawUInt32(data, rssize, &offset, &(item->mMsg.mVoteType)); + + if (offset != rssize) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsVoteItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSCOMMENT_DEBUG + std::cerr << "RsGxsCommentSerialiser::deserialiseGxsVoteItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + diff --git a/libretroshare/src/serialiser/rsgxscommentitems.h b/libretroshare/src/serialiser/rsgxscommentitems.h new file mode 100644 index 000000000..6e1598667 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxscommentitems.h @@ -0,0 +1,97 @@ +/* + * libretroshare/src/serialiser: rsgxscommentitems.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * 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 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". + * + */ + +#ifndef RS_GXS_COMMENT_ITEMS_H +#define RS_GXS_COMMENT_ITEMS_H + +#include + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "rsgxsitems.h" + +#include "retroshare/rsgxscommon.h" + +const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1; +const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM = 0xf2; + +class RsGxsCommentItem : public RsGxsMsgItem +{ +public: + + RsGxsCommentItem(uint8_t service_type): RsGxsMsgItem(service_type, + RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM) {return; } + virtual ~RsGxsCommentItem() { return;} + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsGxsComment mMsg; +}; + + +class RsGxsVoteItem : public RsGxsMsgItem +{ +public: + + RsGxsVoteItem(uint8_t service_type): RsGxsMsgItem(service_type, + RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM) {return; } + virtual ~RsGxsVoteItem() { return;} + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsGxsVote mMsg; +}; + + +class RsGxsCommentSerialiser : public RsSerialType +{ +public: + + RsGxsCommentSerialiser(uint16_t service_type) + :RsSerialType(RS_PKT_VERSION_SERVICE, service_type) + { return; } + virtual ~RsGxsCommentSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + private: + + uint32_t sizeGxsCommentItem(RsGxsCommentItem *item); + bool serialiseGxsCommentItem (RsGxsCommentItem *item, void *data, uint32_t *size); + RsGxsCommentItem * deserialiseGxsCommentItem(void *data, uint32_t *size); + + + uint32_t sizeGxsVoteItem(RsGxsVoteItem *item); + bool serialiseGxsVoteItem (RsGxsVoteItem *item, void *data, uint32_t *size); + RsGxsVoteItem * deserialiseGxsVoteItem(void *data, uint32_t *size); + +}; + +#endif /* RS_GXS_COMMENT_ITEMS_H */ + diff --git a/libretroshare/src/serialiser/rsgxsiditems.cc b/libretroshare/src/serialiser/rsgxsiditems.cc index 02e316bec..1e07a2a40 100644 --- a/libretroshare/src/serialiser/rsgxsiditems.cc +++ b/libretroshare/src/serialiser/rsgxsiditems.cc @@ -79,9 +79,6 @@ bool RsGxsIdSerialiser::serialise(RsItem *item, void *data, uint32_t *size) RsItem* RsGxsIdSerialiser::deserialise(void* data, uint32_t* size) { -#ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::deserialise()" << std::endl; -#endif /* get the type and size */ uint32_t rstype = getRsItemId(data); @@ -160,9 +157,6 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdGroupItem(RsGxsIdGroupItem *item) bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *data, uint32_t *size) { -#ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem()" << std::endl; -#endif uint32_t tlvsize = sizeGxsIdGroupItem(item); uint32_t offset = 0; @@ -208,10 +202,6 @@ bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *da RsGxsIdGroupItem* RsGxsIdSerialiser::deserialiseGxsIdGroupItem(void *data, uint32_t *size) { - -#ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem()" << std::endl; -#endif /* get the type and size */ uint32_t rstype = getRsItemId(data); uint32_t rssize = getRsItemSize(data); @@ -313,9 +303,6 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdOpinionItem(RsGxsIdOpinionItem *item) bool RsGxsIdSerialiser::serialiseGxsIdOpinionItem(RsGxsIdOpinionItem *item, void *data, uint32_t *size) { -#ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::serialiseGxsIdOpinionItem()" << std::endl; -#endif uint32_t tlvsize = sizeGxsIdOpinionItem(item); uint32_t offset = 0; @@ -361,9 +348,6 @@ bool RsGxsIdSerialiser::serialiseGxsIdOpinionItem(RsGxsIdOpinionItem *item, void RsGxsIdOpinionItem* RsGxsIdSerialiser::deserialiseGxsIdOpinionItem(void *data, uint32_t *size) { -#ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdOpinionItem()" << std::endl; -#endif /* get the type and size */ uint32_t rstype = getRsItemId(data); uint32_t rssize = getRsItemSize(data); @@ -460,17 +444,13 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdCommentItem(RsGxsIdCommentItem *item) bool RsGxsIdSerialiser::serialiseGxsIdCommentItem(RsGxsIdCommentItem *item, void *data, uint32_t *size) { -#ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::serialiseGxsIdCommentItem()" << std::endl; -#endif - uint32_t tlvsize = sizeGxsIdCommentItem(item); uint32_t offset = 0; if(*size < tlvsize) { #ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::serialiseGxsIdCommentItem()" << std::endl; + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdCommentItem() Not enough space" << std::endl; #endif return false; } @@ -503,14 +483,11 @@ bool RsGxsIdSerialiser::serialiseGxsIdCommentItem(RsGxsIdCommentItem *item, void #endif return ok; - } +} RsGxsIdCommentItem* RsGxsIdSerialiser::deserialiseGxsIdCommentItem(void *data, uint32_t *size) { -#ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdCommentItem()" << std::endl; -#endif /* get the type and size */ uint32_t rstype = getRsItemId(data); uint32_t rssize = getRsItemSize(data); diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc new file mode 100644 index 000000000..43c48c361 --- /dev/null +++ b/libretroshare/src/services/p3gxschannels.cc @@ -0,0 +1,544 @@ +/* + * libretroshare/src/services p3gxschannels.cc + * + * GxsChannels interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * 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 "services/p3gxschannels.h" +#include "serialiser/rsgxschannelitems.h" + +#include + + +#include "retroshare/rsgxsflags.h" +#include + +// For Dummy Msgs. +#include "util/rsrandom.h" +#include "util/rsstring.h" + +/**** + * #define GXSCHANNEL_DEBUG 1 + ****/ +#define GXSCHANNEL_DEBUG 1 + +RsGxsChannels *rsGxsChannels = NULL; + + +#define CHANNEL_TESTEVENT_DUMMYDATA 0x0001 +#define DUMMYDATA_PERIOD 60 // long enough for some RsIdentities to be generated. + +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + +p3GxsChannels::p3GxsChannels(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs) + : RsGenExchange(gds, nes, new RsGxsChannelSerialiser(), RS_SERVICE_GXSV1_TYPE_CHANNELS, gixs, channelsAuthenPolicy()), RsGxsChannels(this) +{ + // For Dummy Msgs. + mGenActive = false; + mCommentService = new p3GxsCommentService(this, RS_SERVICE_GXSV1_TYPE_CHANNELS); + +//#ifndef GXS_DEV_TESTNET // NO RESET, OR DUMMYDATA for TESTNET + + RsTickEvent::schedule_in(CHANNEL_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD); + +//#endif + +} + + + +uint32_t p3GxsChannels::channelsAuthenPolicy() +{ + uint32_t policy = 0; + uint32_t flag = 0; + + flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN; + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); + + flag = GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; + //RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); + + flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN; + //RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); + //RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); + //RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); + + flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); + + return policy; +} + + + + + +void p3GxsChannels::notifyChanges(std::vector &changes) +{ + RsGxsIfaceHelper::receiveChanges(changes); +} + +void p3GxsChannels::service_tick() +{ + dummy_tick(); + RsTickEvent::tick_events(); + return; +} + +bool p3GxsChannels::getGroupData(const uint32_t &token, std::vector &groups) +{ + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsChannelGroupItem* item = dynamic_cast(*vit); + RsGxsChannelGroup grp = item->mGroup; + item->mGroup.mMeta = item->meta; + grp.mMeta = item->mGroup.mMeta; + delete item; + groups.push_back(grp); + } + } + return ok; +} + +/* Okay - chris is not going to be happy with this... + * but I can't be bothered with crazy data structures + * at the moment - fix it up later + */ + +bool p3GxsChannels::getPostData(const uint32_t &token, std::vector &msgs) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsChannelPostItem* item = dynamic_cast(*vit); + + if(item) + { + RsGxsChannelPost msg = item->mMsg; + msg.mMeta = item->meta; + msgs.push_back(msg); + delete item; + } + else + { + std::cerr << "Not a GxsChannelPostItem, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + + +bool p3GxsChannels::getRelatedPosts(const uint32_t &token, std::vector &msgs) +{ + GxsMsgRelatedDataMap msgData; + bool ok = RsGenExchange::getMsgRelatedData(token, msgData); + + if(ok) + { + GxsMsgRelatedDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsChannelPostItem* item = dynamic_cast(*vit); + + if(item) + { + /* HACK UNTIL CHRIS FIXES RELATED MSGS in GXS */ + if (item->meta.mMsgId == (mit->first).second) + { + std::cerr << "p3GxsChannels::getRelatedPosts()"; + std::cerr << " ERROR Found Original - discarding"; + std::cerr << " Id: " << item->meta.mMsgId; + std::cerr << std::endl; + delete item; + continue; + } + + if (item->meta.mParentId != (mit->first).second) + { + std::cerr << "p3GxsChannels::getRelatedPosts()"; + std::cerr << " ERROR Found !CHILD - discarding"; + std::cerr << " Id: " << item->meta.mMsgId; + std::cerr << std::endl; + delete item; + continue; + } + + RsGxsChannelPost msg = item->mMsg; + msg.mMeta = item->meta; + msgs.push_back(msg); + delete item; + } + else + { + std::cerr << "Not a GxsChannelPostItem, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + + +/********************************************************************************************/ + +bool p3GxsChannels::createGroup(uint32_t &token, RsGxsChannelGroup &group) +{ + std::cerr << "p3GxsChannels::createGroup()" << std::endl; + + RsGxsChannelGroupItem* grpItem = new RsGxsChannelGroupItem(); + grpItem->mGroup = group; + grpItem->meta = group.mMeta; + + RsGenExchange::publishGroup(token, grpItem); + return true; +} + + +bool p3GxsChannels::createPost(uint32_t &token, RsGxsChannelPost &msg) +{ + std::cerr << "p3GxsChannels::createChannelPost() GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + + RsGxsChannelPostItem* msgItem = new RsGxsChannelPostItem(); + msgItem->mMsg = msg; + msgItem->meta = msg.mMeta; + + RsGenExchange::publishMsg(token, msgItem); + return true; +} + + +/********************************************************************************************/ +/********************************************************************************************/ + +void p3GxsChannels::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) +{ + uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNREAD | GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; + uint32_t status = GXS_SERV::GXS_MSG_STATUS_UNREAD; + if (read) + { + status = 0; + } + + setMsgStatusFlags(token, msgId, status, mask); + +} + +/********************************************************************************************/ +/********************************************************************************************/ + +/* so we need the same tick idea as wiki for generating dummy channels + */ + +#define MAX_GEN_GROUPS 5 +#define MAX_GEN_MESSAGES 100 + +std::string p3GxsChannels::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +bool p3GxsChannels::generateDummyData() +{ + mGenCount = 0; + mGenRefs.resize(MAX_GEN_MESSAGES); + + std::string groupName; + rs_sprintf(groupName, "TestChannel_%d", mGenCount); + + std::cerr << "p3GxsChannels::generateDummyData() Starting off with Group: " << groupName; + std::cerr << std::endl; + + /* create a new group */ + generateGroup(mGenToken, groupName); + + mGenActive = true; + + return true; +} + + +void p3GxsChannels::dummy_tick() +{ + /* check for a new callback */ + + if (mGenActive) + { + std::cerr << "p3GxsChannels::dummyTick() AboutActive"; + std::cerr << std::endl; + + uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken); + if (status != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::cerr << "p3GxsChannels::dummy_tick() Status: " << status; + std::cerr << std::endl; + + if (status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + { + std::cerr << "p3GxsChannels::dummy_tick() generateDummyMsgs() FAILED"; + std::cerr << std::endl; + mGenActive = false; + } + return; + } + + if (mGenCount < MAX_GEN_GROUPS) + { + /* get the group Id */ + RsGxsGroupId groupId; + RsGxsMessageId emptyId; + if (!acknowledgeTokenGrp(mGenToken, groupId)) + { + std::cerr << " ERROR "; + std::cerr << std::endl; + mGenActive = false; + return; + } + + std::cerr << "p3GxsChannels::dummy_tick() Acknowledged GroupId: " << groupId; + std::cerr << std::endl; + + ChannelDummyRef ref(groupId, emptyId, emptyId); + mGenRefs[mGenCount] = ref; + } + else if (mGenCount < MAX_GEN_MESSAGES) + { + /* get the msg Id, and generate next snapshot */ + RsGxsGrpMsgIdPair msgId; + if (!acknowledgeTokenMsg(mGenToken, msgId)) + { + std::cerr << " ERROR "; + std::cerr << std::endl; + mGenActive = false; + return; + } + + std::cerr << "p3GxsChannels::dummy_tick() Acknowledged "; + std::cerr << std::endl; + + /* store results for later selection */ + + ChannelDummyRef ref(msgId.first, mGenThreadId, msgId.second); + mGenRefs[mGenCount] = ref; + } + else + { + std::cerr << "p3GxsChannels::dummy_tick() Finished"; + std::cerr << std::endl; + + /* done */ + mGenActive = false; + return; + } + + mGenCount++; + + if (mGenCount < MAX_GEN_GROUPS) + { + std::string groupName; + rs_sprintf(groupName, "TestChannel_%d", mGenCount); + + std::cerr << "p3GxsChannels::dummy_tick() Generating Group: " << groupName; + std::cerr << std::endl; + + /* create a new group */ + generateGroup(mGenToken, groupName); + } + else + { + /* create a new message */ + uint32_t idx = (uint32_t) (mGenCount * RSRandom::random_f32()); + ChannelDummyRef &ref = mGenRefs[idx]; + + RsGxsGroupId grpId = ref.mGroupId; + RsGxsMessageId parentId = ref.mMsgId; + mGenThreadId = ref.mThreadId; + if (mGenThreadId.empty()) + { + mGenThreadId = parentId; + } + + std::cerr << "p3GxsChannels::dummy_tick() Generating Msg ... "; + std::cerr << " GroupId: " << grpId; + std::cerr << " ThreadId: " << mGenThreadId; + std::cerr << " ParentId: " << parentId; + std::cerr << std::endl; + + if (parentId.empty()) + { + generatePost(mGenToken, grpId); + } + else + { + generateComment(mGenToken, grpId, parentId, mGenThreadId); + } + } + } +} + + +bool p3GxsChannels::generatePost(uint32_t &token, const RsGxsGroupId &grpId) +{ + RsGxsChannelPost msg; + + std::string rndId = genRandomId(); + + rs_sprintf(msg.mMsg, "Channel Msg: GroupId: %s, some randomness: %s", + grpId.c_str(), rndId.c_str()); + + msg.mMeta.mMsgName = msg.mMsg; + + msg.mMeta.mGroupId = grpId; + msg.mMeta.mThreadId = ""; + msg.mMeta.mParentId = ""; + + msg.mMeta.mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD; + + createPost(token, msg); + + return true; +} + + +bool p3GxsChannels::generateComment(uint32_t &token, const RsGxsGroupId &grpId, const RsGxsMessageId &parentId, const RsGxsMessageId &threadId) +{ + RsGxsComment msg; + + std::string rndId = genRandomId(); + + rs_sprintf(msg.mComment, "Channel Comment: GroupId: %s, ThreadId: %s, ParentId: %s + some randomness: %s", + grpId.c_str(), threadId.c_str(), parentId.c_str(), rndId.c_str()); + + msg.mMeta.mMsgName = msg.mComment; + + msg.mMeta.mGroupId = grpId; + msg.mMeta.mThreadId = threadId; + msg.mMeta.mParentId = parentId; + + msg.mMeta.mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD; + + /* chose a random Id to sign with */ + std::list ownIds; + std::list::iterator it; + + rsIdentity->getOwnIds(ownIds); + + uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32()); + int i = 0; + for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++); + + if (it != ownIds.end()) + { + std::cerr << "p3GxsChannels::generateMessage() Author: " << *it; + std::cerr << std::endl; + msg.mMeta.mAuthorId = *it; + } + else + { + std::cerr << "p3GxsChannels::generateMessage() No Author!"; + std::cerr << std::endl; + } + + createComment(token, msg); + + return true; +} + + +bool p3GxsChannels::generateGroup(uint32_t &token, std::string groupName) +{ + /* generate a new channel */ + RsGxsChannelGroup channel; + channel.mMeta.mGroupName = groupName; + + createGroup(token, channel); + + return true; +} + + + // Overloaded from RsTickEvent for Event callbacks. +void p3GxsChannels::handle_event(uint32_t event_type, const std::string &elabel) +{ + std::cerr << "p3GxsChannels::handle_event(" << event_type << ")"; + std::cerr << std::endl; + + // stuff. + switch(event_type) + { + case CHANNEL_TESTEVENT_DUMMYDATA: + generateDummyData(); + break; + + default: + /* error */ + std::cerr << "p3GxsChannels::handle_event() Unknown Event Type: " << event_type; + std::cerr << std::endl; + break; + } +} + diff --git a/libretroshare/src/services/p3gxschannels.h b/libretroshare/src/services/p3gxschannels.h new file mode 100644 index 000000000..452ffc052 --- /dev/null +++ b/libretroshare/src/services/p3gxschannels.h @@ -0,0 +1,145 @@ +/* + * libretroshare/src/services: p3gxschannels.h + * + * GxsChannel interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * 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 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". + * + */ + +#ifndef P3_GXSCHANNELS_SERVICE_HEADER +#define P3_GXSCHANNELS_SERVICE_HEADER + + +#include "retroshare/rsgxschannels.h" +#include "services/p3gxscommon.h" +#include "gxs/rsgenexchange.h" + +#include "util/rstickevent.h" + +#include +#include + +/* + * + */ + +class p3GxsChannels: public RsGenExchange, public RsGxsChannels, + public RsTickEvent /* only needed for testing - remove after */ +{ + public: + + p3GxsChannels(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs); + +virtual void service_tick(); + + protected: + + +virtual void notifyChanges(std::vector& changes); + + // Overloaded from RsTickEvent. +virtual void handle_event(uint32_t event_type, const std::string &elabel); + + public: + +virtual bool getGroupData(const uint32_t &token, std::vector &groups); +virtual bool getPostData(const uint32_t &token, std::vector &posts); + +virtual bool getRelatedPosts(const uint32_t &token, std::vector &posts); + + ////////////////////////////////////////////////////////////////////////////// +virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read); + +//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); +//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); + +//virtual bool groupRestoreKeys(const std::string &groupId); +//virtual bool groupShareKeys(const std::string &groupId, std::list& peers); + +virtual bool createGroup(uint32_t &token, RsGxsChannelGroup &group); +virtual bool createPost(uint32_t &token, RsGxsChannelPost &post); + + + + /* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */ +virtual bool getCommentData(const uint32_t &token, std::vector &msgs) + { + return mCommentService->getGxsCommentData(token, msgs); + } + +virtual bool getRelatedComments(const uint32_t &token, std::vector &msgs) + { + return mCommentService->getGxsRelatedComments(token, msgs); + } + +virtual bool createComment(uint32_t &token, RsGxsComment &msg) + { + return mCommentService->createGxsComment(token, msg); + } + +virtual bool createVote(uint32_t &token, RsGxsVote &msg) + { + return mCommentService->createGxsVote(token, msg); + } + +virtual bool acknowledgeComment(const uint32_t& token, std::pair& msgId) + { + return acknowledgeMsg(token, msgId); + } + + private: + +static uint32_t channelsAuthenPolicy(); + + +// DUMMY DATA, +virtual bool generateDummyData(); + +std::string genRandomId(); + +void dummy_tick(); + +bool generatePost(uint32_t &token, const RsGxsGroupId &grpId); +bool generateComment(uint32_t &token, const RsGxsGroupId &grpId, + const RsGxsMessageId &parentId, const RsGxsMessageId &threadId); +bool generateGroup(uint32_t &token, std::string groupName); + + class ChannelDummyRef + { + public: + ChannelDummyRef() { return; } + ChannelDummyRef(const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, const RsGxsMessageId &msgId) + :mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) { return; } + + RsGxsGroupId mGroupId; + RsGxsMessageId mThreadId; + RsGxsMessageId mMsgId; + }; + + uint32_t mGenToken; + bool mGenActive; + int mGenCount; + std::vector mGenRefs; + RsGxsMessageId mGenThreadId; + + p3GxsCommentService *mCommentService; +}; + +#endif diff --git a/libretroshare/src/services/p3gxscommon.cc b/libretroshare/src/services/p3gxscommon.cc new file mode 100644 index 000000000..fba4cf6dd --- /dev/null +++ b/libretroshare/src/services/p3gxscommon.cc @@ -0,0 +1,279 @@ +/* + * libretroshare/src/services p3gxscommon.cc + * + * GxsChannels interface for RetroShare. + * + * Copyright 2012-2013 by Robert Fernie. + * + * 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 "retroshare/rsgxscommon.h" +#include "services/p3gxscommon.h" +#include "serialiser/rsgxscommentitems.h" + +#include + + +RsGxsComment::RsGxsComment() +{ + mUpVotes = 0; + mDownVotes = 0; + score = 0; +} + +RsGxsImage::RsGxsImage() +{ + mData = NULL; + mSize = 0; +} + + +RsGxsFile::RsGxsFile() +{ + mSize = 0; +} + +RsGxsVote::RsGxsVote() +{ + mVoteType = 0; +} + + +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + +p3GxsCommentService::p3GxsCommentService(RsGenExchange *exchange, uint32_t service_type) + : mExchange(exchange), mServiceType(service_type) +{ + return; +} + +bool p3GxsCommentService::getGxsCommentData(const uint32_t &token, std::vector &comments) +{ + GxsMsgDataMap msgData; + bool ok = mExchange->getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + std::multimap voteMap; + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + /* now split into Comments and Votes */ + + for(; vit != msgItems.end(); vit++) + { + RsGxsCommentItem* item = dynamic_cast(*vit); + + if(item) + { + RsGxsComment comment = item->mMsg; + comment.mMeta = item->meta; + comments.push_back(comment); + delete item; + } + else + { + RsGxsVoteItem* vote = dynamic_cast(*vit); + if (vote) + { + voteMap.insert(std::make_pair(vote->meta.mParentId, vote)); + } + else + { + std::cerr << "Not a Comment or Vote, deleting!" << std::endl; + delete *vit; + } + } + } + } + + /* now iterate through comments - and set the vote counts */ + std::vector::iterator cit; + std::multimap::iterator it; + for(cit = comments.begin(); cit != comments.end(); cit++) + { + for (it = voteMap.lower_bound(cit->mMeta.mMsgId); it != voteMap.upper_bound(cit->mMeta.mMsgId); it++) + { + if (it->second->mMsg.mVoteType == GXS_VOTE_UP) + { + cit->mUpVotes++; + } + else + { + cit->mDownVotes++; + } + } + } + /* delete the votes */ + for (it = voteMap.begin(); it != voteMap.end(); it++) + { + delete it->second; + } + } + + return ok; +} + + +bool p3GxsCommentService::getGxsRelatedComments(const uint32_t &token, std::vector &comments) +{ + GxsMsgRelatedDataMap msgData; + bool ok = mExchange->getMsgRelatedData(token, msgData); + + if(ok) + { + GxsMsgRelatedDataMap::iterator mit = msgData.begin(); + std::multimap voteMap; + + for(; mit != msgData.end(); mit++) + { + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsCommentItem* item = dynamic_cast(*vit); + + if(item) + { + /* HACK UNTIL CHRIS FIXES RELATED MSGS in GXS */ + if (item->meta.mMsgId == (mit->first).second) + { + std::cerr << "p3GxsChannels::getRelatedComments()"; + std::cerr << " ERROR Found Original - discarding"; + std::cerr << " Id: " << item->meta.mMsgId; + std::cerr << std::endl; + delete item; + continue; + } + + if (item->meta.mParentId != (mit->first).second) + { + std::cerr << "p3GxsChannels::getRelatedComments()"; + std::cerr << " ERROR Found !CHILD - discarding"; + std::cerr << " Id: " << item->meta.mMsgId; + std::cerr << std::endl; + delete item; + continue; + } + + RsGxsComment comment = item->mMsg; + comment.mMeta = item->meta; + comments.push_back(comment); + delete item; + } + else + { + RsGxsVoteItem* vote = dynamic_cast(*vit); + if (vote) + { + voteMap.insert(std::make_pair(vote->meta.mParentId, vote)); + } + else + { + std::cerr << "Not a Comment or Vote, deleting!" << std::endl; + delete *vit; + } + } + } + } + + /* now iterate through comments - and set the vote counts */ + std::vector::iterator cit; + std::multimap::iterator it; + for(cit = comments.begin(); cit != comments.end(); cit++) + { + for (it = voteMap.lower_bound(cit->mMeta.mMsgId); it != voteMap.upper_bound(cit->mMeta.mMsgId); it++) + { + if (it->second->mMsg.mVoteType == GXS_VOTE_UP) + { + cit->mUpVotes++; + } + else + { + cit->mDownVotes++; + } + } + } + /* delete the votes */ + for (it = voteMap.begin(); it != voteMap.end(); it++) + { + delete it->second; + } + } + + return ok; +} + +/********************************************************************************************/ + +bool p3GxsCommentService::createGxsComment(uint32_t &token, RsGxsComment &msg) +{ + std::cerr << "p3GxsChannels::createGxsComment() GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + + RsGxsCommentItem* msgItem = new RsGxsCommentItem(mServiceType); + msgItem->mMsg = msg; + msgItem->meta = msg.mMeta; + + mExchange->publishMsg(token, msgItem); + return true; +} + + +bool p3GxsCommentService::createGxsVote(uint32_t &token, RsGxsVote &msg) +{ + std::cerr << "p3GxsChannels::createGxsVote() GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + + RsGxsVoteItem* msgItem = new RsGxsVoteItem(mServiceType); + msgItem->mMsg = msg; + msgItem->meta = msg.mMeta; + + mExchange->publishMsg(token, msgItem); + return true; +} + + +/********************************************************************************************/ +/********************************************************************************************/ + +#if 0 +void p3GxsCommentService::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) +{ + uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNREAD | GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; + uint32_t status = GXS_SERV::GXS_MSG_STATUS_UNREAD; + if (read) + { + status = 0; + } + + setMsgStatusFlags(token, msgId, status, mask); + +} + +#endif + diff --git a/libretroshare/src/services/p3gxscommon.h b/libretroshare/src/services/p3gxscommon.h new file mode 100644 index 000000000..6130d6cc8 --- /dev/null +++ b/libretroshare/src/services/p3gxscommon.h @@ -0,0 +1,59 @@ +/* + * libretroshare/src/services p3gxscommon.cc + * + * GxsChannels interface for RetroShare. + * + * Copyright 2012-2013 by Robert Fernie. + * + * 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 "retroshare/rsgxscommon.h" +#include "gxs/rsgenexchange.h" +#include + + +/**** + * This mirrors rsGxsCommentService, with slightly different names, + * provides the implementation for any services requiring Comments. + */ + +class p3GxsCommentService +{ + public: + + p3GxsCommentService(RsGenExchange *exchange, uint32_t service_type); + + bool getGxsCommentData(const uint32_t &token, std::vector &msgs); + bool getGxsRelatedComments(const uint32_t &token, std::vector &msgs); + + bool createGxsComment(uint32_t &token, RsGxsComment &msg); + bool createGxsVote(uint32_t &token, RsGxsVote &msg); + +#if 0 + void setGxsMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read); +#endif + + private: + + RsGenExchange *mExchange; + uint32_t mServiceType; +}; + + + diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 4d24754b5..507b93f1a 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -67,19 +67,16 @@ p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *ne uint32_t p3GxsForums::forumsAuthenPolicy() { uint32_t policy; - uint32_t flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN | - GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; + uint32_t flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN | + GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, - RsGenExchange::RESTRICTED_GRP_BITS); - - RsGenExchange::setAuthenPolicyFlag(flag, policy, - RsGenExchange::PUBLIC_GRP_BITS); - - RsGenExchange::setAuthenPolicyFlag(flag, policy, - RsGenExchange::PRIVATE_GRP_BITS); - return policy; + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); + RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); + return policy; } + + void p3GxsForums::notifyChanges(std::vector &changes) { RsGxsIfaceHelper::receiveChanges(changes);