COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
MsgDataLayer.h
Go to the documentation of this file.
1//
2// Copyright 2014 - 2025 (C). Alex Robenko. All rights reserved.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
10
11#pragma once
12
13#include <tuple>
14#include <iterator>
15#include <type_traits>
16#include "comms/Assert.h"
17#include "comms/Field.h"
18#include "comms/Message.h"
19#include "comms/MessageBase.h"
20#include "comms/details/detect.h"
21#include "comms/details/tag.h"
23#include "comms/protocol/details/MsgDataLayerOptionsParser.h"
24#include "comms/util/Tuple.h"
26#include "ProtocolLayerBase.h"
27
28namespace comms
29{
30
31namespace protocol
32{
33
39template <typename... TOptions>
41{
42 using ParsedOptionsInternal = details::MsgDataLayerOptionsParser<TOptions...>;
43
44public:
46 using ThisLayer = MsgDataLayer<TOptions...>;
47
50 {
51 return *this;
52 }
53
55 const ThisLayer& thisLayer() const
56 {
57 return *this;
58 }
59
65 using Field = typename ParsedOptionsInternal::FieldType;
66
68 using AllFields = std::tuple<Field>;
69
72 using AllMessages = void;
73
76 using MsgFactory = void;
77
79 static const std::size_t NumOfLayers = 1;
80
82 MsgDataLayer() = default;
83
85 MsgDataLayer(const MsgDataLayer&) = default;
86
89
91 ~MsgDataLayer() noexcept = default;
92
94 MsgDataLayer& operator=(const MsgDataLayer&) = default;
95
97 MsgDataLayer& operator=(MsgDataLayer&&) = default;
98
102 static constexpr bool canSplitRead()
103 {
104 return true;
105 }
106
126 template <typename TMsg, typename TIter, typename... TExtraValues>
128 TMsg& msg,
129 TIter& iter,
130 std::size_t size,
131 TExtraValues... extraValues)
132 {
133 using MsgType = typename std::decay<decltype(msg)>::type;
134 using Tag =
136 comms::isMessageBase<MsgType>()
137 >::template Type<
138 DirectOpTag<>,
140 comms::isMessage<MsgType>()
141 >::template Type<
142 InterfaceOpTag<>,
143 typename comms::util::LazyShallowConditional<
144 std::is_pointer<MsgType>::value
145 >::template Type<
146 PointerOpTag,
147 OtherOpTag
148 >
149 >
150 >;
151
152 if (setPayloadRequiredInternal(extraValues...)) {
153 auto fromIter = iter;
154 auto es = readInternal(msg, iter, size, Tag(), extraValues...);
155 setMsgPayloadInternal(fromIter, static_cast<std::size_t>(std::distance(fromIter, iter)), extraValues...);
156 return es;
157 }
158
159 return readInternal(msg, iter, size, Tag(), extraValues...);
160 }
161
165 template <typename TMsg, typename TIter, typename... TExtraValues>
167 TMsg& msg,
168 TIter& iter,
169 std::size_t size,
170 TExtraValues...)
171 {
172 static_cast<void>(msg);
173 static_cast<void>(iter);
174 static_cast<void>(size);
176 }
177
182 template <typename TMsg, typename TIter, typename... TExtraValues>
184 TMsg& msg,
185 TIter& iter,
186 std::size_t size,
187 TExtraValues... extraValues)
188 {
189 return read(msg, iter, size, extraValues...);
190 }
191
216 template <typename TAllFields, typename TMsg, typename TIter, typename... TExtraValues>
218 TAllFields& allFields,
219 TMsg& msg,
220 TIter& iter,
221 std::size_t size,
222 TExtraValues... extraValues)
223 {
224
226 "Expected TAllFields to be tuple.");
227
228 using AllFieldsDecayed = typename std::decay<TAllFields>::type;
229 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(), "Passed tuple is wrong.");
230 static const std::size_t Idx =
231 std::tuple_size<AllFieldsDecayed>::value -
232 std::tuple_size<AllFields>::value;
233
234 static_assert((Idx + 1) == std::tuple_size<TAllFields>::value,
235 "All fields must be read when MsgDataLayer is reached");
236
237 using IterType = typename std::decay<decltype(iter)>::type;
238 using IterTag = typename std::iterator_traits<IterType>::iterator_category;
239 static_assert(std::is_base_of<std::random_access_iterator_tag, IterTag>::value,
240 "Caching read from non random access iterators are not supported at this moment.");
241
242 auto& dataField = std::get<Idx>(allFields);
243
244 using FieldType = typename std::decay<decltype(dataField)>::type;
245 static_assert(
246 std::is_same<Field, FieldType>::value,
247 "Field has wrong type");
248
249 auto dataIter = iter;
250 auto es = read(msg, iter, size, extraValues...);
251 if (es != ErrorStatus::Success) {
252 return es;
253 }
254
255 auto dataSize = static_cast<std::size_t>(std::distance(dataIter, iter));
256 setMsgPayloadInternal(dataIter, dataSize, extraValues...);
257
258 auto dataEs = dataField.read(dataIter, dataSize);
259 static_cast<void>(dataEs);
261 return es;
262 }
263
267 template <typename TAllFields, typename TMsg, typename TIter, typename... TExtraValues>
269 TAllFields& allFields,
270 TMsg& msg,
271 TIter& iter,
272 std::size_t size,
273 TExtraValues...)
274 {
275 static_cast<void>(allFields);
276 static_cast<void>(msg);
277 static_cast<void>(iter);
278 static_cast<void>(size);
280 }
281
286 template <typename TAllFields, typename TMsg, typename TIter, typename... TExtraValues>
288 TAllFields& allFields,
289 TMsg& msg,
290 TIter& iter,
291 std::size_t size,
292 TExtraValues... extraValues)
293 {
294 return readFieldsCached(allFields, msg, iter, size, extraValues...);
295 }
296
314 template <typename TMsg, typename TIter>
316 const TMsg& msg,
317 TIter& iter,
318 std::size_t size)
319 {
320 using MsgType = typename std::decay<decltype(msg)>::type;
321
322 static_assert(
323 comms::isMessage<MsgType>(),
324 "The provided message object must inherit from comms::Message");
325
326 using Tag =
328 comms::isMessageBase<MsgType>()
329 >::template Type<
330 DirectOpTag<>,
332 comms::isMessage<MsgType>()
333 >::template Type<
334 InterfaceOpTag<>,
335 typename comms::util::LazyShallowConditional<
336 std::is_pointer<MsgType>::value
337 >::template Type<
338 PointerOpTag,
339 OtherOpTag
340 >
341 >
342 >;
343
344 return writeInternal(msg, iter, size, Tag());
345 }
346
362 template <typename TAllFields, typename TMsg, typename TIter>
364 TAllFields& allFields,
365 const TMsg& msg,
366 TIter& iter,
367 std::size_t size)
368 {
370 "Expected TAllFields to be tuple.");
371
372 using AllFieldsDecayed = typename std::decay<TAllFields>::type;
373 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(), "Passed tuple is wrong.");
374 static const std::size_t Idx =
375 std::tuple_size<AllFieldsDecayed>::value -
376 std::tuple_size<AllFields>::value;
377
378 static_assert((Idx + 1) == std::tuple_size<TAllFields>::value,
379 "All fields must be written when MsgDataLayer is reached");
380
381 auto& dataField = std::get<Idx>(allFields);
382 using FieldType = typename std::decay<decltype(dataField)>::type;
383 static_assert(
384 std::is_same<Field, FieldType>::value,
385 "Field has wrong type");
386
387 using IterType = typename std::decay<decltype(iter)>::type;
388 using IterTag = typename std::iterator_traits<IterType>::iterator_category;
389 return writeWithFieldCachedInternal(dataField, msg, iter, size, IterTag());
390 }
391
405 template <typename TIter>
406 static comms::ErrorStatus update(TIter& iter, std::size_t size)
407 {
408 std::advance(iter, size);
410 }
411
418 template <typename TMsg, typename TIter>
419 static comms::ErrorStatus update(const TMsg& msg, TIter& iter, std::size_t size)
420 {
421 static_cast<void>(msg);
422 return update(iter, size);
423 }
424
438 template <typename TAllFields, typename TIter>
440 TAllFields& allFields,
441 TIter& iter,
442 std::size_t size)
443 {
444 static_cast<void>(allFields);
445 std::advance(iter, size);
447 }
448
464 template <typename TAllFields, typename TMsg, typename TIter>
466 TAllFields& allFields,
467 const TMsg& msg,
468 TIter& iter,
469 std::size_t size)
470 {
471 static_cast<void>(allFields);
472 static_cast<void>(msg);
473 std::advance(iter, size);
475 }
476
482 static constexpr std::size_t length()
483 {
484 return 0U;
485 }
486
495 template <typename TMsg>
496 static constexpr std::size_t length(const TMsg& msg)
497 {
498 using MsgType = typename std::decay<decltype(msg)>::type;
499
500 static_assert(
501 comms::isMessage<MsgType>(),
502 "The provided message object must inherit from comms::Message");
503
504 using Tag =
505 typename comms::util::LazyShallowConditional<
506 details::ProtocolLayerHasFieldsImpl<MsgType>::Value
507 >::template Type<
508 MsgDirectLengthTag,
509 MsgHasLengthTag
510 >;
511 return getMsgLength(msg, Tag());
512 }
513
518 template <typename TAllFields>
519 static auto accessCachedField(TAllFields& allFields) ->
520 decltype(std::get<std::tuple_size<typename std::decay<TAllFields>::type>::value - std::tuple_size<AllFields>::value>(allFields))
521 {
522 using AllFieldsDecayed = typename std::decay<TAllFields>::type;
523 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(), "Passed tuple is wrong.");
524 static const std::size_t Idx =
525 std::tuple_size<AllFieldsDecayed>::value -
526 std::tuple_size<AllFields>::value;
527
528 return std::get<Idx>(allFields);
529 }
530
531private:
532 template <typename... TParams>
533 using MsgHasLengthTag = comms::details::tag::Tag1<>;
534
535 template <typename... TParams>
536 using MsgNoLengthTag = comms::details::tag::Tag2<>;
537
538 template <typename... TParams>
539 using MsgDirectLengthTag = comms::details::tag::Tag3<>;
540
541 template <typename... TParams>
542 using DirectOpTag = comms::details::tag::Tag4<>;
543
544 template <typename... TParams>
545 using InterfaceOpTag = comms::details::tag::Tag5<>;
546
547 template <typename... TParams>
548 using PointerOpTag = comms::details::tag::Tag6<>;
549
550 template <typename... TParams>
551 using OtherOpTag = comms::details::tag::Tag7<>;
552
553 template <typename TMsg, typename TIter>
554 static ErrorStatus writeWithFieldCachedInternal(
555 Field& field,
556 const TMsg& msg,
557 TIter& iter,
558 std::size_t size,
559 std::random_access_iterator_tag)
560 {
561 return writeWithFieldCachedRandomAccess(field, msg, iter, size);
562 }
563
564 template <typename TMsg, typename TIter>
565 static ErrorStatus writeWithFieldCachedInternal(
566 Field& field,
567 const TMsg& msg,
568 TIter& iter,
569 std::size_t size,
570 std::output_iterator_tag)
571 {
572 return writeWithFieldCachedOutput(field, msg, iter, size);
573 }
574
575 template <typename TMsg, typename TIter>
576 static ErrorStatus writeWithFieldCachedRandomAccess(
577 Field& field,
578 const TMsg& msg,
579 TIter& iter,
580 std::size_t size)
581 {
582 auto dataReadIter = iter;
583 auto es = write(msg, iter, size);
584 if (es != comms::ErrorStatus::Success) {
585 return es;
586 }
587
588 auto writtenCount = static_cast<std::size_t>(std::distance(dataReadIter, iter));
589 auto dataEs = field.read(dataReadIter, writtenCount);
591 static_cast<void>(dataEs);
593 }
594
595 template <typename TMsg, typename TCollection>
596 static ErrorStatus writeWithFieldCachedOutput(
597 Field& field,
598 const TMsg& msg,
599 std::back_insert_iterator<TCollection>& iter,
600 std::size_t size)
601 {
602 auto es = write(msg, iter, size);
603 if (es != comms::ErrorStatus::Success) {
604 return es;
605 }
606
607 TCollection col;
608 auto dataWriteIter = std::back_inserter(col);
609 auto dataWriteEs = write(msg, dataWriteIter, size);
611 static_cast<void>(dataWriteEs);
612
613 auto dataReadIter = col.cbegin();
614 auto dataReadEs = field.read(dataReadIter, col.size());
616 static_cast<void>(dataReadEs);
617
619 }
620
621 template <typename TMsg, typename... TParams>
622 static std::size_t getMsgLength(const TMsg& msg, MsgHasLengthTag<TParams...>)
623 {
624 using MsgType = typename std::decay<decltype(msg)>::type;
625 static_assert(MsgType::hasLength(), "Message interface must define length()");
626 return msg.length();
627 }
628
629 template <typename TMsg, typename... TParams>
630 static constexpr std::size_t getMsgLength(const TMsg& msg, MsgDirectLengthTag<TParams...>)
631 {
632 using MsgType = typename std::decay<decltype(msg)>::type;
633 static_assert(MsgType::hasFields(), "FieldsImpl option hasn't been used");
634 return msg.doLength();
635 }
636
637 template <typename TMsg, typename... TParams>
638 static constexpr std::size_t getMsgLength(const TMsg&, MsgNoLengthTag<TParams...>)
639 {
640 return 0U;
641 }
642
643 template <typename TMsg, typename TIter, typename... TExtraValues>
644 static ErrorStatus readInternalPolymorphic(
645 TMsg& msg,
646 TIter& iter,
647 std::size_t size,
648 TExtraValues... extraValues)
649 {
650 using MsgType = typename std::decay<decltype(msg)>::type;
651
652 static_assert(
653 comms::isMessage<MsgType>(),
654 "The provided message object must inherit from comms::Message");
655
656 static_assert(MsgType::hasRead(),
657 "Message interface must support polymorphic read operation");
658
659 using IterType = typename std::decay<decltype(iter)>::type;
660
661 static_assert(std::is_convertible<IterType, typename MsgType::ReadIterator>::value,
662 "The provided iterator is not convertible to ReadIterator defined by Message class");
663
664 using ReadIter = typename std::add_lvalue_reference<typename MsgType::ReadIterator>::type;
665
666 auto result = msg.read(static_cast<ReadIter>(iter), size);
667 if ((result == ErrorStatus::NotEnoughData) &&
668 missingSizeRequiredInternal(extraValues...)) {
669 using Tag =
670 typename comms::util::LazyShallowConditional<
671 MsgType::hasLength()
672 >::template Type<
673 MsgHasLengthTag,
674 MsgNoLengthTag
675 >;
676
677 std::size_t missingSize = 1U;
678 auto msgLen = getMsgLength(msg, Tag());
679 if (size < msgLen) {
680 missingSize = msgLen - size;
681 }
682 updateMissingSizeInternal(missingSize, extraValues...);
683 }
684 return result;
685 }
686
687 template <typename TMsg, typename TIter, typename... TExtraValues>
688 static ErrorStatus readInternalDirect(
689 TMsg& msg,
690 TIter& iter,
691 std::size_t size,
692 TExtraValues... extraValues)
693 {
694 using MsgType = typename std::decay<decltype(msg)>::type;
695
696 static_assert(
697 comms::isMessageBase<MsgType>(),
698 "The provided message object must inherit from comms::MessageBase");
699
700 static_assert(details::protocolLayerHasFieldsImpl<MsgType>(),
701 "Message class must use FieldsImpl option");
702
703 auto result = msg.doRead(iter, size);
704 if ((result == ErrorStatus::NotEnoughData) &&
705 (missingSizeRequiredInternal(extraValues...))) {
706 std::size_t missingSize = 1U;
707 auto msgLen = getMsgLength(msg, MsgDirectLengthTag<>());
708 if (size < msgLen) {
709 missingSize = msgLen - size;
710 }
711 updateMissingSizeInternal(missingSize, extraValues...);
712 }
713 return result;
714 }
715
716 template <typename TMsg, typename TIter, typename... TExtraValues>
717 static ErrorStatus readInternal(
718 TMsg& msg,
719 TIter& iter,
720 std::size_t size,
721 DirectOpTag<>,
722 TExtraValues... extraValues)
723 {
724 return readInternalDirect(msg, iter, size, extraValues...);
725 }
726
727 template <typename TMsg, typename TIter, typename... TExtraValues>
728 static ErrorStatus readInternal(
729 TMsg& msg,
730 TIter& iter,
731 std::size_t size,
732 InterfaceOpTag<>,
733 TExtraValues... extraValues)
734 {
735 static_assert(comms::isMessage<TMsg>(), "Must be interface class");
736 static_assert(TMsg::hasRead(),
737 "Message interface must support polymorphic read operation");
738
739 return readInternalPolymorphic(msg, iter, size, extraValues...);
740 }
741
742 template <typename TMsg, typename TIter, typename... TExtraValues>
743 static ErrorStatus readInternal(
744 TMsg& msg,
745 TIter& iter,
746 std::size_t size,
747 PointerOpTag<>,
748 TExtraValues... extraValues)
749 {
750 return read(*msg, iter, size, extraValues...);
751 }
752
753 template <typename TMsg, typename TIter, typename... TExtraValues>
754 static ErrorStatus readInternal(
755 TMsg& msg,
756 TIter& iter,
757 std::size_t size,
758 OtherOpTag<>,
759 TExtraValues... extraValues)
760 {
761 using MsgType = typename std::decay<decltype(msg)>::type;
762 static_assert(comms::details::hasElementType<MsgType>(),
763 "Unsupported type of message object, expected to be either message itself, raw pointer or smart pointer");
764 return read(*msg, iter, size, extraValues...);
765 }
766
767 template <typename TMsg, typename TIter, typename... TParams>
768 static ErrorStatus writeInternal(
769 const TMsg& msg,
770 TIter& iter,
771 std::size_t size,
772 DirectOpTag<TParams...>)
773 {
774 return msg.doWrite(iter, size);
775 }
776
777 template <typename TMsg, typename TIter, typename... TParams>
778 static ErrorStatus writeInternal(
779 const TMsg& msg,
780 TIter& iter,
781 std::size_t size,
782 InterfaceOpTag<TParams...>)
783 {
784 using MsgType = typename std::decay<decltype(msg)>::type;
785
786 static_assert(MsgType::hasWrite(),
787 "Message interface must support polymorphic write operation");
788
789 using IterType = typename std::decay<decltype(iter)>::type;
790
791 static_assert(std::is_convertible<IterType, typename MsgType::WriteIterator>::value,
792 "The provided iterator is not convertible to WriteIterator defined by Message class");
793
794 using WriteIter = typename std::add_lvalue_reference<typename MsgType::WriteIterator>::type;
795
796 return msg.write(static_cast<WriteIter>(iter), size);
797 }
798
799 template <typename TMsg, typename TIter, typename... TParams>
800 static ErrorStatus writeInternal(
801 const TMsg& msg,
802 TIter& iter,
803 std::size_t size,
804 PointerOpTag<TParams...>)
805 {
806 return write(*msg, iter, size);
807 }
808
809 template <typename TMsg, typename TIter, typename... TParams>
810 static ErrorStatus writeInternal(
811 const TMsg& msg,
812 TIter& iter,
813 std::size_t size,
814 OtherOpTag<TParams...>)
815 {
816 using MsgType = typename std::decay<decltype(msg)>::type;
817 static_assert(comms::details::hasElementType<MsgType>(),
818 "Unsupported type of message object, expected to be either message itself, raw pointer or smart pointer");
819
820 return write(*msg, iter, size);
821 }
822
823 static constexpr bool missingSizeRequiredInternal()
824 {
825 return false;
826 }
827
828 template <typename... TExtraValues>
829 static bool missingSizeRequiredInternal(details::MissingSizeRetriever<>, TExtraValues...)
830 {
831 return true;
832 }
833
834 template <typename T, typename... TExtraValues>
835 static bool missingSizeRequiredInternal(T, TExtraValues... extraValues)
836 {
837 static_assert(
838 !details::isMissingSizeRetriever<T>(),
839 "Mustn't be missing size retriever");
840 return missingSizeRequiredInternal(extraValues...);
841 }
842
843 static void updateMissingSizeInternal(std::size_t val)
844 {
845 static_cast<void>(val);
846 }
847
848 template <typename... TExtraValues>
849 static void updateMissingSizeInternal(
850 std::size_t val,
851 details::MissingSizeRetriever<> retriever,
852 TExtraValues... extraValues)
853 {
854 retriever.setValue(val);
855 updateMissingSizeInternal(val, extraValues...);
856 }
857
858 template <typename T, typename... TExtraValues>
859 static void updateMissingSizeInternal(std::size_t val, T retriever, TExtraValues... extraValues)
860 {
861 static_cast<void>(retriever);
862 static_assert(
863 !details::isMissingSizeRetriever<typename std::decay<decltype(retriever)>::type>(),
864 "Mustn't be missing size retriever");
865 updateMissingSizeInternal(val, extraValues...);
866 }
867
868 static constexpr bool setPayloadRequiredInternal()
869 {
870 return false;
871 }
872
873 template <typename TIter, typename... TExtraValues>
874 static bool setPayloadRequiredInternal(details::MsgPayloadRetriever<TIter>, TExtraValues...)
875 {
876 return true;
877 }
878
879 template <typename T, typename... TExtraValues>
880 static bool setPayloadRequiredInternal(T, TExtraValues... extraValues)
881 {
882 static_assert(
883 !details::isMsgPayloadRetriever<T>(),
884 "Mustn't be message payload retriever");
885 return setPayloadRequiredInternal(extraValues...);
886 }
887
888 template <typename TIter>
889 static void setMsgPayloadInternal(TIter iter, std::size_t len)
890 {
891 static_cast<void>(iter);
892 static_cast<void>(len);
893 }
894
895 template <typename TIter, typename TOtherIter, typename... TExtraValues>
896 static void setMsgPayloadInternal(
897 TIter iter,
898 std::size_t len,
899 details::MsgPayloadRetriever<TOtherIter> retriever,
900 TExtraValues... extraValues)
901 {
902 retriever.setValue(iter, len);
903 setMsgPayloadInternal(iter, len, extraValues...);
904 }
905
906 template <typename TIter, typename T, typename... TExtraValues>
907 static void setMsgPayloadInternal(
908 TIter iter,
909 std::size_t len,
910 T retriever,
911 TExtraValues... extraValues)
912 {
913 static_cast<void>(retriever);
914 static_assert(
915 !details::isMsgPayloadRetriever<typename std::decay<decltype(retriever)>::type>(),
916 "Mustn't be message payload retriever");
917 setMsgPayloadInternal(iter, len, extraValues...);
918 }
919};
920
921namespace details
922{
923template <typename T>
924struct MsgDataLayerCheckHelper
925{
926 static const bool Value = false;
927};
928
929template <typename... TExtraOpts>
930struct MsgDataLayerCheckHelper<MsgDataLayer<TExtraOpts...> >
931{
932 static const bool Value = true;
933};
934
935} // namespace details
936
940template <typename T>
941constexpr bool isMsgDataLayer()
942{
943 return details::MsgDataLayerCheckHelper<T>::Value;
944}
945
946template <typename... TExtraOpts>
947constexpr
948MsgDataLayer<TExtraOpts...>&
949toProtocolLayerBase(MsgDataLayer<TExtraOpts...>& layer)
950{
951 return layer;
952}
953
954template <typename... TExtraOpts>
955constexpr
956const MsgDataLayer<TExtraOpts...>&
957toProtocolLayerBase(const MsgDataLayer<TExtraOpts...>& layer)
958{
959 return layer;
960}
961
962} // namespace protocol
963
964} // namespace comms
965
966
967
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
Contains definition of comms::Field class.
Contains definition of comms::field::IntValue.
Provides common base class for the custom messages with default implementation.
Contains definition of Message object interface and various base classes for custom messages.
Contains definition of comms::protocol::ProtocolLayerBase.
Contains various tuple type manipulation classes and functions.
Base class to all the field classes.
Definition Field.h:33
Message data layer.
Definition MsgDataLayer.h:41
static constexpr std::size_t length(const TMsg &msg)
Get remaining length of wrapping transport information + length of the provided message.
Definition MsgDataLayer.h:496
static comms::ErrorStatus update(const TMsg &msg, TIter &iter, std::size_t size)
Update recently written (using write()) message contents data.
Definition MsgDataLayer.h:419
constexpr bool isMsgDataLayer()
Compile time check of whether the provided type is a variant of MsgDataLayer.
Definition MsgDataLayer.h:941
static ErrorStatus readFieldsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Read the message contents while caching the read transport information fields.
Definition MsgDataLayer.h:217
typename ParsedOptionsInternal::FieldType Field
Raw data field type.
Definition MsgDataLayer.h:65
void AllMessages
Default value of AllMessages type.
Definition MsgDataLayer.h:72
static ErrorStatus writeFieldsCached(TAllFields &allFields, const TMsg &msg, TIter &iter, std::size_t size)
Write the message contents while caching the written transport information fields.
Definition MsgDataLayer.h:363
static ErrorStatus updateFieldsCached(TAllFields &allFields, const TMsg &msg, TIter &iter, std::size_t size)
Update recently written (using writeFieldsCached()) message data as well as cached transport informat...
Definition MsgDataLayer.h:465
MsgDataLayer(const MsgDataLayer &)=default
Copy constructor.
static const std::size_t NumOfLayers
Static constant indicating amount of transport layers used.
Definition MsgDataLayer.h:79
static ErrorStatus updateFieldsCached(TAllFields &allFields, TIter &iter, std::size_t size)
Update recently written (using writeFieldsCached()) message data as well as cached transport informat...
Definition MsgDataLayer.h:439
const ThisLayer & thisLayer() const
Get "const" access to this layer object.
Definition MsgDataLayer.h:55
static ErrorStatus readUntilDataFieldsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues...)
Read transport fields with caching until data layer.
Definition MsgDataLayer.h:268
static ErrorStatus readFromData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as read().
Definition MsgDataLayer.h:183
~MsgDataLayer() noexcept=default
Destructor.
static ErrorStatus write(const TMsg &msg, TIter &iter, std::size_t size)
Write the message contents.
Definition MsgDataLayer.h:315
ThisLayer & thisLayer()
Get access to this layer object.
Definition MsgDataLayer.h:49
static comms::ErrorStatus update(TIter &iter, std::size_t size)
Update recently written (using write()) message contents data.
Definition MsgDataLayer.h:406
static constexpr std::size_t length()
Get remaining length of wrapping transport information.
Definition MsgDataLayer.h:482
static ErrorStatus read(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Read the message contents.
Definition MsgDataLayer.h:127
MsgDataLayer()=default
Default constructor.
static ErrorStatus readUntilData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues...)
Read transport fields until data layer.
Definition MsgDataLayer.h:166
static constexpr bool canSplitRead()
Compile time check whether split read "until" and "from" data layer is allowed.
Definition MsgDataLayer.h:102
std::tuple< Field > AllFields
All fields of the remaining transport layers, contains only Field.
Definition MsgDataLayer.h:68
void MsgFactory
Default value of MsgFactory type.
Definition MsgDataLayer.h:76
static auto accessCachedField(TAllFields &allFields) -> decltype(std::get< std::tuple_size< typename std::decay< TAllFields >::type >::value - std::tuple_size< AllFields >::value >(allFields))
Access appropriate field from "cached" bundle of all the protocol stack fields.
Definition MsgDataLayer.h:519
MsgDataLayer(MsgDataLayer &&)=default
Move constructor.
static ErrorStatus readFromDataFeildsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as readFieldsCached().
Definition MsgDataLayer.h:287
comms::option::def::MsgType< TMsg > MsgType
Same as comms::option::def::MsgType.
Definition options.h:1468
details::MissingSizeRetriever missingSize(std::size_t &val)
Add "missing size" output parameter to protocol stack's (frame's) "read" operation.
Definition ProtocolLayerBase.h:1561
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
@ Success
Used to indicate successful outcome of the operation.
Replacement to std::conditional.
Definition type_traits.h:28
Check whether provided type is a variant of std::tuple.
Definition Tuple.h:36
Replacement to some types from standard type_traits.