File indexing completed on 2024-05-05 05:40:33

0001 /*************************************************************************
0002  *     Copyright (C) 2011 by Joseph Boudou                               *
0003  *     https://rolisteam.org/                                         *
0004  *                                                                       *
0005  *   rolisteam is free software; you can redistribute it and/or modify   *
0006  *   it under the terms of the GNU General Public License as published   *
0007  *   by the Free Software Foundation; either version 2 of the License,   *
0008  *   or (at your option) any later version.                              *
0009  *                                                                       *
0010  *   This program is distributed in the hope that it will be useful,     *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of      *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *
0013  *   GNU General Public License for more details.                        *
0014  *                                                                       *
0015  *   You should have received a copy of the GNU General Public License   *
0016  *   along with this program; if not, write to the                       *
0017  *   Free Software Foundation, Inc.,                                     *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.           *
0019  *************************************************************************/
0020 
0021 #include "network/networkmessagereader.h"
0022 #include <QDataStream>
0023 #include <QIODevice>
0024 
0025 NetworkMessageReader::NetworkMessageReader() : NetworkMessage() {}
0026 
0027 NetworkMessageReader::NetworkMessageReader(const NetworkMessageHeader& header, const char* buffer) : NetworkMessage()
0028 {
0029     size_t headerSize= sizeof(NetworkMessageHeader);
0030     m_buffer= new char[header.dataSize + headerSize];
0031     memcpy(m_buffer, &header, headerSize);
0032     m_header= reinterpret_cast<NetworkMessageHeader*>(m_buffer);
0033 
0034     m_buffer+= headerSize;
0035     memcpy(m_buffer, buffer, m_header->dataSize);
0036 
0037     m_pos= m_buffer;
0038     m_end= m_buffer + m_header->dataSize;
0039 
0040     readRecipient();
0041 }
0042 
0043 NetworkMessageReader::NetworkMessageReader(const NetworkMessageReader& other) : NetworkMessage()
0044 {
0045     auto size= other.m_end - reinterpret_cast<char*>(other.m_header);
0046     char* copy= new char[size];
0047     memcpy(copy, other.m_header, static_cast<std::size_t>(size));
0048 
0049     m_header= reinterpret_cast<NetworkMessageHeader*>(copy);
0050     m_buffer= copy + sizeof(NetworkMessageHeader);
0051     m_pos= m_buffer;
0052     m_end= copy + size;
0053 
0054     readRecipient();
0055 }
0056 
0057 NetworkMessageReader::~NetworkMessageReader()
0058 {
0059     delete[](reinterpret_cast<char*>(m_header));
0060 }
0061 
0062 bool NetworkMessageReader::isValid()
0063 {
0064     return !m_outMemory;
0065 }
0066 
0067 void NetworkMessageReader::resetToPos(const char* pos)
0068 {
0069     m_pos= pos;
0070 }
0071 const char* NetworkMessageReader::pos() const
0072 {
0073     return m_pos;
0074 }
0075 
0076 void NetworkMessageReader::setData(const QByteArray& bytes)
0077 {
0078     int size= bytes.size();
0079     const char* data= bytes.data();
0080 
0081     size_t headerSize= sizeof(NetworkMessageHeader);
0082     m_buffer= new char[size + static_cast<int>(headerSize)];
0083 
0084     memcpy(m_buffer, data, static_cast<std::size_t>(size) + headerSize);
0085 
0086     m_header= reinterpret_cast<NetworkMessageHeader*>(m_buffer);
0087 
0088     m_pos= m_buffer + headerSize;
0089     m_end= m_buffer + headerSize + m_header->dataSize;
0090 
0091     readRecipient();
0092 }
0093 
0094 void NetworkMessageReader::setInternalData(const QByteArray& bytes)
0095 {
0096     auto size= bytes.size();
0097     m_buffer= new char[size];
0098     memcpy(m_buffer, bytes.constData(), static_cast<std::size_t>(size));
0099     m_header= reinterpret_cast<NetworkMessageHeader*>(m_buffer);
0100     size_t headerSize= sizeof(NetworkMessageHeader);
0101     m_pos= m_buffer + headerSize;
0102     m_end= m_buffer + headerSize + m_header->dataSize;
0103 }
0104 
0105 NetMsg::Category NetworkMessageReader::category() const
0106 {
0107     return NetMsg::Category(m_header->category);
0108 }
0109 
0110 NetMsg::Action NetworkMessageReader::action() const
0111 {
0112     return NetMsg::Action(m_header->action);
0113 }
0114 
0115 NetworkMessageHeader* NetworkMessageReader::buffer() const
0116 {
0117     return m_header;
0118 }
0119 
0120 bool NetworkMessageReader::isSizeReadable(size_t size)
0121 {
0122     m_outMemory= !(left() >= size);
0123     return !m_outMemory;
0124 }
0125 
0126 QStringList NetworkMessageReader::getRecipientList() const
0127 {
0128     return m_recipientList;
0129 }
0130 
0131 NetworkMessage::RecipientMode NetworkMessageReader::getRecipientMode() const
0132 {
0133     return m_mode;
0134 }
0135 
0136 NetworkMessageHeader* NetworkMessageReader::header() const
0137 {
0138     return m_header;
0139 }
0140 
0141 void NetworkMessageReader::setHeader(NetworkMessageHeader* header)
0142 {
0143     m_header= header;
0144 }
0145 
0146 void NetworkMessageReader::reset()
0147 {
0148     m_pos= m_buffer;
0149 }
0150 void NetworkMessageReader::resetToData()
0151 {
0152     m_pos= m_buffer + sizeof(NetworkMessageHeader);
0153     readRecipient();
0154 }
0155 
0156 void NetworkMessageReader::readRecipient()
0157 {
0158     m_mode= static_cast<NetworkMessage::RecipientMode>(uint8());
0159     if(m_mode == NetworkMessage::OneOrMany)
0160     {
0161         int size= uint8();
0162         m_recipientList.clear();
0163         for(int i= 0; i < size; ++i)
0164         {
0165             m_recipientList << string8();
0166         }
0167     }
0168 }
0169 
0170 size_t NetworkMessageReader::left() const
0171 {
0172     return static_cast<size_t>(m_end - m_pos);
0173 }
0174 
0175 size_t NetworkMessageReader::currentPos() const
0176 {
0177     return static_cast<size_t>(m_pos - m_buffer);
0178 }
0179 
0180 quint8 NetworkMessageReader::uint8()
0181 {
0182     size_t size= sizeof(quint8);
0183     if(isSizeReadable(size))
0184     {
0185         quint8 ret= static_cast<quint8>(*m_pos);
0186         m_pos+= size;
0187         return ret;
0188     }
0189     return 0;
0190 }
0191 
0192 quint16 NetworkMessageReader::uint16()
0193 {
0194     size_t size= sizeof(quint16);
0195     if(isSizeReadable(size))
0196     {
0197         quint16 ret;
0198         memcpy(&ret, m_pos, size);
0199         m_pos+= size;
0200         return ret;
0201     }
0202     return 0;
0203 }
0204 
0205 quint32 NetworkMessageReader::uint32()
0206 {
0207     size_t size= sizeof(quint32);
0208     if(isSizeReadable(size))
0209     {
0210         quint32 ret;
0211         memcpy(&ret, m_pos, size);
0212         m_pos+= size;
0213         return ret;
0214     }
0215     return 0;
0216 }
0217 quint64 NetworkMessageReader::uint64()
0218 {
0219     size_t size= sizeof(quint64);
0220     if(isSizeReadable(size))
0221     {
0222         quint64 ret;
0223         memcpy(&ret, m_pos, size);
0224         m_pos+= size;
0225         return ret;
0226     }
0227     return 0;
0228 }
0229 QString NetworkMessageReader::string8()
0230 {
0231     return string(uint8());
0232 }
0233 
0234 QString NetworkMessageReader::string16()
0235 {
0236     return string(uint16());
0237 }
0238 
0239 QString NetworkMessageReader::string32()
0240 {
0241     return string(uint32());
0242 }
0243 
0244 QString NetworkMessageReader::string(quint64 sizeQChar)
0245 {
0246     size_t sizeBytes= sizeQChar * sizeof(QChar);
0247     if(sizeBytes > 0 && isSizeReadable(sizeBytes))
0248     {
0249         QString ret(reinterpret_cast<const QChar*>(m_pos), static_cast<int>(sizeQChar));
0250         m_pos+= sizeBytes;
0251         return ret;
0252     }
0253     return QString();
0254 }
0255 
0256 unsigned int NetworkMessageReader::rgb()
0257 {
0258     size_t size= sizeof(unsigned int);
0259     if(isSizeReadable(size))
0260     {
0261         unsigned int ret;
0262         memcpy(&ret, m_pos, size);
0263         m_pos+= size;
0264         return ret;
0265     }
0266     return 0x00ffffff;
0267 }
0268 
0269 QByteArray NetworkMessageReader::byteArray32()
0270 {
0271     size_t size= static_cast<size_t>(uint32());
0272     if(isSizeReadable(size))
0273     {
0274         QByteArray result(m_pos, static_cast<int>(size));
0275         m_pos+= size;
0276         return result;
0277     }
0278     return {};
0279 }
0280 qint8 NetworkMessageReader::int8()
0281 {
0282     size_t size= sizeof(qint8);
0283     if(isSizeReadable(size))
0284     {
0285         qint8 ret= static_cast<qint8>(*m_pos);
0286         m_pos+= size;
0287         return ret;
0288     }
0289     return 0;
0290 }
0291 
0292 qint16 NetworkMessageReader::int16()
0293 {
0294     size_t size= sizeof(qint16);
0295     if(isSizeReadable(size))
0296     {
0297         qint16 ret;
0298         memcpy(&ret, m_pos, size);
0299         m_pos+= size;
0300         return ret;
0301     }
0302     return 0;
0303 }
0304 
0305 qint32 NetworkMessageReader::int32()
0306 {
0307     size_t size= sizeof(qint32);
0308     if(isSizeReadable(size))
0309     {
0310         qint32 ret;
0311         memcpy(&ret, m_pos, size);
0312         m_pos+= size;
0313         return ret;
0314     }
0315     return 0;
0316 }
0317 qint64 NetworkMessageReader::int64()
0318 {
0319     size_t size= sizeof(qint64);
0320     if(isSizeReadable(size))
0321     {
0322         qint64 ret;
0323         memcpy(&ret, m_pos, size);
0324         m_pos+= size;
0325         return ret;
0326     }
0327     return 0;
0328 }
0329 
0330 #ifdef QT_GUI_LIB
0331 QPixmap NetworkMessageReader::pixmap()
0332 {
0333     bool hasPix= uint8();
0334     if(!hasPix)
0335         return {};
0336 
0337     auto data= byteArray32();
0338     QPixmap res;
0339     res.loadFromData(data);
0340     return res;
0341 }
0342 #endif
0343 
0344 QDateTime NetworkMessageReader::dateTime()
0345 {
0346     auto byte= byteArray32();
0347     QDateTime time;
0348     {
0349         QDataStream input(&byte, QIODevice::ReadOnly);
0350         input.setVersion(QDataStream::Qt_5_15);
0351         input >> time;
0352     }
0353     return time;
0354 }
0355 qreal NetworkMessageReader::real()
0356 {
0357     size_t size= sizeof(qreal);
0358     if(isSizeReadable(size))
0359     {
0360         qreal ret;
0361         memcpy(&ret, m_pos, size);
0362         m_pos+= size;
0363         return ret;
0364     }
0365     return 0;
0366 }