Utils: bitset update to e865429e8a6c17366105e985fd037e42261a1af9.
[marnav.git] / src / marnav / ais / binary_data.hpp
blob937324c59cef4108389a0a61a31383eb157bf071
1 #ifndef MARNAV__AIS__BINARY_DATA__HPP
2 #define MARNAV__AIS__BINARY_DATA__HPP
4 #include <string>
5 #include <marnav/utils/bitset.hpp>
7 namespace marnav
9 namespace ais
11 /// Type for raw AIS data.
12 using raw = utils::bitset<uint8_t>;
14 /// @{
16 char decode_sixbit_ascii(uint8_t value);
17 uint8_t encode_sixbit_ascii(char c);
19 /// @}
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.
25 class binary_data
27 protected:
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.
31 ///
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.
35 ///
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;
42 public:
43 static constexpr std::size_t offset = Offset;
44 static constexpr std::size_t count = Count;
45 using value_type = T;
47 bitset_value(value_type t)
48 : value(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)
64 value = t;
65 return *this;
68 private:
69 value_type value;
72 /// @{
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);
80 /// @}
82 /// @{
84 /// Reads data from the AIS message (bitset).
85 /// This is the `enum` variant.
86 ///
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.
90 ///
91 template <typename T,
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`.
101 /// @see get
102 template <typename T,
103 typename std::enable_if<std::is_same<typename T::value_type, bool>::value, int>::type
104 = 0>
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`.
111 /// @see 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,
115 int>::type
116 = 0>
117 static void get(const raw & bits, T & t)
119 bits.get(t.value, T::offset, T::count);
122 /// The `string` variant of `get`.
123 /// @see 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,
127 int>::type
128 = 0>
129 static void get(const raw & bits, T & t)
131 t.value = read_string(bits, T::offset, T::count);
134 /// @}
136 /// @{
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)
149 bits.set(
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`.
155 /// @see set
156 template <typename T,
157 typename std::enable_if<std::is_same<typename T::value_type, bool>::value, int>::type
158 = 0>
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`.
165 /// @see 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,
169 int>::type
170 = 0>
171 static void set(raw & bits, const T & t)
173 bits.set(t.value, T::offset, T::count);
176 /// The `string` variant of `set`.
177 /// @see 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,
181 int>::type
182 = 0>
183 static void set(raw & bits, const T & t)
185 write_string(bits, T::offset, T::count, t.value);
188 /// @}
193 #endif