Merge pull request #1793 from drbob/fix_photo_group_creation

Update RsPhotoItems and switch Photos to use GxsGroupDialog
This commit is contained in:
csoler 2020-02-15 14:39:55 +01:00 committed by GitHub
commit 93ee9bdd18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 727 additions and 501 deletions

View file

@ -3,7 +3,7 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2008-2012 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright 2008-2020 by Robert Fernie <retroshare@lunamutt.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -26,6 +26,7 @@
#include <string>
#include <list>
#include "rsgxsservice.h"
#include "rsgxscommon.h"
/* The Main Interface Class - for information about your Peers */
class RsPhoto;
@ -37,21 +38,6 @@ extern RsPhoto *rsPhoto;
#define RSPHOTO_MODE_OWN 2
#define RSPHOTO_MODE_REMOTE 3
class RsPhotoThumbnail
{
public:
RsPhotoThumbnail()
:data(NULL), size(0), type("N/A") { return; }
bool deleteImage();
bool copyFrom(const RsPhotoThumbnail &nail);
// Holds Thumbnail image.
uint8_t *data;
uint32_t size;
std::string type;
};
/* If these flags are no set - the Photo inherits values from the Album
*/
@ -96,7 +82,7 @@ class RsPhotoPhoto
int mOrder;
RsPhotoThumbnail mThumbnail;
RsGxsImage mThumbnail;
int mMode;
@ -137,7 +123,7 @@ class RsPhotoAlbum
std::string mHashTags;
RsPhotoThumbnail mThumbnail;
RsGxsImage mThumbnail;
int mMode;

View file

