sigproxy: Modernize RPC calls (remote signals)
[quassel.git] / src / common / message.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2018 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #include "message.h"
22
23 #include <utility>
24
25 #include <QDataStream>
26
27 #include "peer.h"
28 #include "signalproxy.h"
29 #include "util.h"
30
31 Message::Message(
32     BufferInfo bufferInfo, Type type, QString contents, QString sender, QString senderPrefixes, QString realName, QString avatarUrl, Flags flags)
33     : _timestamp(QDateTime::currentDateTime().toUTC())
34     , _bufferInfo(std::move(bufferInfo))
35     , _contents(std::move(contents))
36     , _sender(std::move(sender))
37     , _senderPrefixes(std::move(senderPrefixes))
38     , _realName(std::move(realName))
39     , _avatarUrl(std::move(avatarUrl))
40     , _type(type)
41     , _flags(flags)
42 {}
43
44 Message::Message(QDateTime ts,
45                  BufferInfo bufferInfo,
46                  Type type,
47                  QString contents,
48                  QString sender,
49                  QString senderPrefixes,
50                  QString realName,
51                  QString avatarUrl,
52                  Flags flags)
53     : _timestamp(std::move(ts))
54     , _bufferInfo(std::move(bufferInfo))
55     , _contents(std::move(contents))
56     , _sender(std::move(sender))
57     , _senderPrefixes(std::move(senderPrefixes))
58     , _realName(std::move(realName))
59     , _avatarUrl(std::move(avatarUrl))
60     , _type(type)
61     , _flags(flags)
62 {}
63
64 QDataStream& operator<<(QDataStream& out, const Message& msg)
65 {
66     Q_ASSERT(SignalProxy::current());
67     Q_ASSERT(SignalProxy::current()->targetPeer());
68
69     // We do not serialize the sender prefixes until we have a new protocol or client-features implemented
70     out << msg.msgId();
71
72     if (SignalProxy::current()->targetPeer()->hasFeature(Quassel::Feature::LongTime)) {
73         // toMSecs returns a qint64, signed rather than unsigned
74         out << (qint64)msg.timestamp().toMSecsSinceEpoch();
75     }
76     else {
77         out << (quint32)msg.timestamp().toTime_t();
78     }
79
80     out << (quint32)msg.type() << (quint8)msg.flags() << msg.bufferInfo() << msg.sender().toUtf8();
81
82     if (SignalProxy::current()->targetPeer()->hasFeature(Quassel::Feature::SenderPrefixes))
83         out << msg.senderPrefixes().toUtf8();
84
85     if (SignalProxy::current()->targetPeer()->hasFeature(Quassel::Feature::RichMessages)) {
86         out << msg.realName().toUtf8();
87         out << msg.avatarUrl().toUtf8();
88     }
89
90     out << msg.contents().toUtf8();
91     return out;
92 }
93
94 QDataStream& operator>>(QDataStream& in, Message& msg)
95 {
96     Q_ASSERT(SignalProxy::current());
97     Q_ASSERT(SignalProxy::current()->sourcePeer());
98
99     in >> msg._msgId;
100
101     if (SignalProxy::current()->sourcePeer()->hasFeature(Quassel::Feature::LongTime)) {
102         // timestamp is a qint64, signed rather than unsigned
103         qint64 timeStamp;
104         in >> timeStamp;
105         msg._timestamp = QDateTime::fromMSecsSinceEpoch(timeStamp);
106     }
107     else {
108         quint32 timeStamp;
109         in >> timeStamp;
110         msg._timestamp = QDateTime::fromTime_t(timeStamp);
111     }
112
113     quint32 type;
114     in >> type;
115     msg._type = Message::Type(type);
116
117     quint8 flags;
118     in >> flags;
119     msg._flags = Message::Flags(flags);
120
121     in >> msg._bufferInfo;
122
123     QByteArray sender;
124     in >> sender;
125     msg._sender = QString::fromUtf8(sender);
126
127     QByteArray senderPrefixes;
128     if (SignalProxy::current()->sourcePeer()->hasFeature(Quassel::Feature::SenderPrefixes))
129         in >> senderPrefixes;
130     msg._senderPrefixes = QString::fromUtf8(senderPrefixes);
131
132     QByteArray realName;
133     QByteArray avatarUrl;
134     if (SignalProxy::current()->sourcePeer()->hasFeature(Quassel::Feature::RichMessages)) {
135         in >> realName;
136         in >> avatarUrl;
137     }
138     msg._realName = QString::fromUtf8(realName);
139     msg._avatarUrl = QString::fromUtf8(avatarUrl);
140
141     QByteArray contents;
142     in >> contents;
143     msg._contents = QString::fromUtf8(contents);
144
145     return in;
146 }
147
148 QDebug operator<<(QDebug dbg, const Message& msg)
149 {
150     dbg.nospace() << qPrintable(QString("Message(MsgId:")) << msg.msgId() << qPrintable(QString(",")) << msg.timestamp()
151                   << qPrintable(QString(", Type:")) << msg.type() << qPrintable(QString(", RealName:")) << msg.realName()
152                   << qPrintable(QString(", AvatarURL:")) << msg.avatarUrl() << qPrintable(QString(", Flags:")) << msg.flags()
153                   << qPrintable(QString(")")) << msg.senderPrefixes() << msg.sender() << ":" << msg.contents();
154     return dbg;
155 }