Dev: preparation script added for code coverage.
[marnav.git] / src / marnav / ais / message.cpp
blob841399217fa515cab3a7e8f978edd7eeea389d43
1 #include "message.hpp"
2 #include <algorithm>
4 namespace marnav
6 namespace ais
8 /// @cond DEV
9 namespace
11 static const std::vector<std::pair<uint8_t, char>> SIXBIT_ASCII_TABLE = {
12 {0, '@'}, {1, 'A'}, {2, 'B'}, {3, 'C'}, {4, 'D'}, {5, 'E'}, {6, 'F'}, {7, 'G'}, {8, 'H'},
13 {9, 'I'}, {10, 'J'}, {11, 'K'}, {12, 'L'}, {13, 'M'}, {14, 'N'}, {15, 'O'}, {16, 'P'},
14 {17, 'Q'}, {18, 'R'}, {19, 'S'}, {20, 'T'}, {21, 'U'}, {22, 'V'}, {23, 'W'}, {24, 'X'},
15 {25, 'Y'}, {26, 'Z'}, {27, '['}, {28, '\\'}, {29, ']'}, {30, '^'}, {31, '_'}, {32, ' '},
16 {33, '!'}, {34, '\"'}, {35, '#'}, {36, '$'}, {37, '%'}, {38, '&'}, {39, '\''}, {40, '('},
17 {41, ')'}, {42, '*'}, {43, '+'}, {44, ','}, {45, '-'}, {46, '.'}, {47, '/'}, {48, '0'},
18 {49, '1'}, {50, '2'}, {51, '3'}, {52, '4'}, {53, '5'}, {54, '6'}, {55, '7'}, {56, '8'},
19 {57, '9'}, {58, ':'}, {59, ';'}, {60, '<'}, {61, '='}, {62, '>'}, {63, '?'},
22 /// @endcond
24 char decode_sixbit_ascii(uint8_t value)
26 value &= 0x3f;
27 auto i = std::find_if(SIXBIT_ASCII_TABLE.begin(), SIXBIT_ASCII_TABLE.end(),
28 [value](const std::pair<uint8_t, char> & p) { return p.first == value; });
29 return i != SIXBIT_ASCII_TABLE.end() ? i->second : 0xff;
32 uint8_t encode_sixbit_ascii(char c)
34 auto i = std::find_if(SIXBIT_ASCII_TABLE.begin(), SIXBIT_ASCII_TABLE.end(),
35 [c](const std::pair<uint8_t, char> & p) { return p.second == c; });
36 return i != SIXBIT_ASCII_TABLE.end() ? i->first : 0xff;
39 std::string trim_ais_string(const std::string & s) { return s.substr(0, s.find_first_of("@")); }
41 /// Reads a string from the AIS message at the specified offset.
42 /// The string is decoded and returned.
43 ///
44 /// @param[in] bits The AIS message.
45 /// @param[in] ofs The offset at which the string is being read.
46 /// @param[in] count_sixbits Number of sixbits to be read.
47 /// @return The decoded string.
48 ///
49 /// @todo consider to hide characters after '@'
50 std::string message::read_string(
51 const raw & bits, raw::size_type ofs, raw::size_type count_sixbits)
53 std::string s;
54 s.reserve(count_sixbits);
56 for (raw::size_type i = 0; i < count_sixbits; ++i) {
57 uint8_t sixbit = 0;
58 bits.get(sixbit, ofs + i * 6, 6);
59 s += decode_sixbit_ascii(sixbit);
62 return s;
65 /// Writes the specified string into the AIS message. If the string does not fill
66 /// the entire space within the message, fill characters `@` will be written
67 /// until the specified number of sixbits is reached.
68 ///
69 /// @param[out] bits The AIS message.
70 /// @param[in] ofs The offset at which the string is being written within the message.
71 /// @param[in] count_sixbits Number of sixbits to write into the message.
72 /// @param[in] s The string to be written.
73 ///
74 void message::write_string(
75 raw & bits, raw::size_type ofs, raw::size_type count_sixbits, const std::string & s)
77 for (raw::size_type i = 0; i < count_sixbits; ++i) {
78 uint8_t value;
79 if (i < s.size()) {
80 value = encode_sixbit_ascii(s[i]);
81 } else {
82 value = encode_sixbit_ascii('@');
84 bits.set(value, ofs + i * 6, 6);