/* * This file is part of the Flowee project * Copyright (C) 2016-2021 Tom Zander * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MESSAGEBUILDER_H #define MESSAGEBUILDER_H #include "ConstBuffer.h" #include "Message.h" #include namespace Streaming { class BufferPool; enum MessageType { HeaderOnly, HeaderAndBody, NoHeader }; int serialisedUIntSize(std::uint64_t unsignedInteger); int serialisedIntSize(std::int32_t signedInteger); class MessageBuilder { public: MessageBuilder(MessageType type = NoHeader, int size = 20000); MessageBuilder(BufferPool &pool, MessageType type = NoHeader); MessageBuilder(MessageBuilder &o) = delete; ~MessageBuilder(); void add(uint32_t tag, uint64_t value); /// add an utf8 string void add(uint32_t tag, const std::string &value); inline void add(uint32_t tag, const char *utf8String) { return add(tag, std::string(utf8String)); } void add(uint32_t tag, const std::vector &data); void add(uint32_t tag, const ConstBuffer &data); void addByteArray(uint32_t tag, const void *data, int bytes); void add(uint32_t tag, bool value); void add(uint32_t tag, int32_t value); void add(uint32_t tag, double value); template void add(uint32_t tag, const base_blob &value) { addByteArray(tag, static_cast(value.begin()), static_cast(value.size())); } void add(uint32_t tag, const std::vector &data) { addByteArray(tag, static_cast(data.data()), static_cast(data.size())); } void add(uint32_t tag, const std::vector &data) { addByteArray(tag, static_cast(data.data()), static_cast(data.size())); } inline void add(uint32_t tag, float value) { add(tag, (double) value); } /** * (complete) messages include a message size as the first 4 bytes of the message. * So when the MessageBuilder is used to build the header, you need to set the * size when the complete message is finished building to update the size at the * start of the message. * If you use the builder for the type HeaderAndBody, this will happen automatically * on a call to buffer() or message(). * If you use HeaderOnly, you need to call this method. * This method will just print a warning if you call it for a message Type of BodyOnly. */ void setMessageSize(int size); /** * @brief buffer returns a buffer object for the message we've built. * This is an alternative to the message() call, subsequent calls to either * buffer() or message() will refer to data added after this call. */ ConstBuffer buffer(); /** * Create a message based on the build data and the argument header-data. * This is an alternative to the buffer() call, subsequent calls to either * buffer() or message() will refer to data added after this call. */ Message message(int serviceId = -1, int messageId = -1, int requestId = -1); /** * Create a message based on the build data using the * incoming message as a base, assuming that the resurned one is a reply to. * * Please notice that it is only legal to call this method for * no-header type messages. */ Message reply(const Message &incoming, int messageId = -1); MessageBuilder* operator=(const MessageBuilder &o) = delete; private: void add(uint32_t tag, const unsigned char *data, unsigned int length); BufferPool *m_buffer; bool m_ownsPool; bool m_inHeader; bool m_beforeHeader; int m_headerSize; MessageType m_messageType; }; } #endif