1 /* 2 message.h 3 4 This file is part of GammaRay, the Qt application inspection and 5 manipulation tool. 6 7 Copyright (C) 2013-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com 8 Author: Volker Krause <volker.krause@kdab.com> 9 10 Licensees holding valid commercial KDAB GammaRay licenses may use this file in 11 accordance with GammaRay Commercial License Agreement provided with the Software. 12 13 Contact info@kdab.com if any conditions of this licensing are not clear to you. 14 15 This program is free software; you can redistribute it and/or modify 16 it under the terms of the GNU General Public License as published by 17 the Free Software Foundation, either version 2 of the License, or 18 (at your option) any later version. 19 20 This program is distributed in the hope that it will be useful, 21 but WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 GNU General Public License for more details. 24 25 You should have received a copy of the GNU General Public License 26 along with this program. If not, see <http://www.gnu.org/licenses/>. 27 */ 28 29 #ifndef GAMMARAY_MESSAGE_H 30 #define GAMMARAY_MESSAGE_H 31 32 #include "gammaray_common_export.h" 33 #include "protocol.h" 34 35 #include <QByteArray> 36 #include <QDataStream> 37 38 #include <functional> 39 #include <memory> 40 41 class MessageBuffer; 42 43 namespace GammaRay { 44 /** 45 * Single message send between client and server. 46 * Binary format: 47 * - sizeof(Protocol::PayloadSize) byte size of the message payload (not including the size and other fixed fields itself) in netowork byte order (big endian) 48 * - sizeof(Protocol::ObjectAddress) server object address (big endian) 49 * - sizeof(Protocol::MessageType) command type (big endian) 50 * - size bytes message payload (encoding is user defined, QDataStream provided for convenience) 51 */ 52 class GAMMARAY_COMMON_EXPORT Message 53 { 54 public: 55 /** 56 * Construct a new message to/from @p objectAddress and message type @p type. 57 */ 58 explicit Message(Protocol::ObjectAddress objectAddress, Protocol::MessageType type); 59 Message(Message &&other) Q_DECL_NOEXCEPT; // krazy:exclude=explicit 60 ~Message(); 61 62 Protocol::ObjectAddress address() const; 63 Protocol::MessageType type() const; 64 65 /** Read value from the payload 66 * This operator proxy over payload() allow to do: 67 * - Run time check on the stream status 68 */ 69 template <typename T> 70 GammaRay::Message &operator>>(T &value) 71 { 72 if (Q_UNLIKELY(payload().status() != QDataStream::Ok)) { 73 qWarning("%s: Attempting to read from a non valid stream: status: %i", Q_FUNC_INFO, int(payload().status())); 74 } 75 payload() >> value; 76 if (Q_UNLIKELY(payload().status() != QDataStream::Ok)) { 77 qWarning("%s: Read from a non valid stream: status: %i", Q_FUNC_INFO, int(payload().status())); 78 } 79 return *this; 80 } 81 82 /** Read value from the payload 83 * This overload allow to read content from a const Message. 84 */ 85 template <typename T> 86 GammaRay::Message &operator>>(T &value) const 87 { 88 return const_cast<GammaRay::Message *>(this)->operator>>(value); 89 } 90 91 /** Write value to the payload. 92 * This operator proxy over payload() allow to do: 93 * - Run time check on the stream status 94 */ 95 template <typename T> 96 GammaRay::Message &operator<<(const T &value) 97 { 98 if (Q_UNLIKELY(payload().status() != QDataStream::Ok)) { 99 qWarning("%s: Attempting to write to a non valid stream: status: %i", Q_FUNC_INFO, int(payload().status())); 100 } 101 payload() << value; 102 if (Q_UNLIKELY(payload().status() != QDataStream::Ok)) { 103 qWarning("%s: Write to a non valid stream: status: %i", Q_FUNC_INFO, int(payload().status())); 104 } 105 return *this; 106 } 107 108 /** Checks if there is a full message waiting in @p device. */ 109 static bool canReadMessage(QIODevice *device); 110 /** Read the next message from @p device. */ 111 static Message readMessage(QIODevice *device); 112 113 static quint8 lowestSupportedDataVersion(); 114 static quint8 highestSupportedDataVersion(); 115 116 static quint8 negotiatedDataVersion(); 117 static void setNegotiatedDataVersion(quint8 version); 118 static void resetNegotiatedDataVersion(); 119 120 /** Write this message to @p device. */ 121 void write(QIODevice *device) const; 122 123 /** Size of the uncompressed message payload. */ 124 int size() const; 125 126 private: 127 Message(); 128 129 /** Access to the message payload. This is read-only for received messages 130 * and write-only for messages to be sent. 131 */ 132 QDataStream &payload() const; 133 134 Protocol::ObjectAddress m_objectAddress; 135 Protocol::MessageType m_messageType; 136 137 std::unique_ptr<MessageBuffer, std::function<void(MessageBuffer *)>> m_buffer; 138 }; 139 } 140 141 #endif 142