File indexing completed on 2025-01-30 09:48:59
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MYSQL_IMPL_FIELD_VIEW_HPP
0009 #define BOOST_MYSQL_IMPL_FIELD_VIEW_HPP
0010
0011 #pragma once
0012
0013 #include <boost/mysql/bad_field_access.hpp>
0014 #include <boost/mysql/field_view.hpp>
0015
0016 #include <boost/assert.hpp>
0017 #include <boost/throw_exception.hpp>
0018
0019 #include <cstring>
0020 #include <limits>
0021
0022 namespace boost {
0023 namespace mysql {
0024 namespace detail {
0025
0026 inline bool blobs_equal(blob_view b1, blob_view b2)
0027 {
0028 if (b1.size() != b2.size())
0029 return false;
0030 return b1.empty() || std::memcmp(b1.data(), b2.data(), b2.size()) == 0;
0031 }
0032
0033 }
0034 }
0035 }
0036
0037 BOOST_CXX14_CONSTEXPR inline boost::mysql::field_kind boost::mysql::field_view::kind() const noexcept
0038 {
0039 switch (impl_.ikind)
0040 {
0041 case internal_kind::null: return field_kind::null;
0042 case internal_kind::int64: return field_kind::int64;
0043 case internal_kind::uint64: return field_kind::uint64;
0044 case internal_kind::string: return field_kind::string;
0045 case internal_kind::blob: return field_kind::blob;
0046 case internal_kind::float_: return field_kind::float_;
0047 case internal_kind::double_: return field_kind::double_;
0048 case internal_kind::date: return field_kind::date;
0049 case internal_kind::datetime: return field_kind::datetime;
0050 case internal_kind::time: return field_kind::time;
0051 case internal_kind::field_ptr: return impl_.repr.field_ptr->kind();
0052
0053 default: return field_kind::null;
0054 }
0055 }
0056
0057 BOOST_CXX14_CONSTEXPR std::int64_t boost::mysql::field_view::as_int64() const
0058 {
0059 if (is_field_ptr())
0060 return impl_.repr.field_ptr->as<std::int64_t>();
0061 check_kind(internal_kind::int64);
0062 return impl_.repr.int64;
0063 }
0064
0065 BOOST_CXX14_CONSTEXPR std::uint64_t boost::mysql::field_view::as_uint64() const
0066 {
0067 if (is_field_ptr())
0068 return impl_.repr.field_ptr->as<std::uint64_t>();
0069 check_kind(internal_kind::uint64);
0070 return impl_.repr.uint64;
0071 }
0072
0073 BOOST_CXX14_CONSTEXPR boost::mysql::string_view boost::mysql::field_view::as_string() const
0074 {
0075 if (is_field_ptr())
0076 return impl_.repr.field_ptr->as<std::string>();
0077 check_kind(internal_kind::string);
0078 return impl_.repr.string;
0079 }
0080
0081 BOOST_CXX14_CONSTEXPR boost::mysql::blob_view boost::mysql::field_view::as_blob() const
0082 {
0083 if (is_field_ptr())
0084 return impl_.repr.field_ptr->as<blob>();
0085 check_kind(internal_kind::blob);
0086 return impl_.repr.blob;
0087 }
0088
0089 BOOST_CXX14_CONSTEXPR float boost::mysql::field_view::as_float() const
0090 {
0091 if (is_field_ptr())
0092 return impl_.repr.field_ptr->as<float>();
0093 check_kind(internal_kind::float_);
0094 return impl_.repr.float_;
0095 }
0096
0097 BOOST_CXX14_CONSTEXPR double boost::mysql::field_view::as_double() const
0098 {
0099 if (is_field_ptr())
0100 return impl_.repr.field_ptr->as<double>();
0101 check_kind(internal_kind::double_);
0102 return impl_.repr.double_;
0103 }
0104
0105 BOOST_CXX14_CONSTEXPR boost::mysql::date boost::mysql::field_view::as_date() const
0106 {
0107 if (is_field_ptr())
0108 return impl_.repr.field_ptr->as<date>();
0109 check_kind(internal_kind::date);
0110 return impl_.repr.date_;
0111 }
0112
0113 BOOST_CXX14_CONSTEXPR boost::mysql::datetime boost::mysql::field_view::as_datetime() const
0114 {
0115 if (is_field_ptr())
0116 return impl_.repr.field_ptr->as<datetime>();
0117 check_kind(internal_kind::datetime);
0118 return impl_.repr.datetime_;
0119 }
0120
0121 BOOST_CXX14_CONSTEXPR boost::mysql::time boost::mysql::field_view::as_time() const
0122 {
0123 if (is_field_ptr())
0124 return impl_.repr.field_ptr->as<time>();
0125 check_kind(internal_kind::time);
0126 return impl_.repr.time_;
0127 }
0128
0129 BOOST_CXX14_CONSTEXPR void boost::mysql::field_view::check_kind(internal_kind expected) const
0130 {
0131 if (impl_.ikind != expected)
0132 BOOST_THROW_EXCEPTION(bad_field_access());
0133 }
0134
0135 BOOST_CXX14_CONSTEXPR bool boost::mysql::field_view::operator==(const field_view& rhs) const noexcept
0136 {
0137
0138 if (impl_.ikind == internal_kind::sv_offset_string || impl_.ikind == internal_kind::sv_offset_blob)
0139 {
0140 return rhs.impl_.ikind == impl_.ikind && impl_.repr.sv_offset_ == rhs.impl_.repr.sv_offset_;
0141 }
0142
0143 auto k = kind(), rhs_k = rhs.kind();
0144 switch (k)
0145 {
0146 case field_kind::null: return rhs_k == field_kind::null;
0147 case field_kind::int64:
0148 if (rhs_k == field_kind::int64)
0149 return get_int64() == rhs.get_int64();
0150 else if (rhs_k == field_kind::uint64)
0151 {
0152 std::int64_t this_val = get_int64();
0153 if (this_val < 0)
0154 return false;
0155 else
0156 return static_cast<std::uint64_t>(this_val) == rhs.get_uint64();
0157 }
0158 else
0159 return false;
0160 case field_kind::uint64:
0161 if (rhs_k == field_kind::uint64)
0162 return get_uint64() == rhs.get_uint64();
0163 else if (rhs_k == field_kind::int64)
0164 {
0165 std::int64_t rhs_val = rhs.get_int64();
0166 if (rhs_val < 0)
0167 return false;
0168 else
0169 return static_cast<std::uint64_t>(rhs_val) == get_uint64();
0170 }
0171 else
0172 return false;
0173 case field_kind::string: return rhs_k == field_kind::string && get_string() == rhs.get_string();
0174 case field_kind::blob:
0175 return rhs_k == field_kind::blob && detail::blobs_equal(get_blob(), rhs.get_blob());
0176 case field_kind::float_: return rhs_k == field_kind::float_ && get_float() == rhs.get_float();
0177 case field_kind::double_: return rhs_k == field_kind::double_ && get_double() == rhs.get_double();
0178 case field_kind::date: return rhs_k == field_kind::date && get_date() == rhs.get_date();
0179 case field_kind::datetime: return rhs_k == field_kind::datetime && get_datetime() == rhs.get_datetime();
0180 case field_kind::time: return rhs_k == field_kind::time && get_time() == rhs.get_time();
0181 default: BOOST_ASSERT(false); return false;
0182 }
0183 }
0184
0185 #endif