connection_state_data.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. //
  2. // Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BOOST_MYSQL_IMPL_INTERNAL_SANSIO_CONNECTION_STATE_DATA_HPP
  8. #define BOOST_MYSQL_IMPL_INTERNAL_SANSIO_CONNECTION_STATE_DATA_HPP
  9. #include <boost/mysql/character_set.hpp>
  10. #include <boost/mysql/diagnostics.hpp>
  11. #include <boost/mysql/field_view.hpp>
  12. #include <boost/mysql/metadata_mode.hpp>
  13. #include <boost/mysql/detail/next_action.hpp>
  14. #include <boost/mysql/detail/pipeline.hpp>
  15. #include <boost/mysql/impl/internal/protocol/capabilities.hpp>
  16. #include <boost/mysql/impl/internal/protocol/db_flavor.hpp>
  17. #include <boost/mysql/impl/internal/protocol/serialization.hpp>
  18. #include <boost/mysql/impl/internal/sansio/message_reader.hpp>
  19. #include <array>
  20. #include <cstddef>
  21. #include <cstdint>
  22. #include <vector>
  23. namespace boost {
  24. namespace mysql {
  25. namespace detail {
  26. enum class ssl_state
  27. {
  28. unsupported,
  29. inactive,
  30. active,
  31. torn_down,
  32. };
  33. struct connection_state_data
  34. {
  35. // Is the connection actually connected? Set by handshake
  36. bool is_connected{false};
  37. // Are we talking to MySQL or MariaDB?
  38. db_flavor flavor{db_flavor::mysql};
  39. // What are the connection's capabilities?
  40. capabilities current_capabilities;
  41. // Used by async ops without output diagnostics params, to avoid allocations
  42. diagnostics shared_diag;
  43. // Temporary field storage, re-used by several ops
  44. std::vector<field_view> shared_fields;
  45. // Temporary pipeline stage storage, re-used by several ops
  46. std::array<pipeline_request_stage, 2> shared_pipeline_stages;
  47. // Do we want to retain metadata strings or not? Used to save allocations
  48. metadata_mode meta_mode{metadata_mode::minimal};
  49. // Is SSL supported/enabled for the current connection?
  50. ssl_state ssl;
  51. // Do backslashes represent escape sequences? By default they do, but they can
  52. // be disabled using a variable. OK packets include a flag with this info.
  53. bool backslash_escapes{true};
  54. // The current character set, or a default-constructed character set (will all nullptrs) if unknown
  55. character_set current_charset{};
  56. // The write buffer
  57. std::vector<std::uint8_t> write_buffer;
  58. // Reader
  59. message_reader reader;
  60. std::size_t max_buffer_size() const { return reader.max_buffer_size(); }
  61. bool ssl_active() const { return ssl == ssl_state::active; }
  62. bool supports_ssl() const { return ssl != ssl_state::unsupported; }
  63. connection_state_data(
  64. std::size_t read_buffer_size,
  65. std::size_t max_buff_size = static_cast<std::size_t>(-1),
  66. bool transport_supports_ssl = false
  67. )
  68. : ssl(transport_supports_ssl ? ssl_state::inactive : ssl_state::unsupported),
  69. reader(read_buffer_size, max_buff_size)
  70. {
  71. }
  72. void reset()
  73. {
  74. is_connected = false;
  75. flavor = db_flavor::mysql;
  76. current_capabilities = capabilities();
  77. // Metadata mode does not get reset on handshake
  78. reader.reset();
  79. // Writer does not need reset, since every write clears previous state
  80. if (supports_ssl())
  81. ssl = ssl_state::inactive;
  82. backslash_escapes = true;
  83. current_charset = character_set{};
  84. }
  85. // Reads an OK packet from the reader. This operation is repeated in several places.
  86. error_code deserialize_ok(diagnostics& diag)
  87. {
  88. return deserialize_ok_response(reader.message(), flavor, diag, backslash_escapes);
  89. }
  90. // Helpers for sans-io algorithms
  91. next_action read(std::uint8_t& seqnum, bool keep_parsing_state = false)
  92. {
  93. // buffer is attached by top_level_algo
  94. reader.prepare_read(seqnum, keep_parsing_state);
  95. return next_action::read({});
  96. }
  97. template <class Serializable>
  98. next_action write(const Serializable& msg, std::uint8_t& seqnum)
  99. {
  100. // use_ssl is attached by top_level_algo
  101. write_buffer.clear();
  102. seqnum = serialize_top_level(msg, write_buffer, seqnum);
  103. return next_action::write({write_buffer, false});
  104. }
  105. };
  106. } // namespace detail
  107. } // namespace mysql
  108. } // namespace boost
  109. #endif