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 "comms/Assert.h"
14#include "comms/Field.h"
15#include "comms/details/detect.h"
16#include "comms/details/tag.h"
17#include "comms/frame/details/MsgDataLayerOptionsParser.h"
19#include "comms/Message.h"
20#include "comms/MessageBase.h"
21#include "comms/util/Tuple.h"
23
24#include <iterator>
25#include <tuple>
26#include <type_traits>
27
28namespace comms
29{
30
31namespace frame
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::FrameLayerHasFieldsImpl<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::frameLayerHasFieldsImpl<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...>&
950{
951 return layer;
952}
953
954template <typename... TExtraOpts>
955constexpr
956const MsgDataLayer<TExtraOpts...>&
957toFrameLayerBase(const MsgDataLayer<TExtraOpts...>& layer)
958{
959 return layer;
960}
961
962} // namespace frame
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::frame::FrameLayerBase.
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 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
MsgDataLayer()=default
Default constructor.
static ErrorStatus readFromData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as read().
Definition MsgDataLayer.h:183
static constexpr std::size_t length()
Get remaining length of wrapping transport information.
Definition MsgDataLayer.h:482
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
std::tuple< Field > AllFields
All fields of the remaining transport layers, contains only Field.
Definition MsgDataLayer.h:68
static const std::size_t NumOfLayers
Static constant indicating amount of transport layers used.
Definition MsgDataLayer.h:79
typename ParsedOptionsInternal::FieldType Field
Raw data field type.
Definition MsgDataLayer.h:65
MsgDataLayer(const MsgDataLayer &)=default
Copy constructor.
static comms::ErrorStatus update(TIter &iter, std::size_t size)
Update recently written (using write()) message contents data.
Definition MsgDataLayer.h:406
~MsgDataLayer() noexcept=default
Destructor.
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
void AllMessages
Default value of AllMessages type.
Definition MsgDataLayer.h:72
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 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 frame fields.
Definition MsgDataLayer.h:519
void MsgFactory
Default value of MsgFactory type.
Definition MsgDataLayer.h:76
static ErrorStatus readUntilData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues...)
Read transport fields until data layer.
Definition MsgDataLayer.h:166
static ErrorStatus readFromDataFeildsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as readFieldsCached().
Definition MsgDataLayer.h:287
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 ErrorStatus write(const TMsg &msg, TIter &iter, std::size_t size)
Write the message contents.
Definition MsgDataLayer.h:315
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
static ErrorStatus read(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Read the message contents.
Definition MsgDataLayer.h:127
ThisLayer & thisLayer()
Get access to this layer object.
Definition MsgDataLayer.h:49
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(MsgDataLayer &&)=default
Move constructor.
const ThisLayer & thisLayer() const
Get "const" access to this layer object.
Definition MsgDataLayer.h:55
static constexpr bool canSplitRead()
Compile time check whether split read "until" and "from" data layer is allowed.
Definition MsgDataLayer.h:102
details::MissingSizeRetriever missingSize(std::size_t &val)
Add "missing size" output parameter to frame's "read" operation.
Definition FrameLayerBase.h:1559
FrameLayerBase< TField, TNextLayer, TDerived, TOptions... > & toFrameLayerBase(FrameLayerBase< TField, TNextLayer, TDerived, TOptions... > &layer)
Upcast protocol layer in order to have access to its internal types.
Definition FrameLayerBase.h:1519
comms::option::def::MsgType< TMsg > MsgType
Same as comms::option::def::MsgType.
Definition options.h:1487
comms::frame::MsgDataLayer< TOptions... > MsgDataLayer
Alias to the comms::frame::MsgDataLayer.
Definition MsgDataLayer.h:25
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:29
Check whether provided type is a variant of std::tuple.
Definition Tuple.h:36
Replacement to some types from standard type_traits.