diff --git a/include/mysql/impl/serialization.hpp b/include/mysql/impl/serialization.hpp index da35b088..8dda1904 100644 --- a/include/mysql/impl/serialization.hpp +++ b/include/mysql/impl/serialization.hpp @@ -2,6 +2,7 @@ #define MYSQL_ASIO_IMPL_SERIALIZATION_HPP #include +#include #include #include #include @@ -98,7 +99,7 @@ private: using value_type = typename get_value_type::type; public: static constexpr bool value = - std::is_arithmetic_v && // includes floating point types + std::is_integral_v && std::is_base_of_v, T>; }; @@ -333,6 +334,47 @@ std::size_t get_size(T, const SerializationContext&) noexcept return get_fixed_size>>::value; } +// Floating points +template >> +Error deserialize(value_holder& output, DeserializationContext& ctx) noexcept +{ + // Size check + if (!ctx.enough_size(sizeof(T))) return Error::incomplete_message; + + // Endianness conversion + // Boost.Endian support for floats start at 1.71. TODO: maybe update requirements and CI +#if BOOST_ENDIAN_BIG_BYTE + char buf [sizeof(T)]; + std::memcpy(buf, ctx.first(), sizeof(T)); + std::reverse(buf, buf + sizeof(T)); + std::memcpy(&output.value, buf, sizeof(T)); +#else + std::memcpy(&output.value, ctx.first(), sizeof(T)); +#endif + ctx.advance(sizeof(T)); + return Error::ok; +} + +template >> +void serialize(const value_holder& input, SerializationContext& ctx) noexcept +{ + // Endianness conversion +#if BOOST_ENDIAN_BIG_BYTE + char buf [sizeof(T)]; + std::memcpy(buf, &input.value, sizeof(T)); + std::reverse(buf, buf + sizeof(T)); + ctx.write(buf, sizeof(T)); +#else + ctx.write(&input.value, sizeof(T)); +#endif +} + +template >> +std::size_t get_size(const value_holder&, const SerializationContext&) noexcept +{ + return sizeof(T); +} + // Structs. To allow a limited way of reflection, structs should // specialize get_struct_fields with a tuple of pointers to members, // thus defining which fields should be (de)serialized in the struct