option_space_container.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef OPTION_SPACE_CONTAINER_H
  15. #define OPTION_SPACE_CONTAINER_H
  16. #include <list>
  17. #include <string>
  18. namespace isc {
  19. namespace dhcp {
  20. /// @brief Simple container for option spaces holding various items.
  21. ///
  22. /// This helper class is used to store items of various types
  23. /// that are grouped by option space names. Each option space is
  24. /// mapped to a container that holds items which specifically can
  25. /// be OptionDefinition objects or Subnet::OptionDescriptor structures.
  26. ///
  27. /// @tparam ContainerType of the container holding items within
  28. /// option space.
  29. /// @tparam ItemType type of the item being held by the container.
  30. /// @tparam Selector a string (for option spaces) or uint32_t (for vendor options)
  31. template<typename ContainerType, typename ItemType, typename Selector>
  32. class OptionSpaceContainer {
  33. public:
  34. /// Pointer to the container.
  35. typedef boost::shared_ptr<ContainerType> ItemsContainerPtr;
  36. /// @brief Indicates the container is empty
  37. ///
  38. /// @return true when the container is empty
  39. bool empty() const {
  40. return (option_space_map_.empty());
  41. }
  42. /// @brief Adds a new item to the option_space.
  43. ///
  44. /// @param item reference to the item being added.
  45. /// @param option_space name or vendor-id of the option space
  46. void addItem(const ItemType& item, const Selector& option_space) {
  47. ItemsContainerPtr items = getItems(option_space);
  48. items->push_back(item);
  49. option_space_map_[option_space] = items;
  50. }
  51. /// @brief Get all items for the particular option space.
  52. ///
  53. /// @warning when there are no items for the specified option
  54. /// space an empty container is created and returned. However
  55. /// this container is not added to the list of option spaces.
  56. ///
  57. /// @param option_space name or vendor-id of the option space.
  58. ///
  59. /// @return pointer to the container holding items.
  60. ItemsContainerPtr getItems(const Selector& option_space) const {
  61. const typename OptionSpaceMap::const_iterator& items =
  62. option_space_map_.find(option_space);
  63. if (items == option_space_map_.end()) {
  64. return (ItemsContainerPtr(new ContainerType()));
  65. }
  66. return (items->second);
  67. }
  68. /// @brief Get a list of existing option spaces.
  69. ///
  70. /// @return a list of option spaces.
  71. ///
  72. /// @todo This function is likely to be removed once
  73. /// we create a structore of OptionSpaces defined
  74. /// through the configuration manager.
  75. std::list<Selector> getOptionSpaceNames() const {
  76. std::list<Selector> names;
  77. for (typename OptionSpaceMap::const_iterator space =
  78. option_space_map_.begin();
  79. space != option_space_map_.end(); ++space) {
  80. names.push_back(space->first);
  81. }
  82. return (names);
  83. }
  84. /// @brief Remove all items from the container.
  85. void clearItems() {
  86. option_space_map_.clear();
  87. }
  88. /// @brief Check if two containers are equal.
  89. ///
  90. /// This method checks if option space container contains exactly
  91. /// the same selectors and that there are exactly the same items
  92. /// added for each selector. The order of items doesn't matter.
  93. ///
  94. /// @param other Other container to compare to.
  95. ///
  96. /// @return true if containers are equal, false otherwise.
  97. bool equals(const OptionSpaceContainer& other) const {
  98. for (typename OptionSpaceMap::const_iterator it =
  99. option_space_map_.begin(); it != option_space_map_.end();
  100. ++it) {
  101. typename OptionSpaceMap::const_iterator other_it =
  102. other.option_space_map_.find(it->first);
  103. if (other_it == other.option_space_map_.end()) {
  104. return (false);
  105. }
  106. // If containers have different sizes it is an indication that
  107. // they are unequal.
  108. if (it->second->size() != other_it->second->size()) {
  109. return (false);
  110. }
  111. // If they have the same sizes, we have to compare each element.
  112. for (typename ContainerType::const_iterator items_it =
  113. it->second->begin();
  114. items_it != it->second->end(); ++items_it) {
  115. bool match_found = false;
  116. for (typename ContainerType::const_iterator other_items_it =
  117. other_it->second->begin();
  118. other_items_it != other_it->second->end();
  119. ++other_items_it) {
  120. if (items_it->equals(*other_items_it)) {
  121. match_found = true;
  122. break;
  123. }
  124. }
  125. if (!match_found) {
  126. return (false);
  127. }
  128. }
  129. }
  130. return (true);
  131. }
  132. private:
  133. /// A map holding container (option space name or vendor-id is the key).
  134. typedef std::map<Selector, ItemsContainerPtr> OptionSpaceMap;
  135. OptionSpaceMap option_space_map_;
  136. };
  137. } // end of isc::dhcp namespace
  138. } // end of isc namespace
  139. #endif // OPTION_SPACE_CONTAINER_H