📄 file_messaging.cpp
字号:
// lock file automatically deleted upon return...}static const string COMMAND_END = "### END COMMAND ###";// returns true if some data was read (up to eol) before eofstatic bool ReadSingleLine(CNcbiIfstream& inStream, string *str){ str->erase(); CT_CHAR_TYPE ch; do { ch = inStream.get(); if (inStream.bad() || inStream.fail() || CT_EQ_INT_TYPE(CT_TO_INT_TYPE(ch), CT_EOF)) return false; else if (CT_EQ_INT_TYPE(CT_TO_INT_TYPE(ch), CT_TO_INT_TYPE('\n'))) break; else *str += CT_TO_CHAR_TYPE(ch); } while (1); return true;}// must be called only after lock is established!void FileMessenger::ReceiveCommands(void){ TRACEMSG("receiving commands..."); auto_ptr<CNcbiIfstream> inStream(new ncbi::CNcbiIfstream( messageFile.GetPath().c_str(), IOS_BASE::in)); if (!(*inStream)) { ERRORMSG("cannot open message file for reading!"); return; }#define GET_EXPECTED_LINE \ if (!ReadSingleLine(*inStream, &line)) { \ ERRORMSG("unexpected EOF!"); \ return; \ }#define SKIP_THROUGH_END_OF_COMMAND \ do { \ if (!ReadSingleLine(*inStream, &line)) { \ ERRORMSG("no end-of-command marker found before EOF!"); \ return; \ } \ if (line == COMMAND_END) break; \ } while (1)#define GET_ITEM(ident) \ item = string(ident); \ if (line.substr(0, item.size()) != item) { \ ERRORMSG("Line does not begin with expected '" << item << "'!"); \ return; \ } \ item = line.substr(item.size()); string line, item, from; CommandInfo command; do { // get To: (ignore if not this app) if (!ReadSingleLine(*inStream, &line) || line.size() == 0) { return; } GET_ITEM("To: ") if (item != manager->applicationName) { SKIP_THROUGH_END_OF_COMMAND; continue; } // get From: GET_EXPECTED_LINE GET_ITEM("From: ") from = item; // get ID: GET_EXPECTED_LINE GET_ITEM("ID: ") char *endptr; command.id = strtoul(item.c_str(), &endptr, 10); if (endptr == item.c_str()) { ERRORMSG("Bad " << line << '!'); return; } // get command or reply GET_EXPECTED_LINE if (line.substr(0, 9) != "Command: " && line.substr(0, 7) != "Reply: ") { ERRORMSG("Line does not begin with expected 'Command: ' or 'Reply: '!"); return; } bool isCommand = (line.substr(0, 9) == "Command: "); command.command = line.substr(isCommand ? 9 : 7); // skip commands/replies already read if (isCommand) { CommandOriginators::iterator c = commandsReceived.find(command.id); if (c != commandsReceived.end() && c->second.find(from) != c->second.end()) { SKIP_THROUGH_END_OF_COMMAND; continue; } } else { // reply CommandReplies::iterator r = repliesReceived.find(command.id); if (r != repliesReceived.end() && r->second.find(from) != r->second.end()) { SKIP_THROUGH_END_OF_COMMAND; continue; } } // get data (all lines up to end marker) command.data.erase(); do { GET_EXPECTED_LINE if (line == COMMAND_END) break; command.data += line; command.data += '\n'; } while (1); // process new commands/replies if (isCommand) { commandsReceived[command.id][from] = command.command; TRACEMSG("processing command " << command.id << " from " << from << ": " << command.command); // command received callback responder->ReceivedCommand(from, command.id, command.command, command.data); } else { // reply MessageResponder::ReplyStatus status = MessageResponder::REPLY_ERROR; if (command.command == "OKAY") status = MessageResponder::REPLY_OKAY; else if (command.command != "ERROR") ERRORMSG("Unknown reply status " << command.command << '!'); repliesReceived[command.id][from] = status; TRACEMSG("processing reply " << command.id << " from " << from); // reply received callback responder->ReceivedReply(from, command.id, status, command.data); } } while (1);}// must be called only after lock is established!void FileMessenger::SendPendingCommands(void){ TRACEMSG("sending commands..."); if (pendingCommands.size() == 0) return; auto_ptr<CNcbiOfstream> outStream(new ncbi::CNcbiOfstream( messageFile.GetPath().c_str(), IOS_BASE::out | IOS_BASE::app)); if (!(*outStream)) { ERRORMSG("cannot open message file for writing!"); return; } CommandList::iterator c, ce = pendingCommands.end(); for (c=pendingCommands.begin(); c!=ce; ++c) { // dump the command to the file, noting different syntax for replies bool isReply = (c->command == "OKAY" || c->command == "ERROR"); *outStream << "To: " << c->to << '\n' << "From: " << manager->applicationName << '\n' << "ID: " << c->id << '\n' << (isReply ? "Reply: " : "Command: ") << c->command << '\n'; if (c->data.size() > 0) { *outStream << c->data; if (c->data[c->data.size() - 1] != '\n') // append \n if data doesn't end with one *outStream << '\n'; } *outStream << COMMAND_END << '\n'; outStream->flush(); TRACEMSG("sent " << (isReply ? "reply " : "command ") << c->id << " to " << c->to); } pendingCommands.clear();}FileMessagingManager::FileMessagingManager(const std::string& appName): applicationName(appName){}FileMessagingManager::~FileMessagingManager(void){ FileMessengerList::iterator m, me = messengers.end(); for (m=messengers.begin(); m!=me; ++m) delete *m;}FileMessenger * FileMessagingManager::CreateNewFileMessenger( const std::string& messageFilename, MessageResponder *responderObject, bool readOnly){ if (!responderObject) { ERRORMSG("CreateNewFileMessenger() - got NULL responderObject!"); return NULL; } FileMessenger *newMessenger = new FileMessenger(this, messageFilename, responderObject, readOnly); messengers.push_back(newMessenger); return newMessenger;}void FileMessagingManager::DeleteFileMessenger(FileMessenger *messenger){ FileMessengerList::iterator f, fe = messengers.end(); for (f=messengers.begin(); f!=fe; ++f) { if (*f == messenger) { delete *f; messengers.erase(f); return; } } ERRORMSG("DeleteFileMessenger() - given FileMessenger* not created by this FileMessagingManager!");}void FileMessagingManager::PollMessageFiles(void){ FileMessengerList::iterator f, fe = messengers.end(); for (f=messengers.begin(); f!=fe; ++f) (*f)->PollMessageFile();}END_NCBI_SCOPE/** ---------------------------------------------------------------------------* $Log: file_messaging.cpp,v $* Revision 1000.2 2004/06/01 18:28:37 gouriano* PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11** Revision 1.11 2004/05/21 21:41:39 gorelenk* Added PCH ncbi_pch.hpp** Revision 1.10 2004/03/15 18:25:36 thiessen* prefer prefix vs. postfix ++/-- operators** Revision 1.9 2004/02/19 17:04:56 thiessen* remove cn3d/ from include paths; add pragma to disable annoying msvc warning** Revision 1.8 2003/10/20 23:03:33 thiessen* send pending commands before messenger is destroyed** Revision 1.7 2003/10/02 18:45:22 thiessen* make non-reply message warning only** Revision 1.6 2003/09/22 17:33:12 thiessen* add AlignmentChanged flag; flush message file; check row order of repeats** Revision 1.5 2003/07/10 18:47:29 thiessen* add CDTree->Select command** Revision 1.4 2003/03/19 14:44:36 thiessen* fix char/traits problem** Revision 1.3 2003/03/14 19:22:59 thiessen* add CommandProcessor to handle file-message commands; fixes for GCC 2.9** Revision 1.2 2003/03/13 18:55:04 thiessen* add messenger destroy function** Revision 1.1 2003/03/13 14:26:18 thiessen* add file_messaging module; split cn3d_main_wxwin into cn3d_app, cn3d_glcanvas, structure_window, cn3d_tools**/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -