1 #ifndef MARNAV__AIS__BINARY_DATA__HPP
2 #define MARNAV__AIS__BINARY_DATA__HPP
5 #include <marnav/utils/bitset.hpp>
11 /// Type for raw AIS data.
12 using raw
= utils::bitset
<uint8_t>;
16 char decode_sixbit_ascii(uint8_t value
);
17 uint8_t encode_sixbit_ascii(char c
);
21 std::string
trim_ais_string(const std::string
& s
);
23 /// Empty baseclass for binary data, provides protected functions to read and
24 /// write binary data from/to bitsets.
28 /// Represents data to be read from / written to a bitset.
29 /// The offset and number of bits (or sixbits) is encoded in the
30 /// template signature.
32 /// This template is used to specify the mapping (offset, count) of
33 /// a specific datum within the bitset, without the need of repeating
34 /// the mapping for read and write operations.
36 /// @tparam Offset The offset of the value within the bitset.
37 /// @tparam Count Number of bits of the value within the bitset.
38 /// @tparam T Data type to be used.
39 template <std::size_t Offset
, std::size_t Count
, typename T
> struct bitset_value final
{
40 friend class binary_data
;
43 static constexpr std::size_t offset
= Offset
;
44 static constexpr std::size_t count
= Count
;
47 bitset_value(value_type t
)
52 bitset_value(const bitset_value
&) = default;
53 bitset_value
& operator=(const bitset_value
&) = default;
55 bitset_value(bitset_value
&&) = default;
56 bitset_value
& operator=(bitset_value
&&) = default;
58 value_type
get() const { return value
; }
60 operator value_type() const { return value
; }
62 bitset_value
& operator=(value_type t
)
74 static std::string
read_string(
75 const raw
& bits
, raw::size_type ofs
, raw::size_type count_sixbits
);
77 static void write_string(
78 raw
& bits
, raw::size_type ofs
, raw::size_type count_sixbits
, const std::string
& s
);
84 /// Reads data from the AIS message (bitset).
85 /// This is the `enum` variant.
87 /// @tparam T `bitset_value` type.
88 /// @param[in] bits The AIS message to read from.
89 /// @param[out] t The data read from the message.
92 typename
std::enable_if
<std::is_enum
<typename
T::value_type
>::value
, int>::type
= 0>
93 static void get(const raw
& bits
, T
& t
)
95 typename
std::underlying_type
<typename
T::value_type
>::type tmp
;
96 bits
.get(tmp
, T::offset
, T::count
);
97 t
.value
= static_cast<typename
T::value_type
>(tmp
);
100 /// The `bool` variant of `get`.
102 template <typename T
,
103 typename
std::enable_if
<std::is_same
<typename
T::value_type
, bool>::value
, int>::type
105 static void get(const raw
& bits
, T
& t
)
107 t
= bits
.get_bit(T::offset
);
110 /// The non `enum` and non `string` variant of `get`.
112 template <typename T
, typename
std::enable_if
<!std::is_enum
<typename
T::value_type
>::value
113 && !std::is_same
<typename
T::value_type
, bool>::value
114 && !std::is_same
<typename
T::value_type
, std::string
>::value
,
117 static void get(const raw
& bits
, T
& t
)
119 bits
.get(t
.value
, T::offset
, T::count
);
122 /// The `string` variant of `get`.
124 template <typename T
, typename
std::enable_if
<!std::is_enum
<typename
T::value_type
>::value
125 && !std::is_same
<typename
T::value_type
, bool>::value
126 && std::is_same
<typename
T::value_type
, std::string
>::value
,
129 static void get(const raw
& bits
, T
& t
)
131 t
.value
= read_string(bits
, T::offset
, T::count
);
138 /// Writes data to the AIS message (bitset).
139 /// This is the `enum` variant.
141 /// @tparam T `bitset_value` type.
142 /// @param[in] bits The AIS message to write to.
143 /// @param[out] t The data to write into the message.
145 template <typename T
,
146 typename
std::enable_if
<std::is_enum
<typename
T::value_type
>::value
, int>::type
= 0>
147 static void set(raw
& bits
, const T
& t
)
150 static_cast<typename
std::underlying_type
<typename
T::value_type
>::type
>(t
.value
),
151 T::offset
, T::count
);
154 /// The `bool` variant of `set`.
156 template <typename T
,
157 typename
std::enable_if
<std::is_same
<typename
T::value_type
, bool>::value
, int>::type
159 static void set(raw
& bits
, const T
& t
)
161 bits
.set_bit(T::offset
, t
.value
);
164 /// The non `enum` and non `string` variant of `set`.
166 template <typename T
, typename
std::enable_if
<!std::is_enum
<typename
T::value_type
>::value
167 && !std::is_same
<typename
T::value_type
, bool>::value
168 && !std::is_same
<typename
T::value_type
, std::string
>::value
,
171 static void set(raw
& bits
, const T
& t
)
173 bits
.set(t
.value
, T::offset
, T::count
);
176 /// The `string` variant of `set`.
178 template <typename T
, typename
std::enable_if
<!std::is_enum
<typename
T::value_type
>::value
179 && !std::is_same
<typename
T::value_type
, bool>::value
180 && std::is_same
<typename
T::value_type
, std::string
>::value
,
183 static void set(raw
& bits
, const T
& t
)
185 write_string(bits
, T::offset
, T::count
, t
.value
);