...
This commit is contained in:
parent
f729799335
commit
b8383c1375
@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <unordered_set>
|
|
||||||
#include "mcc_angle.h"
|
#include "mcc_angle.h"
|
||||||
|
#include "mcc_generics.h"
|
||||||
|
#include "mcc_utils.h"
|
||||||
|
|
||||||
namespace mcc::network
|
namespace mcc::network
|
||||||
{
|
{
|
||||||
@ -31,25 +33,50 @@ static constexpr std::string_view MCC_COMMPROTO_SERVER_ERROR_INVPAR_STR = "INVPA
|
|||||||
|
|
||||||
/* predefined parameters */
|
/* predefined parameters */
|
||||||
|
|
||||||
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_RADEC_ICRS = "RADEC_ICRS";
|
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_RADEC_ICRS = "RADEC_ICRS"; // ICRS RA and DEC
|
||||||
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_RADEC = "RADEC"; // apparent RA and DEC
|
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_RADEC = "RADEC"; // apparent RA and DEC
|
||||||
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_HADEC = "HADEC"; // apparent HA and DEC
|
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_HADEC = "HADEC"; // apparent HA and DEC
|
||||||
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_AZZD = "AZZD";
|
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_AZZD = "AZZD"; // azimuth and zenithal distance
|
||||||
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_AZALT = "AZALT";
|
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_AZALT = "AZALT"; // azimuth and altitude
|
||||||
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_XY = "XY";
|
static constexpr std::string_view MCC_COMMPROTO_COORD_KIND_XY = "XY"; // hardware (encoder) coordinates
|
||||||
|
|
||||||
|
|
||||||
static constexpr MccCoordPairKind mcc_str2pairkind(std::string_view spair)
|
// static constexpr MccCoordPairKind mcc_str2pairkind(std::string_view spair)
|
||||||
|
// {
|
||||||
|
// return spair == MCC_COMMPROTO_COORD_KIND_RADEC_ICRS ? MccCoordPairKind::COORDS_KIND_RADEC_ICRS
|
||||||
|
// : spair == MCC_COMMPROTO_COORD_KIND_RADEC ? MccCoordPairKind::COORDS_KIND_RADEC_APP
|
||||||
|
// : spair == MCC_COMMPROTO_COORD_KIND_HADEC ? MccCoordPairKind::COORDS_KIND_HADEC_APP
|
||||||
|
// : spair == MCC_COMMPROTO_COORD_KIND_AZZD ? MccCoordPairKind::COORDS_KIND_AZZD
|
||||||
|
// : spair == MCC_COMMPROTO_COORD_KIND_AZALT ? MccCoordPairKind::COORDS_KIND_AZALT
|
||||||
|
// : spair == MCC_COMMPROTO_COORD_KIND_XY ? MccCoordPairKind::COORDS_KIND_XY
|
||||||
|
// : MccCoordPairKind::COORDS_KIND_GENERIC;
|
||||||
|
// }
|
||||||
|
|
||||||
|
static constexpr MccCoordPairKind mcc_str2pairkind(traits::mcc_char_range auto const& spair)
|
||||||
{
|
{
|
||||||
return spair == MCC_COMMPROTO_COORD_KIND_RADEC_ICRS ? MccCoordPairKind::COORDS_KIND_RADEC_ICRS
|
const auto hash = utils::FNV1aHash(spair);
|
||||||
: spair == MCC_COMMPROTO_COORD_KIND_RADEC ? MccCoordPairKind::COORDS_KIND_RADEC_APP
|
|
||||||
: spair == MCC_COMMPROTO_COORD_KIND_HADEC ? MccCoordPairKind::COORDS_KIND_HADEC_APP
|
return hash == utils::FNV1aHash(MCC_COMMPROTO_COORD_KIND_RADEC_ICRS) ? MccCoordPairKind::COORDS_KIND_RADEC_ICRS
|
||||||
: spair == MCC_COMMPROTO_COORD_KIND_AZZD ? MccCoordPairKind::COORDS_KIND_AZZD
|
: hash == utils::FNV1aHash(MCC_COMMPROTO_COORD_KIND_RADEC) ? MccCoordPairKind::COORDS_KIND_RADEC_APP
|
||||||
: spair == MCC_COMMPROTO_COORD_KIND_AZALT ? MccCoordPairKind::COORDS_KIND_AZALT
|
: hash == utils::FNV1aHash(MCC_COMMPROTO_COORD_KIND_HADEC) ? MccCoordPairKind::COORDS_KIND_HADEC_APP
|
||||||
: spair == MCC_COMMPROTO_COORD_KIND_XY ? MccCoordPairKind::COORDS_KIND_XY
|
: hash == utils::FNV1aHash(MCC_COMMPROTO_COORD_KIND_AZZD) ? MccCoordPairKind::COORDS_KIND_AZZD
|
||||||
: MccCoordPairKind::COORDS_KIND_GENERIC;
|
: hash == utils::FNV1aHash(MCC_COMMPROTO_COORD_KIND_AZALT) ? MccCoordPairKind::COORDS_KIND_AZALT
|
||||||
|
: hash == utils::FNV1aHash(MCC_COMMPROTO_COORD_KIND_XY) ? MccCoordPairKind::COORDS_KIND_XY
|
||||||
|
: MccCoordPairKind::COORDS_KIND_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr std::string_view mcc_pairkind2str(MccCoordPairKind kind)
|
||||||
|
{
|
||||||
|
return kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS ? MCC_COMMPROTO_COORD_KIND_RADEC_ICRS
|
||||||
|
: kind == MccCoordPairKind::COORDS_KIND_RADEC_APP ? MCC_COMMPROTO_COORD_KIND_RADEC
|
||||||
|
: kind == MccCoordPairKind::COORDS_KIND_HADEC_APP ? MCC_COMMPROTO_COORD_KIND_HADEC
|
||||||
|
: kind == MccCoordPairKind::COORDS_KIND_AZZD ? MCC_COMMPROTO_COORD_KIND_AZZD
|
||||||
|
: kind == MccCoordPairKind::COORDS_KIND_AZALT ? MCC_COMMPROTO_COORD_KIND_AZALT
|
||||||
|
: kind == MccCoordPairKind::COORDS_KIND_XY ? MCC_COMMPROTO_COORD_KIND_XY
|
||||||
|
: "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* keywords */
|
/* keywords */
|
||||||
|
|
||||||
// NOTE: THE COORDINATES AND TIME-RELATED QUANTITIES CAN BE EXPRESSED IN THE TWO FORMAT:
|
// NOTE: THE COORDINATES AND TIME-RELATED QUANTITIES CAN BE EXPRESSED IN THE TWO FORMAT:
|
||||||
@ -61,7 +88,13 @@ static constexpr MccCoordPairKind mcc_str2pairkind(std::string_view spair)
|
|||||||
// ALL TIME-RELATED QUANTITIES AND RA/HA COORDINATES MUST BE EXPRESSED
|
// ALL TIME-RELATED QUANTITIES AND RA/HA COORDINATES MUST BE EXPRESSED
|
||||||
// IN FORMAT 'HOURS:MINUTES:SECONDS', WHILE DEC/ALT/AZ/ZD COORDINATES MUST
|
// IN FORMAT 'HOURS:MINUTES:SECONDS', WHILE DEC/ALT/AZ/ZD COORDINATES MUST
|
||||||
// BE EXPRESSED AS '+/-DEGREES:ARCMINUTES:ARCSECONDS'
|
// BE EXPRESSED AS '+/-DEGREES:ARCMINUTES:ARCSECONDS'
|
||||||
|
//
|
||||||
|
// USER-ENTERED (FROM NETWORK CLIENTS) COORDINATE PAIR MAY BE PROVIDED IN A MIXED FORM, I.E.,
|
||||||
|
// 12.34436658678 10:32:11.432 or
|
||||||
|
// 10:32:11.432 12.34436658678
|
||||||
|
//
|
||||||
|
// SERVER-RESPONDED COORDINATES ARE ALWAYS IN THE SAME FORMAT, SEXAGESIMAL OR FIXED-POINT
|
||||||
|
//
|
||||||
|
|
||||||
// format of output coordinates:
|
// format of output coordinates:
|
||||||
// "COORDFMT FMT-type\n"
|
// "COORDFMT FMT-type\n"
|
||||||
@ -93,7 +126,7 @@ static constexpr std::string_view MCC_COMMPROTO_KEYWORD_COORDPREC_STR = "COORDPR
|
|||||||
|
|
||||||
|
|
||||||
// set/get target coordinates
|
// set/get target coordinates
|
||||||
// "TRAGET X-coord Y-coord XY-kind\n", if 'XY-kind' is omitted then one should assume RADEC_ICRS
|
// "TARGET X-coord Y-coord XY-kind\n", if 'XY-kind' is omitted then one should assume RADEC_ICRS
|
||||||
// e.g.:
|
// e.g.:
|
||||||
// "TARGET 12.7683487 10:23:09.75 AZZD\n"
|
// "TARGET 12.7683487 10:23:09.75 AZZD\n"
|
||||||
// "TARGET HADEC\n"
|
// "TARGET HADEC\n"
|
||||||
@ -126,92 +159,197 @@ static constexpr std::string_view MCC_COMMPROTO_KEYWORD_TARGET_STR = "TARGET";
|
|||||||
static constexpr std::string_view MCC_COMMPROTO_KEYWORD_MOUNT_STR = "MOUNT";
|
static constexpr std::string_view MCC_COMMPROTO_KEYWORD_MOUNT_STR = "MOUNT";
|
||||||
|
|
||||||
|
|
||||||
static constexpr std::string_view MCC_COMMPROTO_KEYWORD_TELEMTRY_STR = "TELEMETRY";
|
static constexpr std::string_view MCC_COMMPROTO_KEYWORD_TELEMETRY_STR = "TELEMETRY";
|
||||||
|
|
||||||
|
// init mount
|
||||||
|
// "INIT\n"
|
||||||
|
static constexpr std::string_view MCC_COMMPROTO_KEYWORD_INIT_STR = "INIT";
|
||||||
|
|
||||||
static const std::unordered_set MCC_COMMPROTO_VALID_KEYS = {
|
// stop any movements
|
||||||
|
// "STOP\n"
|
||||||
|
static constexpr std::string_view MCC_COMMPROTO_KEYWORD_STOP_STR = "STOP";
|
||||||
|
|
||||||
|
// slew mount and track target:
|
||||||
|
// "SLEW\n"
|
||||||
|
static constexpr std::string_view MCC_COMMPROTO_KEYWORD_SLEW_STR = "SLEW";
|
||||||
|
|
||||||
|
// slew mount and stop:
|
||||||
|
// "MOVE\n"
|
||||||
|
static constexpr std::string_view MCC_COMMPROTO_KEYWORD_MOVE_STR = "MOVE";
|
||||||
|
|
||||||
|
// track target
|
||||||
|
// "TRACK\n"
|
||||||
|
static constexpr std::string_view MCC_COMMPROTO_KEYWORD_TRACK_STR = "TRACK";
|
||||||
|
|
||||||
|
// valid keywords
|
||||||
|
static constexpr std::array MCC_COMMPROTO_VALID_KEYS = {
|
||||||
MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR, MCC_COMMPROTO_KEYWORD_COORDFMT_STR,
|
MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR, MCC_COMMPROTO_KEYWORD_COORDFMT_STR,
|
||||||
MCC_COMMPROTO_KEYWORD_COORDPREC_STR, MCC_COMMPROTO_KEYWORD_TARGET_STR, MCC_COMMPROTO_KEYWORD_MOUNT_STR,
|
MCC_COMMPROTO_KEYWORD_COORDPREC_STR, MCC_COMMPROTO_KEYWORD_TARGET_STR, MCC_COMMPROTO_KEYWORD_MOUNT_STR,
|
||||||
MCC_COMMPROTO_KEYWORD_TELEMTRY_STR};
|
MCC_COMMPROTO_KEYWORD_TELEMETRY_STR, MCC_COMMPROTO_KEYWORD_INIT_STR, MCC_COMMPROTO_KEYWORD_STOP_STR,
|
||||||
|
MCC_COMMPROTO_KEYWORD_SLEW_STR, MCC_COMMPROTO_KEYWORD_MOVE_STR, MCC_COMMPROTO_KEYWORD_TRACK_STR};
|
||||||
|
|
||||||
auto MCC_COMMPROTO_KEYWORD_SERVER_ACK_HASH =
|
|
||||||
std::unordered_set<std::string_view>::hasher{}(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR);
|
|
||||||
auto MCC_COMMPROTO_KEYWORD_SERVER_ERROR_HASH =
|
|
||||||
std::unordered_set<std::string_view>::hasher{}(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR);
|
|
||||||
|
|
||||||
template <traits::mcc_input_char_range IR, traits::mcc_range_of_output_char_range OT>
|
// hashes valid keywords
|
||||||
std::string_view mcc_parse_netmsg(IR&& netmsg, OT& parse_res, bool from_server = false)
|
static constexpr std::array MCC_COMMPROTO_VALID_KEYS_HASH = []<size_t... Is>(std::index_sequence<Is...>) {
|
||||||
|
return std::array{mcc::utils::FNV1aHash(MCC_COMMPROTO_VALID_KEYS[Is])...};
|
||||||
|
}(std::make_index_sequence<MCC_COMMPROTO_VALID_KEYS.size()>());
|
||||||
|
|
||||||
|
|
||||||
|
static constexpr size_t MCC_COMMPROTO_KEYWORD_SERVER_ACK_HASH =
|
||||||
|
mcc::utils::FNV1aHash(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR);
|
||||||
|
|
||||||
|
static constexpr size_t MCC_COMMPROTO_KEYWORD_SERVER_ERROR_HASH =
|
||||||
|
mcc::utils::FNV1aHash(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR);
|
||||||
|
|
||||||
|
static constexpr size_t MCC_COMMPROTO_KEYWORD_TARGET_HASH = mcc::utils::FNV1aHash(MCC_COMMPROTO_KEYWORD_TARGET_STR);
|
||||||
|
|
||||||
|
static constexpr size_t MCC_COMMPROTO_KEYWORD_MOUNT_HASH = mcc::utils::FNV1aHash(MCC_COMMPROTO_KEYWORD_MOUNT_STR);
|
||||||
|
|
||||||
|
|
||||||
|
template <traits::mcc_char_range T = std::string_view, std::ranges::output_range<T> RT = std::vector<T>>
|
||||||
|
struct mcc_netmsg_parse_result_t {
|
||||||
|
size_t keyword_hash;
|
||||||
|
T keyword;
|
||||||
|
RT params;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept mcc_netmsg_parse_result_c = requires(T t) {
|
||||||
|
requires std::same_as<decltype(t.keyword_hash), size_t>;
|
||||||
|
requires traits::mcc_char_range<decltype(t.keyword)>;
|
||||||
|
requires std::ranges::output_range<decltype(t.params), decltype(t.keyword)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// the function returns hash of message keyword
|
||||||
|
// template <traits::mcc_input_char_range IR, traits::mcc_range_of_output_char_range OT>
|
||||||
|
template <traits::mcc_input_char_range IR, mcc_netmsg_parse_result_c ResT>
|
||||||
|
bool mcc_parse_netmsg(const IR& netmsg, ResT& parse_res, bool from_server = false)
|
||||||
{
|
{
|
||||||
if (std::ranges::size(std::forward<IR>(netmsg)) == 0) {
|
if (std::ranges::size(netmsg) == 0) {
|
||||||
return "";
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string_view ret;
|
auto found = std::ranges::search(netmsg, MCC_COMMPROTO_KEYPARAM_DELIM_SEQ);
|
||||||
|
if (std::distance(netmsg.begin(), found.begin()) == 0) {
|
||||||
auto found = std::ranges::search(std::forward<IR>(netmsg), MCC_COMMPROTO_KEYPARAM_DELIM_SEQ);
|
return false;
|
||||||
|
|
||||||
auto it = MCC_COMMPROTO_VALID_KEYS.find({netmsg.begin(), found.begin()});
|
|
||||||
if (it == MCC_COMMPROTO_VALID_KEYS.end()) {
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = *it;
|
const size_t hash = mcc::utils::FNV1aHash(netmsg.begin(), found.begin());
|
||||||
|
auto it = std::ranges::find(MCC_COMMPROTO_VALID_KEYS_HASH, hash);
|
||||||
|
if (it == MCC_COMMPROTO_VALID_KEYS_HASH.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (from_server) { // only ACK and ERROR
|
if (from_server) { // only ACK or ERROR
|
||||||
auto ok = std::ranges::search(netmsg.begin(), found.begin(), MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR.begin(),
|
auto ok = hash == MCC_COMMPROTO_VALID_KEYS_HASH[0] || hash == MCC_COMMPROTO_VALID_KEYS_HASH[1];
|
||||||
MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR.end());
|
if (!ok) {
|
||||||
if (ok) {
|
return false;
|
||||||
ret = MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = std::ranges::search(netmsg.begin(), found.begin(), MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR.begin(),
|
|
||||||
MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR.end());
|
|
||||||
if (ok) {
|
|
||||||
ret = MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR;
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (found.empty()) { // no parameters?
|
parse_res.keyword_hash = hash;
|
||||||
// if (from_server) {
|
parse_res.keyword = {netmsg.begin(), found.begin()};
|
||||||
// auto ok = std::ranges::search(netmsg.begin(), found.begin(),
|
|
||||||
// MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR.begin(),
|
|
||||||
// MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR.end());
|
|
||||||
// if (ok) {
|
|
||||||
// ret = MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ok = std::ranges::search(netmsg.begin(), found.begin(), MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR.begin(),
|
auto pars = netmsg | std::views::drop(std::distance(netmsg.begin(), found.end())) |
|
||||||
// MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR.end());
|
|
||||||
// if (ok) {
|
|
||||||
// ret = MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR;
|
|
||||||
// } else {
|
|
||||||
// return "";
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (!MCC_COMMPROTO_VALID_KEYS.contains({netmsg.begin(), found.begin()})) {
|
|
||||||
// return "";
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (std::distance(netmsg.begin(), found.begin()) == 0) { // an empty keyword
|
|
||||||
// return "";
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
auto pars = std::forward<IR>(netmsg) | std::views::drop(std::distance(netmsg.begin(), found.end())) |
|
|
||||||
std::views::split(MCC_COMMPROTO_PARAMPARAM_DELIM_SEQ);
|
std::views::split(MCC_COMMPROTO_PARAMPARAM_DELIM_SEQ);
|
||||||
|
|
||||||
OT res;
|
decltype(parse_res.params) res;
|
||||||
for (auto const& el : pars) {
|
|
||||||
|
for (auto const& el : pars) { // parameters
|
||||||
std::back_inserter(res) = {el.begin(), el.end()};
|
std::back_inserter(res) = {el.begin(), el.end()};
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_res = std::move(res);
|
parse_res.params = std::move(res);
|
||||||
|
|
||||||
return ret;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... PTs>
|
||||||
|
bool mcc_netmsg_construct(traits::mcc_output_char_range auto& msg,
|
||||||
|
traits::mcc_input_char_range auto const& keyword,
|
||||||
|
PTs... params)
|
||||||
|
{
|
||||||
|
const size_t hash = utils::FNV1aHash(keyword);
|
||||||
|
if (!std::ranges::contains(MCC_COMMPROTO_VALID_KEYS_HASH, hash)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = {keyword.begin(), keyword.end()};
|
||||||
|
|
||||||
|
if constexpr (sizeof...(PTs)) {
|
||||||
|
std::ranges::copy(MCC_COMMPROTO_KEYPARAM_DELIM_SEQ, std::back_inserter(msg));
|
||||||
|
|
||||||
|
[&msg]<typename T, typename... Ts>(this auto&& self, const T& par, const Ts&... pars) {
|
||||||
|
if constexpr (std::is_arithmetic_v<T>) {
|
||||||
|
std::ranges::copy(std::to_string(par), std::back_inserter(msg));
|
||||||
|
} else if constexpr (std::convertible_to<T, std::string>) {
|
||||||
|
std::ranges::copy(static_cast<std::string>(par), std::back_inserter(msg));
|
||||||
|
} else if constexpr (std::constructible_from<std::string, T>) {
|
||||||
|
std::ranges::copy(std::string(par), std::back_inserter(msg));
|
||||||
|
} else if constexpr (traits::mcc_char_range<T>) {
|
||||||
|
std::ranges::copy(std::string(par.begin(), par.end()), std::back_inserter(msg));
|
||||||
|
} else if constexpr (std::same_as<T, MccCoordPairKind>) {
|
||||||
|
std::ranges::copy(mcc_pairkind2str(par), std::back_inserter(msg));
|
||||||
|
} else {
|
||||||
|
static_assert(false, "UNSUPPORTED TYPE!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (sizeof...(Ts)) {
|
||||||
|
std::ranges::copy(MCC_COMMPROTO_PARAMPARAM_DELIM_SEQ, std::back_inserter(msg));
|
||||||
|
|
||||||
|
std::forward<decltype(self)>(self)(pars...);
|
||||||
|
}
|
||||||
|
}(params...);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mcc_netmsg_get_cpoint(mcc_netmsg_parse_result_c auto const& parse_res,
|
||||||
|
size_t from_idx,
|
||||||
|
mcc_celestial_point_c auto& cpoint,
|
||||||
|
MccCoordPairKind default_kind)
|
||||||
|
requires std::ranges::contiguous_range<decltype(parse_res.keyword)>
|
||||||
|
{
|
||||||
|
if (std::ranges::size(parse_res.params) < (from_idx + 2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MccCoordPairKind kind = default_kind;
|
||||||
|
|
||||||
|
if (std::ranges::size(parse_res.params) > (from_idx + 2)) {
|
||||||
|
kind = mcc_str2pairkind(parse_res.params[from_idx + 2]);
|
||||||
|
if (kind == MccCoordPairKind::COORDS_KIND_GENERIC) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<double> ang1, ang2;
|
||||||
|
|
||||||
|
switch (kind) {
|
||||||
|
case mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS:
|
||||||
|
case mcc::MccCoordPairKind::COORDS_KIND_RADEC_APP:
|
||||||
|
case mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP:
|
||||||
|
ang1 = utils::parsAngleString(parse_res.params[from_idx], true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ang1 = utils::parsAngleString(parse_res.params[from_idx]);
|
||||||
|
}
|
||||||
|
if (!ang1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ang2 = utils::parsAngleString(parse_res.params[from_idx + 1]);
|
||||||
|
if (!ang2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpoint.pair_kind = kind;
|
||||||
|
cpoint.X = MccAngle(ang1.value(), mcc::MccDegreeTag{}); // to radians
|
||||||
|
cpoint.Y = MccAngle(ang2.value(), mcc::MccDegreeTag{}); // to radians
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace mcc::network
|
} // namespace mcc::network
|
||||||
|
|||||||
@ -23,6 +23,11 @@ template <typename R>
|
|||||||
concept mcc_char_view = std::ranges::view<R> && std::same_as<std::ranges::range_value_t<R>, char>;
|
concept mcc_char_view = std::ranges::view<R> && std::same_as<std::ranges::range_value_t<R>, char>;
|
||||||
|
|
||||||
|
|
||||||
|
// range of char/const char
|
||||||
|
template <typename R, typename CharT = char>
|
||||||
|
concept mcc_char_range = std::ranges::range<R> && std::same_as<std::remove_cv_t<std::ranges::range_value_t<R>>, CharT>;
|
||||||
|
|
||||||
|
|
||||||
// input range of char/const char
|
// input range of char/const char
|
||||||
template <typename R, typename CharT = char>
|
template <typename R, typename CharT = char>
|
||||||
concept mcc_input_char_range =
|
concept mcc_input_char_range =
|
||||||
@ -39,6 +44,9 @@ template <typename R>
|
|||||||
concept mcc_view_or_output_char_range = mcc_char_view<R> || mcc_output_char_range<R>;
|
concept mcc_view_or_output_char_range = mcc_char_view<R> || mcc_output_char_range<R>;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
concept mcc_range_of_char_range = std::ranges::range<R> && mcc_char_range<std::ranges::range_value_t<R>>;
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
concept mcc_range_of_input_char_range =
|
concept mcc_range_of_input_char_range =
|
||||||
std::ranges::range<R> && traits::mcc_input_char_range<std::ranges::range_value_t<R>>;
|
std::ranges::range<R> && traits::mcc_input_char_range<std::ranges::range_value_t<R>>;
|
||||||
|
|||||||
@ -355,4 +355,48 @@ std::pair<double, double> parseAnglePair(R&& str, bool hms1 = false, bool hms2 =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <traits::mcc_input_char_range R>
|
||||||
|
static constexpr size_t FNV1aHash(const R& r)
|
||||||
|
{
|
||||||
|
static_assert(sizeof(size_t) == 8 || sizeof(size_t) == 4, "ONLY FOR 32 or 64-bit size_t!!!");
|
||||||
|
|
||||||
|
size_t hash = 0, prime = 0;
|
||||||
|
if constexpr (sizeof(size_t) == 8) { // 64-bit
|
||||||
|
prime = 1099511628211UL;
|
||||||
|
hash = 14695981039346656037UL;
|
||||||
|
} else if constexpr (sizeof(size_t) == 4) { // 32-bit
|
||||||
|
prime = 16777619;
|
||||||
|
hash = 2166136261;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const char& ch : r) {
|
||||||
|
hash ^= ch;
|
||||||
|
hash *= prime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr size_t FNV1aHash(std::forward_iterator auto begin, std::sentinel_for<decltype(begin)> auto end)
|
||||||
|
requires std::same_as<std::remove_cv_t<std::iter_value_t<decltype(begin)>>, char>
|
||||||
|
{
|
||||||
|
static_assert(sizeof(size_t) == 8 || sizeof(size_t) == 4, "ONLY FOR 32 or 64-bit size_t!!!");
|
||||||
|
|
||||||
|
size_t hash = 0, prime = 0;
|
||||||
|
if constexpr (sizeof(size_t) == 8) { // 64-bit
|
||||||
|
prime = 1099511628211UL;
|
||||||
|
hash = 14695981039346656037UL;
|
||||||
|
} else if constexpr (sizeof(size_t) == 4) { // 32-bit
|
||||||
|
prime = 16777619;
|
||||||
|
hash = 2166136261;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = begin; it != end; ++it) {
|
||||||
|
hash ^= *it;
|
||||||
|
hash *= prime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mcc::utils
|
} // namespace mcc::utils
|
||||||
|
|||||||
@ -160,14 +160,42 @@ int main()
|
|||||||
std::cout << "\n\n";
|
std::cout << "\n\n";
|
||||||
|
|
||||||
std::string sm{"ACK TARGET 12:23:45.13 -09.23423525 RADEC"};
|
std::string sm{"ACK TARGET 12:23:45.13 -09.23423525 RADEC"};
|
||||||
std::vector<std::string> sv;
|
// std::vector<std::string> sv;
|
||||||
|
std::vector<std::string_view> sv;
|
||||||
|
mcc::network::mcc_netmsg_parse_result_t<> p_res;
|
||||||
|
|
||||||
auto mr = mcc::network::mcc_parse_netmsg(sm, sv);
|
auto mr = mcc::network::mcc_parse_netmsg(sm, p_res);
|
||||||
|
|
||||||
std::cout << "MSG RET = <" << mr << ">\n";
|
std::cout << "MSG: <" << sm << ">\n";
|
||||||
for (auto const& pr : sv) {
|
std::cout << "\t" << p_res.keyword_hash << "\n";
|
||||||
|
std::cout << "\t[" << p_res.keyword << "]\n";
|
||||||
|
for (auto const& pr : p_res.params) {
|
||||||
std::cout << "\t[" << pr << "]\n";
|
std::cout << "\t[" << pr << "]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "GET CPOINT RET: "
|
||||||
|
<< mcc::network::mcc_netmsg_get_cpoint(p_res, 1, cp, mcc::MccCoordPairKind::COORDS_KIND_AZZD) << "\n";
|
||||||
|
std::cout << "CPOINT.X = " << cp.X << ", CPOINT.Y = " << cp.Y << " ("
|
||||||
|
<< mcc::network::mcc_pairkind2str(cp.pair_kind) << ")\n";
|
||||||
|
|
||||||
|
|
||||||
|
sm = "ERROR ";
|
||||||
|
|
||||||
|
mr = mcc::network::mcc_parse_netmsg(sm, p_res);
|
||||||
|
|
||||||
|
std::cout << "MSG: <" << sm << ">\n";
|
||||||
|
sm[0] = 'e';
|
||||||
|
std::cout << "\t" << p_res.keyword_hash << "\n";
|
||||||
|
std::cout << "\t[" << p_res.keyword << "]\n";
|
||||||
|
for (auto const& pr : p_res.params) {
|
||||||
|
std::cout << "\t[" << pr << "]\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mr = mcc::network::mcc_netmsg_construct(sm, mcc::network::MCC_COMMPROTO_KEYWORD_TARGET_STR, 12.3456789,
|
||||||
|
"34:21:56.132", mcc::MccCoordPairKind::COORDS_KIND_AZZD);
|
||||||
|
|
||||||
|
std::cout << "\nNETMSG: [" << sm << "] (" << mr << ")\n";
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user