Coverage Report

Created: 2026-03-31 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kea/src/lib/dns/master_loader.h
Line
Count
Source
1
// Copyright (C) 2012-2024 Internet Systems Consortium, Inc. ("ISC")
2
//
3
// This Source Code Form is subject to the terms of the Mozilla Public
4
// License, v. 2.0. If a copy of the MPL was not distributed with this
5
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7
#ifndef MASTER_LOADER_H
8
#define MASTER_LOADER_H
9
10
#include <dns/exceptions.h>
11
#include <dns/master_loader_callbacks.h>
12
13
#include <boost/noncopyable.hpp>
14
15
#include <memory>
16
17
namespace isc {
18
namespace dns {
19
20
class Name;
21
class RRClass;
22
23
/// \brief Error while loading by MasterLoader without specifying the
24
///     MANY_ERRORS option.
25
class MasterLoaderError : public isc::Exception {
26
public:
27
    MasterLoaderError(const char* file, size_t line, const char* what) :
28
        Exception(file, line, what)
29
0
    {}
30
};
31
32
/// \brief A class able to load DNS master files
33
///
34
/// This class is able to produce a stream of RRs from a master file.
35
/// It is able to load all of the master file at once, or by blocks
36
/// incrementally.
37
///
38
/// It reports the loaded RRs and encountered errors by callbacks.
39
class MasterLoader : boost::noncopyable {
40
public:
41
    /// \brief Options how the parsing should work.
42
    enum Options {
43
        DEFAULT = 0,       ///< Nothing special.
44
        MANY_ERRORS = 1    ///< Lenient mode (see documentation of MasterLoader
45
                           ///  constructor).
46
    };
47
48
    /// \brief Constructor
49
    ///
50
    /// This creates a master loader and provides it with all
51
    /// relevant information.
52
    ///
53
    /// Except for the exceptions listed below, the constructor doesn't
54
    /// throw. Most errors (like non-existent master file) are reported
55
    /// by the callbacks during load() or loadIncremental().
56
    ///
57
    /// \param master_file Path to the file to load.
58
    /// \param zone_origin The origin of zone to be expected inside
59
    ///     the master file. Currently unused, but it is expected to
60
    ///     be used for some validation.
61
    /// \param zone_class The class of zone to be expected inside the
62
    ///     master file.
63
    /// \param callbacks The callbacks by which it should report problems.
64
    ///     Usually, the callback carries a filename and line number of the
65
    ///     input where the problem happens. There's a special case of empty
66
    ///     filename and zero line in case the opening of the top-level master
67
    ///     file fails.
68
    /// \param add_callback The callback which would be called with each
69
    ///     loaded RR.
70
    /// \param options Options for the parsing, which is bitwise-or of
71
    ///     the Options values or DEFAULT. If the MANY_ERRORS option is
72
    ///     included, the parser tries to continue past errors. If it
73
    ///     is not included, it stops at first encountered error.
74
    /// \throw std::bad_alloc when there's not enough memory.
75
    /// \throw isc::InvalidParameter if add_callback is empty.
76
    MasterLoader(const char* master_file,
77
                 const Name& zone_origin,
78
                 const RRClass& zone_class,
79
                 const MasterLoaderCallbacks& callbacks,
80
                 const AddRRCallback& add_callback,
81
                 Options options = DEFAULT);
82
83
    /// \brief Constructor from a stream
84
    ///
85
    /// This is a constructor very similar to the previous one. The only
86
    /// difference is it doesn't take a filename, but an input stream
87
    /// to read the data from. It is expected to be mostly used in tests,
88
    /// but it is public as it may possibly be useful for other currently
89
    /// unknown purposes.
90
    MasterLoader(std::istream& input,
91
                 const Name& zone_origin,
92
                 const RRClass& zone_class,
93
                 const MasterLoaderCallbacks& callbacks,
94
                 const AddRRCallback& add_callback,
95
                 Options options = DEFAULT);
96
97
    /// \brief Destructor
98
    ~MasterLoader();
99
100
    /// \brief Load some RRs
101
    ///
102
    /// This method loads at most count_limit RRs and reports them. In case
103
    /// an error (either fatal or without MANY_ERRORS) or end of file is
104
    /// encountered, they may be less.
105
    ///
106
    /// \param count_limit Upper limit on the number of RRs loaded.
107
    /// \return In case it stops because of the count limit, it returns false.
108
    ///     It returns true if the loading is done.
109
    /// \throw isc::InvalidOperation when called after loading was done
110
    ///     already.
111
    /// \throw MasterLoaderError when there's an error in the input master
112
    ///     file and the MANY_ERRORS is not specified. It never throws this
113
    ///     in case MANY_ERRORS is specified.
114
    bool loadIncremental(size_t count_limit);
115
116
    /// \brief Load everything
117
    ///
118
    /// This simply calls loadIncremental until the loading is done.
119
    /// \throw isc::InvalidOperation when called after loading was done
120
    ///     already.
121
    /// \throw MasterLoaderError when there's an error in the input master
122
    ///     file and the MANY_ERRORS is not specified. It never throws this
123
    ///     in case MANY_ERRORS is specified.
124
0
    void load() {
125
0
        while (!loadIncremental(1000)) { // 1000 = arbitrary largish number
126
0
            // Body intentionally left blank
127
0
        }
128
0
    }
129
130
    /// \brief Was the loading successful?
131
    ///
132
    /// \return true if and only if the loading was complete (after a call of
133
    ///     load or after loadIncremental returned true) and there was no
134
    ///     error. In other cases, return false.
135
    /// \note While this method works even before the loading is complete (by
136
    ///     returning false in that case), it is meant to be called only after
137
    ///     finishing the load.
138
    bool loadedSuccessfully() const;
139
140
    /// \brief Return the total size of the zone files and streams.
141
    ///
142
    /// This method returns the size of the source of the zone to be loaded
143
    /// (master zone files or streams) that is known at the time of the call.
144
    /// For a zone file, it's the size of the file; for a stream, it's the
145
    /// size of the data (in bytes) available at the start of the load.
146
    /// If separate zone files are included via the $INCLUDE directive, the
147
    /// sum of the sizes of these files are added.
148
    ///
149
    /// If the loader is constructed with a stream, the size can be
150
    /// "unknown" as described for \c MasterLexer::getTotalSourceSize().
151
    /// In this case this method always returns
152
    /// \c MasterLexer::SOURCE_SIZE_UNKNOWN.
153
    ///
154
    /// If the loader is constructed with a zone file, this method
155
    /// initially returns 0.  So until either \c load() or \c loadIncremental()
156
    /// is called, the value is meaningless.
157
    ///
158
    /// Note that when the source includes separate files, this method
159
    /// cannot take into account the included files that the loader has not
160
    /// recognized at the time of call.  So it's possible that this method
161
    /// returns different values at different times of call.
162
    ///
163
    /// \throw None
164
    size_t getSize() const;
165
166
    /// \brief Return the position of the loader in zone.
167
    ///
168
    /// This method returns a conceptual "position" of the loader in the
169
    /// zone to be loaded.  Specifically, it returns the total number of
170
    /// characters contained in the zone files and streams and recognized
171
    /// by the loader.  Before starting the load it returns 0; on successful
172
    /// completion it will be equal to the return value of \c getSize()
173
    /// (unless the latter returns \c MasterLexer::SOURCE_SIZE_UNKNOWN).
174
    ///
175
    /// \throw None
176
    size_t getPosition() const;
177
178
private:
179
    class MasterLoaderImpl;
180
    std::unique_ptr<MasterLoaderImpl> impl_;
181
};
182
183
} // end namespace dns
184
} // end namespace isc
185
186
#endif // MASTER_LOADER_H