...
This commit is contained in:
301
mcc_deser.h
Normal file
301
mcc_deser.h
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "mcc_epoch.h"
|
||||||
|
#include "mcc_serialization_common.h"
|
||||||
|
|
||||||
|
namespace mcc::impl
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class MccDeserializerErrorCode : int {
|
||||||
|
ERROR_OK,
|
||||||
|
ERROR_UNDERLYING_DESERIALIZER,
|
||||||
|
ERROR_INVALID_SERIALIZED_VALUE,
|
||||||
|
ERROR_COORD_TRANSFORM
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mcc::impl
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class is_error_code_enum<mcc::impl::MccDeserializerErrorCode> : public true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
|
||||||
|
namespace mcc::impl
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// error category
|
||||||
|
struct MccDeserializerCategory : public std::error_category {
|
||||||
|
MccDeserializerCategory() : std::error_category() {}
|
||||||
|
|
||||||
|
const char* name() const noexcept
|
||||||
|
{
|
||||||
|
return "MCC-DESERIALIZER-ERR-CATEGORY";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string message(int ec) const
|
||||||
|
{
|
||||||
|
MccDeserializerErrorCode err = static_cast<MccDeserializerErrorCode>(ec);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case MccDeserializerErrorCode::ERROR_OK:
|
||||||
|
return "OK";
|
||||||
|
case MccDeserializerErrorCode::ERROR_UNDERLYING_DESERIALIZER:
|
||||||
|
return "error returned by underlying deserializer";
|
||||||
|
case MccDeserializerErrorCode::ERROR_INVALID_SERIALIZED_VALUE:
|
||||||
|
return "invalid serialized value";
|
||||||
|
case MccDeserializerErrorCode::ERROR_COORD_TRANSFORM:
|
||||||
|
return "coordinates transformation error";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const MccDeserializerCategory& get()
|
||||||
|
{
|
||||||
|
static const MccDeserializerCategory constInst;
|
||||||
|
return constInst;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline std::error_code make_error_code(MccDeserializerErrorCode ec)
|
||||||
|
{
|
||||||
|
return std::error_code(static_cast<int>(ec), MccDeserializerCategory::get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* BASE DESERIALIZER CLASS (FOR IMPLEMENTATIONS BELOW) */
|
||||||
|
|
||||||
|
struct MccDeserializerBase : mcc_deserializer_interface_t<MccError> {
|
||||||
|
using typename mcc_deserializer_interface_t<MccError>::error_t;
|
||||||
|
|
||||||
|
virtual ~MccDeserializerBase() = default;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MccDeserializerBase() = default;
|
||||||
|
|
||||||
|
//
|
||||||
|
// empty == true, if the 'input' is empty or if all elements consist of only spaces
|
||||||
|
//
|
||||||
|
static std::vector<std::string_view> splitValueIntoElements(traits::mcc_input_char_range auto const& input,
|
||||||
|
mcc_serialization_params_c auto const& params,
|
||||||
|
bool& empty)
|
||||||
|
{
|
||||||
|
static_assert(std::ranges::contiguous_range<decltype(input)>, "NOT IMPLEMENTED FOR NON-CONTIGUIUS RANGES!!!");
|
||||||
|
|
||||||
|
std::vector<std::string_view> res;
|
||||||
|
|
||||||
|
if (std::ranges::size(input)) {
|
||||||
|
empty = true;
|
||||||
|
|
||||||
|
std::ranges::for_each(std::views::split(input, params.elem_delim), [&res, &empty](auto const& el) {
|
||||||
|
std::back_inserter(res) = utils::trimSpaces(std::string_view{el.begin(), el.end()});
|
||||||
|
if (empty && res.back().size()) {
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VT, std::ranges::output_range<VT> R, typename... DeserParamsT>
|
||||||
|
static error_t deserializingRange(mcc_deserializer_c auto& dsr,
|
||||||
|
traits::mcc_input_char_range auto const& input,
|
||||||
|
R& r,
|
||||||
|
mcc_serialization_params_c auto const& params)
|
||||||
|
{
|
||||||
|
if (std::ranges::size(input) == 0) { // ignore an empty input, just return empty range?!!
|
||||||
|
r = R{};
|
||||||
|
return MccDeserializerErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto r_str = std::views::split(input, params.seq_delim);
|
||||||
|
VT val;
|
||||||
|
|
||||||
|
auto it = r.begin();
|
||||||
|
for (auto const& el : r_str) {
|
||||||
|
auto err = dsr(el, val, std::forward<DeserParamsT>(params)...);
|
||||||
|
if (err) {
|
||||||
|
return mcc_deduced_err(err, MccDeserializerErrorCode::ERROR_UNDERLYING_DESERIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it == r.end()) {
|
||||||
|
std::back_inserter(r) = val;
|
||||||
|
it = r.end();
|
||||||
|
} else {
|
||||||
|
*it = val;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MccDeserializerErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* MAIN (FALLBACK) TEMPLATED IMPLEMENTATION */
|
||||||
|
|
||||||
|
|
||||||
|
template <typename VT>
|
||||||
|
struct MccDeserializer : MccDeserializerBase {
|
||||||
|
static constexpr std::string_view deserializerName{"MCC-FALLBACK-DESERIALIZER"};
|
||||||
|
|
||||||
|
virtual ~MccDeserializer() = default;
|
||||||
|
|
||||||
|
|
||||||
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
|
error_t operator()(traits::mcc_input_char_range auto const& input,
|
||||||
|
VT& value,
|
||||||
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
|
{
|
||||||
|
if constexpr (std::is_arithmetic_v<VT>) {
|
||||||
|
auto v = mcc::utils::numFromStr<VT>(utils::trimSpaces(input));
|
||||||
|
if (!v.has_value()) {
|
||||||
|
return MccDeserializerErrorCode::ERROR_INVALID_SERIALIZED_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = v.value();
|
||||||
|
} else if constexpr (mcc::traits::mcc_output_char_range<VT>) {
|
||||||
|
VT r;
|
||||||
|
if constexpr (traits::mcc_array_c<VT>) {
|
||||||
|
size_t N =
|
||||||
|
std::ranges::size(r) <= std::ranges::size(input) ? std::ranges::size(r) : std::ranges::size(input);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < N; ++i) {
|
||||||
|
r[i] = input[i];
|
||||||
|
}
|
||||||
|
if (std::ranges::size(r) > N) {
|
||||||
|
for (size_t i = N; i < std::ranges::size(r); ++i) {
|
||||||
|
r[i] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::ranges::copy(input, std::back_inserter(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
value = r;
|
||||||
|
} else if constexpr (std::ranges::range<VT>) {
|
||||||
|
using el_t = std::ranges::range_value_t<VT>;
|
||||||
|
|
||||||
|
static_assert(std::ranges::output_range<VT, el_t>, "INVALID RANGE TYPE!!!");
|
||||||
|
|
||||||
|
// no reference or constants allowed
|
||||||
|
static_assert(std::is_reference_v<el_t> || std::is_const_v<el_t>, "INVALID RANGE ELEMENT TYPE!!!");
|
||||||
|
|
||||||
|
MccDeserializer<el_t> dsr;
|
||||||
|
return deserializingRange<el_t>(dsr, input, value, params);
|
||||||
|
} else if constexpr (traits::mcc_time_duration_c<VT>) {
|
||||||
|
typename VT::rep vd;
|
||||||
|
|
||||||
|
MccDeserializer<typename VT::rep> dsr;
|
||||||
|
|
||||||
|
auto err = dsr(trimSpaces(input), vd, params);
|
||||||
|
if (err) {
|
||||||
|
return mcc_deduced_err(err, MccDeserializerErrorCode::ERROR_UNDERLYING_DESERIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
value = VT{vd};
|
||||||
|
} else {
|
||||||
|
static_assert(false, "UNSUPPORTED VALUE TYPE!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return MccDeserializerErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* SPECIALIZATION FOR THE SOME CONCEPTS */
|
||||||
|
|
||||||
|
template <mcc_coord_epoch_c VT>
|
||||||
|
struct MccDeserializer<VT> : MccDeserializerBase {
|
||||||
|
static constexpr std::string_view deserializerName{"MCC-COORD-EPOCH-DESERIALIZER"};
|
||||||
|
|
||||||
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
|
error_t operator()(traits::mcc_input_char_range auto const& input,
|
||||||
|
VT& value,
|
||||||
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
|
{
|
||||||
|
bool ok = value.fromCharRange(input);
|
||||||
|
if (!ok) {
|
||||||
|
return MccDeserializerErrorCode::ERROR_INVALID_SERIALIZED_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MccDeserializerErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename VT>
|
||||||
|
requires(!std::is_arithmetic_v<VT> && mcc_angle_c<VT>)
|
||||||
|
struct MccDeserializer<VT> : MccDeserializerBase {
|
||||||
|
static constexpr std::string_view deserializerName{"MCC-ANGLE-DESERIALIZER"};
|
||||||
|
|
||||||
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
|
error_t operator()(traits::mcc_input_char_range auto const& input,
|
||||||
|
VT& value,
|
||||||
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
|
{
|
||||||
|
bool hms = params.angle_format == MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURS;
|
||||||
|
|
||||||
|
auto res = utils::parsAngleString(input, hms);
|
||||||
|
if (res) { // returned angle is in degrees!!!
|
||||||
|
value = res.value() * MCC_DEGRESS_TO_RADS;
|
||||||
|
} else {
|
||||||
|
return MccDeserializerErrorCode::ERROR_INVALID_SERIALIZED_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MccDeserializerErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <mcc_skypoint_c VT>
|
||||||
|
struct MccDeserializer<VT> : MccDeserializerBase {
|
||||||
|
static constexpr std::string_view deserializerName{"MCC-SKYPOINT-DESERIALIZER"};
|
||||||
|
|
||||||
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
|
error_t operator()(traits::mcc_input_char_range auto const& input,
|
||||||
|
VT& value,
|
||||||
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
|
{
|
||||||
|
// valid format: X<elem-delim>Y[<elem-delim>TIME-POINT<elem-delim>PAIR-KIND]
|
||||||
|
// X<elem-delim>Y (assumed RADEC_ICRS and J2000.0 epoch)
|
||||||
|
|
||||||
|
bool empty;
|
||||||
|
|
||||||
|
auto elems = MccDeserializerBase::splitValueIntoElements(input, params, empty);
|
||||||
|
|
||||||
|
if (empty || (elems.size() < 2) || (elems.size() == 3)) {
|
||||||
|
return MccDeserializerErrorCode::ERROR_INVALID_SERIALIZED_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MccCoordPairKind pair_kind{MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
|
||||||
|
MccCelestialCoordEpoch epoch; // J2000.0
|
||||||
|
|
||||||
|
MccAngle x, y;
|
||||||
|
MccDeserializer<MccAngle> dsr_ang;
|
||||||
|
|
||||||
|
typename MccDeserializer<MccAngle>::error_t dsr_err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace mcc::impl
|
||||||
17
mcc_ser.h
17
mcc_ser.h
@@ -158,7 +158,7 @@ template <typename VT>
|
|||||||
struct MccSerializer : MccSerializerBase {
|
struct MccSerializer : MccSerializerBase {
|
||||||
constexpr static std::string_view serializerName{"MCC-FALLBACK-SERIALIZER"};
|
constexpr static std::string_view serializerName{"MCC-FALLBACK-SERIALIZER"};
|
||||||
|
|
||||||
template <typename ParamsT = mcc_serialization_params_t>
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||||
VT const& value,
|
VT const& value,
|
||||||
ParamsT const& params = mcc_serialization_params_t{})
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
@@ -207,7 +207,7 @@ struct MccSerializer<VT> : MccSerializerBase {
|
|||||||
|
|
||||||
constexpr static std::string_view serializerName{"MCC-SYSTIME-SERIALIZER"};
|
constexpr static std::string_view serializerName{"MCC-SYSTIME-SERIALIZER"};
|
||||||
|
|
||||||
template <typename ParamsT = mcc_serialization_params_t>
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||||
VT const& value,
|
VT const& value,
|
||||||
ParamsT const& params = mcc_serialization_params_t{})
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
@@ -224,7 +224,7 @@ template <typename VT>
|
|||||||
struct MccSerializer<VT> : MccSerializerBase {
|
struct MccSerializer<VT> : MccSerializerBase {
|
||||||
constexpr static std::string_view serializerName{"MCC-ANGLE-SERIALIZER"};
|
constexpr static std::string_view serializerName{"MCC-ANGLE-SERIALIZER"};
|
||||||
|
|
||||||
template <typename ParamsT = mcc_serialization_params_t>
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||||
VT const& value,
|
VT const& value,
|
||||||
ParamsT const& params = mcc_serialization_params_t{})
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
@@ -270,7 +270,7 @@ template <mcc_coord_epoch_c VT>
|
|||||||
struct MccSerializer<VT> : MccSerializerBase {
|
struct MccSerializer<VT> : MccSerializerBase {
|
||||||
constexpr static std::string_view serializerName{"MCC-COORD-EPOCH-SERIALIZER"};
|
constexpr static std::string_view serializerName{"MCC-COORD-EPOCH-SERIALIZER"};
|
||||||
|
|
||||||
template <typename ParamsT = mcc_serialization_params_t>
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||||
VT const& value,
|
VT const& value,
|
||||||
ParamsT const& params = mcc_serialization_params_t{})
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
@@ -312,7 +312,7 @@ template <mcc_coord_pair_c VT>
|
|||||||
struct MccSerializer<VT> : MccSerializerBase {
|
struct MccSerializer<VT> : MccSerializerBase {
|
||||||
constexpr static std::string_view serializerName{"MCC-COORD-PAIR-SERIALIZER"};
|
constexpr static std::string_view serializerName{"MCC-COORD-PAIR-SERIALIZER"};
|
||||||
|
|
||||||
template <typename ParamsT = mcc_serialization_params_t>
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||||
VT const& value,
|
VT const& value,
|
||||||
ParamsT const& params = mcc_serialization_params_t{})
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
@@ -367,7 +367,7 @@ template <mcc_skypoint_c VT>
|
|||||||
struct MccSerializer<VT> : MccSerializerBase {
|
struct MccSerializer<VT> : MccSerializerBase {
|
||||||
constexpr static std::string_view serializerName{"MCC-SKYPOINT-SERIALIZER"};
|
constexpr static std::string_view serializerName{"MCC-SKYPOINT-SERIALIZER"};
|
||||||
|
|
||||||
template <typename ParamsT = mcc_serialization_params_t>
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||||
VT const& value,
|
VT const& value,
|
||||||
ParamsT const& params = mcc_serialization_params_t{})
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
@@ -434,7 +434,7 @@ template <mcc_telemetry_data_c VT>
|
|||||||
struct MccSerializer<VT> : MccSerializerBase {
|
struct MccSerializer<VT> : MccSerializerBase {
|
||||||
constexpr static std::string_view serializerName{"MCC-TELEMETRY-DATA-SERIALIZER"};
|
constexpr static std::string_view serializerName{"MCC-TELEMETRY-DATA-SERIALIZER"};
|
||||||
|
|
||||||
template <typename ParamsT = mcc_serialization_params_t>
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||||
VT const& value,
|
VT const& value,
|
||||||
ParamsT const& params = mcc_serialization_params_t{})
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
@@ -687,4 +687,7 @@ struct MccSerializer<VT> : MccSerializerBase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static_assert(mcc_serializer_c<MccSerializer<MccAngle>>, "!!!");
|
||||||
|
|
||||||
} // namespace mcc::impl
|
} // namespace mcc::impl
|
||||||
|
|||||||
@@ -352,14 +352,14 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct MccDeserializerBase : mcc_deserializer_interface_t<MccError> {
|
// struct MccDeserializerBase : mcc_deserializer_interface_t<MccError> {
|
||||||
virtual ~MccDeserializerBase() = default;
|
// virtual ~MccDeserializerBase() = default;
|
||||||
|
|
||||||
using typename mcc_deserializer_interface_t<MccError>::error_t;
|
// using typename mcc_deserializer_interface_t<MccError>::error_t;
|
||||||
|
|
||||||
protected:
|
// protected:
|
||||||
MccDeserializerBase() = default;
|
// MccDeserializerBase() = default;
|
||||||
};
|
// };
|
||||||
|
|
||||||
// template <mcc_serialization_params_c ParamsT>
|
// template <mcc_serialization_params_c ParamsT>
|
||||||
// struct MccSerializerBase : mcc_serializer_interface_t<MccError>, details::_params_manipulator_t<ParamsT> {
|
// struct MccSerializerBase : mcc_serializer_interface_t<MccError>, details::_params_manipulator_t<ParamsT> {
|
||||||
|
|||||||
Reference in New Issue
Block a user