///////////////////////////////////////////////////////////////////////// // msgHnd.cpp - message handler, intended for communication // // ver 1.0 between sockets // // // // Language: Visual C++, ver 6.0 // // Platform: Dell Dimension 8100, Windows 2000 Pro, SP1 // // Application: CSE691/791 help // // Author: Jim Fawcett, CST 2-187, Syracuse University // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////////////// #include "msgHnd.h" #include "xmlTran.h" #include "sysUtils.h" ///////////////////////////////////////////////////////////////////////// // message head pattern // Note that size attribute saves 7 digits to hold size, meaning // that you could safely encapsulate up to 9,999,999 bytes in a // message, althought you should never try to send more than a // very few thousand bytes over a socket. // const std::string headPattern = "<#M type=\" \" size=\" \">"; //----< void constructor >------------------------------------- // // constructor builds a finished message, e.g., opening tag // with type and size attributes, body, and end tag are all // part of the message when this function returns // message::message(msgType type, const std::string &myBody) { xmlElem elem(headPattern,myBody); std::string typeStr = TtoStr(type).convert(); elem.elemStr()[10] = typeStr[0]; unsigned int size = (unsigned int)elem.elemStr().size(); std::string sizeStr = TtoStr(size).convert(); int len = sizeStr.size(); for(int i=0; i------------------------------------------- // // Nothing needed here, as the class members all have // correct destruction semantics. message::~message() {} //----< convert message type into string >--------------------- std::string message::typeStr() { switch(_type) { case text : return "text"; case command : return "command"; case request : return "request"; case file : return "file"; default : return "bad type"; } } //----< given head of message, extract its size attribute >---- // // If a socket has used headSize to read the message head // then this static function will figure out the number of // bytes left to read in the message. // unsigned int message::bytesToRead(const std::string &s) { unsigned int rtnVal; std::string temp; std::string::size_type len = s.find("size=\""); if(len < s.size()) { int i=strlen("size=\""); while(s[len+i] != '\"') temp += s[len+i++]; rtnVal = StrToT(temp).convert(); } return rtnVal-headSize; } // //----< test stub >-------------------------------------------------- #ifdef TEST_MSGHND #include using namespace std; void main() { cout << "\n Testing Message Class " << "\n =======================\n"; std::string aBody = "this is a message body"; message myMsg(message::text,aBody); cout << "\n message is: " << myMsg.serialize(); cout << "\n message size = " << myMsg.size(); cout << "\n message type = " << myMsg.typeStr(); cout << "\n message body = " << myMsg.body(); // A socket thread will read headSize bytes and then use this // static member function to extract the size attribute value // of an incoming message. It should then evaluate the value // size - headSize to determine how many more bytes to read cout << "\n bytes to read = " << message::bytesToRead(myMsg.serialize()) << endl; std::string anotherBody = "this is a request"; message myNextMsg(message::request,anotherBody); cout << "\n message is: " << myNextMsg.serialize(); cout << "\n message size = " << myNextMsg.size(); cout << "\n message type = " << myNextMsg.typeStr(); cout << "\n message body = " << myNextMsg.body(); cout << "\n bytes to read = " << message::bytesToRead(myNextMsg.serialize()); cout << "\n\n"; } #endif