diff --git a/mcc/mcc_angle.h b/mcc/mcc_angle.h index 8b7fa28..c6caa25 100644 --- a/mcc/mcc_angle.h +++ b/mcc/mcc_angle.h @@ -533,16 +533,62 @@ enum class MccCoordPairKind : size_t { }; +static constexpr std::string_view MCC_COORDPAIR_KIND_RADEC_ICRS_STR = "RADEC-IRCS"; +static constexpr std::string_view MCC_COORDPAIR_KIND_RADEC_APP_STR = "RADEC-APP"; +static constexpr std::string_view MCC_COORDPAIR_KIND_HADEC_APP_STR = "HADEC-APP"; +static constexpr std::string_view MCC_COORDPAIR_KIND_AZALT_STR = "AZALT"; +static constexpr std::string_view MCC_COORDPAIR_KIND_AZZD_STR = "AZZD"; +static constexpr std::string_view MCC_COORDPAIR_KIND_XY_STR = "XY"; +static constexpr std::string_view MCC_COORDPAIR_KIND_LATLON_STR = "LATLON"; +static constexpr std::string_view MCC_COORDPAIR_KIND_GENERIC_STR = "GENERIC"; +static constexpr std::string_view MCC_COORDPAIR_KIND_UNKNOWN_STR = "UNKNOWN"; + template static constexpr std::string_view MccCoordPairKindStr = - KIND == MccCoordPairKind::COORDS_KIND_RADEC_ICRS ? "RADEC-IRCS" - : KIND == MccCoordPairKind::COORDS_KIND_RADEC_APP ? "RADEC-APP" - : KIND == MccCoordPairKind::COORDS_KIND_HADEC_APP ? "HADEC-APP" - : KIND == MccCoordPairKind::COORDS_KIND_AZALT ? "Azimuth-Altitude" - : KIND == MccCoordPairKind::COORDS_KIND_AZZD ? "Azimuth-Zendist" - : KIND == MccCoordPairKind::COORDS_KIND_XY ? "X-Y" - : KIND == MccCoordPairKind::COORDS_KIND_LATLON ? "Latitude-Longitude" - : "UNKNOWN"; + KIND == MccCoordPairKind::COORDS_KIND_RADEC_ICRS ? MCC_COORDPAIR_KIND_RADEC_ICRS_STR + : KIND == MccCoordPairKind::COORDS_KIND_RADEC_APP ? MCC_COORDPAIR_KIND_RADEC_APP_STR + : KIND == MccCoordPairKind::COORDS_KIND_HADEC_APP ? MCC_COORDPAIR_KIND_HADEC_APP_STR + : KIND == MccCoordPairKind::COORDS_KIND_AZALT ? MCC_COORDPAIR_KIND_AZALT_STR + : KIND == MccCoordPairKind::COORDS_KIND_AZZD ? MCC_COORDPAIR_KIND_AZZD_STR + : KIND == MccCoordPairKind::COORDS_KIND_XY ? MCC_COORDPAIR_KIND_XY_STR + : KIND == MccCoordPairKind::COORDS_KIND_LATLON ? MCC_COORDPAIR_KIND_LATLON_STR + : KIND == MccCoordPairKind::COORDS_KIND_GENERIC ? MCC_COORDPAIR_KIND_GENERIC_STR + : MCC_COORDPAIR_KIND_UNKNOWN_STR; + + +static constexpr std::string_view MccCoordPairKindToStr(MccCoordPairKind KIND) +{ + return KIND == MccCoordPairKind::COORDS_KIND_RADEC_ICRS ? MCC_COORDPAIR_KIND_RADEC_ICRS_STR + : KIND == MccCoordPairKind::COORDS_KIND_RADEC_APP ? MCC_COORDPAIR_KIND_RADEC_APP_STR + : KIND == MccCoordPairKind::COORDS_KIND_HADEC_APP ? MCC_COORDPAIR_KIND_HADEC_APP_STR + : KIND == MccCoordPairKind::COORDS_KIND_AZALT ? MCC_COORDPAIR_KIND_AZALT_STR + : KIND == MccCoordPairKind::COORDS_KIND_AZZD ? MCC_COORDPAIR_KIND_AZZD_STR + : KIND == MccCoordPairKind::COORDS_KIND_XY ? MCC_COORDPAIR_KIND_XY_STR + : KIND == MccCoordPairKind::COORDS_KIND_LATLON ? MCC_COORDPAIR_KIND_LATLON_STR + : KIND == MccCoordPairKind::COORDS_KIND_GENERIC ? MCC_COORDPAIR_KIND_GENERIC_STR + : MCC_COORDPAIR_KIND_UNKNOWN_STR; +} + + +template +static constexpr MccCoordPairKind MccCoordStrToPairKind(R&& spair) +{ + if constexpr (std::is_pointer_v>) { + return MccCoordStrToPairKind(std::string_view{spair}); + } + + const auto hash = mcc::utils::FNV1aHash(std::forward(spair)); + + return hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_RADEC_ICRS_STR) ? MccCoordPairKind::COORDS_KIND_RADEC_ICRS + : hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_RADEC_APP_STR) ? MccCoordPairKind::COORDS_KIND_RADEC_APP + : hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_HADEC_APP_STR) ? MccCoordPairKind::COORDS_KIND_HADEC_APP + : hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_AZALT_STR) ? MccCoordPairKind::COORDS_KIND_AZZD + : hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_AZZD_STR) ? MccCoordPairKind::COORDS_KIND_AZALT + : hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_XY_STR) ? MccCoordPairKind::COORDS_KIND_XY + : hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_LATLON_STR) ? MccCoordPairKind::COORDS_KIND_LATLON + : hash == mcc::utils::FNV1aHash(MCC_COORDPAIR_KIND_GENERIC_STR) ? MccCoordPairKind::COORDS_KIND_GENERIC + : MccCoordPairKind::COORDS_KIND_GENERIC; +} } // namespace mcc diff --git a/mcc/mcc_defaults.h b/mcc/mcc_defaults.h index d4af674..4106716 100644 --- a/mcc/mcc_defaults.h +++ b/mcc/mcc_defaults.h @@ -73,8 +73,14 @@ struct MccGenericCelestialPoint { MccCoordPairKind pair_kind{MccCoordPairKind::COORDS_KIND_RADEC_ICRS}; - MccTimePoint time_point{std::chrono::sys_days(std::chrono::year_month_day{std::chrono::January / 1 / 2000}) + - std::chrono::hours(12)}; // J2000.0 + // MccTimePoint time_point{std::chrono::sys_days(std::chrono::year_month_day{std::chrono::January / 1 / 2000}) + + // std::chrono::hours(12)}; // J2000.0 + + MccTimePoint time_point{std::chrono::sys_days(std::chrono::year_month_day( + std::chrono::January / std::chrono::day(1) / std::chrono::year(2000))) + + std::chrono::hours(11) + std::chrono::minutes(58) + + std::chrono::milliseconds(55816)}; // J2000.0 UTC + coord_t X{}, Y{}; }; diff --git a/mcc/mcc_netserver_proto.h b/mcc/mcc_netserver_proto.h index aeb282b..3130bc9 100644 --- a/mcc/mcc_netserver_proto.h +++ b/mcc/mcc_netserver_proto.h @@ -9,6 +9,7 @@ #include #include #include "mcc_angle.h" +#include "mcc_defaults.h" #include "mcc_generics.h" #include "mcc_utils.h" @@ -493,7 +494,137 @@ class MccNetMessage { static inline utils::MccSimpleDeserializer defaultDeserilizer{MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ}; + class DefaultDeserializer : protected utils::MccSimpleDeserializer + { + protected: + using base_t = utils::MccSimpleDeserializer; + + public: + DefaultDeserializer() : base_t(MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ) {} + + template + std::error_code operator()(IR&& bytes, VT& value) + { + if constexpr (mcc_celestial_point_c) { + std::vector vs; + auto ec = base_t::operator()(std::forward(bytes), vs); + if (ec) { + return ec; + } + + if (vs.size() < 2) { + return std::make_error_code(std::errc::invalid_argument); + } + + MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS}; + + if (vs.size() > 2) { + pt.pair_kind = MccCoordStrToPairKind(vs[2]); + if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_GENERIC) { + return std::make_error_code(std::errc::invalid_argument); + } + } + + if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + // J2000.0: 11:58:55.816 1 January 2000 UTC + auto tp = std::chrono::sys_days(std::chrono::year_month_day( + std::chrono::January / std::chrono::day(1) / std::chrono::year(2000))) + + std::chrono::hours(11) + std::chrono::minutes(58) + std::chrono::milliseconds(55816); + mcc_tp2tp(tp, pt.time_point); + } else { + if (vs.size() > 3) { + std::chrono::sys_time tp; + + std::istringstream iss(std::string{utils::trimSpaces(vs[3])}); + + std::chrono::from_stream(iss, "%FT%T", tp); + if (iss.fail()) { + return std::make_error_code(std::errc::invalid_argument); + } + + mcc_tp2tp(tp, pt.time_point); + } else { // no time point - use NOW + mcc_tp2tp(std::chrono::system_clock::now(), pt.time_point); + } + } + + std::optional ang1, ang2; + + switch (pt.pair_kind) { + // if sexagesimal then hours:minutes:seconds form + case mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS: + case mcc::MccCoordPairKind::COORDS_KIND_RADEC_APP: + case mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP: + ang1 = utils::parsAngleString(vs[0], true); + break; + default: + // if sexagesimal then degrees:arcminutes:arcseconds form + ang1 = utils::parsAngleString(vs[0]); + } + if (!ang1) { + return std::make_error_code(std::errc::invalid_argument); + } + + ang2 = utils::parsAngleString(vs[1]); + if (!ang2) { + return std::make_error_code(std::errc::invalid_argument); + } + + + pt.X = MccAngle(ang1.value(), mcc::MccDegreeTag{}); + pt.Y = MccAngle(ang2.value(), mcc::MccDegreeTag{}); + + mcc_copy_celestial_point(pt, value); + } else { + return base_t::operator()(std::forward(bytes), value); + } + + return {}; + } + }; + public: + // helper method to convert celestial point to char range + // (actually, to range of strings) + template + static R celestialPointToString(mcc_celestial_point_c auto const& pt, + bool degrees = false, + std::pair prec = {2, 1}) + { + R res; + + if (degrees) { + std::format_to(std::back_inserter(res), "{}{}{}", MccAngle(pt.X).degrees(), + MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ, MccAngle(pt.Y).degrees()); + } else { + switch (pt.pair_kind) { + case MccCoordPairKind::COORDS_KIND_RADEC_ICRS: + case MccCoordPairKind::COORDS_KIND_RADEC_APP: + case MccCoordPairKind::COORDS_KIND_HADEC_APP: + std::format_to(std::back_inserter(res), "{}{}", MccAngle(pt.X).sexagesimal(true, prec.first), + MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ); + break; + default: + std::format_to(std::back_inserter(res), "{}{}", MccAngle(pt.X).sexagesimal(false, prec.second), + MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ); + } + + std::format_to(std::back_inserter(res), "{}", MccAngle(pt.Y).sexagesimal(false, prec.second)); + } + + std::format_to(std::back_inserter(res), "{0:}{1:}{2:}{3:%F}T{3:%T}", MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ, + MccCoordPairKindToStr(pt.pair_kind), MCC_COMMPROTO_RANGEPARAM_DELIM_SEQ, pt.time_point); + + return res; + } + + static std::string celestialPointToString(mcc_celestial_point_c auto const& pt, + bool degrees = false, + std::pair prec = {2, 1}) + { + return celestialPointToString(pt, degrees, prec); + } + typedef BASE_T valid_keys_t; typedef BYTEREPR_T byte_repr_t; @@ -544,28 +675,6 @@ public: return _keyword; } - // template - // R params(size_t start_idx, size_t Nelemes = std::numeric_limits::max()) - // { - // if (start_idx >= _params.size()) { - // return R{}; - // } - - // auto stop_idx = start_idx + Nelemes - 1; - // if (stop_idx >= _params.size()) { - // stop_idx = _params.size() - 1; - // } - - // if constexpr (traits::mcc_char_view) { - // return R{_params[start_idx].begin(), _params[stop_idx].end()}; - // } else { - // R r; - // std::ranges::copy(std::string_view{_params[start_idx].begin(), _params[stop_idx].end()}, - // std::back_inserter(r)); - - // return r; - // } - // } template R params(size_t start_idx, size_t Nelemes = std::numeric_limits::max()) @@ -590,7 +699,7 @@ public: std::back_inserter(r) = el_t{el.begin(), el.end()}; } } else { - static_assert(false, "UNSUPPORTED RANGE ELEMENT TYPE!!!"); + static_assert(false, "UNSUPPORTED RANGE TYPE!!!"); } return r; @@ -663,6 +772,77 @@ public: } + // template + // std::expected paramCelestialPoint( + // size_t from_idx, + // MccCoordPairKind default_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS) + // { + // if (_params.size() < (from_idx + 2)) { + // return std::unexpected(std::make_error_code(std::errc::message_size)); + // } + + // MccCelestialPoint pt{.pair_kind = default_kind}; + + // if (_params.size() > (from_idx + 2)) { + // pt.pair_kind = MccCoordStrToPairKind(_params[from_idx + 2]); + // if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_GENERIC) { + // return std::unexpected(std::make_error_code(std::errc::invalid_argument)); + // } + // } + + // if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + // // J2000.0: 11:58:55.816 1 January 2000 UTC + // auto tp = std::chrono::sys_days(std::chrono::year_month_day(std::chrono::January / std::chrono::day(1) / + // std::chrono::year(2000))) + + // std::chrono::hours(11) + std::chrono::minutes(58) + std::chrono::milliseconds(55816); + // mcc_tp2tp(tp, pt.time_point); + // } else { + // if (_params.size() > (from_idx + 3)) { + // std::chrono::sys_time tp; + + // std::istringstream iss(std::string{utils::trimSpaces(_params[from_idx + 3])}); + + // std::chrono::from_stream(iss, "%FT%T", tp); + // if (iss.fail()) { + // return std::unexpected(std::make_error_code(std::errc::invalid_argument)); + // } + + // mcc_tp2tp(tp, pt.time_point); + // } else { // no time point - use NOW + // mcc_tp2tp(std::chrono::system_clock::now(), pt.time_point); + // } + // } + + + // std::optional ang1, ang2; + + // switch (pt.pair_kind) { + // // if sexagesimal then hours:minutes:seconds form + // case mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS: + // case mcc::MccCoordPairKind::COORDS_KIND_RADEC_APP: + // case mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP: + // ang1 = utils::parsAngleString(_params[from_idx], true); + // break; + // default: + // // if sexagesimal then degrees:arcminutes:arcseconds form + // ang1 = utils::parsAngleString(_params[from_idx]); + // } + // if (!ang1) { + // return std::unexpected(std::make_error_code(std::errc::invalid_argument)); + // } + + // ang2 = utils::parsAngleString(_params[from_idx + 1]); + // if (!ang2) { + // return std::unexpected(std::make_error_code(std::errc::invalid_argument)); + // } + + + // pt.X = MccAngle(ang1.value(), mcc::MccDegreeTag{}); + // pt.Y = MccAngle(ang2.value(), mcc::MccDegreeTag{}); + + // return pt; + // } + template R byteRepr() const { @@ -738,9 +918,9 @@ public: return ERROR_EMPTY_MESSAGE; } - std::string_view key, val; + std::string_view key; - auto prev_msg_buff = _msgBuffer; + // auto prev_msg_buff = _msgBuffer; if constexpr (traits::mcc_output_char_range) { _msgBuffer = BYTEREPR_T{}; diff --git a/mcc/tests/netmsg_test.cpp b/mcc/tests/netmsg_test.cpp index e0725d0..9ca2fce 100644 --- a/mcc/tests/netmsg_test.cpp +++ b/mcc/tests/netmsg_test.cpp @@ -49,6 +49,7 @@ int main() } std::cout << ">\n"; + std::cout << msg2_t::celestialPointToString(mcc::MccCelestialPoint{}) << "\n"; return 0; }