1 #ifndef __MARNAV__NMEA__AIS_HELPER__HPP__
2 #define __MARNAV__NMEA__AIS_HELPER__HPP__
5 #include <marnav/nmea/vdm.hpp>
6 #include <marnav/nmea/vdo.hpp>
14 /// @brief Collects payload from proper NMEA sentences.
16 /// @note This function assumes, that all sentences in the specified range are
17 /// providing payload (VDM or VDO).
19 /// @param[in] begin Iterator pointing to the beginning of the messges to process.
20 /// @param[in] end Iterator pointing after the messages to process (will not be
22 /// @return The container with all payload and padding bit information.
24 /// std::unique_ptr<nmea::sentence> variant. Example:
26 /// std::vector<std::unique_ptr<nmea::sentence>> v;
27 /// v.push_back(nmea::make_sentence("..."));
28 /// v.push_back(nmea::make_sentence("..."));
29 /// auto data = nmea::collect_payload(v.begin(), v.end());
31 template <class InputIt
, typename
std::enable_if
<std::is_class
<InputIt
>::value
32 && std::is_convertible
<typename
InputIt::value_type
,
33 std::unique_ptr
<sentence
>>::value
,
36 std::vector
<std::pair
<std::string
, uint32_t>> collect_payload(InputIt begin
, InputIt end
)
38 std::vector
<std::pair
<std::string
, uint32_t>> v
;
39 v
.reserve(std::distance(begin
, end
));
41 for (; begin
!= end
; ++begin
) {
42 const auto & t
= *begin
;
44 // sentence_cast is not dynamic_cast, therefore the class hierarchy
45 // is not detected automatically (the advantage is, it is faster).
46 // this means, we have to check individually for VDM and VDO.
48 if (t
->id() == sentence_id::VDM
) {
49 const auto s
= sentence_cast
<nmea::vdm
>(t
.get());
50 v
.push_back(make_pair(s
->get_payload(), s
->get_n_fill_bits()));
51 } else if (t
->id() == sentence_id::VDO
) {
52 const auto s
= sentence_cast
<nmea::vdo
>(t
.get());
53 v
.push_back(make_pair(s
->get_payload(), s
->get_n_fill_bits()));
55 throw std::runtime_error
{"invalid sentence in collect_payload"};
62 /// Object iterator variant. Example:
64 /// std::vector<nmea::vdm> v; // collect data, for example:
65 /// v.push_back(nmea::vdm{});
66 /// v.push_back(nmea::vdm{});
67 /// auto data = nmea::collect_payload(v.begin(), v.end());
69 template <class InputIt
, typename
std::enable_if
<std::is_class
<InputIt
>::value
70 && !std::is_convertible
<typename
InputIt::value_type
,
71 std::unique_ptr
<sentence
>>::value
,
74 std::vector
<std::pair
<std::string
, uint32_t>> collect_payload(InputIt begin
, InputIt end
)
76 std::vector
<std::pair
<std::string
, uint32_t>> v
;
77 v
.reserve(std::distance(begin
, end
));
78 for (; begin
!= end
; ++begin
) {
79 v
.push_back(make_pair(begin
->get_payload(), begin
->get_n_fill_bits()));
84 /// Pointer variant. Example:
86 /// nmea::vdm v[3]; // initialize them in any way...
87 /// auto data = nmea::collect_payload(v, v + 3);
91 /// nmea::vdm v[3]; // initialize them in any way...
92 /// auto data = nmea::collect_payload(std::begin(v), std::end(v));
94 /// this will not compile, because MTW does not provide payload:
97 /// auto data = nmea::collect_payload(std::begin(v), std::end(v));
99 template <class InputIt
,
100 typename
std::enable_if
<std::is_pointer
<InputIt
>::value
, int>::type
= 0>
101 std::vector
<std::pair
<std::string
, uint32_t>> collect_payload(InputIt begin
, InputIt end
)
103 std::vector
<std::pair
<std::string
, uint32_t>> v
;
104 v
.reserve(std::distance(begin
, end
));
105 for (; begin
!= end
; ++begin
) {
106 v
.push_back(make_pair(begin
->get_payload(), begin
->get_n_fill_bits()));
113 std::vector
<std::unique_ptr
<nmea::sentence
>> make_vdms(
114 const std::vector
<std::pair
<std::string
, uint32_t>> & payload
,
115 utils::optional
<uint32_t> seq_msg_id
= utils::optional
<uint32_t>{},
116 ais_channel radio_channel
= ais_channel::B
);