1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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:
|