Browse Source

[2430] Write API doc for MasterLoaderImpl

Mukund Sivaraman 11 years ago
parent
commit
3fc1c63ddb
1 changed files with 183 additions and 45 deletions
  1. 183 45
      src/lib/dns/master_loader.cc

+ 183 - 45
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 =