From: Mukund Sivaraman Date: Mon, 17 Feb 2014 05:55:19 +0000 (+0530) Subject: [2430] Write API doc for MasterLoaderImpl X-Git-Tag: bind10-1.2.0beta1-release~50^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3fc1c63ddb5524345e80c07c5dbea3cfc785e683;p=thirdparty%2Fkea.git [2430] Write API doc for MasterLoaderImpl --- diff --git a/src/lib/dns/master_loader.cc b/src/lib/dns/master_loader.cc index f8e4552230..da31132c35 100644 --- a/src/lib/dns/master_loader.cc +++ b/src/lib/dns/master_loader.cc @@ -56,9 +56,34 @@ public: } // end unnamed namespace +/// \brief Private implementation class for the \c MasterLoader +/// +/// This class is used internally by the \c MasterLoader and is not +/// publicly visible. It is present to avoid polluting the public API +/// with internal implementation details of the \c MasterLoader. // cppcheck-suppress noConstructor class MasterLoader::MasterLoaderImpl { public: + /// \brief Constructor. + /// + /// \param master_file Path to the file to load. + /// \param zone_origin The origin of zone to be expected inside + /// the master file. Currently unused, but it is expected to + /// be used for some validation. + /// \param zone_class The class of zone to be expected inside the + /// master file. + /// \param callbacks The callbacks by which it should report problems. + /// Usually, the callback carries a filename and line number of the + /// input where the problem happens. There's a special case of empty + /// filename and zero line in case the opening of the top-level master + /// file fails. + /// \param add_callback The callback which would be called with each + /// loaded RR. + /// \param options Options for the parsing, which is bitwise-or of + /// the Options values or DEFAULT. If the MANY_ERRORS option is + /// included, the parser tries to continue past errors. If it + /// is not included, it stops at first encountered error. + /// \throw std::bad_alloc when there's not enough memory. MasterLoaderImpl(const char* master_file, const Name& zone_origin, const RRClass& zone_class, @@ -83,6 +108,16 @@ public: rr_count_(0) {} + /// \brief Wrapper around \c MasterLexer::pushSource() (file version) + /// + /// This method is used as a wrapper around the lexer's + /// \c pushSource() to also save the current origin and the last + /// seen name (to be restored upon \c popSource()). It also calls + /// \c pushSource(). See \c doInclude() implementation for more + /// details. + /// + /// \param filename Path to the file to push as a new source. + /// \param current_origin The current origin name to save. void pushSource(const std::string& filename, const Name& current_origin) { std::string error; if (!lexer_.pushSource(filename.c_str(), &error)) { @@ -100,17 +135,35 @@ public: previous_name_ = false; } + /// \brief Wrapper around \c MasterLexer::pushSource() (stream version) + /// + /// Similar to \c pushSource(). This method need not save the + /// current origin as it is not used with $INCLUDE processing. + /// + /// \param stream The input stream to use as a new source. void pushStreamSource(std::istream& stream) { lexer_.pushSource(stream); initialized_ = true; } + /// \brief Implementation of \c MasterLoader::loadIncremental() + /// + /// See \c MasterLoader::loadIncremental() for details. bool loadIncremental(size_t count_limit); + /// \brief Return the total size of the input sources pushed so + /// far. See \c MasterLexer::getTotalSourceSize(). size_t getSize() const { return (lexer_.getTotalSourceSize()); } + + /// \brief Return the line number being parsed in the pushed input + /// sources. See \c MasterLexer::getPosition(). size_t getPosition() const { return (lexer_.getPosition()); } private: + /// \brief Report an error using the callbacks that were supplied + /// during \c MasterLoader construction. Note that this method also + /// throws \c MasterLoaderError exception if necessary, so the + /// caller need not throw it. void reportError(const std::string& filename, size_t line, const std::string& reason) { @@ -125,6 +178,12 @@ private: } } + /// \brief Wrapper around \c MasterLexer::popSource() + /// + /// This method is used as a wrapper around the lexer's + /// \c popSource() to also restore the current origin and the last + /// seen name (at time of push). It also calls \c popSource(). See + /// \c doInclude() implementation for more details. bool popSource() { if (lexer_.getSourceCount() == 1) { return (false); @@ -143,16 +202,43 @@ private: return (true); } - // Get a string token. Handle it as error if it is not string. + /// \brief Get a string token. Handle it as error if it is not string. const string getString() { lexer_.getNextToken(MasterToken::STRING).getString(string_token_); return (string_token_); } + /// \brief Parse the initial token at the beginning of a line in a + /// master file (or stream). + /// + /// A helper method of \c loadIncremental(), parsing the first token + /// of a new line. If it looks like an RR, detect its owner name + /// and return a string token for the next field of the RR. + /// + /// Otherwise, return either \c END_OF_LINE or \c END_OF_FILE token + /// depending on whether the loader continues to the next line or + /// completes the load, respectively. Other corner cases including + /// $-directive handling is done here. + /// + /// For unexpected errors, it throws an exception, which will be + /// handled in \c loadIncremental(). MasterToken handleInitialToken(); + + /// \brief Helper method for \c doGenerate(). + /// + /// This is a helper method for \c doGenerate() that processes the + /// LHS or RHS for a single iteration in the range that is requested + /// by the $GENERATE directive and returns a generated string (that + /// is used to build a name (LHS) or RDATA (RHS) for an RR). See the + /// commented implementation for details. std::string generateForIter(const std::string& str, const int it); + + /// \brief Process the $GENERATE directive. + /// + /// See the commented implementation for details. void doGenerate(); + /// \brief Process the $ORIGIN directive. void doOrigin(bool is_optional) { // Parse and create the new origin. It is relative to the previous // one. @@ -185,6 +271,7 @@ private: } } + /// \brief Process the $INCLUDE directive. void doInclude() { // First, get the filename to include const string @@ -205,11 +292,16 @@ private: pushSource(filename, current_origin); } - // A helper method for loadIncremental(). It parses part of an RR - // until it finds the RR type field. If TTL or RR class is - // specified before the RR type, it also recognizes and validates - // them. explicit_ttl will be set to true if this method finds a - // valid TTL field. + /// \brief Parse RR fields (TTL, CLASS and TYPE). + /// + /// A helper method for \c loadIncremental(). It parses part of an + /// RR until it finds the RR type field. If TTL or RR class is + /// specified before the RR type, it also recognizes and validates + /// them. + /// + /// \param explicit_ttl will be set to true if this method finds a + /// valid TTL field. + /// \param rrparam_token Pass the current (parsed) token here. RRType parseRRParams(bool& explicit_ttl, MasterToken rrparam_token) { // Find TTL, class and type. Both TTL and class are // optional and may occur in any order if they exist. TTL @@ -249,20 +341,25 @@ private: return (RRType(rrparam_token.getString())); } - // Upper limit check when recognizing a specific TTL value from the - // zone file ($TTL, the RR's TTL field, or the SOA minimum). RFC2181 - // Section 8 limits the range of TTL values to 2^31-1 (0x7fffffff), - // and prohibits transmitting a TTL field exceeding this range. We - // guarantee that by limiting the value at the time of zone - // parsing/loading, following what BIND 9 does. Resetting it to 0 - // at this point may not be exactly what the RFC states (depending on - // the meaning of 'received'), but the end result would be the same (i.e., - // the guarantee on transmission). Again, we follow the BIND 9's behavior - // here. - // - // post_parsing is true iff this method is called after parsing the entire - // RR and the lexer is positioned at the next line. It's just for - // calculating the accurate source line when callback is necessary. + /// \brief Check and limit TTL to maximum value. + /// + /// Upper limit check when recognizing a specific TTL value from the + /// zone file ($TTL, the RR's TTL field, or the SOA minimum). RFC2181 + /// Section 8 limits the range of TTL values to 2^31-1 (0x7fffffff), + /// and prohibits transmitting a TTL field exceeding this range. We + /// guarantee that by limiting the value at the time of zone + /// parsing/loading, following what BIND 9 does. Resetting it to 0 + /// at this point may not be exactly what the RFC states (depending on + /// the meaning of 'received'), but the end result would be the same (i.e., + /// the guarantee on transmission). Again, we follow the BIND 9's behavior + /// here. + /// + /// \param ttl the TTL to check. If it is larger than the maximum + /// allowed, it is set to 0. + /// \param post_parsing should be true iff this method is called + /// after parsing the entire RR and the lexer is positioned at the + /// next line. It's just for calculating the accurate source line + /// when callback is necessary. void limitTTL(RRTTL& ttl, bool post_parsing) { if (ttl > RRTTL::MAX_TTL()) { const size_t src_line = lexer_.getSourceLine() - @@ -274,19 +371,25 @@ private: } } - // Set/reset the default TTL. This should be from either $TTL or SOA - // minimum TTL (it's the caller's responsibility; this method doesn't - // care about where it comes from). see LimitTTL() for parameter - // post_parsing. + /// \brief Set/reset the default TTL. + /// + /// This should be from either $TTL or SOA minimum TTL (it's the + /// caller's responsibility; this method doesn't care about where it + /// comes from). See \c limitTTL() for parameter post_parsing. void setDefaultTTL(const RRTTL& ttl, bool post_parsing) { assignTTL(default_ttl_, ttl); limitTTL(*default_ttl_, post_parsing); } - // Try to set/reset the current TTL from candidate TTL text. It's possible - // it does not actually represent a TTL (which is not immediately - // considered an error). Return true iff it's recognized as a valid TTL - // (and only in which case the current TTL is set). + /// \brief Try to set/reset the current TTL from candidate TTL text. + /// + /// It's possible it that the text does not actually represent a TTL + /// (which is not immediately considered an error). Returns \c true + /// iff it's recognized as a valid TTL (and only in which case the + /// current TTL is set). + /// + /// \param ttl_txt The text to parse as a TTL. + /// \return true if a TTL was parsed (and set as the current TTL). bool setCurrentTTL(const string& ttl_txt) { // We use the factory version instead of RRTTL constructor as we // need to expect cases where ttl_txt does not actually represent a TTL @@ -300,14 +403,15 @@ private: return (false); } - // Determine the TTL of the current RR based on the given parsing context. - // - // explicit_ttl is true iff the TTL is explicitly specified for that RR - // (in which case current_ttl_ is set to that TTL). - // rrtype is the type of the current RR, and rdata is its RDATA. They - // only matter if the type is SOA and no available TTL is known. In this - // case the minimum TTL of the SOA will be used as the TTL of that SOA - // and the default TTL for subsequent RRs. + /// \brief Determine the TTL of the current RR based on the given + /// parsing context. + /// + /// \c explicit_ttl is true iff the TTL is explicitly specified for that RR + /// (in which case current_ttl_ is set to that TTL). + /// \c rrtype is the type of the current RR, and \c rdata is its RDATA. They + /// only matter if the type is SOA and no available TTL is known. In this + /// case the minimum TTL of the SOA will be used as the TTL of that SOA + /// and the default TTL for subsequent RRs. const RRTTL& getCurrentTTL(bool explicit_ttl, const RRType& rrtype, const rdata::ConstRdataPtr& rdata) { // We've completed parsing the full of RR, and the lexer is already @@ -346,6 +450,10 @@ private: return (*current_ttl_); } + /// \brief Handle a $DIRECTIVE + /// + /// This method is called when a $DIRECTIVE is encountered in the + /// input stream. void handleDirective(const char* directive, size_t length) { if (iequals(directive, "INCLUDE")) { doInclude(); @@ -364,6 +472,7 @@ private: } } + /// \brief Skip tokens until end-of-line. void eatUntilEOL(bool reportExtra) { // We want to continue. Try to read until the end of line for (;;) { @@ -446,6 +555,44 @@ public: namespace { // begin unnamed namespace +/// \brief Generate a dotted nibble sequence. +/// +/// This method generates a dotted nibble sequence and returns it as a +/// string. The nibbles are appended from the least significant digit +/// (in hex representation of \c num) to the most significant digit with +/// dots ('.') to separate the digits. If \c width is non-zero and the +/// dotted nibble sequence has not filled the requested width, the rest +/// of the width is filled with a dotted nibble sequence of 0 nibbles. +/// +/// Some sample representations: +/// +/// num = 0x1234, width = 0 +/// "4.3.2.1" +/// +/// num = 0x1234, width = 1 +/// "4.3.2.1" +/// +/// num = 0x1234, width = 8 +/// "4.3.2.1" +/// +/// num = 0x1234, width = 9 +/// "4.3.2.1." +/// +/// num = 0x1234, width = 10 +/// "4.3.2.1.0" +/// +/// num = 0x1234, width = 11 +/// "4.3.2.1.0." +/// +/// num = 0xabcd, width = 0, uppercase = true +/// "D.C.B.A" +/// +/// \param num The number for which the dotted nibble sequence should be +/// generated. +/// \param width The width of the generated string. +/// \param uppercase Whether to use uppercase characters in nibble +/// sequence. +/// \return A string containing the dotted nibble sequence. std::string genNibbles(int num, unsigned int width, bool uppercase) { static const char *hex = "0123456789abcdef0123456789ABCDEF"; @@ -704,15 +851,6 @@ MasterLoader::MasterLoaderImpl::doGenerate() { } } -// A helper method of loadIncremental, parsing the first token of a new line. -// If it looks like an RR, detect its owner name and return a string token for -// the next field of the RR. -// Otherwise, return either END_OF_LINE or END_OF_FILE token depending on -// whether the loader continues to the next line or completes the load, -// respectively. Other corner cases including $-directive handling is done -// here. -// For unexpected errors, it throws an exception, which will be handled in -// loadIncremental. MasterToken MasterLoader::MasterLoaderImpl::handleInitialToken() { const MasterToken& initial_token =