LCOV - code coverage report
Current view: top level - dns - name.h (source / functions) Hit Total Coverage
Test: report.info Lines: 30 35 85.7 %
Date: 2012-05-15 Functions: 11 24 45.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 50 94 53.2 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #ifndef __NAME_H
      16                 :            : #define __NAME_H 1
      17                 :            : 
      18                 :            : #include <stdint.h>
      19                 :            : 
      20                 :            : #include <string>
      21                 :            : #include <vector>
      22                 :            : 
      23                 :            : #include <exceptions/exceptions.h>
      24                 :            : 
      25                 :            : namespace isc {
      26                 :            : namespace util {
      27                 :            : class InputBuffer;
      28                 :            : class OutputBuffer;
      29                 :            : }
      30                 :            : 
      31                 :            : namespace dns {
      32                 :            : class AbstractMessageRenderer;
      33                 :            : 
      34                 :            : ///
      35                 :            : /// \brief Base class for name parser exceptions.
      36                 :            : ///
      37                 :         52 : class NameParserException : public Exception {
      38                 :            : public:
      39                 :            :     NameParserException(const char* file, size_t line, const char* what) :
      40 [ +  - ][ #  # ]:         52 :         isc::Exception(file, line, what) {}
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
      41                 :            : };
      42                 :            : 
      43                 :            : ///
      44                 :            : /// \brief A standard DNS module exception that is thrown if the name parser
      45                 :            : /// encounters an empty label in the middle of a name.
      46                 :            : ///
      47                 :         20 : class EmptyLabel : public NameParserException {
      48                 :            : public:
      49                 :            :     EmptyLabel(const char* file, size_t line, const char* what) :
      50                 :         40 :         NameParserException(file, line, what) {}
      51                 :            : };
      52                 :            : 
      53                 :            : ///
      54                 :            : /// \brief A standard DNS module exception that is thrown if the name parser
      55                 :            : /// encounters too long a name.
      56                 :            : ///
      57                 :          6 : class TooLongName : public NameParserException {
      58                 :            : public:
      59                 :            :     TooLongName(const char* file, size_t line, const char* what) :
      60                 :         12 :         NameParserException(file, line, what) {}
      61                 :            : };
      62                 :            : 
      63                 :            : ///
      64                 :            : /// \brief A standard DNS module exception that is thrown if the name parser
      65                 :            : /// encounters too long a label.
      66                 :            : ///
      67                 :         13 : class TooLongLabel : public NameParserException {
      68                 :            : public:
      69                 :            :     TooLongLabel(const char* file, size_t line, const char* what) :
      70                 :         26 :         NameParserException(file, line, what) {}
      71                 :            : };
      72                 :            : 
      73                 :            : ///
      74                 :            : /// \brief A standard DNS module exception that is thrown if the name parser
      75                 :            : /// encounters an obsolete or incomplete label type.  In effect "obsolete" only
      76                 :            : /// applies to bitstring labels, which would begin with "\[".  Incomplete cases
      77                 :            : /// include an incomplete escaped sequence such as "\12".
      78                 :            : ///
      79                 :          3 : class BadLabelType : public NameParserException {
      80                 :            : public:
      81                 :            :     BadLabelType(const char* file, size_t line, const char* what) :
      82                 :          6 :         NameParserException(file, line, what) {}
      83                 :            : };
      84                 :            : 
      85                 :            : ///
      86                 :            : /// \brief A standard DNS module exception that is thrown if the name parser
      87                 :            : /// fails to decode a "\"-escaped sequence.
      88                 :            : ///
      89                 :          5 : class BadEscape : public NameParserException {
      90                 :            : public:
      91                 :            :     BadEscape(const char* file, size_t line, const char* what) :
      92                 :         10 :         NameParserException(file, line, what) {}
      93                 :            : };
      94                 :            : 
      95                 :            : ///
      96                 :            : /// \brief A standard DNS module exception that is thrown if the name parser
      97                 :            : /// finds the input (string or wire-format %data) is incomplete.
      98                 :            : ///
      99                 :            : /// An attempt of constructing a name from an empty string will trigger this
     100                 :            : /// exception.
     101                 :            : ///
     102                 :          5 : class IncompleteName : public NameParserException {
     103                 :            : public:
     104                 :            :     IncompleteName(const char* file, size_t line, const char* what) :
     105                 :         10 :         NameParserException(file, line, what) {}
     106                 :            : };
     107                 :            : 
     108                 :            : ///
     109                 :            : /// This is a supplemental class used only as a return value of Name::compare().
     110                 :            : /// It encapsulate a tuple of the comparison: ordering, number of common labels,
     111                 :            : /// and relationship as follows:
     112                 :            : /// - ordering: relative ordering under the DNSSEC order relation
     113                 :            : /// - labels: the number of common significant labels of the two names being
     114                 :            : ///   compared
     115                 :            : /// - relationship: see NameComparisonResult::NameRelation
     116                 :            : ///
     117                 :            : class NameComparisonResult {
     118                 :            : public:
     119                 :            :     /// The relation of two names under comparison.
     120                 :            :     /// Its semantics for the case of
     121                 :            :     /// <code>name1->compare(name2)</code> (where name1 and name2 are instances
     122                 :            :     /// of the Name class) is as follows:
     123                 :            :     ///    - SUPERDOMAIN: name1 properly contains name2; name2 is a proper
     124                 :            :     ///      subdomain of name1
     125                 :            :     ///    - SUBDOMAIN: name1 is a proper subdomain of name2
     126                 :            :     ///    - EQUAL: name1 and name2 are equal
     127                 :            :     ///    - COMMONANCESTOR: name1 and name2 share a common ancestor
     128                 :            :     ///
     129                 :            :     /// Note that in our implementation there's always a hierarchical
     130                 :            :     /// relationship between any two names since all names are absolute and
     131                 :            :     /// they at least share the trailing empty label.
     132                 :            :     /// So, for example, the relationship between "com." and "net." is
     133                 :            :     /// "commonancestor".  This may be counter intuitive and inconvenient, but
     134                 :            :     /// we'll keep this design at the moment until we decide whether and how to
     135                 :            :     /// handle "non absolute" names (see the description of the \c Name class).
     136                 :            :     /// If we want to (re)introduce the notion of non absolute names, we'll
     137                 :            :     /// want to distinguish "com" and "com.", and the current definition would
     138                 :            :     /// be more compatible for that purpose.
     139                 :            :     /// If, on the other hand, we finally decide we really don't need that
     140                 :            :     /// notion, we'll probably reconsider the design here, too. 
     141                 :            :     enum NameRelation {
     142                 :            :         SUPERDOMAIN = 0,
     143                 :            :         SUBDOMAIN = 1,
     144                 :            :         EQUAL = 2,
     145                 :            :         COMMONANCESTOR = 3
     146                 :            :     };
     147                 :            : 
     148                 :            :     ///
     149                 :            :     /// \name Constructors and Destructor
     150                 :            :     ///
     151                 :            :     //@{
     152                 :            :     /// \brief Constructor from a comparison tuple
     153                 :            :     ///
     154                 :            :     /// This constructor simply initializes the object in the straightforward
     155                 :            :     /// way.
     156                 :            :     NameComparisonResult(int order, unsigned int nlabels,
     157                 :            :                          NameRelation relation) :
     158                 :     204879 :         order_(order), nlabels_(nlabels), relation_(relation) {}
     159                 :            :     //@}
     160                 :            : 
     161                 :            :     ///
     162                 :            :     /// \name Getter Methods
     163                 :            :     ///
     164                 :            :     //@{
     165                 :            :     /// Returns the ordering of the comparison result
     166                 :          0 :     int getOrder() const { return (order_); }
     167                 :            :     /// Returns the number of common labels of the comparison result
     168                 :          0 :     unsigned int getCommonLabels() const { return (nlabels_); }
     169                 :            :     /// Returns the NameRelation of the comparison result
     170                 :          0 :     NameRelation getRelation() const { return (relation_); }
     171                 :            :     //@}
     172                 :            : private:
     173                 :            :     int order_;
     174                 :            :     unsigned int nlabels_;
     175                 :            :     NameRelation relation_;
     176                 :            : };
     177                 :            : 
     178                 :            : ///
     179                 :            : /// The \c Name class encapsulates DNS names.
     180                 :            : ///
     181                 :            : /// It provides interfaces to construct a name from string or wire-format %data,
     182                 :            : /// transform a name into a string or wire-format %data, compare two names, get
     183                 :            : /// access to various properties of a name, etc.
     184                 :            : ///
     185                 :            : /// Notes to developers: Internally, a name object maintains the name %data
     186                 :            : /// in wire format as an instance of \c std::string.  Since many string
     187                 :            : /// implementations adopt copy-on-write %data sharing, we expect this approach
     188                 :            : /// will make copying a name less expensive in typical cases.  If this is
     189                 :            : /// found to be a significant performance bottleneck later, we may reconsider
     190                 :            : /// the internal representation or perhaps the API.
     191                 :            : ///
     192                 :            : /// A name object also maintains a vector of offsets (\c offsets_ member),
     193                 :            : /// each of which is the offset to a label of the name: The n-th element of
     194                 :            : /// the vector specifies the offset to the n-th label.  For example, if the
     195                 :            : /// object represents "www.example.com", the elements of the offsets vector
     196                 :            : /// are 0, 4, 12, and 16.  Note that the offset to the trailing dot (16) is
     197                 :            : /// included.  In the BIND9 DNS library from which this implementation is
     198                 :            : /// derived, the offsets are optional, probably due to performance
     199                 :            : /// considerations (in fact, offsets can always be calculated from the name
     200                 :            : /// %data, and in that sense are redundant).  In our implementation, however,
     201                 :            : /// we always build and maintain the offsets.  We believe we need more low
     202                 :            : /// level, specialized %data structure and interface where we really need to
     203                 :            : /// pursue performance, and would rather keep this generic API and
     204                 :            : /// implementation simpler.
     205                 :            : ///
     206                 :            : /// While many other DNS APIs introduce an "absolute or relative"
     207                 :            : /// attribute of names as defined in RFC1035, names are always "absolute" in
     208                 :            : /// the initial design of this API.
     209                 :            : /// In fact, separating absolute and relative would confuse API users
     210                 :            : /// unnecessarily.  For example, it's not so intuitive to consider the
     211                 :            : /// comparison result of an absolute name with a relative name.
     212                 :            : /// We've looked into how the concept of absolute names is used in BIND9,
     213                 :            : /// and found that in many cases names are generally absolute.
     214                 :            : /// The only reasonable case of separating absolute and relative is in a master
     215                 :            : /// file parser, where a relative name must be a complete name with an "origin"
     216                 :            : /// name, which must be absolute.  So, in this initial design, we chose a
     217                 :            : /// simpler approach: the API generally handles names as absolute; when we
     218                 :            : /// introduce a parser of master files, we'll introduce the notion of relative
     219                 :            : /// names as a special case.
     220                 :            : ///
     221 [ +  - ][ +  + ]:     537958 : class Name {
              [ +  -  + ]
                 [ +  - ]
     222                 :            :     // LabelSequences use knowledge about the internal data structure
     223                 :            :     // of this class for efficiency (they use the offsets_ vector and
     224                 :            :     // the ndata_ string)
     225                 :            :     friend class LabelSequence;
     226                 :            : 
     227                 :            :     ///
     228                 :            :     /// \name Constructors and Destructor
     229                 :            :     ///
     230                 :            :     //@{
     231                 :            : private:
     232                 :            :     /// The default constructor
     233                 :            :     ///
     234                 :            :     /// This is used internally in the class implementation, but at least at
     235                 :            :     /// the moment defined as private because it will construct an incomplete
     236                 :            :     /// object in that it doesn't have any labels.  We may reconsider this
     237                 :            :     /// design choice as we see more applications of the class.
     238                 :      96195 :     Name() : length_(0), labelcount_(0) {}
     239                 :            : public:
     240                 :            :     /// Constructor from a string
     241                 :            :     ///
     242                 :            :     /// If the given string does not represent a valid DNS name, an exception
     243                 :            :     /// of class \c EmptyLabel, \c TooLongLabel, \c BadLabelType, \c BadEscape,
     244                 :            :     /// \c TooLongName, or \c IncompleteName will be thrown.
     245                 :            :     /// In addition, if resource allocation for the new name fails, a
     246                 :            :     /// corresponding standard exception will be thrown.
     247                 :            :     ///
     248                 :            :     /// \param namestr A string representation of the name to be constructed.
     249                 :            :     /// \param downcase Whether to convert upper case alphabets to lower case.
     250                 :            :     explicit Name(const std::string& namestr, bool downcase = false);
     251                 :            :     /// Constructor from wire-format %data.
     252                 :            :     ///
     253                 :            :     /// The \c buffer parameter normally stores a complete DNS message
     254                 :            :     /// containing the name to be constructed.  The current read position of
     255                 :            :     /// the buffer points to the head of the name.
     256                 :            :     ///
     257                 :            :     /// The input %data may or may not be compressed; if it's compressed, this
     258                 :            :     /// method will automatically decompress it.
     259                 :            :     ///
     260                 :            :     /// If the given %data does not represent a valid DNS name, an exception
     261                 :            :     /// of class \c DNSMessageFORMERR will be thrown.
     262                 :            :     /// In addition, if resource allocation for the new name fails, a
     263                 :            :     /// corresponding standard exception will be thrown.
     264                 :            :     ///
     265                 :            :     /// \param buffer A buffer storing the wire format %data.
     266                 :            :     /// \param downcase Whether to convert upper case alphabets to lower case.
     267                 :            :     explicit Name(isc::util::InputBuffer& buffer, bool downcase = false);
     268                 :            :     ///
     269                 :            :     /// We use the default copy constructor intentionally.
     270                 :            :     //@}
     271                 :            :     /// We use the default copy assignment operator intentionally.
     272                 :            :     ///
     273                 :            : 
     274                 :            :     ///
     275                 :            :     /// \name Getter Methods
     276                 :            :     ///
     277                 :            :     //@{
     278                 :            :     /// \brief Provides one-byte name %data in wire format at the specified
     279                 :            :     /// position.
     280                 :            :     ///
     281                 :            :     /// This method returns the unsigned 8-bit value of wire-format \c Name
     282                 :            :     /// %data at the given position from the head.
     283                 :            :     ///
     284                 :            :     /// For example, if \c n is a \c Name object for "example.com",
     285                 :            :     /// \c n.at(3) would return \c 'a', and \c n.at(7) would return \c 'e'.
     286                 :            :     /// Note that \c n.at(0) would be 7 (decimal), the label length of
     287                 :            :     /// "example", instead of \c 'e', because it returns a %data portion
     288                 :            :     /// in wire-format.  Likewise, \c n.at(8) would return 3 (decimal)
     289                 :            :     /// instead of <code>'.'</code>
     290                 :            :     ///
     291                 :            :     /// This method would be useful for an application to examine the
     292                 :            :     /// wire-format name %data without dumping the %data into a buffer,
     293                 :            :     /// which would involve %data copies and would be less efficient.
     294                 :            :     /// One common usage of this method would be something like this:
     295                 :            :     /// \code for (size_t i = 0; i < name.getLength(); ++i) {
     296                 :            :     ///     uint8_t c = name.at(i);
     297                 :            :     ///     // do something with c
     298                 :            :     /// } \endcode
     299                 :            :     ///
     300                 :            :     /// Parameter \c pos must be in the valid range of the name %data, that is,
     301                 :            :     /// must be less than \c Name.getLength().  Otherwise, an exception of
     302                 :            :     /// class \c OutOfRange will be thrown.
     303                 :            :     /// This method never throws an exception in other ways.
     304                 :            :     ///
     305                 :            :     /// \param pos The position in the wire format name %data to be returned.
     306                 :            :     /// \return An unsigned 8-bit integer corresponding to the name %data
     307                 :            :     /// at the position of \c pos.
     308                 :      84422 :     uint8_t at(size_t pos) const
     309                 :            :     {
     310         [ +  + ]:      84422 :         if (pos >= length_) {
     311         [ +  - ]:          6 :             isc_throw(OutOfRange, "Out of range access in Name::at()");
     312                 :            :         }
     313                 :      84419 :         return (ndata_[pos]);
     314                 :            :     }
     315                 :            : 
     316                 :            :     /// \brief Gets the length of the <code>Name</code> in its wire format.
     317                 :            :     ///
     318                 :            :     /// This method never throws an exception.
     319                 :            :     ///
     320                 :            :     /// \return the length (the number of octets in wire format) of the
     321                 :            :     /// <code>Name</code>
     322                 :          0 :     size_t getLength() const { return (length_); }
     323                 :            : 
     324                 :            :     /// \brief Returns the number of labels contained in the <code>Name</code>.
     325                 :            :     ///
     326                 :            :     /// Note that an empty label (corresponding to a trailing '.') is counted
     327                 :            :     /// as a single label, so the return value of this method must be >0.
     328                 :            :     ///
     329                 :            :     /// This method never throws an exception.
     330                 :            :     ///
     331                 :            :     /// \return the number of labels
     332                 :          0 :     unsigned int getLabelCount() const { return (labelcount_); }
     333                 :            :     //@}
     334                 :            : 
     335                 :            :     ///
     336                 :            :     /// \name Converter methods
     337                 :            :     ///
     338                 :            :     //@{
     339                 :            :     /// \brief Convert the Name to a string.
     340                 :            :     ///
     341                 :            :     /// This method returns a <code>std::string</code> object representing the
     342                 :            :     /// Name as a string.  Unless <code>omit_final_dot</code> is
     343                 :            :     /// <code>true</code>, the returned string ends with a dot '.'; the default
     344                 :            :     /// is <code>false</code>.  The default value of this parameter is
     345                 :            :     /// <code>true</code>; converted names will have a trailing dot by default.
     346                 :            :     ///
     347                 :            :     /// This function assumes the name is in proper uncompressed wire format.
     348                 :            :     /// If it finds an unexpected label character including compression pointer,
     349                 :            :     /// an exception of class \c BadLabelType will be thrown.
     350                 :            :     /// In addition, if resource allocation for the result string fails, a
     351                 :            :     /// corresponding standard exception will be thrown.
     352                 :            :     //
     353                 :            :     /// \param omit_final_dot whether to omit the trailing dot in the output.
     354                 :            :     /// \return a string representation of the <code>Name</code>.
     355                 :            :     std::string toText(bool omit_final_dot = false) const;
     356                 :            : 
     357                 :            :     /// \brief Render the <code>Name</code> in the wire format with compression.
     358                 :            :     ///
     359                 :            :     /// This method dumps the Name in wire format with help of \c renderer,
     360                 :            :     /// which encapsulates output buffer and name compression algorithm to
     361                 :            :     /// render the name.
     362                 :            :     ///
     363                 :            :     /// If resource allocation in rendering process fails, a corresponding
     364                 :            :     /// standard exception will be thrown.
     365                 :            :     ///
     366                 :            :     /// \param renderer DNS message rendering context that encapsulates the
     367                 :            :     /// output buffer and name compression information.
     368                 :            :     void toWire(AbstractMessageRenderer& renderer) const;
     369                 :            : 
     370                 :            :     /// \brief Render the <code>Name</code> in the wire format without
     371                 :            :     /// compression.
     372                 :            :     ///
     373                 :            :     /// If resource allocation in rendering process fails, a corresponding
     374                 :            :     /// standard exception will be thrown.  This can be avoided by preallocating
     375                 :            :     /// a sufficient size of \c buffer.  Specifically, if
     376                 :            :     /// <code>buffer.getCapacity() - buffer.getLength() >= Name::MAX_WIRE</code>
     377                 :            :     /// then this method should not throw an exception.
     378                 :            :     ///
     379                 :            :     /// \param buffer An output buffer to store the wire %data.
     380                 :            :     void toWire(isc::util::OutputBuffer& buffer) const;
     381                 :            :     //@}
     382                 :            : 
     383                 :            :     ///
     384                 :            :     /// \name Comparison methods
     385                 :            :     ///
     386                 :            :     //@{
     387                 :            :     /// \brief Compare two <code>Name</code>s.
     388                 :            :     ///
     389                 :            :     /// This method compares the <code>Name</code> and <code>other</code> and
     390                 :            :     /// returns the result in the form of a <code>NameComparisonResult</code>
     391                 :            :     /// object.
     392                 :            :     ///
     393                 :            :     /// Note that this is case-insensitive comparison.
     394                 :            :     ///
     395                 :            :     /// This method never throws an exception.
     396                 :            :     ///
     397                 :            :     /// \param other the right-hand operand to compare against.
     398                 :            :     /// \return a <code>NameComparisonResult</code> object representing the
     399                 :            :     /// comparison result.
     400                 :            :     NameComparisonResult compare(const Name& other) const;
     401                 :            : 
     402                 :            :     /// \brief Return true iff two names are equal.
     403                 :            :     ///
     404                 :            :     /// Semantically this could be implemented based on the result of the
     405                 :            :     /// \c compare() method, but the actual implementation uses different code
     406                 :            :     /// that simply performs character-by-character comparison (case
     407                 :            :     /// insensitive for the name label parts) on the two names.  This is because
     408                 :            :     /// it would be much faster and the simple equality check would be pretty
     409                 :            :     /// common.
     410                 :            :     ///
     411                 :            :     /// This method never throws an exception.
     412                 :            :     ///
     413                 :            :     /// \param other the <code>Name</code> object to compare against.
     414                 :            :     /// \return true if the two names are equal; otherwise false.
     415                 :            :     bool equals(const Name& other) const;
     416                 :            : 
     417                 :            :     /// Same as equals()
     418 [ +  - ][ +  - ]:      12275 :     bool operator==(const Name& other) const { return (equals(other)); }
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  + ]
               [ + ][ - ]
         [ +  -  + ][ - ]
         [ +  - ][ +  - ]
     419                 :            : 
     420                 :            :     /// \brief Return true iff two names are not equal.
     421                 :            :     ///
     422                 :            :     /// This method simply negates the result of \c equal() method, and in that
     423                 :            :     /// sense it's redundant.  The separate method is provided just for
     424                 :            :     /// convenience.
     425 [ +  + ][ +  - ]:      12575 :     bool nequals(const Name& other) const { return (!(equals(other))); }
            [ - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     426                 :            : 
     427                 :            :     /// Same as nequals()
     428                 :            :     bool operator!=(const Name& other) const { return (nequals(other)); }
     429                 :            : 
     430                 :            :     /// \brief Less-than or equal comparison for Name against <code>other</code>
     431                 :            :     ///
     432                 :            :     /// The comparison is based on the result of the \c compare() method.
     433                 :            :     ///
     434                 :            :     /// This method never throws an exception.
     435                 :            :     ///
     436                 :            :     /// \param other the <code>Name</code> object to compare against.
     437                 :            :     /// \return true if <code>compare(other).getOrder() <= 0</code>;
     438                 :            :     /// otherwise false.
     439                 :            :     bool leq(const Name& other) const;
     440                 :            : 
     441                 :            :     /// Same as leq()
     442                 :          6 :     bool operator<=(const Name& other) const { return (leq(other)); }
     443                 :            : 
     444                 :            :     /// \brief Greater-than or equal comparison for Name against
     445                 :            :     /// <code>other</code>
     446                 :            :     ///
     447                 :            :     /// The comparison is based on the result of the \c compare() method.
     448                 :            :     ///
     449                 :            :     /// This method never throws an exception.
     450                 :            :     ///
     451                 :            :     /// \param other the <code>Name</code> object to compare against.
     452                 :            :     /// \return true if <code>compare(other).getOrder() >= 0</code>;
     453                 :            :     /// otherwise false.
     454                 :            :     bool geq(const Name& other) const;
     455                 :            : 
     456                 :            :     /// Same as geq()
     457                 :          6 :     bool operator>=(const Name& other) const { return (geq(other)); }
     458                 :            : 
     459                 :            :     /// \brief Less-than comparison for Name against <code>other</code>
     460                 :            :     ///
     461                 :            :     /// The comparison is based on the result of the \c compare() method.
     462                 :            :     ///
     463                 :            :     /// This method never throws an exception.
     464                 :            :     ///
     465                 :            :     /// \param other the <code>Name</code> object to compare against.
     466                 :            :     /// \return true if <code>compare(other).getOrder() < 0</code>;
     467                 :            :     /// otherwise false.
     468                 :            :     bool lthan(const Name& other) const;
     469                 :            : 
     470                 :            :     /// Same as lthan()
     471 [ #  # ][ +  - ]:      44378 :     bool operator<(const Name& other) const { return (lthan(other)); }
                 [ +  - ]
     472                 :            : 
     473                 :            :     /// \brief Greater-than comparison for Name against <code>other</code>
     474                 :            :     ///
     475                 :            :     /// The comparison is based on the result of the \c compare() method.
     476                 :            :     ////
     477                 :            :     /// This method never throws an exception.
     478                 :            :     ///
     479                 :            :     /// \param other the <code>Name</code> object to compare against.
     480                 :            :     /// \return true if <code>compare(other).getOrder() > 0</code>;
     481                 :            :     /// otherwise false.
     482                 :            :     bool gthan(const Name& other) const;
     483                 :            : 
     484                 :            :     /// Same as gthan()
     485 [ +  - ][ +  - ]:          8 :     bool operator>(const Name& other) const { return (gthan(other)); }
     486                 :            :     //@}
     487                 :            : 
     488                 :            :     ///
     489                 :            :     /// \name Transformer methods
     490                 :            :     ///
     491                 :            :     //@{
     492                 :            :     /// \brief Extract a specified subpart of Name.
     493                 :            :     ///
     494                 :            :     /// <code>name.split(first, n)</code> constructs a new name starting from
     495                 :            :     /// the <code>first</code>-th label of the \c name, and subsequent \c n
     496                 :            :     /// labels including the \c first one.  Since names in this current
     497                 :            :     /// implementation are always "absolute", if the specified range doesn't
     498                 :            :     /// contain the trailing dot of the original \c name, then a dot will be
     499                 :            :     /// appended to the resulting name.  As a result, the number of labels
     500                 :            :     /// will be <code>n + 1</code>, rather than \c n.  For example,
     501                 :            :     /// when \c n is <code>Name("www.example.com")</code>,
     502                 :            :     /// both <code>n.split(1, 2)</code> and <code>n.split(1, 3)</code>
     503                 :            :     /// will produce a name corresponding to "example.com.", which has 3 labels.
     504                 :            :     /// Note also that labels are counted from 0, and so <code>first = 1</code>
     505                 :            :     /// in this example specified the label "example", not "www".
     506                 :            :     ///
     507                 :            :     /// Parameter \c n must be larger than 0, and the range specified by
     508                 :            :     /// \c first and \c n must not exceed the valid range of the original name;
     509                 :            :     /// otherwise, an exception of class \c OutOfRange will be thrown.
     510                 :            :     ///
     511                 :            :     /// Note to developers: we may want to have different versions (signatures)
     512                 :            :     /// of this method.  For example, we want to split the Name based on a given
     513                 :            :     /// suffix name.
     514                 :            :     ///
     515                 :            :     /// \param first The start position (in labels) of the extracted name
     516                 :            :     /// \param n Number of labels of the extracted name
     517                 :            :     /// \return A new Name object based on the Name containing <code>n</code>
     518                 :            :     /// labels including and following the <code>first</code> label.  
     519                 :            :     Name split(unsigned int first, unsigned int n) const;
     520                 :            : 
     521                 :            :     /// \brief Extract a specified super domain name of Name.
     522                 :            :     ///
     523                 :            :     /// This function constructs a new \c Name object that is a super domain
     524                 :            :     /// of \c this name.
     525                 :            :     /// The new name is \c level labels upper than \c this name.
     526                 :            :     /// For example, when \c name is www.example.com,
     527                 :            :     /// <code>name.split(1)</code> will return a \c Name object for example.com.
     528                 :            :     /// \c level can be 0, in which case this method returns a copy of
     529                 :            :     /// \c this name.
     530                 :            :     /// The possible maximum value for \c level is
     531                 :            :     /// <code>this->getLabelCount()-1</code>, in which case this method
     532                 :            :     /// returns a root name.
     533                 :            :     ///
     534                 :            :     /// One common expected usage of this method is to iterate over super
     535                 :            :     /// domains of a given name, label by label, as shown in the following
     536                 :            :     /// sample code:
     537                 :            :     /// \code // if name is www.example.com...
     538                 :            :     /// for (int i = 0; i < name.getLabelCount(); ++i) {
     539                 :            :     ///     Name upper_name(name.split(i));
     540                 :            :     ///     // upper_name'll be www.example.com., example.com., com., and then .
     541                 :            :     /// }
     542                 :            :     /// \endcode
     543                 :            :     ///
     544                 :            :     /// \c level must be smaller than the number of labels of \c this name;
     545                 :            :     /// otherwise an exception of class \c OutOfRange will be thrown.
     546                 :            :     /// In addition, if resource allocation for the new name fails, a
     547                 :            :     /// corresponding standard exception will be thrown.
     548                 :            :     ///
     549                 :            :     /// Note to developers: probably as easily imagined, this method is a
     550                 :            :     /// simple wrapper to one usage of the other
     551                 :            :     /// <code>split(unsigned int, unsigned int) const</code> method and is
     552                 :            :     /// redundant in some sense.
     553                 :            :     /// We provide the "redundant" method for convenience, however, because
     554                 :            :     /// the expected usage shown above seems to be common, and the parameters
     555                 :            :     /// to the other \c split(unsigned int, unsigned int) const to implement
     556                 :            :     /// it may not be very intuitive.
     557                 :            :     ///
     558                 :            :     /// We are also aware that it is generally discouraged to add a public
     559                 :            :     /// member function that could be implemented using other member functions.
     560                 :            :     /// We considered making it a non member function, but we could not come
     561                 :            :     /// up with an intuitive function name to represent the specific service.
     562                 :            :     /// Some other BIND 10 developers argued, probably partly because of the
     563                 :            :     /// counter intuitive function name, a different signature of \c split
     564                 :            :     /// would be better to improve code readability.
     565                 :            :     /// While that may be a matter of personal preference, we accepted the
     566                 :            :     /// argument.  One major goal of public APIs like this is wider acceptance
     567                 :            :     /// from internal/external developers, so unless there is a clear advantage
     568                 :            :     /// it would be better to respect the preference of the API users.
     569                 :            :     ///
     570                 :            :     /// Since this method doesn't have to be a member function in other way,
     571                 :            :     /// it is intentionally implemented only using public interfaces of the
     572                 :            :     /// \c Name class; it doesn't refer to private members of the class even if
     573                 :            :     /// it could.
     574                 :            :     /// This way we hope we can avoid damaging the class encapsulation,
     575                 :            :     /// which is a major drawback of public member functions.
     576                 :            :     /// As such if and when this "method" has to be extended, it should be
     577                 :            :     /// implemented without the privilege of being a member function unless
     578                 :            :     /// there is a very strong reason to do so.  In particular a minor
     579                 :            :     /// performance advantage shouldn't justify that approach.
     580                 :            :     ///
     581                 :            :     /// \param level The number of labels to be removed from \c this name to
     582                 :            :     /// create the super domain name.
     583                 :            :     /// (0 <= \c level < <code>this->getLabelCount()</code>)
     584                 :            :     /// \return A new \c Name object to be created.
     585                 :            :     Name split(unsigned int level) const;
     586                 :            : 
     587                 :            :     /// \brief Reverse the labels of a name
     588                 :            :     ///
     589                 :            :     /// This method reverses the labels of a name.  For example, if
     590                 :            :     /// \c this is "www.example.com.", this method will return 
     591                 :            :     /// "com.example.www."  (This is useful because DNSSEC sort order
     592                 :            :     /// is equivalent to a lexical sort of label-reversed names.)
     593                 :            :     Name reverse() const;
     594                 :            : 
     595                 :            :     /// \brief Concatenate two names.
     596                 :            :     ///
     597                 :            :     /// This method appends \c suffix to \c this Name.  The trailing dot of
     598                 :            :     /// \c this Name will be removed.  For example, if \c this is "www."
     599                 :            :     /// and \c suffix is "example.com.", a successful return of this method
     600                 :            :     /// will be a name of "www.example.com."
     601                 :            :     ///
     602                 :            :     ///The resulting length of the concatenated name must not exceed
     603                 :            :     /// \c Name::MAX_WIRE; otherwise an exception of class
     604                 :            :     /// \c TooLongName will be thrown.
     605                 :            :     ///
     606                 :            :     /// \param suffix a Name object to be appended to the Name.
     607                 :            :     /// \return a new Name object concatenating \c suffix to \c this Name.
     608                 :            :     Name concatenate(const Name& suffix) const;
     609                 :            : 
     610                 :            :     /// \brief Downcase all upper case alphabet characters in the name.
     611                 :            :     ///
     612                 :            :     /// This method modifies the calling object so that it can perform the
     613                 :            :     /// conversion as fast as possible and can be exception free.
     614                 :            :     ///
     615                 :            :     /// The return value of this version of \c downcase() is a reference to
     616                 :            :     /// the calling object (i.e., \c *this) so that the caller can use the
     617                 :            :     /// result of downcasing in a single line.  For example, if variable
     618                 :            :     /// \c n is a \c Name class object possibly containing upper case
     619                 :            :     /// characters, and \c b is an \c OutputBuffer class object, then the
     620                 :            :     /// following code will dump the name in wire format to \c b with
     621                 :            :     /// downcasing upper case characters:
     622                 :            :     ///
     623                 :            :     /// \code n.downcase().toWire(b); \endcode
     624                 :            :     ///
     625                 :            :     /// Since this method modifies the calling object, a \c const name object
     626                 :            :     /// cannot call it.  If \c n is a \c const Name class object, it must first
     627                 :            :     /// be copied to a different object and the latter must be used for the
     628                 :            :     /// downcase modification.
     629                 :            :     ///
     630                 :            :     /// \return A reference to the calling object with being downcased.
     631                 :            :     Name& downcase();
     632                 :            :     //@}
     633                 :            : 
     634                 :            :     ///
     635                 :            :     /// \name Testing methods
     636                 :            :     ///
     637                 :            :     //@{
     638                 :            :     /// \brief Test if this is a wildcard name.
     639                 :            :     ///
     640                 :            :     /// \return \c true if the least significant label of this Name is
     641                 :            :     /// <code>'*'</code>; otherwise \c false.
     642                 :            :     bool isWildcard() const;
     643                 :            :     //@}
     644                 :            : 
     645                 :            :     ///
     646                 :            :     /// \name Protocol constants
     647                 :            :     ///
     648                 :            :     //@{
     649                 :            :     /// \brief Max allowable length of domain names.
     650                 :            :     static const size_t MAX_WIRE = 255;
     651                 :            : 
     652                 :            :     /// \brief Max allowable labels of domain names.
     653                 :            :     ///
     654                 :            :     /// This is <code>ceil(MAX_WIRE / 2)</code>, and is equal to the number of
     655                 :            :     /// labels of name "a.a.a.a....a." (127 "a"'s and trailing dot).
     656                 :            :     static const size_t MAX_LABELS = 128;
     657                 :            : 
     658                 :            :     /// \brief Max allowable length of labels of a domain name.
     659                 :            :     static const size_t MAX_LABELLEN = 63;
     660                 :            : 
     661                 :            :     /// \brief Max possible pointer value for name compression.
     662                 :            :     ///
     663                 :            :     /// This is the highest number of 14-bit unsigned integer.  Name compression
     664                 :            :     /// pointers are identified as a 2-byte value starting with the upper two
     665                 :            :     /// bit being 11.
     666                 :            :     static const uint16_t MAX_COMPRESS_POINTER = 0x3fff;
     667                 :            :     /// \brief A 8-bit masked value indicating a start of compression pointer.
     668                 :            :     static const uint16_t COMPRESS_POINTER_MARK8 = 0xc0;
     669                 :            :     /// \brief A 16-bit masked value indicating a start of compression pointer.
     670                 :            :     static const uint16_t COMPRESS_POINTER_MARK16 = 0xc000;
     671                 :            :     //@}
     672                 :            : 
     673                 :            :     ///
     674                 :            :     /// \name Well-known name constants
     675                 :            :     ///
     676                 :            :     //@{
     677                 :            :     /// \brief Root name (i.e. ".").
     678                 :            :     static const Name& ROOT_NAME();
     679                 :            :     //@}
     680                 :            : 
     681                 :            : private:
     682                 :            :     std::string ndata_;
     683                 :            :     std::vector<unsigned char> offsets_;
     684                 :            :     unsigned int length_;
     685                 :            :     unsigned int labelcount_;
     686                 :            : };
     687                 :            : 
     688                 :            : inline const Name&
     689                 :        985 : Name::ROOT_NAME() {
     690 [ +  + ][ +  - ]:        985 :     static Name root_name(".");
         [ +  - ][ +  - ]
     691                 :        985 :     return (root_name);
     692                 :            : }
     693                 :            : 
     694                 :            : ///
     695                 :            : /// \brief Insert the name as a string into stream.
     696                 :            : ///
     697                 :            : /// This method convert the \c name into a string and inserts it into the
     698                 :            : /// output stream \c os.
     699                 :            : ///
     700                 :            : /// This function overloads the global operator<< to behave as described in
     701                 :            : /// ostream::operator<< but applied to \c Name objects.
     702                 :            : ///
     703                 :            : /// \param os A \c std::ostream object on which the insertion operation is
     704                 :            : /// performed.
     705                 :            : /// \param name The \c Name object output by the operation.
     706                 :            : /// \return A reference to the same \c std::ostream object referenced by
     707                 :            : /// parameter \c os after the insertion operation.
     708                 :            : std::ostream&
     709                 :            : operator<<(std::ostream& os, const Name& name);
     710                 :            : }
     711                 :            : }
     712                 :            : #endif // __NAME_H
     713                 :            : 
     714                 :            : // Local Variables: 
     715                 :            : // mode: c++
     716                 :            : // End: 

Generated by: LCOV version 1.9