COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
process.h
Go to the documentation of this file.
1//
2// Copyright 2019 - 2024 (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 <type_traits>
14#include <iterator>
15
16#include "comms/ErrorStatus.h"
17#include "comms/iterator.h"
18#include "comms/dispatch.h"
19#include "comms/Message.h"
20#include "comms/Assert.h"
21#include "comms/MsgDispatcher.h"
22#include "comms/details/detect.h"
23#include "comms/details/process.h"
26
27namespace comms
28{
29
51template <typename TBufIter, typename TFrame, typename TMsg, typename... TExtraValues>
53 TBufIter& bufIter,
54 std::size_t len,
55 TFrame&& frame,
56 TMsg& msg,
57 TExtraValues... extraValues)
58{
59 std::size_t consumed = 0U;
60 auto onExit =
61 comms::util::makeScopeGuard(
62 [&bufIter, &consumed]()
63 {
64 std::advance(bufIter, consumed);
65 });
66 static_cast<void>(onExit);
67
68 while (consumed < len) {
69 auto begIter = comms::readIteratorFor(msg, bufIter + consumed);
70 auto iter = begIter;
71
72 // Do the read
73 auto es = frame.read(msg, iter, len - consumed, extraValues...);
75 return es;
76 }
77
79 // Something is not right with the data, remove one character and try again
80 ++consumed;
81 continue;
82 }
83
84 consumed += static_cast<decltype(consumed)>(std::distance(begIter, iter));
85 return es;
86 }
87
89}
90
118template <typename TBufIter, typename TFrame, typename TMsg, typename THandler, typename... TExtraValues>
120 TBufIter& bufIter,
121 std::size_t len,
122 TFrame&& frame,
123 TMsg& msg,
124 THandler& handler,
125 TExtraValues... extraValues)
126{
127 using LocalMsgIdType = details::ProcessMsgIdType<typename std::decay<decltype(msg)>::type>;
128 LocalMsgIdType id = LocalMsgIdType();
129 std::size_t idx = 0U;
130
131 auto es =
133 bufIter,
134 len,
135 std::forward<TFrame>(frame),
136 msg,
139 extraValues...);
140
141 if (es != comms::ErrorStatus::Success) {
142 return es;
143 }
144
145 static_cast<void>(handler);
146 using FrameType = typename std::decay<decltype(frame)>::type;
147 using AllMessagesType = typename FrameType::AllMessages;
148 auto& msgObj = details::processMsgCastToMsgObj(msg);
149 comms::dispatchMsg<AllMessagesType>(id, idx, msgObj, handler);
150 return es;
151}
152
183template <typename TDispatcher, typename TBufIter, typename TFrame, typename TMsg, typename THandler, typename... TExtraValues>
185 TBufIter& bufIter,
186 std::size_t len,
187 TFrame&& frame,
188 TMsg& msg,
189 THandler& handler,
190 TExtraValues... extraValues)
191{
192 using LocalMsgIdType = details::ProcessMsgIdType<typename std::decay<decltype(msg)>::type>;
193 static_assert(!std::is_void<LocalMsgIdType>(), "Invalid type of msg param");
194
195 LocalMsgIdType id = LocalMsgIdType();
196 std::size_t idx = 0U;
197
198 auto es =
200 bufIter,
201 len,
202 std::forward<TFrame>(frame),
203 msg,
206 extraValues...);
207
208 if (es != comms::ErrorStatus::Success) {
209 return es;
210 }
211
212 using FrameType = typename std::decay<decltype(frame)>::type;
213 using AllMessagesType = typename FrameType::AllMessages;
214 static_assert(
215 comms::isMsgDispatcher<TDispatcher>(),
216 "TDispatcher is expected to be a variant of comms::MsgDispatcher");
217
218 auto& msgObj = details::processMsgCastToMsgObj(msg);
219 TDispatcher::template dispatch<AllMessagesType>(id, idx, msgObj, handler);
220 return es;
221}
222
245template <typename TBufIter, typename TFrame, typename THandler, typename... TExtraValues>
247 TBufIter bufIter,
248 std::size_t len,
249 TFrame&& frame,
250 THandler& handler)
251{
252 std::size_t consumed = 0U;
253 using FrameType = typename std::decay<decltype(frame)>::type;
254 using MsgPtr = typename FrameType::MsgPtr;
255 while (consumed < len) {
256 auto begIter = bufIter + consumed;
257 auto iter = begIter;
258
259 MsgPtr msg;
260 auto es = processSingleWithDispatch(iter, len - consumed, std::forward<TFrame>(frame), msg, handler);
261 consumed += static_cast<decltype(consumed)>(std::distance(begIter, iter));
263 break;
264 }
265 COMMS_ASSERT(consumed <= len);
266 }
267
268 return consumed;
269}
270
294template <typename TDispatcher, typename TBufIter, typename TFrame, typename THandler, typename... TExtraValues>
296 TBufIter bufIter,
297 std::size_t len,
298 TFrame&& frame,
299 THandler& handler)
300{
301 std::size_t consumed = 0U;
302 using FrameType = typename std::decay<decltype(frame)>::type;
303 using MsgPtr = typename FrameType::MsgPtr;
304 while (consumed < len) {
305 auto begIter = bufIter + consumed;
306 auto iter = begIter;
307
308 MsgPtr msg;
309 auto es = processSingleWithDispatchViaDispatcher<TDispatcher>(iter, len - consumed, std::forward<TFrame>(frame), msg, handler);
310 consumed += static_cast<decltype(consumed)>(std::distance(begIter, iter));
312 break;
313 }
314 COMMS_ASSERT(consumed <= len);
315 }
316
317 return consumed;
318}
319
320} // namespace comms
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
This file contain definition of error statuses used by comms module.
Contains definition of Message object interface and various base classes for custom messages.
Contains definition of MsgDispatcher class which facilitates dispatching of message object to appropr...
Contains definition of comms::protocol::ProtocolLayerBase.
Contains definition of the "Scope Guard" idiom, see comms::util::ScopeGuard.
Contains extra logic to help with dispatching message types and objects.
Provides auxiliary functions for retrieving best type of iterator for read/write operations.
details::MsgIdRetriever< TId > msgId(TId &val)
Add "message ID" output parameter to protocol stack's (frame's) "read" operation.
Definition ProtocolLayerBase.h:1588
details::MsgIndexRetriever msgIndex(std::size_t &val)
Add "message index" output parameter to protocol stack's (frame's) "read" operation.
Definition ProtocolLayerBase.h:1626
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.
std::size_t processAllWithDispatch(TBufIter bufIter, std::size_t len, TFrame &&frame, THandler &handler)
Process all available input and dispatch all created message objects to appropriate handling function...
Definition process.h:246
auto readIteratorFor(TIter &&iter) -> decltype(details::ReadIteratorHelper<>::template get< TMessage >(std::forward< TIter >(iter)))
Create and initialise iterator for message read.
Definition iterator.h:24
comms::ErrorStatus processSingle(TBufIter &bufIter, std::size_t len, TFrame &&frame, TMsg &msg, TExtraValues... extraValues)
Process input until first message is recognized and its object is created or missing data is reported...
Definition process.h:52
comms::ErrorStatus processSingleWithDispatch(TBufIter &bufIter, std::size_t len, TFrame &&frame, TMsg &msg, THandler &handler, TExtraValues... extraValues)
Process input until first message is recognized, its object is created and dispatched to appropriate ...
Definition process.h:119
comms::ErrorStatus processSingleWithDispatchViaDispatcher(TBufIter &bufIter, std::size_t len, TFrame &&frame, TMsg &msg, THandler &handler, TExtraValues... extraValues)
Process input until first message is recognized, its object is created and dispatched to appropriate ...
Definition process.h:184
std::size_t processAllWithDispatchViaDispatcher(TBufIter bufIter, std::size_t len, TFrame &&frame, THandler &handler)
Process all available input and dispatch all created message objects to appropriate handling function...
Definition process.h:295