diff options
Diffstat (limited to 'src/lib/dns/rrcollator.h')
-rw-r--r-- | src/lib/dns/rrcollator.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/lib/dns/rrcollator.h b/src/lib/dns/rrcollator.h new file mode 100644 index 0000000..9442fd3 --- /dev/null +++ b/src/lib/dns/rrcollator.h @@ -0,0 +1,125 @@ +// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef RRCOLLATOR_H +#define RRCOLLATOR_H 1 + +#include <dns/master_loader_callbacks.h> +#include <dns/rrset.h> + +#include <boost/noncopyable.hpp> +#include <functional> + +namespace isc { +namespace dns { + +/// \brief A converter from a stream of RRs to a stream of collated RRsets +/// +/// This class is mainly intended to be a helper used as an adapter for +/// user applications of the \c MasterLoader class; it works as a callback +/// for \c MasterLoader, buffers given RRs from the loader, collating +/// consecutive RRs that belong to the same RRset (ones having the same +/// owner name, RR type and class), and produces a stream of RRsets through +/// its own callback. RRSIGs are also separated if their type covered fields +/// have different values even if the owner name and RR class are the same. +/// +/// It also "normalizes" TTLs of the RR; if collated RRs have different TTLs, +/// this class guarantees that the TTL of the resulting RRsets has the +/// smallest TTL among them. +/// +/// The conversion will be useful for applications of \c MasterLoader because +/// many of this library have interfaces that take an RRset object (or +/// a pointer to it). Note, however, that this class doesn't guarantee that +/// all RRs that would belong to the same RRset are collated into the same +/// single RRset. In fact, it can only collate RRs that are consecutive +/// in the original stream; once it encounters an RR of a different RRset, +/// any subsequent RRs of the previous RRset will form a separate RRset object. +/// +/// This class is non-copyable; it's partially for the convenience of internal +/// implementation details, but it actually doesn't make sense to copy +/// an object of this class, if not harmful, for the intended usage of +/// the class. +class RRCollator : boost::noncopyable { +public: + /// \brief Callback functor type for \c RRCollator. + /// + /// This type of callback is given to an \c RRCollator object on its + /// construction, and will be called for each collated RRset built in + /// the \c RRCollator. + /// + /// \param rrset The collated RRset. + typedef std::function<void(const RRsetPtr& rrset)> AddRRsetCallback; + + /// \brief Constructor. + /// + /// \throw std::bad_alloc Internal memory allocation fails. This should + /// be very rare. + /// + /// \param callback The callback functor to be called for each collated + /// RRset. + RRCollator(const AddRRsetCallback& callback); + + /// \brief Destructor. + /// + /// It only performs trivial internal cleanup. In particular, even if + /// it still has a buffered RRset it will be simply discarded. This is + /// because the given callback could throw an exception, and it's + /// impossible to predict how this class is used (to see if it's a very + /// rare case where propagating an exception from a destructor is + /// justified). Instead, the application needs to make sure that + /// \c flush() is called before the object of this class is destroyed. + /// + /// \throw None + ~RRCollator(); + + /// \brief Call the callback on the remaining RRset, if any. + /// + /// This method is expected to be called that it's supposed all RRs have + /// been passed to this class object. Since there is no explicit + /// indicator of the end of the stream, the user of this class needs to + /// explicitly call this method to call the callback for the last buffered + /// RRset (see also the destructor's description). + /// + /// If there is no buffered RRset, this method does nothing. It can happen + /// if it's called without receiving any RRs, or called more than once. + /// + /// It propagates any exception thrown from the callback; otherwise it + /// doesn't throw anything. + void flush(); + + /// \brief Return \c MasterLoader compatible callback. + /// + /// This method returns a functor in the form of \c AddRRCallback + /// that works as an adapter between \c MasterLoader and an application + /// that needs to get a stream of RRsets. When the returned callback + /// is called, this \c RRCollator object accepts the corresponding RR, + /// and collates it with other RRs of the same RRset if necessary. + /// Every time the \c RRCollator object encounters an RR of a different + /// RRset, it calls the callback passed to the constructor with the RRset + /// built so far. + /// + /// Like \c flush(), this \c AddRRCallback functor propagates any exception + /// thrown from the callback. + /// + /// This method is expected to be called only once for a given + /// \c RRCollator object. It doesn't prohibit duplicate calls, but + /// returned functor objects internally refer to the same \c RRCollator + /// object, and calling the both callbacks randomly will just cause + /// confusion. + AddRRCallback getCallback(); + +private: + class Impl; + Impl* impl_; +}; + +} // namespace dns +} // namespace isc +#endif // RRCOLLATOR_H + +// Local Variables: +// mode: c++ +// End: |