Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:41

0001 //
0002 // Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 
0008 #ifndef BOOST_MYSQL_IMPL_INTERNAL_PROTOCOL_BINARY_SERIALIZATION_IPP
0009 #define BOOST_MYSQL_IMPL_INTERNAL_PROTOCOL_BINARY_SERIALIZATION_IPP
0010 
0011 #pragma once
0012 
0013 #include <boost/mysql/days.hpp>
0014 
0015 #include <boost/mysql/detail/config.hpp>
0016 
0017 #include <boost/mysql/impl/internal/protocol/binary_serialization.hpp>
0018 #include <boost/mysql/impl/internal/protocol/constants.hpp>
0019 #include <boost/mysql/impl/internal/protocol/serialization.hpp>
0020 
0021 #include <chrono>
0022 
0023 namespace boost {
0024 namespace mysql {
0025 namespace detail {
0026 
0027 // Binary serialization
0028 template <class T>
0029 BOOST_MYSQL_STATIC_OR_INLINE void serialize_binary_float(serialization_context& ctx, T input)
0030 {
0031     boost::endian::endian_store<T, sizeof(T), boost::endian::order::little>(ctx.first(), input);
0032     ctx.advance(sizeof(T));
0033 }
0034 
0035 BOOST_MYSQL_STATIC_OR_INLINE
0036 void serialize_binary_date(serialization_context& ctx, const date& input)
0037 {
0038     using namespace binc;
0039     serialize(ctx, static_cast<std::uint8_t>(date_sz), input.year(), input.month(), input.day());
0040 }
0041 
0042 BOOST_MYSQL_STATIC_OR_INLINE
0043 void serialize_binary_datetime(serialization_context& ctx, const datetime& input)
0044 {
0045     using namespace binc;
0046 
0047     // Serialize
0048     serialize(
0049         ctx,
0050         static_cast<std::uint8_t>(datetime_dhmsu_sz),
0051         input.year(),
0052         input.month(),
0053         input.day(),
0054         input.hour(),
0055         input.minute(),
0056         input.second(),
0057         input.microsecond()
0058     );
0059 }
0060 
0061 BOOST_MYSQL_STATIC_OR_INLINE
0062 void serialize_binary_time(serialization_context& ctx, const boost::mysql::time& input)
0063 {
0064     using namespace binc;
0065     using boost::mysql::days;
0066     using std::chrono::duration_cast;
0067     using std::chrono::hours;
0068     using std::chrono::microseconds;
0069     using std::chrono::minutes;
0070     using std::chrono::seconds;
0071 
0072     // Break time
0073     auto num_micros = duration_cast<microseconds>(input % seconds(1));
0074     auto num_secs = duration_cast<seconds>(input % minutes(1) - num_micros);
0075     auto num_mins = duration_cast<minutes>(input % hours(1) - num_secs);
0076     auto num_hours = duration_cast<hours>(input % days(1) - num_mins);
0077     auto num_days = duration_cast<days>(input - num_hours);
0078     std::uint8_t is_negative = (input.count() < 0) ? 1 : 0;
0079 
0080     // Serialize
0081     serialize(
0082         ctx,
0083         static_cast<std::uint8_t>(time_dhmsu_sz),
0084         is_negative,
0085         static_cast<std::uint32_t>(std::abs(num_days.count())),
0086         static_cast<std::uint8_t>(std::abs(num_hours.count())),
0087         static_cast<std::uint8_t>(std::abs(num_mins.count())),
0088         static_cast<std::uint8_t>(std::abs(num_secs.count())),
0089         static_cast<std::uint32_t>(std::abs(num_micros.count()))
0090     );
0091 }
0092 
0093 }  // namespace detail
0094 }  // namespace mysql
0095 }  // namespace boost
0096 
0097 std::size_t boost::mysql::detail::get_size(field_view input) noexcept
0098 {
0099     switch (input.kind())
0100     {
0101     case field_kind::null: return 0;
0102     case field_kind::int64: return 8;
0103     case field_kind::uint64: return 8;
0104     case field_kind::string: return get_size(string_lenenc{input.get_string()});
0105     case field_kind::blob: return get_size(string_lenenc{to_string(input.get_blob())});
0106     case field_kind::float_: return 4;
0107     case field_kind::double_: return 8;
0108     case field_kind::date: return binc::date_sz + binc::length_sz;
0109     case field_kind::datetime: return binc::datetime_dhmsu_sz + binc::length_sz;
0110     case field_kind::time: return binc::time_dhmsu_sz + binc::length_sz;
0111     default: BOOST_ASSERT(false); return 0;
0112     }
0113 }
0114 
0115 void boost::mysql::detail::serialize(serialization_context& ctx, field_view input) noexcept
0116 {
0117     switch (input.kind())
0118     {
0119     case field_kind::null: break;
0120     case field_kind::int64: serialize(ctx, input.get_int64()); break;
0121     case field_kind::uint64: serialize(ctx, input.get_uint64()); break;
0122     case field_kind::string: serialize(ctx, string_lenenc{input.get_string()}); break;
0123     case field_kind::blob: serialize(ctx, string_lenenc{to_string(input.get_blob())}); break;
0124     case field_kind::float_: serialize_binary_float(ctx, input.get_float()); break;
0125     case field_kind::double_: serialize_binary_float(ctx, input.get_double()); break;
0126     case field_kind::date: serialize_binary_date(ctx, input.get_date()); break;
0127     case field_kind::datetime: serialize_binary_datetime(ctx, input.get_datetime()); break;
0128     case field_kind::time: serialize_binary_time(ctx, input.get_time()); break;
0129     default: BOOST_ASSERT(false); break;
0130     }
0131 }
0132 
0133 #endif