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/networkmessagewriter.h"
0022 #include <QBuffer>
0023 #include <QDataStream>
0024 #include <QDebug>
0025 
0026 NetworkMessageWriter::NetworkMessageWriter(NetMsg::Category category, NetMsg::Action action,
0027                                            NetworkMessage::RecipientMode mode, int size)
0028     : NetworkMessage(), m_mode(mode)
0029 {
0030     int headerSize= sizeof(NetworkMessageHeader);
0031     if(size == 0)
0032         qDebug() << "size 0";
0033 
0034     if(size < headerSize)
0035     {
0036         size= 128;
0037     }
0038     m_sizeBuffer= size;
0039     m_sizeData= headerSize;
0040     m_buffer= new char[m_sizeBuffer];
0041     m_header= reinterpret_cast<NetworkMessageHeader*>(m_buffer);
0042 
0043     m_begin= m_buffer + headerSize;
0044     m_currentPos= m_begin;
0045     m_end= m_buffer + m_sizeBuffer;
0046 
0047     m_header->category= category;
0048     m_header->action= action;
0049 
0050     uint8(static_cast<quint8>(m_mode));
0051 }
0052 
0053 NetworkMessageWriter::~NetworkMessageWriter()
0054 {
0055     delete[] m_buffer;
0056 }
0057 quint32 NetworkMessageWriter::getDataSize() const
0058 {
0059     return static_cast<quint32>(m_currentPos - m_begin);
0060 }
0061 
0062 quint32 NetworkMessageWriter::bufferSize() const
0063 {
0064     return m_sizeBuffer;
0065 }
0066 NetMsg::Category NetworkMessageWriter::category() const
0067 {
0068     return NetMsg::Category(m_header->category);
0069 }
0070 
0071 NetMsg::Action NetworkMessageWriter::action() const
0072 {
0073     return NetMsg::Action(m_header->action);
0074 }
0075 
0076 void NetworkMessageWriter::reset()
0077 {
0078     m_currentPos= m_begin;
0079     uint8(static_cast<quint8>(m_mode));
0080 }
0081 
0082 NetworkMessageHeader* NetworkMessageWriter::buffer() const
0083 {
0084     m_header->dataSize= getDataSize();
0085     return m_header;
0086 }
0087 
0088 void NetworkMessageWriter::uint8(quint8 data)
0089 {
0090     int size= sizeof(quint8);
0091     makeRoom(size);
0092 
0093     *(reinterpret_cast<quint8*>(m_currentPos))= data;
0094     m_currentPos+= size;
0095 }
0096 
0097 void NetworkMessageWriter::uint16(quint16 data)
0098 {
0099     int size= sizeof(quint16);
0100     makeRoom(size);
0101 
0102     *(reinterpret_cast<quint16*>(m_currentPos))= data;
0103     m_currentPos+= size;
0104 }
0105 
0106 void NetworkMessageWriter::uint32(quint32 data)
0107 {
0108     int size= sizeof(quint32);
0109     makeRoom(size);
0110 
0111     *(reinterpret_cast<quint32*>(m_currentPos))= data;
0112     m_currentPos+= size;
0113 }
0114 void NetworkMessageWriter::uint64(quint64 data)
0115 {
0116     int size= sizeof(quint64);
0117     makeRoom(size);
0118 
0119     *(reinterpret_cast<quint64*>(m_currentPos))= data;
0120     m_currentPos+= size;
0121 }
0122 
0123 void NetworkMessageWriter::string8(const QString& data)
0124 {
0125     quint8 sizeQChar= static_cast<quint8>(data.size());
0126     uint8(sizeQChar);
0127     string(data, sizeQChar);
0128 }
0129 
0130 void NetworkMessageWriter::string16(const QString& data)
0131 {
0132     quint16 sizeQChar= static_cast<quint16>(data.size());
0133     uint16(sizeQChar);
0134     string(data, sizeQChar);
0135 }
0136 
0137 void NetworkMessageWriter::string32(const QString& data)
0138 {
0139     quint32 sizeQChar= static_cast<quint32>(data.size());
0140     uint32(sizeQChar);
0141     string(data, static_cast<int>(sizeQChar));
0142 }
0143 
0144 void NetworkMessageWriter::string(const QString& data, int sizeQChar)
0145 {
0146     quint64 sizeBytes= static_cast<quint64>(sizeQChar) * static_cast<quint64>(sizeof(QChar));
0147 
0148     makeRoom(static_cast<int>(sizeBytes));
0149     memcpy(m_currentPos, data.constData(), static_cast<std::size_t>(sizeBytes));
0150     m_currentPos+= sizeBytes;
0151 }
0152 
0153 void NetworkMessageWriter::byteArray32(const QByteArray& data)
0154 {
0155     quint32 size= static_cast<quint32>(data.size());
0156     uint32(size);
0157     makeRoom(static_cast<int>(size));
0158     memcpy(m_currentPos, data.constData(), size);
0159     m_currentPos+= size;
0160 }
0161 
0162 #ifdef QT_GUI_LIB
0163 bool NetworkMessageWriter::pixmap(const QPixmap& pix)
0164 {
0165     QByteArray baImage;
0166     QBuffer bufImage(&baImage);
0167     bool res= false;
0168 
0169     if(pix.save(&bufImage, pix.hasAlpha() ? "png" : "jpg", 70))
0170     {
0171         uint8(true);
0172         byteArray32(baImage);
0173         res= true;
0174     }
0175     else
0176     {
0177         uint8(false);
0178     }
0179     return res;
0180 }
0181 #endif
0182 
0183 void NetworkMessageWriter::rgb(unsigned int color)
0184 {
0185     int size= sizeof(unsigned int);
0186     makeRoom(size);
0187 
0188     *(reinterpret_cast<unsigned int*>(m_currentPos))= color;
0189     m_currentPos+= size;
0190 }
0191 
0192 void NetworkMessageWriter::makeRoom(int size)
0193 {
0194     while(m_currentPos + size > m_end)
0195     {
0196         auto newSize= (m_end - m_buffer) * 2;
0197         char* newBuffer= new char[newSize];
0198         memcpy(newBuffer, m_buffer, static_cast<std::size_t>(m_currentPos - m_buffer));
0199 
0200         long long int diff= newBuffer - m_buffer;
0201 
0202         m_begin= newBuffer + sizeof(NetworkMessageHeader);
0203         m_currentPos+= diff;
0204         m_end= newBuffer + newSize;
0205 
0206         delete[] m_buffer;
0207 
0208         m_buffer= newBuffer;
0209         m_header= reinterpret_cast<NetworkMessageHeader*>(m_buffer);
0210 
0211         m_sizeBuffer= m_end - m_buffer;
0212         m_sizeData= m_sizeBuffer - static_cast<long long int>(sizeof(NetworkMessageHeader));
0213     }
0214 }
0215 void NetworkMessageWriter::int8(qint8 data)
0216 {
0217     int size= sizeof(qint8);
0218     makeRoom(size);
0219 
0220     *(reinterpret_cast<qint8*>(m_currentPos))= data;
0221     m_currentPos+= size;
0222 }
0223 
0224 void NetworkMessageWriter::int16(qint16 data)
0225 {
0226     int size= sizeof(qint16);
0227     makeRoom(size);
0228 
0229     *(reinterpret_cast<qint16*>(m_currentPos))= data;
0230     m_currentPos+= size;
0231 }
0232 
0233 void NetworkMessageWriter::int32(qint32 data)
0234 {
0235     int size= sizeof(qint32);
0236     makeRoom(size);
0237 
0238     *(reinterpret_cast<qint32*>(m_currentPos))= data;
0239     m_currentPos+= size;
0240 }
0241 void NetworkMessageWriter::int64(qint64 data)
0242 {
0243     int size= sizeof(qint64);
0244     makeRoom(size);
0245 
0246     *(reinterpret_cast<qint64*>(m_currentPos))= data;
0247     m_currentPos+= size;
0248 }
0249 void NetworkMessageWriter::real(qreal data)
0250 {
0251     int size= sizeof(qreal);
0252     makeRoom(size);
0253 
0254     *(reinterpret_cast<qreal*>(m_currentPos))= data;
0255     m_currentPos+= size;
0256 }
0257 void NetworkMessageWriter::setRecipientList(QStringList list, NetworkMessage::RecipientMode mode)
0258 {
0259     m_recipientList= list;
0260     m_mode= mode;
0261     reset();
0262 
0263     if(mode != NetworkMessage::All)
0264     {
0265         uint8(static_cast<quint8>(list.size()));
0266         for(auto& string : list)
0267         {
0268             string8(string);
0269         }
0270     }
0271 }
0272 QStringList NetworkMessageWriter::getRecipientList() const
0273 {
0274     return m_recipientList;
0275 }
0276 NetworkMessage::RecipientMode NetworkMessageWriter::getRecipientMode() const
0277 {
0278     return m_mode;
0279 }
0280 
0281 size_t NetworkMessageWriter::currentPos() const
0282 {
0283     return static_cast<size_t>(m_currentPos - m_buffer);
0284 }
0285 
0286 void NetworkMessageWriter::dateTime(const QDateTime& time)
0287 {
0288     QByteArray array;
0289     {
0290         QDataStream output(&array, QIODevice::WriteOnly);
0291         output.setVersion(QDataStream::Qt_5_15);
0292         output << time;
0293     }
0294     byteArray32(array);
0295 }
0296 
0297 QByteArray NetworkMessageWriter::data() const
0298 {
0299     auto size= getDataSize() + sizeof(NetworkMessageHeader);
0300     m_header->dataSize= getDataSize();
0301     QByteArray array(m_buffer, static_cast<int>(size));
0302     return array;
0303 }