Core Library 1.7.0.0 Library containing core utilities and tools for threading, networking, logging, INI and CSV file management etc.

MessageUtils.h
Go to the documentation of this file.
1
2 // This file is part of CoreLibrary containing useful reusable utility
3 // classes.
4 //
5 // Copyright (C) 2014 to present, Duncan Crutchley
6 // Contact <dac1976github@outlook.com>
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Lesser General Public License as published
10 // by the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License and GNU Lesser General Public License
17 // for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // and GNU Lesser General Public License along with this program. If
21 // not, see <http://www.gnu.org/licenses/>.
22
28 #ifndef MESSAGEUTILS
29 #define MESSAGEUTILS
30
31 #include <iterator>
32 #include <algorithm>
33 #include <cstring>
34 #include <cassert>
35 #include "AsioDefines.h"
36 #include "Serialization/SerializeToVector.h"
37
39 namespace core_lib
40 {
42 namespace asio
43 {
45 namespace messages
46 {
47
55 class CORE_LIBRARY_DLL_SHARED_API MessageHandler final
56 {
57 public:
58 #ifdef USE_DEFAULT_CONSTRUCTOR_
59
60 MessageHandler();
61 #else
62
63 MessageHandler() = default;
64 #endif
65
77 MessageHandler(const defs::default_message_dispatcher_t& messageDispatcher,
78 const std::string& magicString,
79 size_t memPoolMsgCount = 0,
80 size_t defaultMsgSize = udp::DEFAULT_UDP_BUF_SIZE);
82 ~MessageHandler() = default;
84 MessageHandler(const MessageHandler&) = default;
86 MessageHandler& operator=(const MessageHandler&) = default;
87
88 #ifdef USE_EXPLICIT_MOVE_
89
90 MessageHandler(MessageHandler&& mh);
92 MessageHandler& operator=(MessageHandler&& mh);
93 #else
94
95 MessageHandler(MessageHandler&&) = default;
97 MessageHandler& operator=(MessageHandler&&) = default;
98 #endif
99
103 size_t CheckBytesLeftToRead(const defs::char_buffer_t& message) const;
108 void MessageReceivedHandler(const defs::char_buffer_t& message) const;
109
110 private:
115 static bool CheckMessage(const defs::char_buffer_t& message);
121 void InitialiseMsgPool(size_t memPoolMsgCount, size_t defaultMsgSize);
126 defs::default_received_message_ptr_t GetNewMessgeObject() const;
127
128 private:
130 defs::default_message_dispatcher_t m_messageDispatcher;
131 #ifdef USE_DEFAULT_CONSTRUCTOR_
132
133 std::string m_magicString;
134 #else
135
136 std::string m_magicString{static_cast<char const*>(defs::DEFAULT_MAGIC_STRING)};
137 #endif
138 mutable size_t m_msgPoolIndex{0};
139 std::vector<defs::default_received_message_ptr_t> m_msgPool;
140 };
141
159 void CORE_LIBRARY_DLL_SHARED_API FillHeader(const std::string& magicString,
160 defs::eArchiveType archiveType, int32_t messageId,
161 const defs::connection_t& responseAddress,
162 uint32_t messageLength, defs::MessageHeader& header);
163
170 template <typename A> struct ArchiveTypeToEnum
171 {
176 static defs::eArchiveType Enumerate()
177 {
178 BOOST_THROW_EXCEPTION(std::invalid_argument("unknown archive type"));
179 return defs::eArchiveType::raw;
180 }
181 };
182
184 template <> struct ArchiveTypeToEnum<serialize::archives::out_bin_t>
185 {
190 static defs::eArchiveType Enumerate()
191 {
192 return defs::eArchiveType::binary;
193 }
194 };
195
197 template <> struct ArchiveTypeToEnum<serialize::archives::out_port_bin_t>
198 {
203 static defs::eArchiveType Enumerate()
204 {
205 return defs::eArchiveType::portableBinary;
206 }
207 };
208
210 template <> struct ArchiveTypeToEnum<serialize::archives::out_raw_t>
211 {
216 static defs::eArchiveType Enumerate()
217 {
218 return defs::eArchiveType::raw;
219 }
220 };
221
224 template <> struct ArchiveTypeToEnum<serialize::archives::out_protobuf_t>
225 {
230 static defs::eArchiveType Enumerate()
231 {
232 return defs::eArchiveType::protobuf;
233 }
234 };
235
237 template <> struct ArchiveTypeToEnum<serialize::archives::out_json_t>
238 {
243 static defs::eArchiveType Enumerate()
244 {
245 return defs::eArchiveType::json;
246 }
247 };
248
250 template <> struct ArchiveTypeToEnum<serialize::archives::out_xml_t>
251 {
256 static defs::eArchiveType Enumerate()
257 {
258 return defs::eArchiveType::xml;
259 }
260 };
261
268 class CORE_LIBRARY_DLL_SHARED_API MessageBuilder final
269 {
270 public:
271 #ifdef USE_DEFAULT_CONSTRUCTOR_
272
273 MessageBuilder();
274 #else
275
276 MessageBuilder() = default;
277 #endif
278
282 explicit MessageBuilder(const std::string& magicString);
284 ~MessageBuilder() = default;
286 MessageBuilder(const MessageBuilder&) = default;
288 MessageBuilder& operator=(const MessageBuilder&) = default;
289 #ifdef USE_EXPLICIT_MOVE_
290
291 MessageBuilder(MessageBuilder&& mb);
293 MessageBuilder& operator=(MessageBuilder&& mb);
294 #else
295
296 MessageBuilder(MessageBuilder&&) = default;
298 MessageBuilder& operator=(MessageBuilder&&) = default;
299 #endif
300
310 defs::char_buffer_t const& Build(int32_t messageId,
311 const defs::connection_t& responseAddress) const;
320 defs::char_buffer_t const&
321 Build(const defs::char_buffer_t& message, int32_t messageId,
322 const defs::connection_t& responseAddress,
323 defs::eArchiveType archiveType = defs::eArchiveType::raw) const;
333 defs::char_buffer_t const&
334 Build(const void* message, size_t messageLength, int32_t messageId,
335 const defs::connection_t& responseAddress,
336 defs::eArchiveType archiveType = defs::eArchiveType::raw) const;
351 template <typename T, typename A>
352 defs::char_buffer_t const& Build(const T& message, int32_t messageId,
353 const defs::connection_t& responseAddress) const
354 {
355 // Serialise message.
356 serialize::ToCharVector<T, A>(message, m_serialisationBuffer);
357
358 if (m_serialisationBuffer.empty())
359 {
360 BOOST_THROW_EXCEPTION(std::runtime_error("cannot serialize message"));
361 }
362
363 // Resize message buffer.
364 auto totalLength = sizeof(defs::MessageHeader) + m_serialisationBuffer.size();
365 m_messageBuffer.resize(totalLength);
366
367 // Fill header.
368 const defs::eArchiveType archiveType = ArchiveTypeToEnum<A>().Enumerate();
369 defs::MessageHeader* header =
370 reinterpret_cast<defs::MessageHeader*>(m_messageBuffer.data());
371 FillHeader(m_magicString,
372 archiveType,
373 messageId,
374 responseAddress,
375 static_cast<uint32_t>(m_serialisationBuffer.size()),
376 *header);
377
378 auto writePosIter = std::next(m_messageBuffer.begin(), sizeof(defs::MessageHeader));
379 std::copy(m_serialisationBuffer.begin(), m_serialisationBuffer.end(), writePosIter);
380
381 return m_messageBuffer;
382 }
383
384 private:
385 #ifdef USE_DEFAULT_CONSTRUCTOR_
386
387 std::string m_magicString;
388 #else
389
390 std::string m_magicString{static_cast<char const*>(defs::DEFAULT_MAGIC_STRING)};
391 #endif
392 mutable defs::char_buffer_t m_messageBuffer;
393 mutable defs::char_buffer_t m_serialisationBuffer;
394 };
395
410 template <typename MsgBldr>
411 defs::char_buffer_t const&
412 BuildMessage(int32_t messageId, const defs::connection_t& responseAddress,
413 const defs::connection_t& fallbackResponseAddress, const MsgBldr& messageBuilder)
414 {
415 auto responseConn =
416 (responseAddress == defs::NULL_CONNECTION) ? fallbackResponseAddress : responseAddress;
417 return messageBuilder.Build(messageId, responseConn);
418 }
434 template <typename MsgBldr>
435 defs::char_buffer_t const& BuildMessage(defs::char_buffer_t const& message, int32_t messageId,
436 const defs::connection_t& responseAddress,
437 const defs::connection_t& fallbackResponseAddress,
438 const MsgBldr& messageBuilder)
439 {
440 auto responseConn =
441 (responseAddress == defs::NULL_CONNECTION) ? fallbackResponseAddress : responseAddress;
442 return messageBuilder.Build(message, messageId, responseConn);
443 }
460 template <typename T, typename A, typename MsgBldr>
461 defs::char_buffer_t const&
462 BuildMessage(const T& message, int32_t messageId, const defs::connection_t& responseAddress,
463 const defs::connection_t& fallbackResponseAddress, const MsgBldr& messageBuilder)
464 {
465 auto responseConn =
466 (responseAddress == defs::NULL_CONNECTION) ? fallbackResponseAddress : responseAddress;
467 return messageBuilder.template Build<T, A>(message, messageId, responseConn);
468 }
469
476 template <typename T>
477 T DeserializeMessage(const defs::char_buffer_t& messageBuffer, defs::eArchiveType archiveType)
478 {
479 assert((archiveType != defs::eArchiveType::raw) &&
480 (archiveType != defs::eArchiveType::protobuf));
481
482 switch (archiveType)
483 {
484 case defs::eArchiveType::binary:
485 return serialize::ToObject<T, serialize::archives::in_bin_t>(messageBuffer);
486 case defs::eArchiveType::portableBinary:
487 return serialize::ToObject<T, serialize::archives::in_port_bin_t>(messageBuffer);
488 case defs::eArchiveType::raw:
489 // Do nothing.
490 break;
491 case defs::eArchiveType::json:
492 return serialize::ToObject<T, serialize::archives::in_json_t>(messageBuffer);
493 case defs::eArchiveType::xml:
494 return serialize::ToObject<T, serialize::archives::in_xml_t>(messageBuffer);
495 case defs::eArchiveType::protobuf:
496 // Do nothing;
497 break;
498 }
499
500 return T();
501 }
502
508 template <typename T> T DeserializeMessage(const defs::char_buffer_t& messageBuffer)
509 {
510 return serialize::ToObject<T, serialize::archives::in_raw_t>(messageBuffer);
511 }
512
518 template <typename T> T DeserializeProtobuf(const defs::char_buffer_t& messageBuffer)
519 {
520 return serialize::ToObject<T, serialize::archives::in_protobuf_t>(messageBuffer);
521 }
522
523 } // namespace messages
524 } // namespace asio
525 } // namespace core_lib
526
527 #endif // MESSAGEUTILS
core_lib::asio::messages::MessageHandler::m_messageDispatcher
defs::default_message_dispatcher_t m_messageDispatcher
Message dispatcher function object.
Definition: MessageUtils.h:130
core_lib::asio::messages::DeserializeMessage
T DeserializeMessage(const defs::char_buffer_t &messageBuffer, defs::eArchiveType archiveType)
Templated message deserializer function for non-POD data.
Definition: MessageUtils.h:477
core_lib::asio::defs::default_message_dispatcher_t
std::function< void(default_received_message_ptr_t)> default_message_dispatcher_t
Typedef to default message dispatcher function object.
Definition: AsioDefines.h:286
core_lib::serialize::archives::out_json_t
cereal::JSONOutputArchive out_json_t
Typedef to output json archive.
Definition: SerializeToVector.h:82
core_lib::asio::messages::MessageBuilder::Build
defs::char_buffer_t const & Build(const T &message, int32_t messageId, const defs::connection_t &responseAddress) const
Build message method for header + messaage body messages.
Definition: MessageUtils.h:352
core_lib::asio::defs::eArchiveType::portableBinary
Portable binary archive, requires Cereal serialization.
core_lib::asio::defs::eArchiveType::raw
Raw data, only for POD objects.
core_lib::asio::messages::ArchiveTypeToEnum< serialize::archives::out_json_t >::Enumerate
static defs::eArchiveType Enumerate()
Enumerate method.
Definition: MessageUtils.h:243
AsioDefines.h
File containing useful definitions.
core_lib::asio::messages::ArchiveTypeToEnum::Enumerate
static defs::eArchiveType Enumerate()
Enumerate method.
Definition: MessageUtils.h:176
core_lib::asio::messages::MessageHandler
Default message handler class.
Definition: MessageUtils.h:55
core_lib::asio::defs::eArchiveType::xml
XML archive, requires Cereal serialization.
core_lib::asio::messages::ArchiveTypeToEnum< serialize::archives::out_raw_t >::Enumerate
static defs::eArchiveType Enumerate()
Enumerate method.
Definition: MessageUtils.h:216
SerializeToVector.h
File containing utilities to serialize objects to byte vectors.
core_lib::asio::defs::eArchiveType::binary
Binary archive, requires Cereal serialization.
core_lib::asio::defs::eArchiveType::protobuf
Google protocol buffer.
core_lib::asio::defs::eArchiveType::json
JSON archive, requires Cereal serialization.
core_lib
The core_lib namespace.
Definition: AsioDefines.h:59
core_lib::asio::defs::default_received_message_ptr_t
std::shared_ptr< default_received_message_t > default_received_message_ptr_t
Typedef to default version of received message shared pointer.
Definition: AsioDefines.h:284
core_lib::asio::messages::ArchiveTypeToEnum< serialize::archives::out_port_bin_t >::Enumerate
static defs::eArchiveType Enumerate()
Enumerate method.
Definition: MessageUtils.h:203
core_lib::asio::defs::connection_t
std::pair< std::string, uint16_t > connection_t
Typedef describing a network connection as (address, port).
Definition: AsioDefines.h:152
core_lib::asio::messages::ArchiveTypeToEnum< serialize::archives::out_xml_t >::Enumerate
static defs::eArchiveType Enumerate()
Enumerate method.
Definition: MessageUtils.h:256
core_lib::asio::messages::ArchiveTypeToEnum< serialize::archives::out_bin_t >::Enumerate
static defs::eArchiveType Enumerate()
Enumerate method.
Definition: MessageUtils.h:190
core_lib::asio::defs::MessageHeader
Default message header structure that is also POD.
Definition: AsioDefines.h:194
core_lib::serialize::archives::out_bin_t
cereal::BinaryOutputArchive out_bin_t
Typedef to output binary archive.
Definition: SerializeToVector.h:78
core_lib::asio::messages::FillHeader
void CORE_LIBRARY_DLL_SHARED_API FillHeader(const std::string &magicString, defs::eArchiveType archiveType, int32_t messageId, const defs::connection_t &responseAddress, uint32_t messageLength, defs::MessageHeader &header)
Header filler function.
Definition: MessageUtils.cpp:181
core_lib::asio::messages::ArchiveTypeToEnum< serialize::archives::out_protobuf_t >::Enumerate
static defs::eArchiveType Enumerate()
Enumerate method.
Definition: MessageUtils.h:230
core_lib::asio::defs::eArchiveType
eArchiveType
Message serialization archive type enumeration.
Definition: AsioDefines.h:171
core_lib::asio::messages::BuildMessage
defs::char_buffer_t const & BuildMessage(int32_t messageId, const defs::connection_t &responseAddress, const defs::connection_t &fallbackResponseAddress, const MsgBldr &messageBuilder)
Message builder wrapper function for header only messages.
Definition: MessageUtils.h:412
core_lib::asio::messages::DeserializeProtobuf
T DeserializeProtobuf(const defs::char_buffer_t &messageBuffer)
Templated message deserializer function for Google protocol buffer data.
Definition: MessageUtils.h:518
core_lib::asio::defs::DEFAULT_MAGIC_STRING
const char DEFAULT_MAGIC_STRING[]
Constant defining default magc string as "_BEGIN_MESSAGE_".
Definition: AsioDefines.cpp:38
core_lib::serialize::archives::out_xml_t
cereal::XMLOutputArchive out_xml_t
Typedef to output xml archive.
Definition: SerializeToVector.h:80
core_lib::asio::messages::MessageBuilder
Default message builder class.
Definition: MessageUtils.h:268
core_lib::serialize::archives::out_port_bin_t
cereal::PortableBinaryOutputArchive out_port_bin_t
Typedef to output portable binary archive.
Definition: SerializeToVector.h:76
core_lib::serialize::archives::out_protobuf_t
protobuf_oarchive out_protobuf_t
Typedef to output using Google protocol buffers.
Definition: SerializeToVector.h:86
core_lib::asio::defs::char_buffer_t
std::vector< char > char_buffer_t
Typedef to generic char buffer based on s std::vector<char>.
Definition: AsioDefines.h:239
core_lib::serialize::archives::out_raw_t
raw_oarchive out_raw_t
Typedef to output raw archive.
Definition: SerializeToVector.h:84
core_lib::asio::defs::NULL_CONNECTION
const connection_t NULL_CONNECTION
Constant defining a null network connection as ("0.0.0.0", 0).
core_lib::asio::messages::ArchiveTypeToEnum
Archive type enumerator as a template class.
Definition: MessageUtils.h:170