diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index abe39f363..bfcee886c 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -105,7 +105,6 @@ class RsGeneralDataService public: - static const std::string MSG_META_SERV_STRING; static const std::string MSG_META_STATUS; diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 5712bf4f6..da2153171 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -47,6 +47,8 @@ #define PRIV_GRP_OFFSET 16 #define GRP_OPTIONS_OFFSET 24 +#define GXS_MASK "GXS_MASK_HACK" + #define GEN_EXCH_DEBUG 1 RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns, @@ -986,6 +988,7 @@ void RsGenExchange::setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& GrpLocMetaData g; g.grpId = grpId; g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, (int32_t)flag); + g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location mGrpLocMetaMap.insert(std::make_pair(token, g)); } @@ -998,6 +1001,7 @@ void RsGenExchange::setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grp GrpLocMetaData g; g.grpId = grpId; g.val.put(RsGeneralDataService::GRP_META_STATUS, (int32_t)status); + g.val.put(RsGeneralDataService::GRP_META_STATUS+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location mGrpLocMetaMap.insert(std::make_pair(token, g)); } @@ -1021,6 +1025,7 @@ void RsGenExchange::setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& MsgLocMetaData m; m.val.put(RsGeneralDataService::MSG_META_STATUS, (int32_t)status); + m.val.put(RsGeneralDataService::MSG_META_STATUS+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location m.msgId = msgId; mMsgLocMetaMap.insert(std::make_pair(token, m)); } @@ -1047,7 +1052,43 @@ void RsGenExchange::processMsgMetaChanges() for(; mit != mit_end; mit++) { MsgLocMetaData& m = mit->second; - bool ok = mDataStore->updateMessageMetaData(m) == 1; + + int32_t value, mask; + bool ok = true; + + // for meta flag changes get flag to apply mask + if(m.val.getAsInt32(RsGeneralDataService::MSG_META_STATUS, value)) + { + ok = false; + if(m.val.getAsInt32(RsGeneralDataService::MSG_META_STATUS+GXS_MASK, mask)) + { + GxsMsgReq req; + std::vector msgIdV; + msgIdV.push_back(m.msgId.second); + req.insert(std::make_pair(m.msgId.first, msgIdV)); + GxsMsgMetaResult result; + mDataStore->retrieveGxsMsgMetaData(req, result); + GxsMsgMetaResult::iterator mit = result.find(m.msgId.first); + + if(mit != result.end()) + { + std::vector& msgMetaV = mit->second; + + if(!msgMetaV.empty()) + { + RsGxsMsgMetaData* meta = *(msgMetaV.begin()); + value = (meta->mMsgStatus & ~mask) | (mask & value); + m.val.put(RsGeneralDataService::MSG_META_STATUS, value); + delete meta; + ok = true; + } + } + m.val.removeKeyValue(RsGeneralDataService::MSG_META_STATUS+GXS_MASK); + } + } + + + ok &= mDataStore->updateMessageMetaData(m) == 1; uint32_t token = mit->first; if(ok) @@ -1074,7 +1115,11 @@ void RsGenExchange::processGrpMetaChanges() { GrpLocMetaData& g = mit->second; uint32_t token = mit->first; - bool ok = mDataStore->updateGroupMetaData(g) == 1; + + // process mask + bool ok = processGrpMask(g.grpId, g.val); + + ok &= mDataStore->updateGroupMetaData(g) == 1; if(ok) { @@ -1089,6 +1134,59 @@ void RsGenExchange::processGrpMetaChanges() mGrpLocMetaMap.clear(); } +bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpCv) +{ + // first find out which mask is involved + int32_t value, mask, currValue; + std::string key; + RsGxsGrpMetaData* grpMeta = NULL; + bool ok = false; + + + std::map grpMetaMap; + std::map::iterator mit; + grpMetaMap.insert(std::make_pair(grpId, (RsGxsGrpMetaData*)(NULL))); + + mDataStore->retrieveGxsGrpMetaData(grpMetaMap); + + if((mit = grpMetaMap.find(grpId)) != grpMetaMap.end()) + { + grpMeta = mit->second; + ok = true; + } + + if(grpCv.getAsInt32(RsGeneralDataService::GRP_META_STATUS, value)) + { + key = RsGeneralDataService::GRP_META_STATUS; + currValue = grpMeta->mGroupStatus; + } + else if(grpCv.getAsInt32(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, value)) + { + key = RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG; + currValue = grpMeta->mSubscribeFlags; + }else + { + if(grpMeta) + delete grpMeta; + return true; + } + + ok &= grpCv.getAsInt32(key+GXS_MASK, mask); + + // remove mask entry so it doesn't affect + grpCv.removeKeyValue(key+GXS_MASK); + + // apply mask to current value + value = (currValue & ~mask) | (value & mask); + + grpCv.put(key, value); + + if(grpMeta) + delete grpMeta; + + return ok; +} + void RsGenExchange::publishMsgs() { RsStackMutex stack(mGenMtx); @@ -1487,6 +1585,7 @@ void RsGenExchange::processRecvdMessages() if(ok) { + meta->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD; msgs.insert(std::make_pair(msg, meta)); msgIds[msg->grpId].push_back(msg->msgId); } @@ -1540,6 +1639,7 @@ void RsGenExchange::processRecvdGroups() if(ok) { + meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD; grps.insert(std::make_pair(grp, meta)); grpIds.push_back(grp->grpId); } diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 0efd32343..06df6ba9e 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -430,6 +430,8 @@ protected: * as it is called by the backend GXS system to \n * update client of changes which should \n * instigate client to retrieve new content from the system + * Note! For newly received message and groups, bit 0xf00 is set to + * GXS_SERV::GXS_MSG_STATUS_UNPROCESSED and GXS_SERV::GXS_MSG_STATUS_UNREAD * @param changes the changes that have occured to data held by this service */ virtual void notifyChanges(std::vector& changes) = 0; @@ -459,6 +461,13 @@ private: */ void processGrpMetaChanges(); + /*! + * Convenience function for properly applying masks for status and subscribe flag + * of a group. + * @warning mask entry is removed from grpCv + */ + bool processGrpMask(const RsGxsGroupId& grpId, ContentValue& grpCv); + /*! * This completes the creation of an instance on RsNxsGrp * by assigning it a groupId and signature via SHA1 and EVP_sign respectively \n diff --git a/libretroshare/src/gxs/rsgxsflags.h b/libretroshare/src/gxs/rsgxsflags.h index ba352171b..3b4d22897 100644 --- a/libretroshare/src/gxs/rsgxsflags.h +++ b/libretroshare/src/gxs/rsgxsflags.h @@ -93,6 +93,14 @@ namespace GXS_SERV { /** END GXS Msg status flags **/ + /** START GXS Grp status flags **/ + + static const uint32_t GXS_GRP_STATUS_UNPROCESSED = 0x000000100; + + static const uint32_t GXS_GRP_STATUS_UNREAD = 0x00000200; + + /** END GXS Grp status flags **/ + } diff --git a/libretroshare/src/serialiser/rsgxsitems.h b/libretroshare/src/serialiser/rsgxsitems.h index 151219c2c..2726e21b9 100644 --- a/libretroshare/src/serialiser/rsgxsitems.h +++ b/libretroshare/src/serialiser/rsgxsitems.h @@ -46,6 +46,7 @@ public: mPop = 0; mMsgCount = 0; mLastPost = 0; + mGroupStatus = 0; //mPublishTs = 0; @@ -86,6 +87,7 @@ public: { mPublishTs = 0; mMsgFlags = 0; + mMsgStatus = 0; mChildTs = 0; } diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index d02bab577..3a2e14e53 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -3,6 +3,9 @@ #include "gxs/rsdataservice.h" #include "gxs/rsgxsflags.h" +#define TEST_FLAG 0x00004; +#define TEST_MASK 0x0000f; + GenExchangeTester::GenExchangeTester() : mGenTestMutex("genTest") { @@ -277,7 +280,6 @@ bool GenExchangeTester::testGrpMetaRetrieval() opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - std::list grpIds; mTokenService->requestGroupInfo(token, 0, opts); pollForToken(token, opts); @@ -372,6 +374,8 @@ bool GenExchangeTester::testGrpMetaModRequest() init(dgrp1); init(dgrp2); init(dgrp3); + dgrp1->meta.mSubscribeFlags = 0; + dgrp1->meta.mGroupStatus = 0; uint32_t token; RsTokReqOptions opts; @@ -397,8 +401,9 @@ bool GenExchangeTester::testGrpMetaModRequest() bool ok = true; std::string newServiceString; - uint32_t newGrpStatus = randNum(); - uint32_t newSubscribeGrpFlag = randNum(); + uint32_t newGrpStatus = TEST_FLAG; + uint32_t newSubscribeGrpFlag = TEST_FLAG; + uint32_t testMask = TEST_MASK; randString(SHORT_STR, newServiceString); // mod service flag for first grp @@ -406,11 +411,11 @@ bool GenExchangeTester::testGrpMetaModRequest() pollForToken(token, opts); ok = mTestService->acknowledgeTokenGrp(token, grpId); - mTestService->setGroupStatusFlagTS(token, grpIds[0], newGrpStatus); + mTestService->setGroupStatusFlagTS(token, grpIds[0], newGrpStatus, testMask); pollForToken(token, opts); ok = mTestService->acknowledgeTokenGrp(token, grpId); - mTestService->setGroupSubscribeFlagTS(token, grpIds[0], newSubscribeGrpFlag); + mTestService->setGroupSubscribeFlagTS(token, grpIds[0], newSubscribeGrpFlag, testMask); pollForToken(token, opts); ok = mTestService->acknowledgeTokenGrp(token, grpId); @@ -432,10 +437,10 @@ bool GenExchangeTester::testGrpMetaModRequest() if(meta.mServiceString != newServiceString) ok = false; - if(meta.mSubscribeFlags != newSubscribeGrpFlag) + if(!(meta.mSubscribeFlags & newSubscribeGrpFlag)) ok = false; - if(meta.mGroupStatus != newGrpStatus) + if(!(meta.mGroupStatus & newGrpStatus)) ok = false; @@ -475,6 +480,7 @@ bool GenExchangeTester::testMsgMetaModRequest() uint32_t token; RsDummyMsg* msgOut = new RsDummyMsg(); *msgOut = *msg; + msg->meta.mMsgStatus = 0; mTestService->publishDummyMsg(token, msg); // poll will block until found @@ -499,9 +505,10 @@ bool GenExchangeTester::testMsgMetaModRequest() mTestService->acknowledgeTokenMsg(token, msgId); - uint32_t newStatus = 2; + uint32_t newStatus = TEST_FLAG; + uint32_t testMask = TEST_MASK; // first modify service string - mTestService->setMsgStatusFlagTS(token, msgId, newStatus); + mTestService->setMsgStatusFlagTS(token, msgId, newStatus, testMask); pollForToken(token, opts); mTestService->acknowledgeTokenMsg(token, msgId); @@ -539,7 +546,7 @@ bool GenExchangeTester::testMsgMetaModRequest() if(meta.mServiceString != newServiceString) ok &= false; - if(meta.mMsgStatus != newStatus) + if(!(meta.mMsgStatus & newStatus)) ok &= false; diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.cpp b/libretroshare/src/tests/gxs/genexchangetestservice.cpp index f8858bb64..7e8b69957 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.cpp +++ b/libretroshare/src/tests/gxs/genexchangetestservice.cpp @@ -67,14 +67,14 @@ void GenExchangeTestService::setGroupServiceStringTS(uint32_t &token, const RsGx RsGenExchange::setGroupServiceString(token, grpId, servString); } -void GenExchangeTestService::setGroupStatusFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status) +void GenExchangeTestService::setGroupStatusFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status, const uint32_t& mask) { - RsGenExchange::setGroupStatusFlags(token, grpId, status, 0xff); + RsGenExchange::setGroupStatusFlags(token, grpId, status, mask); } -void GenExchangeTestService::setGroupSubscribeFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status) +void GenExchangeTestService::setGroupSubscribeFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status, const uint32_t& mask) { - RsGenExchange::setGroupSubscribeFlags(token, grpId, status, 0xff); + RsGenExchange::setGroupSubscribeFlags(token, grpId, status, mask); } void GenExchangeTestService::setMsgServiceStringTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const std::string &servString) @@ -82,9 +82,9 @@ void GenExchangeTestService::setMsgServiceStringTS(uint32_t &token, const RsGxsG RsGenExchange::setMsgServiceString(token, msgId, servString); } -void GenExchangeTestService::setMsgStatusFlagTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const uint32_t &status) +void GenExchangeTestService::setMsgStatusFlagTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const uint32_t &status, const uint32_t& mask) { - RsGenExchange::setMsgStatusFlags(token, msgId, status, 0xff); + RsGenExchange::setMsgStatusFlags(token, msgId, status, mask); } void GenExchangeTestService::service_tick() diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.h b/libretroshare/src/tests/gxs/genexchangetestservice.h index 6cdb2e041..60fa0488b 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.h +++ b/libretroshare/src/tests/gxs/genexchangetestservice.h @@ -76,13 +76,13 @@ public: bool getMsgRelatedDataTS(const uint32_t &token, GxsMsgRelatedDataMap& msgItems); - void setGroupSubscribeFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + void setGroupSubscribeFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); - void setGroupStatusFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + void setGroupStatusFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); void setGroupServiceStringTS(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString); - void setMsgStatusFlagTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status); + void setMsgStatusFlagTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask); void setMsgServiceStringTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 3f572d291..b275df062 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -21,13 +21,13 @@ int main() // CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); // CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); // CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); - CHECK(tester.testMsgRelatedChildDataRetrieval()); REPORT("tester.testMsgRelatedChildDataRetrieval()"); + //CHECK(tester.testMsgRelatedChildDataRetrieval()); REPORT("tester.testMsgRelatedChildDataRetrieval()"); // CHECK(tester.testMsgAllVersions()); REPORT("tester.testMsgAllVersions()"); // CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); -// CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); + // CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); // CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); -// CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); + CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); FINALREPORT("RsGenExchangeTest");