@ -26,39 +26,34 @@
#include "serialiser/rstlvbinary.h"
#include "serialiser/rstypeserializer.h"
#define GXS_PHOTO_SERIAL_DEBUG
RsItem *RsGxsPhotoSerialiser::create_item(uint16_t service, uint8_t item_sub_id) const
{
if(service != RS_SERVICE_GXS_TYPE_PHOTO)
return NULL ;
if(service != RS_SERVICE_GXS_TYPE_PHOTO)
return NULL ;
switch(item_sub_id)
{
case RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM: return new RsGxsPhotoCommentItem() ;
case RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM: return new RsGxsPhotoAlbumItem() ;
case RS_PKT_SUBTYPE_PHOTO_ITEM: return new RsGxsPhotoPhotoItem() ;
default:
return NULL ;
}
switch(item_sub_id)
{
case RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM: return new RsGxsPhotoCommentItem() ;
case RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM: return new RsGxsPhotoPhotoItem() ;
case RS_PKT_SUBTYPE_PHOTO_ITEM: return new RsGxsPhotoAlbumItem() ;
default:
return NULL ;
}
}
void RsGxsPhotoAlbumItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CAPTION, album.mCaption, "mCaption");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CATEGORY, album.mCategory, "mCategory");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR, album.mDescription, "mDescription");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_HASH_TAG, album.mHashTags, "mHashTags");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG, album.mOther, "mOther");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PATH, album.mPhotoPath, "mPhotoPath");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME, album.mPhotographer, "mPhotographer");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DATE, album.mWhen, "mWhen");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_LOCATION, album.mWhere, "mWhere");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PIC_TYPE, album.mThumbnail.type,"mThumbnail.type");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CAPTION, album.mCaption, "mCaption");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CATEGORY, album.mCategory, "mCategory");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR, album.mDescription, "mDescription");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_HASH_TAG, album.mHashTags, "mHashTags");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG, album.mOther, "mOther");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PATH, album.mPhotoPath, "mPhotoPath");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME, album.mPhotographer, "mPhotographer");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DATE, album.mWhen, "mWhen");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_LOCATION, album.mWhere, "mWhere");
RsTlvBinaryDataRef b(RS_SERVICE_GXS_TYPE_PHOTO, album.mThumbnail.data, album.mThumbnail.size);
RsTypeSerializer::serial_process<RsTlvItem>(j, ctx, b, "thumbnail binary data") ;
album.mThumbnail.serial_process(j, ctx);
}
void RsGxsPhotoPhotoItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
@ -70,15 +65,13 @@ void RsGxsPhotoPhotoItem::serial_process(RsGenericSerializer::SerializeJob j,RsG
RsTypeSerializer::serial_process(j, ctx, TLV_TYPE_STR_PIC_AUTH, photo.mPhotographer, "mPhotographer");
RsTypeSerializer::serial_process(j, ctx, TLV_TYPE_STR_DATE, photo.mWhen, "mWhen");
RsTypeSerializer::serial_process(j, ctx, TLV_TYPE_STR_LOCATION, photo.mWhere, "mWhere");
RsTypeSerializer::serial_process(j, ctx, TLV_TYPE_STR_PIC_TYPE, photo.mThumbnail.type, "mThumbnail.type");
RsTlvBinaryDataRef b(RS_SERVICE_GXS_TYPE_PHOTO, photo.mThumbnail.data, photo.mThumbnail.size);
RsTypeSerializer::serial_process<RsTlvItem>(j, ctx, b, "mThumbnail") ;
photo.mThumbnail.serial_process(j, ctx);
}
void RsGxsPhotoCommentItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_COMMENT,comment.mComment,"mComment");
RsTypeSerializer::serial_process<uint32_t>(j,ctx,comment.mCommentFlag,"mCommentFlag");
RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_COMMENT,comment.mComment,"mComment");
RsTypeSerializer::serial_process<uint32_t>(j,ctx,comment.mCommentFlag,"mCommentFlag");
}
void RsGxsPhotoAlbumItem::clear()
@ -92,13 +85,13 @@ void RsGxsPhotoAlbumItem::clear()
album.mPhotographer.clear();
album.mWhen.clear();
album.mWhere.clear();
album.mThumbnail.deleteImage();
album.mThumbnail.clear();
}
void RsGxsPhotoCommentItem::clear()
{
comment.mComment.clear();
comment.mCommentFlag = 0;
comment.mComment.clear();
comment.mCommentFlag = 0;
}
void RsGxsPhotoPhotoItem::clear()
@ -111,5 +104,5 @@ void RsGxsPhotoPhotoItem::clear()
photo.mPhotographer.clear();
photo.mWhen.clear();
photo.mWhere.clear();
photo.mThumbnail.deleteImage();
photo.mThumbnail.clear();
}

View file

