rrset_collection_base.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Copyright (C) 2012 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 RRSET_COLLECTION_BASE_H
  15. #define RRSET_COLLECTION_BASE_H 1
  16. #include <dns/rrset.h>
  17. #include <dns/name.h>
  18. #include <boost/shared_ptr.hpp>
  19. #include <iterator>
  20. namespace isc {
  21. namespace dns {
  22. /// \brief Error during RRsetCollectionBase find() operation
  23. ///
  24. /// This exception is thrown when calling an implementation of
  25. /// \c RRsetCollectionBase::find() results in an error which is not due
  26. /// to unmatched data, but because of some other underlying error
  27. /// condition.
  28. class RRsetCollectionError : public Exception {
  29. public:
  30. RRsetCollectionError(const char* file, size_t line, const char* what) :
  31. Exception(file, line, what)
  32. {}
  33. };
  34. /// \brief Generic class to represent a set of RRsets.
  35. ///
  36. /// This is a generic container and the stored set of RRsets does not
  37. /// necessarily form a valid zone (e.g. there doesn't necessarily have
  38. /// to be an SOA at the "origin"). Instead, it will be used to represent
  39. /// a single zone for the purpose of zone loading/checking. It provides
  40. /// a simple find() method to find an RRset for the given name and type
  41. /// (and maybe class) and a way to iterate over all RRsets.
  42. ///
  43. /// See \c RRsetCollection for a simple libdns++ implementation using an
  44. /// STL container. libdatasrc will have another implementation.
  45. class RRsetCollectionBase {
  46. public:
  47. /// \brief Find a matching RRset in the collection.
  48. ///
  49. /// Returns the RRset in the collection that exactly matches the
  50. /// given \c name, \c rrclass and \c rrtype. If no matching RRset
  51. /// is found, \c NULL is returned.
  52. ///
  53. /// This method's implementations currently are not specified to
  54. /// handle \c RRTypes such as RRSIG and NSEC3. This interface may be
  55. /// refined to clarify this point in the future, and perhaps, provide
  56. /// additional API for these RRType.
  57. ///
  58. /// As for RRSIG, there are some fundamental open questions. For
  59. /// example, it's not clear whether we want to return all RRSIGs of
  60. /// the given name covering any RR types (in which case, we need to
  61. /// figure out how), or we need to extend the interface so we can
  62. /// specify the covered type. A specific derived implementation may
  63. /// return something if type RRSIG is specified, but this is not
  64. /// specified here at the base class level. So, for RRSIGs the
  65. /// behavior should be assumed as undefined.
  66. ///
  67. /// As for NSEC3, it's not clear whether owner names (which included
  68. /// hashed labels) are the best choice of search key, because in many
  69. /// cases, what the application wants to find is an NSEC3 that has the
  70. /// hash of some particular "normal" domain names. Also, if the underlying
  71. /// implementation encapsulates a single zone, NSEC3 records conceptually
  72. /// belong to a separate name space, which may cause implementation
  73. /// difficulty.
  74. ///
  75. /// Behavior with meta types such as ANY and AXFR are also
  76. /// undefined. A specific implementation may return something for
  77. /// these. But, unlike the case of RRSIGs, these types of RRsets
  78. /// are not expected to be added to any implementation of
  79. /// collection in the first place (by the definition of "meta
  80. /// types"), so querying for such types is basically an invalid
  81. /// operation. The API doesn't require implementations to check
  82. /// this condition and reject it, so the behavior is
  83. /// undefined. This interface will not be refined in future
  84. /// versions for these meta types.
  85. ///
  86. /// \throw RRsetCollectionError if find() results in some
  87. /// implementation-specific error.
  88. /// \param name The name of the RRset to search for.
  89. /// \param rrtype The type of the RRset to search for.
  90. /// \param rrclass The class of the RRset to search for.
  91. /// \return The RRset if found, \c NULL otherwise.
  92. virtual isc::dns::ConstRRsetPtr find
  93. (const isc::dns::Name& name, const isc::dns::RRClass& rrclass,
  94. const isc::dns::RRType& rrtype)
  95. const = 0;
  96. /// \brief Destructor
  97. virtual ~RRsetCollectionBase() {}
  98. protected:
  99. class Iter; // forward declaration
  100. /// \brief Wraps Iter with a reference count.
  101. typedef boost::shared_ptr<Iter> IterPtr;
  102. /// \brief A helper iterator interface for \c RRsetCollectionBase.
  103. ///
  104. /// This is a protected iterator class that is a helper interface
  105. /// used by the public iterator. Derived classes of
  106. /// \c RRsetCollectionBase are supposed to implement this class and
  107. /// the \c getBeginning() and \c getEnd() methods, so that the
  108. /// public interator interface can be provided. This is a forward
  109. /// iterator only.
  110. class Iter {
  111. public:
  112. virtual ~Iter() {};
  113. /// \brief Returns the \c AbstractRRset currently pointed to by
  114. /// the iterator.
  115. virtual const isc::dns::AbstractRRset& getValue() = 0;
  116. /// \brief Returns an \c IterPtr wrapping an Iter pointing to
  117. /// the next \c AbstractRRset in sequence in the collection.
  118. virtual IterPtr getNext() = 0;
  119. /// \brief Check if another iterator is equal to this one.
  120. ///
  121. /// Returns \c true if this iterator is equal to \c other,
  122. /// \c false otherwise. Note that if \c other is not the same
  123. /// type as \c this, or cannot be compared meaningfully, the
  124. /// method must return \c false.
  125. ///
  126. /// \param other The other iterator to compare against.
  127. /// \return \c true if equal, \c false otherwise.
  128. virtual bool equals(Iter& other) = 0;
  129. };
  130. /// \brief Returns an \c IterPtr wrapping an Iter pointing to the
  131. /// beginning of the collection.
  132. ///
  133. /// \throw isc::dns::RRsetCollectionError if using the iterator
  134. /// results in some underlying datasrc error.
  135. virtual IterPtr getBeginning() = 0;
  136. /// \brief Returns an \c IterPtr wrapping an Iter pointing past the
  137. /// end of the collection.
  138. ///
  139. /// \throw isc::dns::RRsetCollectionError if using the iterator
  140. /// results in some underlying datasrc error.
  141. virtual IterPtr getEnd() = 0;
  142. public:
  143. /// \brief A forward \c std::iterator for \c RRsetCollectionBase.
  144. ///
  145. /// It behaves like a \c std::iterator forward iterator, so please
  146. /// see its documentation for usage.
  147. class Iterator : std::iterator<std::forward_iterator_tag,
  148. const isc::dns::AbstractRRset>
  149. {
  150. public:
  151. explicit Iterator(IterPtr iter) :
  152. iter_(iter)
  153. {}
  154. reference operator*() {
  155. return (iter_->getValue());
  156. }
  157. Iterator& operator++() {
  158. iter_ = iter_->getNext();
  159. return (*this);
  160. }
  161. Iterator operator++(int) {
  162. Iterator tmp(iter_);
  163. ++*this;
  164. return (tmp);
  165. }
  166. bool operator==(const Iterator& other) const {
  167. return (iter_->equals(*other.iter_));
  168. }
  169. bool operator!=(const Iterator& other) const {
  170. return (!iter_->equals(*other.iter_));
  171. }
  172. private:
  173. IterPtr iter_;
  174. };
  175. /// \brief Returns an iterator pointing to the beginning of the
  176. /// collection.
  177. Iterator begin() {
  178. return Iterator(getBeginning());
  179. }
  180. /// \brief Returns an iterator pointing past the end of the
  181. /// collection.
  182. Iterator end() {
  183. return Iterator(getEnd());
  184. }
  185. };
  186. } // end of namespace dns
  187. } // end of namespace isc
  188. #endif // RRSET_COLLECTION_BASE_H
  189. // Local Variables:
  190. // mode: c++
  191. // End: