topic_alias_recv.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright Takatoshi Kondo 2020
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #if !defined(MQTT_TOPIC_ALIAS_RECV_HPP)
  7. #define MQTT_TOPIC_ALIAS_RECV_HPP
  8. #include <string>
  9. #include <unordered_map>
  10. #include <array>
  11. #include <boost/multi_index_container.hpp>
  12. #include <boost/multi_index/ordered_index.hpp>
  13. #include <boost/multi_index/member.hpp>
  14. #include <mqtt/namespace.hpp>
  15. #include <mqtt/string_view.hpp>
  16. #include <mqtt/constant.hpp>
  17. #include <mqtt/type.hpp>
  18. #include <mqtt/move.hpp>
  19. #include <mqtt/log.hpp>
  20. namespace MQTT_NS {
  21. namespace mi = boost::multi_index;
  22. class topic_alias_recv {
  23. public:
  24. topic_alias_recv(topic_alias_t max)
  25. :max_{max} {}
  26. void insert_or_update(string_view topic, topic_alias_t alias) {
  27. MQTT_LOG("mqtt_impl", trace)
  28. << MQTT_ADD_VALUE(address, this)
  29. << "topic_alias_recv insert"
  30. << " topic:" << topic
  31. << " alias:" << alias;
  32. BOOST_ASSERT(!topic.empty() && alias >= min_ && alias <= max_);
  33. auto it = aliases_.lower_bound(alias);
  34. if (it == aliases_.end() || it->alias != alias) {
  35. aliases_.emplace_hint(it, std::string(topic), alias);
  36. }
  37. else {
  38. aliases_.modify(
  39. it,
  40. [&](entry& e) {
  41. e.topic = std::string{topic};
  42. },
  43. [](auto&) { BOOST_ASSERT(false); }
  44. );
  45. }
  46. }
  47. std::string find(topic_alias_t alias) const {
  48. BOOST_ASSERT(alias >= min_ && alias <= max_);
  49. std::string topic;
  50. auto it = aliases_.find(alias);
  51. if (it != aliases_.end()) topic = it->topic;
  52. MQTT_LOG("mqtt_impl", info)
  53. << MQTT_ADD_VALUE(address, this)
  54. << "find_topic_by_alias"
  55. << " alias:" << alias
  56. << " topic:" << topic;
  57. return topic;
  58. }
  59. void clear() {
  60. MQTT_LOG("mqtt_impl", info)
  61. << MQTT_ADD_VALUE(address, this)
  62. << "clear_topic_alias";
  63. aliases_.clear();
  64. }
  65. topic_alias_t max() const { return max_; }
  66. private:
  67. static constexpr topic_alias_t min_ = 1;
  68. topic_alias_t max_;
  69. struct entry {
  70. entry(std::string topic, topic_alias_t alias)
  71. : topic{force_move(topic)}, alias{alias} {}
  72. std::string topic;
  73. topic_alias_t alias;
  74. };
  75. using mi_topic_alias = mi::multi_index_container<
  76. entry,
  77. mi::indexed_by<
  78. mi::ordered_unique<
  79. BOOST_MULTI_INDEX_MEMBER(entry, topic_alias_t, alias)
  80. >
  81. >
  82. >;
  83. mi_topic_alias aliases_;
  84. };
  85. } // namespace MQTT_NS
  86. #endif // MQTT_TOPIC_ALIAS_RECV_HPP