// We recall messages stored in the database size_t CPartner::Recall( const string& rsClientData, CSocket* poSocket ) { typedef map<string, string> CMapString2String; CMapString2String moQuery; for (string::size_type p1=0, p2=0; string::npos != ( p2 = rsClientData.find('\n', p1) ); p1 = p2+1) { string s = rsClientData.substr(p1, p2-p1); size_t l = s.length(); if ( (l > 2) && (s[1] == ':') ) { if ( l > 4) moQuery[ s.substr(0, 3) ] = s.substr(4); else moQuery[ s.substr(0, 3) ] = ""; } } // for (string::size_type p1=0, p2=0; ... /* client command | send to server | receive from server ====================+==================+==================== list all | l:a | m:<message-id> | | [...] list partially | l:p <message-id> | m:<message-id> | | [...] list mine | l:m | m:<message-id> | | [...] list mine partially | l:y <message-id> | m:<message-id> | | [...] list senders | l:s | s:<sender-id> | | [...] call all | c:a | m:<message-id> | | [...] call MsgID | c:m <message-id> | m:<message-id> | | [<body>] | | [n:<next message-id>] cbsr MsgID | c:s <message-id> | m:<message-id> | | [<body>] | | [n:<next message-id>] */ for ( CMapString2String::iterator itQuery = moQuery.begin(); itQuery != moQuery.end(); ++itQuery) { if ( g_bVerbose) { cout << " * " << itQuery->first; if ( itQuery->second.length() > 0 ) cout << " with " << itQuery->second; cout << "\n"; } CContainerMapByCLUID::iterator it; switch ( itQuery->first[0] ) { case 'l': // list operations switch ( itQuery->first[2] ) { case 'a': // l:a list all if ( g_bVerbose) cout << " * list all \n"; /* 1) get the recipient from the TLS-session 2) resend all message ids for this sender */ for ( it = g_oContainerMapByCLUID.begin(); it != g_oContainerMapByCLUID.end(); ++it ) { *poSocket << it->first << "\n"; } break; case 'p': // l:p list part, beginning with message-id /* 1) get the recipient from the TLS-session 2) resend all message ids for this sender starting with the given message-id */ if ( g_bVerbose) cout << " * list partial, beginning with '" << itQuery->second << "'\n"; for ( it = g_oContainerMapByCLUID.find(itQuery->second); it != g_oContainerMapByCLUID.end(); ++it ) { *poSocket << it->first << "\n"; } break; case 'm': // l:m list mine (sent by me) if ( g_bVerbose) cout << " * list mine\n"; /* 1) get the recipient from the TLS-session 2) resend all message ids from this sender */ break; case 'y': // l:y list mine part, beginning with message-id if ( g_bVerbose) cout << " * list mine partial, beginning with '" << itQuery->second << "'\n"; /* 1) get the recipient from the TLS-session 2) resend all message ids from this sender starting at the given message-id */ break; case 's': // l:s list senders if ( g_bVerbose) cout << " * list senders\n"; /* 1) get the recipient from the TLS-session 2) resend all senders with messages for this recipients */ typedef map<string, bool> CMapString2Bool; CMapString2Bool omSenders; for ( it = g_oContainerMapByCLUID.begin(); it != g_oContainerMapByCLUID.end(); ++it ) { omSenders[ it->second->SenderGet() ] = true; } for ( CMapString2Bool::iterator itSenders = omSenders.begin(); itSenders != omSenders.end(); ++itSenders ) { *poSocket << itSenders->first << "\n"; } break; } // switch ( itQuery->first[2] ) break; // switch ( itQuery->first[0] ) => case 'l' case 'c': // call operations CContainer* poc; CContainer::iterator itc; switch ( itQuery->first[2] ) { case 'a': // c:a = call all if ( g_bVerbose) cout << " * recall all for me\n"; /* 1) get the recipient from the TLS-session 2) resend all messages for the recipient */ for ( it = g_oContainerMapByCLUID.begin(); it != g_oContainerMapByCLUID.end(); ++it ) { poc = it->second; *poSocket << string(1, CContainer::scn_sender) << ":" << poc->SenderGet() << "\n"; *poSocket << it->first << "\n"; for ( itc = poc->begin(); itc != poc->end(); ++itc ) { *poSocket << *itc << "\n"; } // for ( CContainer::iterator itc = poc->begin(); } // for ( it = g_oContainerMapByCLUID.begin(); ... break; // case 'a': // c:a = call all case 'm': // c:m = call message if ( g_bVerbose) cout << " * recall message '" << itQuery->second << "'\n"; /* 1) get the recipient from the TLS-session 2) resend the queried message if its for the recipient 3) resend the next message-id from the same sender (if any) */ it = g_oContainerMapByCLUID.find( itQuery->second ); if ( it != g_oContainerMapByCLUID.end() ) { poc = it->second; *poSocket << string(1, CContainer::scn_sender) << ":" << poc->SenderGet() << "\n"; *poSocket << it->first << "\n"; for ( itc = poc->begin(); itc != poc->end(); ++itc ) { *poSocket << *itc << "\n"; } // for ( CContainer::iterator itc = poc->begin(); // the next message id (has to be filtered for receiver later) if ( ++it != g_oContainerMapByCLUID.end() ) { *poSocket << string(1, CContainer::scn_messageid_next) << ":" << it->first << "\n"; } // if ( ++it != g_oContainerMapByCLUID.end() ) } // if ( it != g_oContainerMapByCLUID.end() ) break; // case 'm': // c:m = call message case 's': // c:s = call message by sender if ( g_bVerbose) cout << " * recall message '" << itQuery->second << "' by sender\n"; /* 1) get the sender from the message-id 2) resend the queried message 3) resend the next message-id from the same sender (if any) */ string sMsgId = itQuery->second; size_t nCut = sMsgId.find( ":" ); if ( nCut != string::npos ) { string sSender = sMsgId.substr(0, nCut); if ( g_bVerbose) cout << " * from sender '" << sSender << "'\n"; for ( it = g_oContainerMapByCLUID.find( itQuery->second ); it != g_oContainerMapByCLUID.end(); ++it ) { poc = it->second; if ( poc->SenderGet() != sSender ) continue; *poSocket << string(1, CContainer::scn_sender) << ":" << poc->SenderGet() << "\n"; *poSocket << it->first << "\n"; for ( itc = poc->begin(); itc != poc->end(); ++itc ) { *poSocket << *itc << "\n"; } // for ( CContainer::iterator itc = poc->begin(); } // for ( it = g_oContainerMapByCLUID.begin(); ... } // if ( nCut != string:npos ) break; // case 's': // c:s = call message by sender } // switch ( itQuery->first[2] ) break; // switch ( itQuery->first[0] ) => case 'c' } // switch ( itQuery->first[0] ) } // for ( CMapString2String::iterator itQuery = moQuery.begin(); return 0; } // size_t CPartner::Recall( ... )