mirror of
https://github.com/boostorg/mysql.git
synced 2026-02-14 12:52:17 +00:00
Refactored basic_types header
Split into value_holder, bytestring and protocol_types
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "boost/mysql/detail/protocol/channel.hpp"
|
||||
#include "boost/mysql/detail/network_algorithms/handshake.hpp"
|
||||
#include "boost/mysql/detail/basic_types.hpp"
|
||||
#include "boost/mysql/detail/protocol/protocol_types.hpp"
|
||||
#include "boost/mysql/error.hpp"
|
||||
#include "boost/mysql/resultset.hpp"
|
||||
#include "boost/mysql/prepared_statement.hpp"
|
||||
|
||||
21
include/boost/mysql/detail/aux/bytestring.hpp
Normal file
21
include/boost/mysql/detail/aux/bytestring.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef INCLUDE_BOOST_MYSQL_DETAIL_AUX_BYTESTRING_HPP_
|
||||
#define INCLUDE_BOOST_MYSQL_DETAIL_AUX_BYTESTRING_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <typename Allocator>
|
||||
using basic_bytestring = std::vector<std::uint8_t, Allocator>;
|
||||
|
||||
using bytestring = std::vector<std::uint8_t>;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUX_BYTESTRING_HPP_ */
|
||||
54
include/boost/mysql/detail/aux/value_holder.hpp
Normal file
54
include/boost/mysql/detail/aux/value_holder.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef INCLUDE_BOOST_MYSQL_DETAIL_AUX_VALUE_HOLDER_HPP_
|
||||
#define INCLUDE_BOOST_MYSQL_DETAIL_AUX_VALUE_HOLDER_HPP_
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct value_holder
|
||||
{
|
||||
using value_type = T;
|
||||
|
||||
value_type value;
|
||||
|
||||
value_holder(): value{} {};
|
||||
|
||||
template <typename U>
|
||||
explicit constexpr value_holder(U&& u): value(std::forward<U>(u)) {}
|
||||
|
||||
constexpr bool operator==(const value_holder<T>& rhs) const { return value == rhs.value; }
|
||||
constexpr bool operator!=(const value_holder<T>& rhs) const { return value != rhs.value; }
|
||||
};
|
||||
|
||||
// Operations on value holders
|
||||
struct get_value_type_helper
|
||||
{
|
||||
struct no_value_type {};
|
||||
|
||||
template <typename T>
|
||||
static constexpr typename T::value_type get(typename T::value_type*);
|
||||
|
||||
template <typename T>
|
||||
static constexpr no_value_type get(...);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct get_value_type
|
||||
{
|
||||
using type = decltype(get_value_type_helper().get<T>(nullptr));
|
||||
using no_value_type = get_value_type_helper::no_value_type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using get_value_type_t = typename get_value_type<T>::type;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUX_VALUE_HOLDER_HPP_ */
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <string_view>
|
||||
#include "boost/mysql/detail/protocol/channel.hpp"
|
||||
#include "boost/mysql/detail/basic_types.hpp"
|
||||
#include "boost/mysql/detail/protocol/protocol_types.hpp"
|
||||
#include "boost/mysql/collation.hpp"
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define MYSQL_ASIO_IMPL_CHANNEL_HPP
|
||||
|
||||
#include "boost/mysql/error.hpp"
|
||||
#include "boost/mysql/detail/basic_types.hpp"
|
||||
#include "boost/mysql/detail/aux/bytestring.hpp"
|
||||
#include "boost/mysql/detail/protocol/capabilities.hpp"
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef MYSQL_ASIO_IMPL_CONSTANTS_HPP
|
||||
#define MYSQL_ASIO_IMPL_CONSTANTS_HPP
|
||||
|
||||
#include "boost/mysql/detail/basic_types.hpp"
|
||||
#include "boost/mysql/detail/protocol/protocol_types.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
|
||||
125
include/boost/mysql/detail/protocol/impl/serialization.ipp
Normal file
125
include/boost/mysql/detail/protocol/impl/serialization.ipp
Normal file
@@ -0,0 +1,125 @@
|
||||
#ifndef INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_IMPL_SERIALIZATION_IPP_
|
||||
#define INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_IMPL_SERIALIZATION_IPP_
|
||||
|
||||
inline boost::mysql::errc boost::mysql::detail::deserialize(
|
||||
int_lenenc& output,
|
||||
deserialization_context& ctx
|
||||
) noexcept
|
||||
{
|
||||
int1 first_byte;
|
||||
errc err = deserialize(first_byte, ctx);
|
||||
if (err != errc::ok)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (first_byte.value == 0xFC)
|
||||
{
|
||||
int2 value;
|
||||
err = deserialize(value, ctx);
|
||||
output.value = value.value;
|
||||
}
|
||||
else if (first_byte.value == 0xFD)
|
||||
{
|
||||
int3 value;
|
||||
err = deserialize(value, ctx);
|
||||
output.value = value.value;
|
||||
}
|
||||
else if (first_byte.value == 0xFE)
|
||||
{
|
||||
int8 value;
|
||||
err = deserialize(value, ctx);
|
||||
output.value = value.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = errc::ok;
|
||||
output.value = first_byte.value;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
inline void boost::mysql::detail::serialize(
|
||||
int_lenenc input,
|
||||
serialization_context& ctx
|
||||
) noexcept
|
||||
{
|
||||
if (input.value < 251)
|
||||
{
|
||||
serialize(int1(static_cast<std::uint8_t>(input.value)), ctx);
|
||||
}
|
||||
else if (input.value < 0x10000)
|
||||
{
|
||||
ctx.write(0xfc);
|
||||
serialize(int2(static_cast<std::uint16_t>(input.value)), ctx);
|
||||
}
|
||||
else if (input.value < 0x1000000)
|
||||
{
|
||||
ctx.write(0xfd);
|
||||
serialize(int3(static_cast<std::uint32_t>(input.value)), ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.write(0xfe);
|
||||
serialize(int8(static_cast<std::uint64_t>(input.value)), ctx);
|
||||
}
|
||||
}
|
||||
|
||||
inline std::size_t boost::mysql::detail::get_size(
|
||||
int_lenenc input, const
|
||||
serialization_context&
|
||||
) noexcept
|
||||
{
|
||||
if (input.value < 251) return 1;
|
||||
else if (input.value < 0x10000) return 3;
|
||||
else if (input.value < 0x1000000) return 4;
|
||||
else return 9;
|
||||
}
|
||||
|
||||
inline boost::mysql::errc boost::mysql::detail::deserialize(
|
||||
string_null& output,
|
||||
deserialization_context& ctx
|
||||
) noexcept
|
||||
{
|
||||
auto string_end = std::find(ctx.first(), ctx.last(), 0);
|
||||
if (string_end == ctx.last())
|
||||
{
|
||||
return errc::incomplete_message;
|
||||
}
|
||||
output.value = get_string(ctx.first(), string_end-ctx.first());
|
||||
ctx.set_first(string_end + 1); // skip the null terminator
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
inline boost::mysql::errc boost::mysql::detail::deserialize(
|
||||
string_eof& output,
|
||||
deserialization_context& ctx
|
||||
) noexcept
|
||||
{
|
||||
output.value = get_string(ctx.first(), ctx.last()-ctx.first());
|
||||
ctx.set_first(ctx.last());
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
inline boost::mysql::errc boost::mysql::detail::deserialize(
|
||||
string_lenenc& output,
|
||||
deserialization_context& ctx
|
||||
) noexcept
|
||||
{
|
||||
int_lenenc length;
|
||||
errc err = deserialize(length, ctx);
|
||||
if (err != errc::ok)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
if (!ctx.enough_size(length.value))
|
||||
{
|
||||
return errc::incomplete_message;
|
||||
}
|
||||
|
||||
output.value = get_string(ctx.first(), length.value);
|
||||
ctx.advance(length.value);
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_IMPL_SERIALIZATION_IPP_ */
|
||||
@@ -2,8 +2,9 @@
|
||||
#define MYSQL_ASIO_IMPL_MESSAGES_HPP
|
||||
|
||||
#include "boost/mysql/detail/protocol/serialization.hpp"
|
||||
#include "boost/mysql/detail/basic_types.hpp"
|
||||
#include "boost/mysql/detail/protocol/protocol_types.hpp"
|
||||
#include "boost/mysql/detail/protocol/constants.hpp"
|
||||
#include "boost/mysql/detail/aux/bytestring.hpp"
|
||||
#include "boost/mysql/collation.hpp"
|
||||
#include "boost/mysql/value.hpp"
|
||||
#include <string>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef MYSQL_ASIO_IMPL_BASIC_TYPES_HPP
|
||||
#define MYSQL_ASIO_IMPL_BASIC_TYPES_HPP
|
||||
|
||||
#include "boost/mysql/detail/aux/value_holder.hpp"
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
#include <array>
|
||||
@@ -11,22 +12,6 @@ namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct value_holder
|
||||
{
|
||||
using value_type = T;
|
||||
|
||||
value_type value;
|
||||
|
||||
value_holder(): value{} {};
|
||||
|
||||
template <typename U>
|
||||
explicit constexpr value_holder(U&& u): value(std::forward<U>(u)) {}
|
||||
|
||||
constexpr bool operator==(const value_holder<T>& rhs) const { return value == rhs.value; }
|
||||
constexpr bool operator!=(const value_holder<T>& rhs) const { return value != rhs.value; }
|
||||
};
|
||||
|
||||
struct int1 : value_holder<std::uint8_t> { using value_holder::value_holder; };
|
||||
struct int2 : value_holder<std::uint16_t> { using value_holder::value_holder; };
|
||||
struct int3 : value_holder<std::uint32_t> { using value_holder::value_holder; };
|
||||
@@ -53,10 +38,6 @@ struct string_null : value_holder<std::string_view> { using value_holder::value_
|
||||
struct string_eof : value_holder<std::string_view> { using value_holder::value_holder; };
|
||||
struct string_lenenc : value_holder<std::string_view> { using value_holder::value_holder; };
|
||||
|
||||
template <typename Allocator>
|
||||
using basic_bytestring = std::vector<std::uint8_t, Allocator>;
|
||||
|
||||
using bytestring = std::vector<std::uint8_t>;
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
@@ -6,9 +6,10 @@
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
#include <variant>
|
||||
#include "boost/mysql/detail/basic_types.hpp"
|
||||
#include "boost/mysql/detail/protocol/protocol_types.hpp"
|
||||
#include "boost/mysql/detail/protocol/serialization_context.hpp"
|
||||
#include "boost/mysql/detail/protocol/deserialization_context.hpp"
|
||||
#include "boost/mysql/detail/aux/value_holder.hpp"
|
||||
#include "boost/mysql/error.hpp"
|
||||
|
||||
namespace boost {
|
||||
@@ -24,40 +25,14 @@ namespace detail {
|
||||
*/
|
||||
|
||||
// Fixed-size types
|
||||
struct get_value_type_helper
|
||||
{
|
||||
struct no_value_type {};
|
||||
|
||||
template <typename T>
|
||||
static constexpr typename T::value_type get(typename T::value_type*);
|
||||
|
||||
template <typename T>
|
||||
static constexpr no_value_type get(...);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct get_value_type
|
||||
{
|
||||
using type = decltype(get_value_type_helper().get<T>(nullptr));
|
||||
using no_value_type = get_value_type_helper::no_value_type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_fixed_size
|
||||
{
|
||||
private:
|
||||
using value_type = typename get_value_type<T>::type;
|
||||
public:
|
||||
static constexpr bool value =
|
||||
std::is_integral_v<value_type> &&
|
||||
std::is_base_of_v<value_holder<value_type>, T>;
|
||||
std::is_integral<get_value_type_t<T>>::value &&
|
||||
std::is_base_of<value_holder<get_value_type_t<T>>, T>::value;
|
||||
};
|
||||
|
||||
// Serialization of these types relies on this fact
|
||||
static_assert(std::numeric_limits<float>::is_iec559);
|
||||
static_assert(std::numeric_limits<double>::is_iec559);
|
||||
|
||||
|
||||
template <> struct is_fixed_size<int_lenenc> : std::false_type {};
|
||||
template <std::size_t N> struct is_fixed_size<string_fixed<N>>: std::true_type {};
|
||||
|
||||
@@ -117,69 +92,9 @@ get_size(T, const serialization_context&) noexcept
|
||||
}
|
||||
|
||||
// int_lenenc
|
||||
inline errc deserialize(int_lenenc& output, deserialization_context& ctx) noexcept
|
||||
{
|
||||
int1 first_byte;
|
||||
errc err = deserialize(first_byte, ctx);
|
||||
if (err != errc::ok)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (first_byte.value == 0xFC)
|
||||
{
|
||||
int2 value;
|
||||
err = deserialize(value, ctx);
|
||||
output.value = value.value;
|
||||
}
|
||||
else if (first_byte.value == 0xFD)
|
||||
{
|
||||
int3 value;
|
||||
err = deserialize(value, ctx);
|
||||
output.value = value.value;
|
||||
}
|
||||
else if (first_byte.value == 0xFE)
|
||||
{
|
||||
int8 value;
|
||||
err = deserialize(value, ctx);
|
||||
output.value = value.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = errc::ok;
|
||||
output.value = first_byte.value;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
inline void serialize(int_lenenc input, serialization_context& ctx) noexcept
|
||||
{
|
||||
if (input.value < 251)
|
||||
{
|
||||
serialize(int1(static_cast<std::uint8_t>(input.value)), ctx);
|
||||
}
|
||||
else if (input.value < 0x10000)
|
||||
{
|
||||
ctx.write(0xfc);
|
||||
serialize(int2(static_cast<std::uint16_t>(input.value)), ctx);
|
||||
}
|
||||
else if (input.value < 0x1000000)
|
||||
{
|
||||
ctx.write(0xfd);
|
||||
serialize(int3(static_cast<std::uint32_t>(input.value)), ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.write(0xfe);
|
||||
serialize(int8(static_cast<std::uint64_t>(input.value)), ctx);
|
||||
}
|
||||
}
|
||||
inline std::size_t get_size(int_lenenc input, const serialization_context&) noexcept
|
||||
{
|
||||
if (input.value < 251) return 1;
|
||||
else if (input.value < 0x10000) return 3;
|
||||
else if (input.value < 0x1000000) return 4;
|
||||
else return 9;
|
||||
}
|
||||
inline errc deserialize(int_lenenc& output, deserialization_context& ctx) noexcept;
|
||||
inline void serialize(int_lenenc input, serialization_context& ctx) noexcept;
|
||||
inline std::size_t get_size(int_lenenc input, const serialization_context&) noexcept;
|
||||
|
||||
// Helper for strings
|
||||
inline std::string_view get_string(const std::uint8_t* from, std::size_t size)
|
||||
@@ -188,17 +103,7 @@ inline std::string_view get_string(const std::uint8_t* from, std::size_t size)
|
||||
}
|
||||
|
||||
// string_null
|
||||
inline errc deserialize(string_null& output, deserialization_context& ctx) noexcept
|
||||
{
|
||||
auto string_end = std::find(ctx.first(), ctx.last(), 0);
|
||||
if (string_end == ctx.last())
|
||||
{
|
||||
return errc::incomplete_message;
|
||||
}
|
||||
output.value = get_string(ctx.first(), string_end-ctx.first());
|
||||
ctx.set_first(string_end + 1); // skip the null terminator
|
||||
return errc::ok;
|
||||
}
|
||||
inline errc deserialize(string_null& output, deserialization_context& ctx) noexcept;
|
||||
inline void serialize(string_null input, serialization_context& ctx) noexcept
|
||||
{
|
||||
ctx.write(input.value.data(), input.value.size());
|
||||
@@ -210,12 +115,7 @@ inline std::size_t get_size(string_null input, const serialization_context&) noe
|
||||
}
|
||||
|
||||
// string_eof
|
||||
inline errc deserialize(string_eof& output, deserialization_context& ctx) noexcept
|
||||
{
|
||||
output.value = get_string(ctx.first(), ctx.last()-ctx.first());
|
||||
ctx.set_first(ctx.last());
|
||||
return errc::ok;
|
||||
}
|
||||
inline errc deserialize(string_eof& output, deserialization_context& ctx) noexcept;
|
||||
inline void serialize(string_eof input, serialization_context& ctx) noexcept
|
||||
{
|
||||
ctx.write(input.value.data(), input.value.size());
|
||||
@@ -226,35 +126,15 @@ inline std::size_t get_size(string_eof input, const serialization_context&) noex
|
||||
}
|
||||
|
||||
// string_lenenc
|
||||
inline errc deserialize(string_lenenc& output, deserialization_context& ctx) noexcept
|
||||
{
|
||||
int_lenenc length;
|
||||
errc err = deserialize(length, ctx);
|
||||
if (err != errc::ok)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
if (!ctx.enough_size(length.value))
|
||||
{
|
||||
return errc::incomplete_message;
|
||||
}
|
||||
|
||||
output.value = get_string(ctx.first(), length.value);
|
||||
ctx.advance(length.value);
|
||||
return errc::ok;
|
||||
}
|
||||
inline errc deserialize(string_lenenc& output, deserialization_context& ctx) noexcept;
|
||||
inline void serialize(string_lenenc input, serialization_context& ctx) noexcept
|
||||
{
|
||||
int_lenenc length;
|
||||
length.value = input.value.size();
|
||||
serialize(length, ctx);
|
||||
serialize(int_lenenc(input.value.size()), ctx);
|
||||
ctx.write(input.value.data(), input.value.size());
|
||||
}
|
||||
inline std::size_t get_size(string_lenenc input, const serialization_context& ctx) noexcept
|
||||
{
|
||||
int_lenenc length;
|
||||
length.value = input.value.size();
|
||||
return get_size(length, ctx) + input.value.size();
|
||||
return get_size(int_lenenc(input.value.size()), ctx) + input.value.size();
|
||||
}
|
||||
|
||||
// Enums
|
||||
@@ -285,6 +165,9 @@ std::size_t get_size(T, const serialization_context&) noexcept
|
||||
}
|
||||
|
||||
// Floating points
|
||||
static_assert(std::numeric_limits<float>::is_iec559);
|
||||
static_assert(std::numeric_limits<double>::is_iec559);
|
||||
|
||||
template <typename T, typename=std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
errc deserialize(value_holder<T>& output, deserialization_context& ctx) noexcept
|
||||
{
|
||||
@@ -486,11 +369,10 @@ inline std::size_t get_size(dummy_serializable, const serialization_context&) no
|
||||
inline void serialize(dummy_serializable, serialization_context&) noexcept {}
|
||||
inline errc deserialize(dummy_serializable, deserialization_context&) noexcept { return errc::ok; }
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_fixed_size_fn() { return is_fixed_size<T>::value; }
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
#include "boost/mysql/detail/protocol/impl/serialization.ipp"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define MYSQL_ASIO_METADATA_HPP
|
||||
|
||||
#include "boost/mysql/detail/protocol/messages.hpp"
|
||||
#include "boost/mysql/detail/basic_types.hpp"
|
||||
#include "boost/mysql/detail/aux/bytestring.hpp"
|
||||
#include "boost/mysql/field_type.hpp"
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "boost/mysql/metadata.hpp"
|
||||
#include "boost/mysql/detail/protocol/messages.hpp"
|
||||
#include "boost/mysql/detail/protocol/channel.hpp"
|
||||
#include "boost/mysql/detail/aux/bytestring.hpp"
|
||||
#include "boost/mysql/detail/network_algorithms/common.hpp" // deserialize_row_fn
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <cassert>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#ifndef MYSQL_ASIO_ROW_HPP
|
||||
#define MYSQL_ASIO_ROW_HPP
|
||||
|
||||
#include "boost/mysql/detail/basic_types.hpp"
|
||||
#include "boost/mysql/detail/aux/bytestring.hpp"
|
||||
#include "boost/mysql/detail/aux/container_equals.hpp"
|
||||
#include "boost/mysql/value.hpp"
|
||||
#include "boost/mysql/metadata.hpp"
|
||||
#include "boost/mysql/detail/aux/container_equals.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
|
||||
Reference in New Issue
Block a user