rrset_collection.h 6.22 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#ifndef RRSET_COLLECTION_H
#define RRSET_COLLECTION_H 1

#include <dns/rrset_collection_base.h>
#include <dns/rrclass.h>

21 22 23
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>

24 25 26 27 28 29 30 31 32
#include <map>

namespace isc {
namespace dns {

/// \brief libdns++ implementation of RRsetCollectionBase using an STL
/// container.
class RRsetCollection : public RRsetCollectionBase {
public:
33
    /// \brief Constructor.
34 35 36 37
    ///
    /// This constructor creates an empty collection without any data in
    /// it. RRsets can be added to the collection with the \c addRRset()
    /// method.
38
    RRsetCollection() {}
39

40 41 42 43 44
    /// \brief Constructor.
    ///
    /// The \c origin and \c rrclass arguments are required for the zone
    /// loading, but \c RRsetCollection itself does not do any
    /// validation, and the collection of RRsets does not have to form a
45
    /// valid zone.
46
    ///
47
    /// \throws MasterLoaderError if there is an error during loading.
48 49
    /// \param filename Name of a file containing a collection of RRs in
    /// the master file format (which may or may not form a valid zone).
50 51
    /// \param origin The zone origin.
    /// \param rrclass The zone class.
52 53 54
    RRsetCollection(const char* filename, const isc::dns::Name& origin,
                    const isc::dns::RRClass& rrclass);

55 56 57 58
    /// \brief Constructor.
    ///
    /// This constructor is similar to the previous one, but instead of
    /// taking a filename to load a zone from, it takes an input
59
    /// stream.
60
    ///
61
    /// \throws MasterLoaderError if there is an error during loading.
62 63 64 65 66 67
    /// \param input_stream The input stream to load from.
    /// \param origin The zone origin.
    /// \param rrclass The zone class.
    RRsetCollection(std::istream& input_stream, const isc::dns::Name& origin,
                    const isc::dns::RRClass& rrclass);

68 69 70
    /// \brief Destructor
    virtual ~RRsetCollection() {}

71 72 73
    /// \brief Add an RRset to the collection.
    ///
    /// Does not do any validation whether \c rrset belongs to a
74 75 76 77 78 79
    /// particular zone or not. A reference to \c rrset is taken in an
    /// internally managed \c shared_ptr, so even if the caller's
    /// \c RRsetPtr is destroyed, the RRset it wrapped is still alive
    /// and managed by the \c RRsetCollection. It throws an
    /// \c isc::InvalidParameter exception if an rrset with the same
    /// class, type and name already exists.
80 81 82 83
    ///
    /// Callers must not modify the RRset after adding it to the
    /// collection, as the rrset is indexed internally by the
    /// collection.
84 85 86 87 88 89
    void addRRset(isc::dns::RRsetPtr rrset);

    /// \brief Remove an RRset from the collection.
    ///
    /// RRset(s) matching the \c name, \c rrclass and \c rrtype are
    /// removed from the collection.
90 91 92 93
    ///
    /// \returns \c true if a matching RRset was deleted, \c false if no
    /// such RRset exists.
    bool removeRRset(const isc::dns::Name& name,
94 95 96 97 98 99
                     const isc::dns::RRClass& rrclass,
                     const isc::dns::RRType& rrtype);

    /// \brief Find a matching RRset in the collection.
    ///
    /// Returns the RRset in the collection that exactly matches the
100 101
    /// given \c name, \c rrclass and \c rrtype.  If no matching RRset
    /// is found, \c NULL is returned.
102 103
    ///
    /// \param name The name of the RRset to search for.
104
    /// \param rrclass The class of the RRset to search for.
105 106 107 108 109
    /// \param rrtype The type of the RRset to search for.
    /// \returns The RRset if found, \c NULL otherwise.
    virtual isc::dns::ConstRRsetPtr find(const isc::dns::Name& name,
                                         const isc::dns::RRClass& rrclass,
                                         const isc::dns::RRType& rrtype) const;
110

111 112
    /// \brief Find a matching RRset in the collection (non-const
    /// variant).
113 114
    ///
    /// See above for a description of the method and arguments.
115 116 117 118 119
    isc::dns::RRsetPtr find(const isc::dns::Name& name,
                            const isc::dns::RRClass& rrclass,
                            const isc::dns::RRType& rrtype);

private:
120 121 122
    template<typename T>
    void constructHelper(T source, const isc::dns::Name& origin,
                         const isc::dns::RRClass& rrclass);
123 124
    void loaderCallback(const std::string&, size_t, const std::string&);

125 126
    typedef boost::tuple<isc::dns::RRClass, isc::dns::RRType, isc::dns::Name>
        CollectionKey;
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
    typedef std::map<CollectionKey, isc::dns::RRsetPtr> CollectionMap;

    CollectionMap rrsets_;

protected:
    class DnsIter : public RRsetCollectionBase::Iter {
    public:
        DnsIter(CollectionMap::iterator& iter) :
            iter_(iter)
        {}

        virtual const isc::dns::AbstractRRset& getValue() {
            isc::dns::RRsetPtr& rrset = iter_->second;
            return (*rrset);
        }

        virtual IterPtr getNext() {
            CollectionMap::iterator it = iter_;
            it++;
            return (RRsetCollectionBase::IterPtr(new DnsIter(it)));
        }

        virtual bool equals(Iter& other) {
150 151 152 153 154
            const DnsIter* other_real = dynamic_cast<DnsIter*>(&other);
            if (other_real == NULL) {
                return (false);
            }
            return (iter_ == other_real->iter_);
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
        }

    private:
        CollectionMap::iterator iter_;
    };

    virtual RRsetCollectionBase::IterPtr getBeginning();
    virtual RRsetCollectionBase::IterPtr getEnd();
};

} // end of namespace dns
} // end of namespace isc

#endif  // RRSET_COLLECTION_H

// Local Variables:
// mode: c++
// End: