/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 |