@ -26,140 +26,100 @@
RsPhoto *rsPhoto = NULL;
const uint32_t RsPhoto::FLAG_MSG_TYPE_MASK = 0x000f;
const uint32_t RsPhoto::FLAG_MSG_TYPE_MASK = 0x000f;
const uint32_t RsPhoto::FLAG_MSG_TYPE_PHOTO_POST = 0x0001;
const uint32_t RsPhoto::FLAG_MSG_TYPE_PHOTO_COMMENT = 0x0002;
bool RsPhotoThumbnail::copyFrom(const RsPhotoThumbnail &nail)
{
if (data)
{
deleteImage();
}
if ((!nail.data) || (nail.size == 0))
{
return false;
}
size = nail.size;
type = nail.type;
data = (uint8_t *) rs_malloc(size);
if(data == NULL)
return false ;
memcpy(data, nail.data, size);
return true;
}
bool RsPhotoThumbnail::deleteImage()
{
if (data)
{
free(data);
data = NULL;
size = 0;
type.clear();
}
return true;
}
RsPhotoPhoto::RsPhotoPhoto()
:mSetFlags(0), mOrder(0), mMode(0), mModFlags(0)
:mSetFlags(0), mOrder(0), mMode(0), mModFlags(0)
{
return;
return;
}
RsPhotoAlbum::RsPhotoAlbum()
:mMode(0), mSetFlags(0), mModFlags(0)
:mMode(0), mSetFlags(0), mModFlags(0)
{
return;
return;
}
RsPhotoComment::RsPhotoComment()
: mComment(""), mCommentFlag(0) {
: mComment(""), mCommentFlag(0) {
}
RsPhotoComment::RsPhotoComment(const RsGxsPhotoCommentItem &comment)
: mComment(""), mCommentFlag(0) {
: mComment(""), mCommentFlag(0) {
*this = comment.comment;
(*this).mMeta = comment.meta;
*this = comment.comment;
(*this).mMeta = comment.meta;
}
std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo)
{
out << "RsPhotoPhoto [ ";
out << "Title: " << photo.mMeta.mMsgName;
out << "]";
return out;
out << "RsPhotoPhoto [ ";
out << "Title: " << photo.mMeta.mMsgName;
out << "]";
return out;
}
std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album)
{
out << "RsPhotoAlbum [ ";
out << "Title: " << album.mMeta.mGroupName;
out << "]";
return out;
out << "RsPhotoAlbum [ ";
out << "Title: " << album.mMeta.mGroupName;
out << "]";
return out;
}
p3PhotoService::p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs)
: RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXS_TYPE_PHOTO, gixs, photoAuthenPolicy()),
mPhotoMutex(std::string("Photo Mutex"))
: RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXS_TYPE_PHOTO, gixs, photoAuthenPolicy()),
mPhotoMutex(std::string("Photo Mutex"))
{
}
const std::string GXS_PHOTO_APP_NAME = "gxsphoto";
const uint16_t GXS_PHOTO_APP_MAJOR_VERSION = 1;
const uint16_t GXS_PHOTO_APP_MINOR_VERSION = 0;
const uint16_t GXS_PHOTO_MIN_MAJOR_VERSION = 1;
const uint16_t GXS_PHOTO_MIN_MINOR_VERSION = 0;
const uint16_t GXS_PHOTO_APP_MAJOR_VERSION = 1;
const uint16_t GXS_PHOTO_APP_MINOR_VERSION = 0;
const uint16_t GXS_PHOTO_MIN_MAJOR_VERSION = 1;
const uint16_t GXS_PHOTO_MIN_MINOR_VERSION = 0;
RsServiceInfo p3PhotoService::getServiceInfo()
{
return RsServiceInfo(RS_SERVICE_GXS_TYPE_PHOTO,
GXS_PHOTO_APP_NAME,
GXS_PHOTO_APP_MAJOR_VERSION,
GXS_PHOTO_APP_MINOR_VERSION,
GXS_PHOTO_MIN_MAJOR_VERSION,
GXS_PHOTO_MIN_MINOR_VERSION);
return RsServiceInfo(RS_SERVICE_GXS_TYPE_PHOTO,
GXS_PHOTO_APP_NAME,
GXS_PHOTO_APP_MAJOR_VERSION,
GXS_PHOTO_APP_MINOR_VERSION,
GXS_PHOTO_MIN_MAJOR_VERSION,
GXS_PHOTO_MIN_MINOR_VERSION);
}
uint32_t p3PhotoService::photoAuthenPolicy()
{
uint32_t policy = 0;
uint8_t flag = 0;
uint32_t policy = 0;
uint8_t flag = 0;
flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS);
flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS);
flag |= GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS);
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS);
flag |= GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS);
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS);
flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS);
flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS);
return policy;
return policy;
}
bool p3PhotoService::updated()
{
RsStackMutex stack(mPhotoMutex);
RsStackMutex stack(mPhotoMutex);
bool changed = (!mGroupChange.empty() || !mMsgChange.empty());
bool changed = (!mGroupChange.empty() || !mMsgChange.empty());
return changed;
return changed;
}
void p3PhotoService::service_tick()
@ -171,33 +131,34 @@ void p3PhotoService::service_tick()
void p3PhotoService::groupsChanged(std::list<RsGxsGroupId>& grpIds)
{
RsStackMutex stack(mPhotoMutex);
RsStackMutex stack(mPhotoMutex);
while(!mGroupChange.empty())
{
RsGxsGroupChange* gc = mGroupChange.back();
std::list<RsGxsGroupId>& gList = gc->mGrpIdList;
std::list<RsGxsGroupId>::iterator lit = gList.begin();
for(; lit != gList.end(); ++lit)
grpIds.push_back(*lit);
while(!mGroupChange.empty())
{
RsGxsGroupChange* gc = mGroupChange.back();
std::list<RsGxsGroupId>& gList = gc->mGrpIdList;
std::list<RsGxsGroupId>::iterator lit = gList.begin();
for(; lit != gList.end(); ++lit) {
grpIds.push_back(*lit);
}
mGroupChange.pop_back();
delete gc;
}
mGroupChange.pop_back();
delete gc;
}
}
void p3PhotoService::msgsChanged(GxsMsgIdResult& msgs)
{
RsStackMutex stack(mPhotoMutex);
RsStackMutex stack(mPhotoMutex);
while(!mMsgChange.empty())
{
RsGxsMsgChange* mc = mMsgChange.back();
msgs = mc->msgChangeMap;
mMsgChange.pop_back();
delete mc;
}
while(!mMsgChange.empty())
{
RsGxsMsgChange* mc = mMsgChange.back();
msgs = mc->msgChangeMap;
mMsgChange.pop_back();
delete mc;
}
}
@ -210,7 +171,8 @@ RsTokenService* p3PhotoService::getTokenService() {
bool p3PhotoService::getGroupList(const uint32_t& token,
std::list<RsGxsGroupId>& groupIds)
{
return RsGenExchange::getGroupList(token, groupIds);
bool okay = RsGenExchange::getGroupList(token, groupIds);
return okay;
}
@ -225,7 +187,8 @@ bool p3PhotoService::getMsgList(const uint32_t& token,
bool p3PhotoService::getGroupSummary(const uint32_t& token,
std::list<RsGroupMetaData>& groupInfo)
{
return RsGenExchange::getGroupMeta(token, groupInfo);
bool okay = RsGenExchange::getGroupMeta(token, groupInfo);
return okay;
}
@ -306,61 +269,59 @@ bool p3PhotoService::getPhoto(const uint32_t& token, PhotoResult& photos)
bool p3PhotoService::getPhotoComment(const uint32_t &token, PhotoCommentResult &comments)
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); ++mit)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; mit != msgData.end(); ++mit)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); ++vit)
{
RsGxsPhotoCommentItem* item = dynamic_cast<RsGxsPhotoCommentItem*>(*vit);
for(; vit != msgItems.end(); ++vit)
{
RsGxsPhotoCommentItem* item = dynamic_cast<RsGxsPhotoCommentItem*>(*vit);
if(item)
{
RsPhotoComment comment = item->comment;
comment.mMeta = item->meta;
comments[grpId].push_back(comment);
delete item;
}else
{
std::cerr << "Not a comment Item, deleting!" << std::endl;
delete *vit;
}
}
}
}
if(item)
{
RsPhotoComment comment = item->comment;
comment.mMeta = item->meta;
comments[grpId].push_back(comment);
delete item;
}else
{
std::cerr << "Not a comment Item, deleting!" << std::endl;
delete *vit;
}
}
}
}
return ok;
return ok;
}
RsPhotoComment& RsPhotoComment::operator=(const RsGxsPhotoCommentItem& comment)
{
*this = comment.comment;
return *this;
*this = comment.comment;
return *this;
}
bool p3PhotoService::getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments)
{
return RsGenExchange::getMsgRelatedDataT<RsGxsPhotoCommentItem, RsPhotoComment>(token, comments);
return RsGenExchange::getMsgRelatedDataT<RsGxsPhotoCommentItem, RsPhotoComment>(token, comments);
}
bool p3PhotoService::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album)
{
RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem();
albumItem->album = album;
albumItem->meta = album.mMeta;
RsGenExchange::publishGroup(token, albumItem);
return true;
RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem();
albumItem->album = album;
albumItem->meta = album.mMeta;
RsGenExchange::publishGroup(token, albumItem);
return true;
}
@ -368,28 +329,28 @@ bool p3PhotoService::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album)
void p3PhotoService::notifyChanges(std::vector<RsGxsNotify*>& changes)
{
RsStackMutex stack(mPhotoMutex);
RsStackMutex stack(mPhotoMutex);
std::vector<RsGxsNotify*>::iterator vit = changes.begin();
std::vector<RsGxsNotify*>::iterator vit = changes.begin();
for(; vit != changes.end(); ++vit)
{
RsGxsNotify* n = *vit;
RsGxsGroupChange* gc;
RsGxsMsgChange* mc;
if((mc = dynamic_cast<RsGxsMsgChange*>(n)) != NULL)
{
mMsgChange.push_back(mc);
}
else if((gc = dynamic_cast<RsGxsGroupChange*>(n)) != NULL)
{
mGroupChange.push_back(gc);
}
else
{
delete n;
}
}
for(; vit != changes.end(); ++vit)
{
RsGxsNotify* n = *vit;
RsGxsGroupChange* gc;
RsGxsMsgChange* mc;
if((mc = dynamic_cast<RsGxsMsgChange*>(n)) != NULL)
{
mMsgChange.push_back(mc);
}
else if((gc = dynamic_cast<RsGxsGroupChange*>(n)) != NULL)
{
mGroupChange.push_back(gc);
}
else
{
delete n;
}
}
}
bool p3PhotoService::submitPhoto(uint32_t& token, RsPhotoPhoto& photo)
@ -397,21 +358,20 @@ bool p3PhotoService::submitPhoto(uint32_t& token, RsPhotoPhoto& photo)
RsGxsPhotoPhotoItem* photoItem = new RsGxsPhotoPhotoItem();
photoItem->photo = photo;
photoItem->meta = photo.mMeta;
photoItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_POST;
RsGenExchange::publishMsg(token, photoItem);
return true;
RsGenExchange::publishMsg(token, photoItem);
return true;
}
bool p3PhotoService::submitComment(uint32_t &token, RsPhotoComment &comment)
{
RsGxsPhotoCommentItem* commentItem = new RsGxsPhotoCommentItem();
commentItem->comment = comment;
commentItem->meta = comment.mMeta;
commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_COMMENT;
RsGxsPhotoCommentItem* commentItem = new RsGxsPhotoCommentItem();
commentItem->comment = comment;
commentItem->meta = comment.mMeta;
commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_COMMENT;
RsGenExchange::publishMsg(token, commentItem);
return true;
RsGenExchange::publishMsg(token, commentItem);
return true;
}
bool p3PhotoService::acknowledgeMsg(const uint32_t& token,
@ -429,12 +389,12 @@ bool p3PhotoService::acknowledgeGrp(const uint32_t& token,
bool p3PhotoService::subscribeToAlbum(uint32_t &token, const RsGxsGroupId &grpId, bool subscribe)
{
if(subscribe)
RsGenExchange::setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, GXS_SERV::GROUP_SUBSCRIBE_MASK);
else
RsGenExchange::setGroupSubscribeFlags(token, grpId, 0, GXS_SERV::GROUP_SUBSCRIBE_MASK);
if(subscribe)
RsGenExchange::setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, GXS_SERV::GROUP_SUBSCRIBE_MASK);
else
RsGenExchange::setGroupSubscribeFlags(token, grpId, 0, GXS_SERV::GROUP_SUBSCRIBE_MASK);
return true;
return true;
}