/* # Copyright (c) 2010 - OpenSLX Project, Computer Center University of Freiburg # # This program is free software distributed under the GPL version 2. # See http://openslx.org/COPYING # # If you have any feedback please consult http://openslx.org/feedback and # send your suggestions, praise, or complaints to feedback@openslx.org # # General information about OpenSLX can be found at http://openslx.org/ # ----------------------------------------------------------------------------- # src/net/pvsMsg.cpp # - ??? . # ----------------------------------------------------------------------------- */ #include "pvsMsg.h" #include #include #include #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif static unsigned char PVS_ID = 'P'; // Several constructors for the PVSMsg class... PVSMsg::PVSMsg() { _msgType = PVSMESSAGE; _buffer = NULL; _buffLen = 0; _buffFill = 0; } PVSMsg::PVSMsg(PVSMsgType type, QString ident, QString msg, int recID) { this->_recID = recID; if (ident.size()) _msgIdent = ident; else _msgIdent = QString("invalid"); _msgType = type; _msgString = msg; _buffer = NULL; _buffLen = 0; _buffFill = 0; } PVSMsg::PVSMsg(PVSMsg const& copyMe) { _msgType = copyMe._msgType; _msgString = copyMe._msgString; _msgIdent = copyMe._msgIdent; _remoteIp = copyMe._remoteIp; _buffLen = copyMe._buffLen; _buffFill = copyMe._buffFill; if (_buffLen > 0) { _buffer = new char[_buffLen]; memcpy(_buffer, copyMe._buffer, _buffLen); } else _buffer = NULL; _sndID = copyMe._sndID; _recID = copyMe._recID; } // Destructor... PVSMsg::~PVSMsg() { if (_buffer) delete[] _buffer; } int PVSMsg::readMessage(QAbstractSocket* sock, bool udp) { if (_buffFill > 0 && _buffLen <= _buffFill) return 1; qint64 ret = 0; if (_buffFill < 4) // message header is not complete yet { if (_buffer == NULL) { _remoteIp = sock->peerAddress().toString(); if (udp) _buffer = new char[1000]; else _buffer = new char[4]; } // Read as many bytes as needed to complete the 4 byte header if (udp) ret = ((QUdpSocket*)sock)->readDatagram(_buffer, 1000); else ret = sock->read(_buffer + _buffFill, 4 - _buffFill); if (ret == -1) return -1; _buffFill += (int)ret; if (_buffFill == 0) return 0; if (_buffer[0] != PVS_ID) { // check if the id byte is correct // otherwise either the message parsing is broken // or someone is sending garbage return -1; } if (_buffFill >= 4) { // header complete, allocate buffer _buffLen = 4 + (unsigned char)_buffer[2] + (unsigned char)_buffer[3]; char *nb = new char[_buffLen + 1]; // +1 for \0 memcpy(nb, _buffer, _buffFill); delete[] _buffer; _buffer = nb; } } if (_buffFill >= 4) { // got header, assemble rest of msg if (!udp) { ret = sock->read(_buffer + _buffFill, _buffLen - _buffFill); // read remaining bytes if (ret == -1) return -1; _buffFill += (int)ret; } if (_buffFill >= _buffLen) { // message is complete _buffer[_buffLen] = '\0'; // first, terminate with nullchar _msgString = QString::fromUtf8(_buffer + 4 + (unsigned char)_buffer[2]); // get message _buffer[4 + (unsigned char)_buffer[2]] = '\0'; _msgIdent = QString::fromUtf8(_buffer + 4); // get ident _msgType = (PVSMsgType)_buffer[1]; // get msg type return 1; } } return 0; } void PVSMsg::setMessage(QString text) { _msgString = text; } void PVSMsg::setIdent(QString ident) { _msgIdent = ident; } QString PVSMsg::getMessage() { return _msgString; } QString PVSMsg::getIdent() { return _msgIdent; } bool PVSMsg::getBinaryData(char*& data, int& dataLen) { if (_msgIdent.size() == 0) return false; this->makeSndBuff(); data = (char*) _buffer; dataLen = _buffLen; return true; } void PVSMsg::setSndID(int id) { _sndID = id; } void PVSMsg::setRecID(int id) { _recID = id; } // Create a send buffer with the necessary size bool PVSMsg::makeSndBuff() { QByteArray uIdent = _msgIdent.toUtf8(); QByteArray uString = _msgString.toUtf8(); uIdent.truncate(255); uString.truncate(255); _buffLen = 4 + uIdent.size() + uString.size(); if (_buffer != NULL) delete[] _buffer; unsigned char *tmpBuffer = new unsigned char[_buffLen + 1]; tmpBuffer[0] = PVS_ID; tmpBuffer[1] = (unsigned char) _msgType; tmpBuffer[2] = (unsigned char) uIdent.size(); tmpBuffer[3] = (unsigned char) uString.size(); memcpy(tmpBuffer + 4, uIdent.data(), uIdent.size()); memcpy(tmpBuffer + 4 + uIdent.size(), uString.data(), uString.size()); //printf("[%c] '%s' - '%s'\n", (char)_msgType, _msgIdent.toUtf8().data(), _msgString.toUtf8().data()); tmpBuffer[_buffLen] = '\0'; //printf("Binary: '%s'\n", _buffer); _buffer = (char*)tmpBuffer; return true; }