1 #include "message_21.hpp"
3 #include <marnav/ais/angle.hpp>
9 MARNAV_AIS_DEFINE_MESSAGE_PARSE_FUNC(message_21
)
11 message_21::message_21()
13 , name("@@@@@@@@@@@@@@@@@@@@")
17 message_21::message_21(const raw
& bits
)
19 , name("@@@@@@@@@@@@@@@@@@@@")
21 if ((bits
.size() < SIZE_BITS_MIN
) || (bits
.size() > SIZE_BITS_MAX
))
22 throw std::invalid_argument
{"invalid number of bits in message_21"};
26 void message_21::read_data(const raw
& bits
)
28 get(bits
, repeat_indicator
);
32 get(bits
, position_accuracy
);
33 get(bits
, longitude_minutes
);
34 get(bits
, latitude_minutes
);
38 get(bits
, to_starboard
);
40 get(bits
, utc_second
);
41 get(bits
, off_position
);
44 get(bits
, virtual_aid_flag
);
47 auto rest
= static_cast<decltype(SIZE_BITS_MAX
)>(bits
.size()) - SIZE_BITS_MIN
;
49 rest
= std::min(rest
, SIZE_BITS_MAX
- SIZE_BITS_MIN
);
50 name_extension
= read_string(bits
, 272, rest
/ 6);
54 raw
message_21::get_data() const
56 raw bits
{SIZE_BITS_MIN
};
58 bits
.set(type(), 0, 6);
59 set(bits
, repeat_indicator
);
63 set(bits
, position_accuracy
);
64 set(bits
, longitude_minutes
);
65 set(bits
, latitude_minutes
);
69 set(bits
, to_starboard
);
71 set(bits
, utc_second
);
72 set(bits
, off_position
);
75 set(bits
, virtual_aid_flag
);
78 if (name_extension
.size() > 0) {
79 // compute number of bits, must be on a 8-bit boundary
80 auto size
= name_extension
.size() * 6;
82 size
+= 8 - (size
% 8);
84 if (size
<= SIZE_BITS_MAX
- SIZE_BITS_MIN
) {
85 // append a temporary bitset to the real one
87 write_string(t
, 0, name_extension
.size(), name_extension
);
95 std::string
message_21::get_name() const { return trim_ais_string(name
); }
97 void message_21::set_name(const std::string
& t
)
100 name
= t
.substr(0, 20);
106 std::string
message_21::get_name_extension() const { return trim_ais_string(name_extension
); }
108 void message_21::set_name_extension(const std::string
& t
)
110 // 88 bits with 6-bit encoding are 14 characters
112 name_extension
= t
.substr(0, 14);
118 utils::optional
<geo::longitude
> message_21::get_longitude() const
120 if (longitude_minutes
== longitude_not_available
)
121 return utils::make_optional
<geo::longitude
>();
122 return to_geo_longitude(longitude_minutes
);
125 utils::optional
<geo::latitude
> message_21::get_latitude() const
127 if (latitude_minutes
== latitude_not_available
)
128 return utils::make_optional
<geo::latitude
>();
129 return to_geo_latitude(latitude_minutes
);
132 void message_21::set_longitude(const utils::optional
<geo::longitude
> & t
)
134 longitude_minutes
= t
? to_longitude_minutes(t
.value()) : longitude_not_available
;
137 void message_21::set_latitude(const utils::optional
<geo::latitude
> & t
)
139 latitude_minutes
= t
? to_latitude_minutes(t
.value()) : latitude_not_available
;