diff --git a/libretroshare/src/services/p3chatservice.cc b/libretroshare/src/services/p3chatservice.cc index ceeb07f2a..aac5b4628 100644 --- a/libretroshare/src/services/p3chatservice.cc +++ b/libretroshare/src/services/p3chatservice.cc @@ -42,7 +42,7 @@ */ p3ChatService::p3ChatService(p3ConnectMgr *cm) - :p3Service(RS_SERVICE_TYPE_CHAT), pqiConfig(CONFIG_TYPE_CHAT), mConnMgr(cm) + :p3Service(RS_SERVICE_TYPE_CHAT), p3Config(CONFIG_TYPE_CHAT), mConnMgr(cm) { addSerialType(new RsChatSerialiser()); @@ -116,12 +116,34 @@ class p3ChatService::AvatarInfo public: AvatarInfo() { + _image_size = 0 ; + _image_data = NULL ; _peer_is_new = false ; // true when the peer has a new avatar _own_is_new = false ; // true when I myself a new avatar to send to this peer. } + ~AvatarInfo() + { + delete[] _image_data ; + _image_data = NULL ; + _image_size = 0 ; + } + + AvatarInfo(const AvatarInfo& ai) + { + init(ai._image_data,ai._image_size) ; + } + + void init(const unsigned char *jpeg_data,int size) + { + _image_size = size ; + _image_data = new unsigned char[size] ; + memcpy(_image_data,jpeg_data,size) ; + } AvatarInfo(const unsigned char *jpeg_data,int size) { + init(jpeg_data,size) ; +#ifdef TO_REMOVE int n_c = size ; int p = 2 ;// minimum value for sizeof(wchar_t) over win/mac/linux ; int n = n_c/p + 1 ; @@ -139,13 +161,42 @@ class p3ChatService::AvatarInfo } _jpeg_wstring[i] = h ; } +#endif } - AvatarInfo(const std::wstring& s) : _jpeg_wstring(s) {} - - const std::wstring& toStdWString() const { return _jpeg_wstring; } - - void toUnsignedChar(unsigned char *& data,int& size) const +#ifdef AVATAR_KEEP_BACKWRD_COMP + AvatarInfo(const std::wstring& s) { + int p = 2 ;// minimum value for sizeof(wchar_t) over win/mac/linux ; + int n = s.size() ; + int n_c = p*n ; + + _image_data = new unsigned char[n_c] ; + _image_size = n_c ; + + for(int i=0;i> 8 ; + } + } + + } +#endif + +#ifdef TO_REMOVE + const std::wstring& toStdWString() const { return _jpeg_wstring; } +#endif + + void toUnsignedChar(unsigned char *& data,uint32_t& size) const + { + data = new unsigned char[_image_size] ; + size = _image_size ; + memcpy(data,_image_data,size*sizeof(unsigned char)) ; +#ifdef TO_REMOVE int p = 2 ;// minimum value for sizeof(wchar_t) over win/mac/linux ; int n = _jpeg_wstring.size() ; int n_c = p*n ; @@ -163,11 +214,16 @@ class p3ChatService::AvatarInfo h = h >> 8 ; } } +#endif } + uint32_t _image_size ; + unsigned char *_image_data ; +#ifdef TO_REMOVE std::wstring _jpeg_wstring; +#endif int _peer_is_new ; // true when the peer has a new avatar - int _own_is_new ; // true when I myself a new avatar to send to this peer. + int _own_is_new ; // true when I myself a new avatar to send to this peer. }; @@ -255,9 +311,19 @@ std::list p3ChatService::getChatQueue() #endif if(ci->chatFlags & RS_CHAT_FLAG_CONTAINS_AVATAR) // no msg here. Just an avatar. - receiveAvatarJpegData(ci) ; + { +#ifdef AVATAR_KEEP_BACKWRD_COMP + receiveAvatarJpegData(ci) ; // Do we keep this for backward compatibility ? +#endif + delete item ; + continue ; + } else if(ci->chatFlags & RS_CHAT_FLAG_REQUESTS_AVATAR) // no msg here. Just an avatar request. + { sendAvatarJpegData(ci->PeerId()) ; + delete item ; + continue ; + } else // normal msg. Return it normally. { // Check if new avatar is available at peer's. If so, send a request to get the avatar. @@ -294,6 +360,16 @@ std::list p3ChatService::getChatQueue() rsicontrol->getNotify().notifyChatStatus(cs->PeerId(),cs->status_string) ; delete item ; + continue ; + } + + RsChatAvatarItem *ca = dynamic_cast(item) ; + + if(ca != NULL) + { + receiveAvatarJpegData(ca) ; + delete item ; + continue ; } } @@ -319,6 +395,8 @@ void p3ChatService::setOwnAvatarJpegData(const unsigned char *data,int size) std::cerr << "p3chatservice:setOwnAvatarJpegData() done." << std::endl ; } +#ifdef AVATAR_KEEP_BACKWRD_COMP +// This one is kept for compatibility void p3ChatService::receiveAvatarJpegData(RsChatMsgItem *ci) { RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ @@ -330,17 +408,34 @@ void p3ChatService::receiveAvatarJpegData(RsChatMsgItem *ci) _avatars[ci->PeerId()]->_peer_is_new = true ; _avatars[ci->PeerId()]->_own_is_new = new_peer ; } +#endif + +void p3ChatService::receiveAvatarJpegData(RsChatAvatarItem *ci) +{ + RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + std::cerr << "p3chatservice: received avatar jpeg data for peer " << ci->PeerId() << ". Storing it." << std::endl ; + + bool new_peer = (_avatars.find(ci->PeerId()) == _avatars.end()) ; + + _avatars[ci->PeerId()] = new AvatarInfo(ci->image_data,ci->image_size) ; + _avatars[ci->PeerId()]->_peer_is_new = true ; + _avatars[ci->PeerId()]->_own_is_new = new_peer ; +} void p3ChatService::getOwnAvatarJpegData(unsigned char *& data,int& size) { // should be a Mutex here. RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + uint32_t s = 0 ; std::cerr << "p3chatservice:: own avatar requested from above. " << std::endl ; // has avatar. Return it strait away. // if(_own_avatar != NULL) - _own_avatar->toUnsignedChar(data,size) ; + { + _own_avatar->toUnsignedChar(data,s) ; + size = s ; + } else { data=NULL ; @@ -359,7 +454,9 @@ void p3ChatService::getAvatarJpegData(const std::string& peer_id,unsigned char * // if(it!=_avatars.end()) { - it->second->toUnsignedChar(data,size) ; + uint32_t s=0 ; + it->second->toUnsignedChar(data,s) ; + size = s ; it->second->_peer_is_new = false ; std::cerr << "Already has avatar. Returning it" << std::endl ; return ; @@ -387,14 +484,21 @@ void p3ChatService::sendAvatarRequest(const std::string& peer_id) sendItem(ci); } -RsChatMsgItem *p3ChatService::makeOwnAvatarItem() +RsChatAvatarItem *p3ChatService::makeOwnAvatarItem() { +#ifdef TO_REMOVE RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ RsChatMsgItem *ci = new RsChatMsgItem(); ci->chatFlags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_CONTAINS_AVATAR ; ci->sendTime = time(NULL); ci->message = _own_avatar->toStdWString() ; +#else + RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + RsChatAvatarItem *ci = new RsChatAvatarItem(); + + _own_avatar->toUnsignedChar(ci->image_data,ci->image_size) ; +#endif return ci ; } @@ -406,12 +510,12 @@ void p3ChatService::sendAvatarJpegData(const std::string& peer_id) if(_own_avatar != NULL) { - RsChatMsgItem *ci = makeOwnAvatarItem(); + RsChatAvatarItem *ci = makeOwnAvatarItem(); ci->PeerId(peer_id); // take avatar, and embed it into a std::wstring. // - std::cerr << "p3ChatService::sending avatar image to peer" << peer_id << ", string size = " << ci->message.size() << std::endl ; + std::cerr << "p3ChatService::sending avatar image to peer" << peer_id << ", image size = " << ci->image_size << std::endl ; std::cerr << std::endl; sendItem(ci) ; @@ -420,89 +524,47 @@ void p3ChatService::sendAvatarJpegData(const std::string& peer_id) std::cerr << "Doing nothing" << std::endl ; } -bool p3ChatService::loadConfiguration(std::string &loadHash) +bool p3ChatService::loadList(std::list load) { - std::list::iterator it; - std::string msgfile = Filename(); - - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsChatSerialiser()); - - BinFileInterface *in = new BinFileInterface(msgfile.c_str(), BIN_FLAGS_READABLE | BIN_FLAGS_HASH_DATA); - pqistore *pa_in = new pqistore(rss, "CHATCONFIG", in, BIN_FLAGS_READABLE); - RsItem *item; - RsChatMsgItem *mitem; - - while((item = pa_in -> GetItem())) + for(std::list::const_iterator it(load.begin());it!=load.end();++it) { - if(NULL != (mitem = dynamic_cast(item))) + RsChatAvatarItem *ai = NULL ; + + if(NULL != (ai = dynamic_cast(*it))) { RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - _own_avatar = new AvatarInfo(mitem->message) ; + _own_avatar = new AvatarInfo(ai->image_data,ai->image_size) ; } - delete item; + delete *it; } - - std::string hashin = in->gethash(); - delete pa_in; - - if (hashin != loadHash) - { - /* big error message! */ - std::cerr << "p3ChatService::loadConfiguration() FAILED! avatar Tampered" << std::endl; - std::string msgfileold = msgfile + ".failed"; - - rename(msgfile.c_str(), msgfileold.c_str()); - - std::cerr << "Moving Old file to: " << msgfileold << std::endl; - std::cerr << "removing dodgey msgs" << std::endl; - - _own_avatar = NULL ; - - setHash(""); - return false; - } - - setHash(hashin); - return true; } -bool p3ChatService::saveConfiguration() +std::list p3ChatService::saveList(bool& cleanup) { + cleanup = true ; /* now we create a pqistore, and stream all the msgs into it */ - std::string msgfile = Filename(); - std::string msgfiletmp = Filename()+".tmp"; - - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsChatSerialiser()); - - BinFileInterface *out = new BinFileInterface(msgfiletmp.c_str(), BIN_FLAGS_WRITEABLE | BIN_FLAGS_HASH_DATA); - pqistore *pa_out = new pqistore(rss, "CHATCONFIG", out, BIN_FLAGS_WRITEABLE); + std::list list ; if(_own_avatar != NULL) { - std::cerr << "Saving avatar config to file " << msgfile << std::endl ; - RsChatMsgItem *ci = makeOwnAvatarItem() ; + RsChatAvatarItem *ci = makeOwnAvatarItem() ; ci->PeerId(mConnMgr->getOwnId()); - if(!pa_out -> SendItem(ci)) - return false ; + list.push_back(ci) ; } + return list; +} - setHash(out->gethash()); - delete pa_out; +RsSerialiser *p3ChatService::setupSerialiser() +{ + RsSerialiser *rss = new RsSerialiser ; + rss->addSerialType(new RsChatSerialiser) ; - if(!RsDirUtil::renameFile(msgfiletmp,msgfile)) - { - getPqiNotify()->AddSysMessage(0, RS_SYS_WARNING, "File rename error", "Error while renaming file " + msgfile) ; - return false ; - } - - return true; + return rss ; } diff --git a/libretroshare/src/services/p3chatservice.h b/libretroshare/src/services/p3chatservice.h index 96ac9879f..acce045fc 100644 --- a/libretroshare/src/services/p3chatservice.h +++ b/libretroshare/src/services/p3chatservice.h @@ -39,7 +39,9 @@ #include "services/p3service.h" #include "pqi/p3connmgr.h" -class p3ChatService: public p3Service, public pqiConfig +#define AVATAR_KEEP_BACKWRD_COMP + +class p3ChatService: public p3Service, public p3Config { public: p3ChatService(p3ConnectMgr *cm); @@ -64,9 +66,10 @@ class p3ChatService: public p3Service, public pqiConfig std::list getChatQueue(); - /*** Overloaded from pqiConfig ****/ - virtual bool loadConfiguration(std::string &loadHash); - virtual bool saveConfiguration(); + /************* from p3Config *******************/ + virtual RsSerialiser *setupSerialiser() ; + virtual std::list saveList(bool& cleanup) ; + virtual bool loadList(std::list load) ; private: RsMutex mChatMtx; @@ -77,12 +80,15 @@ class p3ChatService: public p3Service, public pqiConfig void sendAvatarJpegData(const std::string& peer_id) ; /// Receive the avatar in a chat item, with RS_CHAT_RECEIVE_AVATAR flag. - void receiveAvatarJpegData(RsChatMsgItem *ci) ; +#ifdef AVATAR_KEEP_BACKWRD_COMP + void receiveAvatarJpegData(RsChatMsgItem *ci) ; // old method +#endif + void receiveAvatarJpegData(RsChatAvatarItem *ci) ; // new method /// Sends a request for an avatar to the peer of given id void sendAvatarRequest(const std::string& peer_id) ; - RsChatMsgItem *makeOwnAvatarItem() ; + RsChatAvatarItem *makeOwnAvatarItem() ; p3ConnectMgr *mConnMgr;