LCOV - code coverage report
Current view: top level - util - strutil.h (source / functions) Hit Total Coverage
Test: report.info Lines: 14 18 77.8 %
Date: 2012-05-15 Functions: 6 9 66.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 26 52 50.0 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2011  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 __STRUTIL_H
      16                 :            : #define __STRUTIL_H
      17                 :            : 
      18                 :            : #include <algorithm>
      19                 :            : #include <cctype>
      20                 :            : #include <string>
      21                 :            : #include <sstream>
      22                 :            : #include <vector>
      23                 :            : #include <exceptions/exceptions.h>
      24                 :            : #include <boost/lexical_cast.hpp>
      25                 :            : 
      26                 :            : namespace isc {
      27                 :            : namespace util {
      28                 :            : namespace str {
      29                 :            : 
      30                 :            : /// \brief A Set of C++ Utilities for Manipulating Strings
      31                 :            : 
      32                 :            : ///
      33                 :            : /// \brief A standard string util exception that is thrown if getToken or
      34                 :            : /// numToToken are called with bad input data
      35                 :            : ///
      36                 :         34 : class StringTokenError : public Exception {
      37                 :            : public:
      38                 :         12 :     StringTokenError(const char* file, size_t line, const char* what) :
      39 [ +  - ][ -  + ]:         37 :         isc::Exception(file, line, what) {}
         [ +  - ][ #  # ]
      40                 :            : };
      41                 :            : 
      42                 :            : /// \brief Normalize Backslash
      43                 :            : ///
      44                 :            : /// Only relevant to Windows, this replaces all "\" in a string with "/" and
      45                 :            : /// returns the result.  On other systems it is a no-op.  Note that Windows does
      46                 :            : /// recognise file names with the "\" replaced by "/" (at least in system calls,
      47                 :            : /// if not the command line).
      48                 :            : ///
      49                 :            : /// \param name Name to be substituted
      50                 :            : void normalizeSlash(std::string& name);
      51                 :            : 
      52                 :            : 
      53                 :            : /// \brief Trim Leading and Trailing Spaces
      54                 :            : ///
      55                 :            : /// Returns a copy of the input string but with any leading or trailing spaces
      56                 :            : /// or tabs removed.
      57                 :            : ///
      58                 :            : /// \param instring Input string to modify
      59                 :            : ///
      60                 :            : /// \return String with leading and trailing spaces removed
      61                 :            : std::string trim(const std::string& instring);
      62                 :            : 
      63                 :            : 
      64                 :            : /// \brief Split String into Tokens
      65                 :            : ///
      66                 :            : /// Splits a string into tokens (the tokens being delimited by one or more of
      67                 :            : /// the delimiter characters) and returns the tokens in a vector array. Note
      68                 :            : /// that adjacent delimiters are considered to be a single delimiter.
      69                 :            : ///
      70                 :            : /// Special cases are:
      71                 :            : /// -# The empty string is considered to be zero tokens.
      72                 :            : /// -# A string comprising nothing but delimiters is considered to be zero
      73                 :            : ///    tokens.
      74                 :            : ///
      75                 :            : /// The reasoning behind this is that the string can be thought of as having
      76                 :            : /// invisible leading and trailing delimiter characters.  Therefore both cases
      77                 :            : /// reduce to a set of contiguous delimiters, which are considered a single
      78                 :            : /// delimiter (so getting rid of the string).
      79                 :            : ///
      80                 :            : /// We could use Boost for this, but this (simple) function eliminates one
      81                 :            : /// dependency in the code.
      82                 :            : ///
      83                 :            : /// \param text String to be split.  Passed by value as the internal copy is
      84                 :            : /// altered during the processing.
      85                 :            : /// \param delim Delimiter characters
      86                 :            : ///
      87                 :            : /// \return Vector of tokens.
      88                 :            : std::vector<std::string> tokens(const std::string& text,
      89                 :            :         const std::string& delim = std::string(" \t\n"));
      90                 :            : 
      91                 :            : 
      92                 :            : /// \brief Uppercase Character
      93                 :            : ///
      94                 :            : /// Used in uppercase() to pass as an argument to std::transform().  The
      95                 :            : /// function std::toupper() can't be used as it takes an "int" as its argument;
      96                 :            : /// this confuses the template expansion mechanism because dereferencing a
      97                 :            : /// string::iterator returns a char.
      98                 :            : ///
      99                 :            : /// \param chr Character to be upper-cased.
     100                 :            : ///
     101                 :            : /// \return Uppercase version of the argument
     102                 :          0 : inline char toUpper(char chr) {
     103                 :          0 :     return (static_cast<char>(std::toupper(static_cast<int>(chr))));
     104                 :            : }
     105                 :            : 
     106                 :            : 
     107                 :            : /// \brief Uppercase String
     108                 :            : ///
     109                 :            : /// A convenience function to uppercase a string.
     110                 :            : ///
     111                 :            : /// \param text String to be upper-cased.
     112                 :         31 : inline void uppercase(std::string& text) {
     113                 :            :     std::transform(text.begin(), text.end(), text.begin(),
     114         [ +  - ]:         43 :         isc::util::str::toUpper);
     115                 :         31 : }
     116                 :            : 
     117                 :            : /// \brief Lowercase Character
     118                 :            : ///
     119                 :            : /// Used in lowercase() to pass as an argument to std::transform().  The
     120                 :            : /// function std::tolower() can't be used as it takes an "int" as its argument;
     121                 :            : /// this confuses the template expansion mechanism because dereferencing a
     122                 :            : /// string::iterator returns a char.
     123                 :            : ///
     124                 :            : /// \param chr Character to be lower-cased.
     125                 :            : ///
     126                 :            : /// \return Lowercase version of the argument
     127                 :          0 : inline char toLower(char chr) {
     128                 :          0 :     return (static_cast<char>(std::tolower(static_cast<int>(chr))));
     129                 :            : }
     130                 :            : 
     131                 :            : /// \brief Lowercase String
     132                 :            : ///
     133                 :            : /// A convenience function to lowercase a string
     134                 :            : ///
     135                 :            : /// \param text String to be lower-cased.
     136                 :            : inline void lowercase(std::string& text) {
     137                 :            :     std::transform(text.begin(), text.end(), text.begin(),
     138         [ +  - ]:          1 :         isc::util::str::toLower);
     139                 :            : }
     140                 :            : 
     141                 :            : 
     142                 :            : /// \brief Apply Formatting
     143                 :            : ///
     144                 :            : /// Given a printf-style format string containing only "%s" place holders
     145                 :            : /// (others are ignored) and a vector of strings, this produces a single string
     146                 :            : /// with the placeholders replaced.
     147                 :            : ///
     148                 :            : /// \param format Format string
     149                 :            : /// \param args Vector of argument strings
     150                 :            : ///
     151                 :            : /// \return Resultant string
     152                 :            : std::string format(const std::string& format,
     153                 :            :     const std::vector<std::string>& args);
     154                 :            : 
     155                 :            : 
     156                 :            : /// \brief Returns one token from the given stringstream
     157                 :            : ///
     158                 :            : /// Using the >> operator, with basic error checking
     159                 :            : ///
     160                 :            : /// \exception StringTokenError if the token cannot be read from the stream
     161                 :            : ///
     162                 :            : /// \param iss stringstream to read one token from
     163                 :            : ///
     164                 :            : /// \return the first token read from the stringstream
     165                 :            : std::string getToken(std::istringstream& iss);
     166                 :            : 
     167                 :            : /// \brief Converts a string token to an *unsigned* integer.
     168                 :            : ///
     169                 :            : /// The value is converted using a lexical cast, with error and bounds
     170                 :            : /// checking.
     171                 :            : ///
     172                 :            : /// NumType is a *signed* integral type (e.g. int32_t) that is sufficiently
     173                 :            : /// wide to store resulting integers.
     174                 :            : ///
     175                 :            : /// BitSize is the maximum number of bits that the resulting integer can take.
     176                 :            : /// This function first checks whether the given token can be converted to
     177                 :            : /// an integer of NumType type.  It then confirms the conversion result is
     178                 :            : /// within the valid range, i.e., [0, 2^BitSize - 1].  The second check is
     179                 :            : /// necessary because lexical_cast<T> where T is an unsigned integer type
     180                 :            : /// doesn't correctly reject negative numbers when compiled with SunStudio.
     181                 :            : ///
     182                 :            : /// \exception StringTokenError if the value is out of range, or if it
     183                 :            : ///            could not be converted
     184                 :            : ///
     185                 :            : /// \param num_token the string token to convert
     186                 :            : ///
     187                 :            : /// \return the converted value, of type NumType
     188                 :            : template <typename NumType, int BitSize>
     189                 :            : NumType
     190                 :        490 : tokenToNum(const std::string& num_token) {
     191                 :            :     NumType num;
     192                 :            :     try {
     193                 :        472 :         num = boost::lexical_cast<NumType>(num_token);
     194 [ -  + ][ -  + ]:         36 :     } catch (const boost::bad_lexical_cast&) {
     195 [ -  + ][ -  + ]:         36 :         isc_throw(StringTokenError, "Invalid SRV numeric parameter: " <<
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
                 [ #  # ]
     196                 :            :                   num_token);
     197                 :            :     }
     198 [ +  + ][ +  + ]:        472 :     if (num < 0 || num >= (static_cast<NumType>(1) << BitSize)) {
     199 [ +  - ][ +  - ]:         28 :         isc_throw(StringTokenError, "Numeric SRV parameter out of range: " <<
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     200                 :            :                   num);
     201                 :            :     }
     202                 :        459 :     return (num);
     203                 :            : }
     204                 :            : 
     205                 :            : } // namespace str
     206                 :            : } // namespace util
     207                 :            : } // namespace isc
     208                 :            : 
     209                 :            : #endif // __STRUTIL_H

Generated by: LCOV version 1.9